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

Subsystems: the rest

DORMANTno replies

2 messages, 2 authors, 2016-06-15 · open the first message on its own page

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

From: David Steven Tweed <hidden>
Date: 2016-06-15 22:44:11

Write errors when repacking (eg, due to out-of-space conditions)
can leave temporary packs (and possibly other files beginning
with "tmp_") lying around which no existing
codepath removes and which aren't obvious to the casual user.
These can also be multi-megabyte files wasting noticeable space.
Unfortunately there's no way to definitely tell in builtin-prune
that a tmp_ file is not being used by a concurrent process.
However, it is documented that pruning should only be done
on a quiet repository and --expire is honoured (using code
from Johannes Schindelin). The names of removed files are printed.

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

This version incorporates all the agreed with changes from the
previous version, and since I was modifying the relevant
context lines it includes Johannes' code honouring --expire
(but not the test he wrote which is presumably best sent as a separate 
patch from him).

Hopefully this one won't get whitespace munged.

 builtin-prune.c |   39 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)
diff --git a/builtin-prune.c b/builtin-prune.c
index b5e7684..f25ddb6 100644
--- a/builtin-prune.c
+++ b/builtin-prune.c
@@ -83,6 +83,44 @@ static void prune_object_dir(const char *path)
 	}
 }

+/*
+ * Write errors (particularly out of space) can result in
+ * failed temporary packs (and more rarely indexes and other
+ * files begining with "tmp_") accumulating in the
+ * object directory.
+ */
+static void remove_temporary_files(void)
+{
+	DIR *dir;
+	struct dirent *de;
+	char* dirname=get_object_directory();
+
+	dir = opendir(dirname);
+	if (!dir) {
+		fprintf(stderr, "Unable to open object directory %s\n",
+			dirname);
+		return;
+	}
+	while ((de = readdir(dir)) != NULL) {
+		if (!prefixcmp(de->d_name, "tmp_")) {
+			char name[PATH_MAX];
+			int c = snprintf(name, PATH_MAX, "%s/%s",
+					 dirname, de->d_name);
+			if (c < 0 || c >= PATH_MAX)
+				continue;
+			if (expire) {
+				struct stat st;
+				if (stat(name, &st) != 0 || st.st_mtime >= expire)
+					continue;
+			}
+			printf("Removing stale temporary file %s\n", name);
+			if (!show_only)
+				unlink(name);
+		}
+	}
+	closedir(dir);
+}
+
 int cmd_prune(int argc, const char **argv, const char *prefix)
 {
 	int i;
@@ -115,5 +153,6 @@ int cmd_prune(int argc, const char **argv, const char *prefix)

 	sync();
 	prune_packed_objects(show_only);
+	remove_temporary_files();
 	return 0;
 }

Re: [PATCH v2] Make git prune remove temporary packs that look like write failures

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:44:11

Hi,

On Wed, 6 Feb 2008, David Steven Tweed wrote:
This version incorporates all the agreed with changes from the previous 
version, and since I was modifying the relevant context lines it 
includes Johannes' code honouring --expire (but not the test he wrote 
which is presumably best sent as a separate patch from him).
No, I don't want the tests as a separate patch.  They are intrinsic to 
your patch, since they show that your patch does what it's supposed to do 
(at least in an empirical way).

Ciao,
Dscho
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help