Skip to content

Commit df06201

Browse files
peffgitster
authored andcommitted
filter-branch: avoid passing commit message through sed
On some systems (like OS X), if sed encounters input without a trailing newline, it will silently add it. As a result, "git filter-branch" on such systems may silently rewrite commit messages that omit a trailing newline. Even though this is not something we generate ourselves with "git commit", it's better for filter-branch to preserve the original data as closely as possible. We're using sed here only to strip the header fields from the commit object. We can accomplish the same thing with a shell loop. Since shell "read" calls are slow (usually one syscall per byte), we use "cat" once we've skipped past the header. Depending on the size of your commit messages, this is probably faster (you pay the cost to fork, but then read the data in saner-sized chunks). This idea is shamelessly stolen from Junio. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 282616c commit df06201

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

git-filter-branch.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,15 @@ while read commit parents; do
346346
die "parent filter failed: $filter_parent"
347347
fi
348348

349-
sed -e '1,/^$/d' <../commit | \
349+
{
350+
while read -r header_line && test -n "$header_line"
351+
do
352+
# skip header lines...
353+
:;
354+
done
355+
# and output the actual commit message
356+
cat
357+
} <../commit |
350358
eval "$filter_msg" > ../message ||
351359
die "msg filter failed: $filter_msg"
352360
workdir=$workdir @SHELL_PATH@ -c "$filter_commit" "git commit-tree" \

t/t7003-filter-branch.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,4 +394,14 @@ test_expect_success 'replace submodule revision' '
394394
test $orig_head != `git show-ref --hash --head HEAD`
395395
'
396396

397+
test_expect_success 'filter commit message without trailing newline' '
398+
git reset --hard original &&
399+
commit=$(printf "no newline" | git commit-tree HEAD^{tree}) &&
400+
git update-ref refs/heads/no-newline $commit &&
401+
git filter-branch -f refs/heads/no-newline &&
402+
echo $commit >expect &&
403+
git rev-parse refs/heads/no-newline >actual &&
404+
test_cmp expect actual
405+
'
406+
397407
test_done

0 commit comments

Comments
 (0)