Merge branch 'bc/filter-branch'
authorJunio C Hamano <gitster@pobox.com>
Tue, 6 May 2008 02:16:20 +0000 (19:16 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 6 May 2008 02:16:20 +0000 (19:16 -0700)
* bc/filter-branch:
filter-branch.sh: support nearly proper tag name filtering

1  2 
Documentation/git-filter-branch.txt
git-filter-branch.sh
t/t7003-filter-branch.sh
index 6454e49bf2805fcf0a000ed6f96ff9f73d718299,9d11b418bb951d945e3c89dfef5c67ed7197287c..8d80f0d074c92fccc2a9746c5f374c1626fdde97
@@@ -133,10 -133,16 +133,16 @@@ use "--tag-name-filter cat" to simply u
  case, be very careful and make sure you have the old tags
  backed up in case the conversion has run afoul.
  +
- Note that there is currently no support for proper rewriting of
- tag objects; in layman terms, if the tag has a message or signature
- attached, the rewritten tag won't have it.  Sorry.  (It is by
- definition impossible to preserve signatures at any rate.)
+ Nearly proper rewriting of tag objects is supported. If the tag has
+ a message attached, a new tag object will be created with the same message,
+ author, and timestamp. If the tag has a signature attached, the
+ signature will be stripped. It is by definition impossible to preserve
+ signatures. The reason this is "nearly" proper, is because ideally if
+ the tag did not change (points to the same object, has the same name, etc.)
+ it should retain any signature. That is not the case, signatures will always
+ be removed, buyer beware. There is also no support for changing the
+ author or timestamp (or the tag message for that matter). Tags which point
+ to other tags will be rewritten to point to the underlying commit.
  
  --subdirectory-filter <directory>::
        Only look at the history which touches the given subdirectory.
@@@ -243,12 -249,12 +249,12 @@@ committed a merge between P1 and P2, i
  and all children of the merge will become merge commits with P1,P2
  as their parents instead of the merge commit.
  
 -You can rewrite the commit log messages using `--message-filter`.  For
 +You can rewrite the commit log messages using `--msg-filter`.  For
  example, `git-svn-id` strings in a repository created by `git-svn` can
  be removed this way:
  
  -------------------------------------------------------
 -git filter-branch --message-filter '
 +git filter-branch --msg-filter '
        sed -e "/^git-svn-id:/d"
  '
  -------------------------------------------------------
diff --combined git-filter-branch.sh
index ea59015baa2507fdc8fe77d1c77ebdb2d5db2fa7,ee906606c410fd1e367007ac1b9a3a90cca52aee..333f6a8f3b783d46a0ce3b2f59bae152936cd11c
@@@ -281,7 -281,7 +281,7 @@@ while read commit parents; d
                        die "Could not checkout the index"
                # files that $commit removed are now still in the working tree;
                # remove them, else they would be added again
 -              git clean -q -f -x
 +              git clean -d -q -f -x
                eval "$filter_tree" < /dev/null ||
                        die "tree filter failed: $filter_tree"
  
@@@ -406,8 -406,22 +406,22 @@@ if [ "$filter_tag_name" ]; the
                echo "$ref -> $new_ref ($sha1 -> $new_sha1)"
  
                if [ "$type" = "tag" ]; then
-                       # Warn that we are not rewriting the tag object itself.
-                       warn "unreferencing tag object $sha1t"
+                       new_sha1=$(git cat-file tag "$ref" |
+                               sed -n \
+                                   -e "1,/^$/{
+                                         s/^object .*/object $new_sha1/
+                                         s/^type .*/type commit/
+                                         s/^tag .*/tag $new_ref/
+                                       }" \
+                                   -e '/^-----BEGIN PGP SIGNATURE-----/q' \
+                                   -e 'p' |
+                               git mktag) ||
+                               die "Could not create new tag object for $ref"
+                       if git cat-file tag "$ref" | \
+                          grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1
+                       then
+                               warn "gpg signature stripped from tag object $sha1t"
+                       fi
                fi
  
                git update-ref "refs/tags/$new_ref" "$new_sha1" ||
diff --combined t/t7003-filter-branch.sh
index efd658adb6d6327863f430b10ab65aa3f112f996,1daaf544d9ad1f3eafce024b92cf0640c4dee766..16df3d4adb1cc6bc970dd79829adbc46492bc66c
@@@ -17,8 -17,6 +17,8 @@@ test_expect_success 'setup' 
        make_commit B
        git checkout -b branch B
        make_commit D
 +      mkdir dir
 +      make_commit dir/D
        make_commit E
        git checkout master
        make_commit C
@@@ -43,23 -41,9 +43,23 @@@ test_expect_success 'rewrite, renaming 
  '
  
  test_expect_success 'test that the file was renamed' '
 -      test d = $(git show HEAD:doh) &&
 +      test d = "$(git show HEAD:doh --)" &&
 +      ! test -f d &&
        test -f doh &&
 -      test d = $(cat doh)
 +      test d = "$(cat doh)"
 +'
 +
 +test_expect_success 'rewrite, renaming a specific directory' '
 +      git-filter-branch -f --tree-filter "mv dir diroh || :" HEAD
 +'
 +
 +test_expect_success 'test that the directory was renamed' '
 +      test dir/d = "$(git show HEAD:diroh/d --)" &&
 +      ! test -d dir &&
 +      test -d diroh &&
 +      ! test -d diroh/dir &&
 +      test -f diroh/d &&
 +      test dir/d = "$(cat diroh/d)"
  '
  
  git tag oldD HEAD~4
@@@ -219,4 -203,36 +219,36 @@@ test_expect_success 'Subdirectory filte
        test $(git rev-list master | wc -l) = 3
  '
  
+ test_expect_success 'Tag name filtering retains tag message' '
+       git tag -m atag T &&
+       git cat-file tag T > expect &&
+       git filter-branch -f --tag-name-filter cat &&
+       git cat-file tag T > actual &&
+       git diff expect actual
+ '
+ faux_gpg_tag='object XXXXXX
+ type commit
+ tag S
+ tagger T A Gger <tagger@example.com> 1206026339 -0500
+ This is a faux gpg signed tag.
+ -----BEGIN PGP SIGNATURE-----
+ Version: FauxGPG v0.0.0 (FAUX/Linux)
+ gdsfoewhxu/6l06f1kxyxhKdZkrcbaiOMtkJUA9ITAc1mlamh0ooasxkH1XwMbYQ
+ acmwXaWET20H0GeAGP+7vow=
+ =agpO
+ -----END PGP SIGNATURE-----
+ '
+ test_expect_success 'Tag name filtering strips gpg signature' '
+       sha1=$(git rev-parse HEAD) &&
+       sha1t=$(echo "$faux_gpg_tag" | sed -e s/XXXXXX/$sha1/ | git mktag) &&
+       git update-ref "refs/tags/S" "$sha1t" &&
+       echo "$faux_gpg_tag" | sed -e s/XXXXXX/$sha1/ | head -n 6 > expect &&
+       git filter-branch -f --tag-name-filter cat &&
+       git cat-file tag S > actual &&
+       git diff expect actual
+ '
  test_done