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

Re: git filter-branch doesn't dereference annotated tags

From
Grégory Pakosz <gpakosz@visionobjects.com>
Date
Jan 2, 2013, 22:03 UTC
Message-ID
<CAC_01E2iHgNvh5PnBh3TcNKr2pLazZwRojVK9ksaE3x0a1QHmQ@mail.gmail.com>
In-Reply-To
<7vk3rwaa3r.fsf@alter.siamese.dyndns.org>
Show 30 quoted lines
> I was wondering if it should be
>
>         sha1=$(git rev-parse --verify "$ref")
>
> or something that does not dereference a tag at all.
>
> The way I read what that loop seems to want to do is:
>
>         Read each refname that was given originally from the file
>         $tempdir/heads, find out the object it used to refer to and
>         have it in $sha1, find out what new object the object was
>         rewritten to and have it in $rewritten, and:
>
>         (1) if the rewrite left the object unchanged, do nothing but
>             warn users just in case this was a mistake;
>         (2) if the rewrite told us to remove it, then delete the
>             ref; or
>         (3) if the rewrite gave us a new object, replace the ref to
>             point to that new one.
>
>         And in the latter two cases, save the original one in
>         $orig_namespace so that the user can choose to recover if
>         this filter-branch was done by mistake.
>
> So I do not think unwraping the ref at that point makes any sense,
> unless it is not prepared to handle annotated tags at all by
> unwrapping tags too early.
>
> What am I missing?
>

So we have an annotated tag that points to a commit that is rewritten to nothing as the result of the filtering. What should happen?

My initial questions and patching suggestions are based on git
1.7.10.4 behavior.
However, playing with git HEAD exhibits a slightly different behavior:
it breaks when invoking git mktag line 459 (introduced by
1bf6551e42c79a594689a356a9b14759d55f3cf5):
  error: char7: could not get SHA1 hash
  fatal: invalid tag signature file
  Could not create new tag object for tag-a

It's basically the same problem. In my opinion, lines 447-466 should take into account $new_sha1 is empty.

Please forgive me again for not having configured my mailer yet :( When I'm ready to provide a patch that implements a solution we all agree with I'll use git send-email. In the mean time, I would like to pursue the discussion in this mail thread so please find attached a patch that deletes a tag instead of invoking the tag-name-filter when it detects $new_sha1 is empty.

I tested the patch doesn't break t7003. What do you think?
Gregory
From 2cb9d5bc605cc2f2d8a6603b6a06657516959aa6 Mon Sep 17 00:00:00 2001
From: Gregory Pakosz <gpakosz@visionobjects.com>
Date: Wed, 2 Jan 2013 23:02:03 +0100
Subject: [PATCH] git-filter-branch: allow deletion of tags when referenced
 commit gets rewritten to nothing
---
 git-filter-branch.sh | 61 ++++++++++++++++++++++++++++------------------------
 1 file changed, 33 insertions(+), 28 deletions(-)
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index 5314249..2e8569c 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -436,36 +436,41 @@ if [ "$filter_tag_name" ]; then
 
 		[ -f "../map/$sha1" ] || continue
 		new_sha1="$(cat "../map/$sha1")"
-		GIT_COMMIT="$sha1"
-		export GIT_COMMIT
-		new_ref="$(echo "$ref" | eval "$filter_tag_name")" ||
-			die "tag name filter failed: $filter_tag_name"
-
-		echo "$ref -> $new_ref ($sha1 -> $new_sha1)"
-
-		if [ "$type" = "tag" ]; then
-			new_sha1=$( ( printf 'object %s\ntype commit\ntag %s\n' \
-						"$new_sha1" "$new_ref"
-				git cat-file tag "$ref" |
-				sed -n \
-				    -e '1,/^$/{
-					  /^object /d
-					  /^type /d
-					  /^tag /d
-					}' \
-				    -e '/^-----BEGIN PGP SIGNATURE-----/q' \
-				    -e 'p' ) |
-				git mktag) ||
-				die "Could not create new tag object for $ref"
-			if git cat-file tag "$ref" | \
-			   sane_grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1
-			then
-				warn "gpg signature stripped from tag object $sha1t"
+		if [ -n "$new_sha1" ]; then
+			GIT_COMMIT="$sha1"
+			export GIT_COMMIT
+			new_ref="$(echo "$ref" | eval "$filter_tag_name")" ||
+				die "tag name filter failed: $filter_tag_name"
+
+			echo "$ref -> $new_ref ($sha1 -> $new_sha1)"
+
+			if [ "$type" = "tag" ]; then
+				new_sha1=$( ( printf 'object %s\ntype commit\ntag %s\n' \
+							"$new_sha1" "$new_ref"
+					git cat-file tag "$ref" |
+					sed -n \
+							-e '1,/^$/{
+							/^object /d
+							/^type /d
+							/^tag /d
+						}' \
+							-e '/^-----BEGIN PGP SIGNATURE-----/q' \
+							-e 'p' ) |
+					git mktag) ||
+					die "Could not create new tag object for $ref"
+				if git cat-file tag "$ref" | \
+					sane_grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1
+				then
+					warn "gpg signature stripped from tag object $sha1t"
+				fi
 			fi
-		fi
 
-		git update-ref "refs/tags/$new_ref" "$new_sha1" ||
-			die "Could not write tag $new_ref"
+			git update-ref "refs/tags/$new_ref" "$new_sha1" ||
+				die "Could not write tag $new_ref"
+		else
+			git update-ref -d "refs/tags/$ref" "$sha1t" ||
+				die "Could not delete tag $ref"
+		fi
 	done
 fi
 
-- 
1.8.0.1
Previous: Junio C HamanoNext: Junio C Hamano
Message 7 of 13 in “git filter-branch doesn't dereference annotated tags”
  1. Grégory PakoszDec 31, 2012
  2. Junio C HamanoDec 31, 2012
  3. Grégory PakoszJan 1, 2013
  4. Junio C HamanoJan 1, 2013
  5. Grégory PakoszJan 1, 2013
  6. Junio C HamanoJan 1, 2013
  7. Grégory PakoszJan 2, 2013
  8. Junio C HamanoJan 2, 2013
  9. Johannes SixtJan 3, 2013
  10. Grégory PakoszJan 3, 2013
  11. Johannes SixtJan 3, 2013
  12. Brandon CaseyJan 3, 2013
  13. Johannes SixtJan 1, 2013

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.