]> arthur.barton.de Git - bup.git/blobdiff - cmd/save-cmd.py
get: convert opt.source to bytes
[bup.git] / cmd / save-cmd.py
index 306e3fd5c5994868efe3d8a9dec9d510506d4761..a6190b0a09623a6654d7e860b3a8405f5df33066 100755 (executable)
@@ -126,8 +126,11 @@ handle_ctrl_c()
 # Since the git tree elements are sorted according to
 # git.shalist_item_sort_key, the metalist items are accumulated as
 # (sort_key, metadata) tuples, and then sorted when the .bupm file is
-# created.  The sort_key must be computed using the element's real
-# name and mode rather than the git mode and (possibly mangled) name.
+# created.  The sort_key should have been computed using the element's
+# mangled name and git mode (after hashsplitting), but the code isn't
+# actually doing that but rather uses the element's real name and mode.
+# This makes things a bit more difficult when reading it back, see
+# vfs.ordered_tree_entries().
 
 # Maintain a stack of information representing the current location in
 # the archive being constructed.  The current path is recorded in
@@ -159,26 +162,31 @@ def _pop(force_tree, dir_metadata=None):
     else:
         names_seen = set()
         clean_list = []
+        metaidx = 1 # entry at 0 is for the dir
         for x in shalist:
             name = x[1]
             if name in names_seen:
                 parent_path = b'/'.join(parts) + b'/'
                 add_error('error: ignoring duplicate path %s in %s'
                           % (path_msg(name), path_msg(parent_path)))
+                if not stat.S_ISDIR(x[0]):
+                    del metalist[metaidx]
             else:
                 names_seen.add(name)
                 clean_list.append(x)
+                if not stat.S_ISDIR(x[0]):
+                    metaidx += 1
+
+        if dir_metadata: # Override the original metadata pushed for this dir.
+            metalist = [(b'', dir_metadata)] + metalist[1:]
+        sorted_metalist = sorted(metalist, key = lambda x : x[0])
+        metadata = b''.join([m[1].encode() for m in sorted_metalist])
+        metadata_f = BytesIO(metadata)
+        mode, id = hashsplit.split_to_blob_or_tree(w.new_blob, w.new_tree,
+                                                   [metadata_f],
+                                                   keep_boundaries=False)
+        clean_list.append((mode, b'.bupm', id))
 
-        if metalist:
-            if dir_metadata: # Override the original metadata pushed for this dir.
-                metalist = [(b'', dir_metadata)] + metalist[1:]
-            sorted_metalist = sorted(metalist, key = lambda x : x[0])
-            metadata = b''.join([m[1].encode() for m in sorted_metalist])
-            metadata_f = BytesIO(metadata)
-            mode, id = hashsplit.split_to_blob_or_tree(w.new_blob, w.new_tree,
-                                                       [metadata_f],
-                                                       keep_boundaries=False)
-            clean_list.append((mode, b'.bupm', id))
         tree = w.new_tree(clean_list)
     if shalists:
         shalists[-1].append((GIT_MODE_TREE,