summaryrefslogtreecommitdiff
path: root/builtin-prune.c
diff options
context:
space:
mode:
authorDavid Steven Tweed <d.s.tweed@reading.ac.uk>2008-02-07 02:55:14 (GMT)
committerJunio C Hamano <gitster@pobox.com>2008-02-11 20:22:58 (GMT)
commit8464010f974245b1e392d34ddbfb914fcf3d8c23 (patch)
tree420e72fb71c667be1e8518f71a7f81cd5951810e /builtin-prune.c
parent65ae89bc315753e7bb31e941e77e002003665bc0 (diff)
downloadgit-8464010f974245b1e392d34ddbfb914fcf3d8c23.zip
git-8464010f974245b1e392d34ddbfb914fcf3d8c23.tar.gz
git-8464010f974245b1e392d34ddbfb914fcf3d8c23.tar.bz2
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 (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, such as a fetch. However, it is documented that pruning should only be done on a quiet repository and --expire is honoured (using code from Johannes Schindelin, along with a test case he wrote) so that its safety is the same as that of loose object pruning. Since they might be signs of a problem (unlike orphaned loose objects) the names of any removed files are printed. Signed-off-by: David Tweed (david.tweed@gmail.com) Acked-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-prune.c')
-rw-r--r--builtin-prune.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/builtin-prune.c b/builtin-prune.c
index b5e7684..bb8ead9 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;
}