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