]> arthur.barton.de Git - bup.git/commitdiff
save-cmd.py: don't crash when a path disappears between index and save.
authorDamien Robert <damien.olivier.robert@gmail.com>
Tue, 20 Nov 2012 20:52:45 +0000 (21:52 +0100)
committerRob Browning <rlb@defaultvalue.org>
Mon, 25 Mar 2013 00:24:54 +0000 (19:24 -0500)
Protect calls to metadata.from_path() with a try/catch and defer
errors via add_error() instead of just crashing.

Signed-off-by: Damien Robert <damien.olivier.robert@gmail.com>
[git@tim-riemenschneider.de: rebase to current tmp/pending/meta: since
 metadata is (now) stored in the index, only 1 of 2 hunks still
 applies (race condition between reading the file for its content and
 stat-ing it for metadata).]
[rlb@defaultvalue.org: edit commit message; squash file and dir
 removal fixes into this commit; limit the scope of the try/catch to
 the from_path() call, and put the remaining code in an else clause.]
Signed-off-by: Rob Browning <rlb@defaultvalue.org>
cmd/save-cmd.py

index 3f1649a5e74c87f875f96c91d4bbff76439554f2..66d56e2449a45a4db61a378d77fce694caa0ef8c 100755 (executable)
@@ -296,8 +296,13 @@ for (transname,ent) in r.filter(extra, wantrecurse=wantrecurse_during):
         dir_name, fs_path = dirp[0]
         first_root = dirp[0]
         # Not indexed, so just grab the FS metadata or use empty metadata.
-        meta = metadata.from_path(fs_path) if fs_path else metadata.Metadata()
-        _push(dir_name, meta)
+        try:
+           meta = metadata.from_path(fs_path) if fs_path else metadata.Metadata()
+        except (OSError, IOError), e:
+            add_error(e)
+            lastskip_name = dir_name
+        else:
+           _push(dir_name, meta)
     elif first_root != dirp[0]:
         root_collision = True
 
@@ -309,8 +314,13 @@ for (transname,ent) in r.filter(extra, wantrecurse=wantrecurse_during):
     for path_component in dirp[len(parts):]:
         dir_name, fs_path = path_component
         # Not indexed, so just grab the FS metadata or use empty metadata.
-        meta = metadata.from_path(fs_path) if fs_path else metadata.Metadata()
-        _push(dir_name, meta)
+        try:
+           meta = metadata.from_path(fs_path) if fs_path else metadata.Metadata()
+        except (OSError, IOError), e:
+            add_error(e)
+            lastskip_name = dir_name
+        else:
+           _push(dir_name, meta)
 
     if not file:
         if len(parts) == 1:
@@ -381,9 +391,14 @@ for (transname,ent) in r.filter(extra, wantrecurse=wantrecurse_during):
             shalists[-1].append(git_info)
             sort_key = git.shalist_item_sort_key((ent.mode, file, id))
             hlink = find_hardlink_target(hlink_db, ent)
-            metalists[-1].append((sort_key,
-                                  metadata.from_path(ent.name,
-                                                     hardlink_target=hlink)))
+            try:
+                meta = metadata.from_path(ent.name, hardlink_target=hlink)
+            except (OSError, IOError), e:
+                add_error(e)
+                lastskip_name = ent.name
+            else:
+                metalists[-1].append((sort_key, meta))
+
     if exists and wasmissing:
         count += oldsize
         subcount = 0