Repository: borgbackup/borg

Issue:
deal with canonicalisation change
From IRC:

```
lfam: Hm, I think the SSH relative path changes in 1.0.8rc1 trigger a relocated repository warning
ThomasWaldmann$ lfam: yes, it is due to a change of canonicalisation
ThomasWaldmann$ old: relpath -> /~/relpath, new: relpath -> /./relpath
lfam$ It breaks automation until the user confirms the new location. But it's okay if that's expected
ThomasWaldmann$ guess a better visible changelog entry is needed
```



Discussion:
Can we fix this so that it doesn't say that two actually identical paths are not identical?

. is relative and on the server, so only the server after connection is established knows what it is (outside influence via ssh forced command with "cd ..."). the warning comes from the client.

maybe a one-time "cache upgrade" can do it:
- the old code transformed both relative pathes and ~/... pathes to same /~/... canonicalisation - so they were treated as equivalent and we can't know what was what just from the cache later.
- but we also have the repo url on commandline


Resolving patch:
diff --git a/borg/cache.py b/borg/cache.py
--- a/borg/cache.py
+++ b/borg/cache.py
@@ -10,7 +10,7 @@
 from .logger import create_logger
 logger = create_logger()
 from .helpers import Error, get_cache_dir, decode_dict, int_to_bigint, \
-    bigint_to_int, format_file_size, yes, bin_to_hex
+    bigint_to_int, format_file_size, yes, bin_to_hex, Location
 from .locking import Lock
 from .hashindex import ChunkIndex
 
@@ -140,10 +140,7 @@ def create(self):
         with open(os.path.join(self.path, 'files'), 'wb') as fd:
             pass  # empty file
 
-    def _do_open(self):
-        self.config = configparser.ConfigParser(interpolation=None)
-        config_path = os.path.join(self.path, 'config')
-        self.config.read(config_path)
+    def _check_upgrade(self, config_path):
         try:
             cache_version = self.config.getint('cache', 'version')
             wanted_version = 1
@@ -154,6 +151,25 @@ def _do_open(self):
         except configparser.NoSectionError:
             self.close()
             raise Exception('%s does not look like a Borg cache.' % config_path) from None
+        # borg < 1.0.8rc1 had different canonicalization for the repo location (see #1655 and #1741).
+        cache_loc = self.config.get('cache', 'previous_location', fallback=None)
+        if cache_loc:
+            repo_loc = self.repository._location.canonical_path()
+            rl = Location(repo_loc)
+            cl = Location(cache_loc)
+            if cl.proto == rl.proto and cl.user == rl.user and cl.host == rl.host and cl.port == rl.port \
+                    and \
+                    cl.path and rl.path and \
+                    cl.path.startswith('/~/') and rl.path.startswith('/./') and cl.path[3:] == rl.path[3:]:
+                # everything is same except the expected change in relative path canonicalization,
+                # update previous_location to avoid warning / user query about changed location:
+                self.config.set('cache', 'previous_location', repo_loc)
+
+    def _do_open(self):
+        self.config = configparser.ConfigParser(interpolation=None)
+        config_path = os.path.join(self.path, 'config')
+        self.config.read(config_path)
+        self._check_upgrade(config_path)
         self.id = self.config.get('cache', 'repository')
         self.manifest_id = unhexlify(self.config.get('cache', 'manifest'))
         self.timestamp = self.config.get('cache', 'timestamp', fallback=None)


Test patch: