[RFC,PATCH] Make git prune remove temporary packs that look like write failures

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Make git prune remove temporary packs that look like write failures

Write errors when repacking (eg, due to out-of-space conditions)
can leave temporary packs lying around which no existing
codepath removes and  which aren't obvious to the casual user.
Unfortunately the only way to tell in builtin-prune that a tmp_pack file is
of this sort is that it hasn't been modified recently. We assume a pack
which hasn't been modified within 10 minutes is of this sort and
delete it, printing a notification to help debugging. (Nicolas Pitre
suggested this functionality should be activated only by --prune.)

Signed-off-by: David Tweed (david.tweed@xxxxxxxxx)
---

I KNOW this initial RFC is mailer whitespace damaged. Finally version won't be.

In principle this is a really trivial patch, but I'm being cautious because I
don't like the fact that I don't know (and AFAICS can't reliably check) that
the files being deleting are definitely dead. An alternative would
be to make prune just print out that the suspicious packs are
there and let the user delete them manually. (My itch is that once
a write-failure pack gets created, nothing in git operations tells the
user that a generally multimegabyte file hidden in .git occupying space.)

 builtin-prune.c |   34 ++++++++++++++++++++++++++++++++++
 1 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/builtin-prune.c b/builtin-prune.c
index b5e7684..90111ab 100644
--- a/builtin-prune.c
+++ b/builtin-prune.c
@@ -83,6 +83,39 @@ static void prune_object_dir(const char *path)
        }
 }

+/*
+ * Write errors (particularly out of space) can result in
+ * failed temporary packs accumulating in the object directory.
+ * This removes anything in the object directory beginning
+ * with tmp_ using the heuristic that anything
+ * that was last modified more than 10 minutes
+ * ago is the abandoned result of a write failure.
+ */
+static void remove_temporary_files(void)
+{
+       DIR *dir;
+       struct stat status;
+       time_t now;
+       struct dirent *de;
+       char* dirname=get_object_directory();
+
+       now = time(NULL);
+       dir = opendir(dirname);
+       while ((de = readdir(dir)) != NULL) {
+               if(strncmp(de->d_name, "tmp_", 4) == 0){
+                       char name[4096];
+                       int c=snprintf(name, 4095, "%s/%s", dirname,
de->d_name);
+                       if(c>0 && c<4096 && stat(name, &status) == 0
+                          && status.st_mtime < now - 600){
+                               printf("Removing apparently abandoned
%s\n",name);
+                               unlink(name);
+                       }
+               }
+       }
+       closedir(dir);
+}
+
+
 int cmd_prune(int argc, const char **argv, const char *prefix)
 {
        int i;
@@ -115,5 +148,6 @@ int cmd_prune(int argc, const char **argv, const
char *prefix)

        sync();
        prune_packed_objects(show_only);
+       remove_temporary_files();
        return 0;
 }
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux