Junio C Hamano wrote: > If you want to see if A is an ancestor of > any of B C D..., the standard and most efficient way to do so is > with rev-list. > > git rev-list A --not B C D... > > will show _nothing_ only when A is an ancestor of one (or more) > of B C D..., so you invoke it and upon getting the first line of > output you declare A cannot be removed without reading the > remainder of the output. Sure. I figured the commands I put would only use about 30MB for a 300,000 commit repository, so it wouldn't be too bad. But I didn't think of that. Here we go, also based upon 'next' rather than the result of my previous patches of the day. Subject: [PATCH] git-remote: implement prune -c It would be nice to be able to prune local refs which just point to some place in the remote; add an option to git-remote prune, with documentation. Signed-off-by: Sam Vilain <sam.vilain@xxxxxxxxxxxxxxx> --- Documentation/git-remote.txt | 5 +++++ git-remote.perl | 25 +++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt index f96b304..6a28e6c 100644 --- a/Documentation/git-remote.txt +++ b/Documentation/git-remote.txt @@ -54,6 +54,11 @@ Gives some information about the remote <name>. Deletes all stale tracking branches under <name>. These stale branches have already been removed from the remote repository referenced by <name>, but are still locally available in "remotes/<name>". ++ +With `-c` option, all *local* branches that exist in the history of +any of the mirrored heads from the remote are removed. This is useful +for discarding temporary local branches that you did not make any +commits to. DISCUSSION diff --git a/git-remote.perl b/git-remote.perl index 670bafb..84ac534 100755 --- a/git-remote.perl +++ b/git-remote.perl @@ -210,7 +210,7 @@ sub show_mapping { } sub prune_remote { - my ($name, $ls_remote) = @_; + my ($name, $ls_remote, $clean_local) = @_; if (!exists $remote->{$name}) { print STDERR "No such remote $name\n"; return; @@ -224,6 +224,24 @@ sub prune_remote { my @v = $git->command(qw(rev-parse --verify), "$prefix/$to_prune"); $git->command(qw(update-ref -d), "$prefix/$to_prune", $v[0]); } + if ( $clean_local ) { + my @remote = map { (split " ")[0] } + $git->command(qw(for-each-ref), $prefix); + my %local = map { (split " ")[2,0] } + $git->command(qw(for-each-ref refs/heads)); + my %not_remote = map { ($_ => undef) } + $git->command("rev-list", keys %local, "--not", @remote); + # don't delete the current branch + my ($checked_out) = $git->command(qw(symbolic-ref HEAD)); + + while ( my ($ref, $rev) = each %local ) { + next if $checked_out and $ref eq $checked_out; + if ( not exists $not_remote{$rev} ) { + print "$ref is obsolete\n"; + $git->command(qw(update-ref -d), $ref, $rev); + } + } + } } sub show_remote { @@ -310,6 +328,9 @@ elsif ($ARGV[0] eq 'prune') { if ($ARGV[$i] eq '-n') { $ls_remote = 0; } + elsif ($ARGV[$i] eq '-c') { + $clean_local = 1; + } else { last; } @@ -319,7 +340,7 @@ elsif ($ARGV[0] eq 'prune') { exit(1); } for (; $i < @ARGV; $i++) { - prune_remote($ARGV[$i], $ls_remote); + prune_remote($ARGV[$i], $ls_remote, $clean_local); } } elsif ($ARGV[0] eq 'add') { -- 1.5.0.2.214.gb318 - 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