filter-branch.sh: support nearly proper tag name filtering
Add support for creating a new tag object and retaining the tag message, author, and date when rewriting tags. The gpg signature, if one exists, will be stripped. This adds nearly proper tag name filtering to filter-branch. Proper tag name filtering would include the ability to change the tagger, tag date, tag message, and _not_ strip a gpg signature if the tag did not change. Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Brandon Casey committed
Mar 26, 2008 at 10:47 UTC
1bf6551e42c79a594689a356a9b14759d55f3cf5
3 files changed
+58
-6
Documentation/git-filter-branch.txt
+10
-4
@@ -133,10 +133,16 @@ use "--tag-name-filter cat" to simply update the tags. In this
133
case, be very careful and make sure you have the old tags
134
backed up in case the conversion has run afoul.
135
+
136
-Note that there is currently no support for proper rewriting of
137
-tag objects; in layman terms, if the tag has a message or signature
138
-attached, the rewritten tag won't have it. Sorry. (It is by
139
-definition impossible to preserve signatures at any rate.)
136
+Nearly proper rewriting of tag objects is supported. If the tag has
137
+a message attached, a new tag object will be created with the same message,
138
+author, and timestamp. If the tag has a signature attached, the
139
+signature will be stripped. It is by definition impossible to preserve
140
+signatures. The reason this is "nearly" proper, is because ideally if
141
+the tag did not change (points to the same object, has the same name, etc.)
142
+it should retain any signature. That is not the case, signatures will always
143
+be removed, buyer beware. There is also no support for changing the
144
+author or timestamp (or the tag message for that matter). Tags which point
145
+to other tags will be rewritten to point to the underlying commit.
146
147
--subdirectory-filter <directory>::
148
Only look at the history which touches the given subdirectory.
git-filter-branch.sh
+16
-2
@@ -406,8 +406,22 @@ if [ "$filter_tag_name" ]; then
406
echo "$ref -> $new_ref ($sha1 -> $new_sha1)"
407
408
if [ "$type" = "tag" ]; then
409
- # Warn that we are not rewriting the tag object itself.
410
- warn "unreferencing tag object $sha1t"
409
+ new_sha1=$(git cat-file tag "$ref" |
410
+ sed -n \
411
+ -e "1,/^$/{
412
+ s/^object .*/object $new_sha1/
413
+ s/^type .*/type commit/
414
+ s/^tag .*/tag $new_ref/
415
+ }" \
416
+ -e '/^-----BEGIN PGP SIGNATURE-----/q' \
417
+ -e 'p' |
418
+ git mktag) ||
419
+ die "Could not create new tag object for $ref"
420
+ if git cat-file tag "$ref" | \
421
+ grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1
422
+ then
423
+ warn "gpg signature stripped from tag object $sha1t"
424
+ fi
425
fi
426
427
git update-ref "refs/tags/$new_ref" "$new_sha1" ||
t/t7003-filter-branch.sh
+32
@@ -203,4 +203,36 @@ test_expect_success 'Subdirectory filter with disappearing trees' '
203
test $(git rev-list master | wc -l) = 3
204
'
205
206
+test_expect_success 'Tag name filtering retains tag message' '
207
+ git tag -m atag T &&
208
+ git cat-file tag T > expect &&
209
+ git filter-branch -f --tag-name-filter cat &&
210
+ git cat-file tag T > actual &&
211
+ git diff expect actual
212
+'
213
+
214
+faux_gpg_tag='object XXXXXX
215
+type commit
216
+tag S
217
+tagger T A Gger <tagger@example.com> 1206026339 -0500
218
+
219
+This is a faux gpg signed tag.
220
+-----BEGIN PGP SIGNATURE-----
221
+Version: FauxGPG v0.0.0 (FAUX/Linux)
222
+
223
+gdsfoewhxu/6l06f1kxyxhKdZkrcbaiOMtkJUA9ITAc1mlamh0ooasxkH1XwMbYQ
224
+acmwXaWET20H0GeAGP+7vow=
225
+=agpO
226
+-----END PGP SIGNATURE-----
227
+'
228
+test_expect_success 'Tag name filtering strips gpg signature' '
229
+ sha1=$(git rev-parse HEAD) &&
230
+ sha1t=$(echo "$faux_gpg_tag" | sed -e s/XXXXXX/$sha1/ | git mktag) &&
231
+ git update-ref "refs/tags/S" "$sha1t" &&
232
+ echo "$faux_gpg_tag" | sed -e s/XXXXXX/$sha1/ | head -n 6 > expect &&
233
+ git filter-branch -f --tag-name-filter cat &&
234
+ git cat-file tag S > actual &&
235
+ git diff expect actual
236
+'
237
+
238
test_done