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.
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"
'
-------------------------------------------------------
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"
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" ||
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
'
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
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