Skip to content

Commit

Permalink
Add "--expire <time>" option to 'git prune'
Browse files Browse the repository at this point in the history
Earlier, 'git prune' would prune all loose unreachable objects.
This could be quite dangerous, as the objects could be used in
an ongoing operation.

This patch adds a mode to expire only loose, unreachable objects
which are older than a certain time.  For example, by

	git prune --expire 14.days

you can prune only those objects which are loose, unreachable
and older than 14 days (and thus probably outdated).

The implementation uses st.st_mtime rather than st.st_ctime,
because it can be tested better, using 'touch -d <time>' (and
omitting the test when the platform does not support that
command line switch).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Johannes Schindelin authored and Junio C Hamano committed Nov 30, 2007
1 parent 28391a8 commit f01913e
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
5 changes: 4 additions & 1 deletion Documentation/git-prune.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ git-prune - Prune all unreachable objects from the object database

SYNOPSIS
--------
'git-prune' [-n] [--] [<head>...]
'git-prune' [-n] [--expire <expire>] [--] [<head>...]

DESCRIPTION
-----------
Expand All @@ -31,6 +31,9 @@ OPTIONS
\--::
Do not interpret any more arguments as options.

\--expire <time>::
Only expire loose objects older than <time>.

<head>...::
In addition to objects
reachable from any of our references, keep objects
Expand Down
21 changes: 20 additions & 1 deletion builtin-prune.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,24 @@

static const char prune_usage[] = "git-prune [-n]";
static int show_only;
static unsigned long expire;

static int prune_object(char *path, const char *filename, const unsigned char *sha1)
{
const char *fullpath = mkpath("%s/%s", path, filename);
if (expire) {
struct stat st;
if (lstat(fullpath, &st))
return error("Could not stat '%s'", fullpath);
if (st.st_mtime > expire)
return 0;
}
if (show_only) {
enum object_type type = sha1_object_info(sha1, NULL);
printf("%s %s\n", sha1_to_hex(sha1),
(type > 0) ? typename(type) : "unknown");
} else
unlink(mkpath("%s/%s", path, filename));
unlink(fullpath);
return 0;
}

Expand Down Expand Up @@ -85,6 +94,16 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
show_only = 1;
continue;
}
if (!strcmp(arg, "--expire")) {
if (++i < argc) {
expire = approxidate(argv[i]);
continue;
}
}
else if (!prefixcmp(arg, "--expire=")) {
expire = approxidate(arg + 9);
continue;
}
usage(prune_usage);
}

Expand Down
18 changes: 18 additions & 0 deletions t/t1410-reflog.sh
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,22 @@ test_expect_success 'recover and check' '
'

test_expect_success 'prune --expire' '
before=$(git count-objects | sed "s/ .*//") &&
BLOB=$(echo aleph | git hash-object -w --stdin) &&
BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") &&
test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
test -f $BLOB_FILE &&
git reset --hard &&
git prune --expire=1.hour.ago &&
test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
test -f $BLOB_FILE &&
test-chmtime -86500 $BLOB_FILE &&
git prune --expire 1.day &&
test $before = $(git count-objects | sed "s/ .*//") &&
! test -f $BLOB_FILE
'

test_done

0 comments on commit f01913e

Please sign in to comment.