git/list[1] front-page[2] threads[3] people[4] search[5] about
 

(unknown)

From
Sam Vilain <sam.vilain@catalyst.net.nz>
Date
Mar 19, 2007, 23:37 UTC
Message-ID
<20070319234722.CF1FF13A382@magnus.utsl.gen.nz>
In-Reply-To
<7v4pohka7g.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano wrote:
Show 10 quoted lines
> 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@catalyst.net.nz>
---
 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
Previous: Junio C Hamano
Message 8 of 8 in “[wishlist] git branch -d -r remotename”
  1. Sam VilainMar 18, 2007
  2. Sam VilainMar 18, 2007
  3. Sam VilainMar 18, 2007
  4. Junio C HamanoMar 18, 2007
  5. Sam VilainMar 18, 2007
  6. Junio C HamanoMar 19, 2007
  7. Junio C HamanoMar 19, 2007
  8. (unknown)Sam Vilain, Mar 19, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.