Skip to content

Commit deb2458

Browse files
committed
Merge branch 'jk/sh-setup-in-filter-branch'
Refactoring to avoid code duplication in shell scripts. * jk/sh-setup-in-filter-branch: filter-branch: use git-sh-setup's ident parsing functions git-sh-setup: refactor ident-parsing functions
2 parents e034d1b + 3c730fa commit deb2458

File tree

3 files changed

+59
-54
lines changed

3 files changed

+59
-54
lines changed

git-filter-branch.sh

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -64,37 +64,19 @@ EOF
6464

6565
eval "$functions"
6666

67-
# When piped a commit, output a script to set the ident of either
68-
# "author" or "committer
67+
finish_ident() {
68+
# Ensure non-empty id name.
69+
echo "case \"\$GIT_$1_NAME\" in \"\") GIT_$1_NAME=\"\${GIT_$1_EMAIL%%@*}\" && export GIT_$1_NAME;; esac"
70+
# And make sure everything is exported.
71+
echo "export GIT_$1_NAME"
72+
echo "export GIT_$1_EMAIL"
73+
echo "export GIT_$1_DATE"
74+
}
6975

7076
set_ident () {
71-
lid="$(echo "$1" | tr "[A-Z]" "[a-z]")"
72-
uid="$(echo "$1" | tr "[a-z]" "[A-Z]")"
73-
pick_id_script='
74-
/^'$lid' /{
75-
s/'\''/'\''\\'\'\''/g
76-
h
77-
s/^'$lid' \([^<]*\) <[^>]*> .*$/\1/
78-
s/'\''/'\''\'\'\''/g
79-
s/.*/GIT_'$uid'_NAME='\''&'\''; export GIT_'$uid'_NAME/p
80-
81-
g
82-
s/^'$lid' [^<]* <\([^>]*\)> .*$/\1/
83-
s/'\''/'\''\'\'\''/g
84-
s/.*/GIT_'$uid'_EMAIL='\''&'\''; export GIT_'$uid'_EMAIL/p
85-
86-
g
87-
s/^'$lid' [^<]* <[^>]*> \(.*\)$/@\1/
88-
s/'\''/'\''\'\'\''/g
89-
s/.*/GIT_'$uid'_DATE='\''&'\''; export GIT_'$uid'_DATE/p
90-
91-
q
92-
}
93-
'
94-
95-
LANG=C LC_ALL=C sed -ne "$pick_id_script"
96-
# Ensure non-empty id name.
97-
echo "case \"\$GIT_${uid}_NAME\" in \"\") GIT_${uid}_NAME=\"\${GIT_${uid}_EMAIL%%@*}\" && export GIT_${uid}_NAME;; esac"
77+
parse_ident_from_commit author AUTHOR committer COMMITTER
78+
finish_ident AUTHOR
79+
finish_ident COMMITTER
9880
}
9981

10082
USAGE="[--env-filter <command>] [--tree-filter <command>]
@@ -320,10 +302,8 @@ while read commit parents; do
320302
git cat-file commit "$commit" >../commit ||
321303
die "Cannot read commit $commit"
322304

323-
eval "$(set_ident AUTHOR <../commit)" ||
324-
die "setting author failed for commit $commit"
325-
eval "$(set_ident COMMITTER <../commit)" ||
326-
die "setting committer failed for commit $commit"
305+
eval "$(set_ident <../commit)" ||
306+
die "setting author/committer failed for commit $commit"
327307
eval "$filter_env" < /dev/null ||
328308
die "env filter failed: $filter_env"
329309

git-sh-setup.sh

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -191,28 +191,52 @@ require_clean_work_tree () {
191191
fi
192192
}
193193
194+
# Generate a sed script to parse identities from a commit.
195+
#
196+
# Reads the commit from stdin, which should be in raw format (e.g., from
197+
# cat-file or "--pretty=raw").
198+
#
199+
# The first argument specifies the ident line to parse (e.g., "author"), and
200+
# the second specifies the environment variable to put it in (e.g., "AUTHOR"
201+
# for "GIT_AUTHOR_*"). Multiple pairs can be given to parse author and
202+
# committer.
203+
pick_ident_script () {
204+
while test $# -gt 0
205+
do
206+
lid=$1; shift
207+
uid=$1; shift
208+
printf '%s' "
209+
/^$lid /{
210+
s/'/'\\\\''/g
211+
h
212+
s/^$lid "'\([^<]*\) <[^>]*> .*$/\1/'"
213+
s/.*/GIT_${uid}_NAME='&'/p
214+
215+
g
216+
s/^$lid "'[^<]* <\([^>]*\)> .*$/\1/'"
217+
s/.*/GIT_${uid}_EMAIL='&'/p
218+
219+
g
220+
s/^$lid "'[^<]* <[^>]*> \(.*\)$/@\1/'"
221+
s/.*/GIT_${uid}_DATE='&'/p
222+
}
223+
"
224+
done
225+
echo '/^$/q'
226+
}
227+
228+
# Create a pick-script as above and feed it to sed. Stdout is suitable for
229+
# feeding to eval.
230+
parse_ident_from_commit () {
231+
LANG=C LC_ALL=C sed -ne "$(pick_ident_script "$@")"
232+
}
233+
234+
# Parse the author from a commit given as an argument. Stdout is suitable for
235+
# feeding to eval to set the usual GIT_* ident variables.
194236
get_author_ident_from_commit () {
195-
pick_author_script='
196-
/^author /{
197-
s/'\''/'\''\\'\'\''/g
198-
h
199-
s/^author \([^<]*\) <[^>]*> .*$/\1/
200-
s/.*/GIT_AUTHOR_NAME='\''&'\''/p
201-
202-
g
203-
s/^author [^<]* <\([^>]*\)> .*$/\1/
204-
s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p
205-
206-
g
207-
s/^author [^<]* <[^>]*> \(.*\)$/@\1/
208-
s/.*/GIT_AUTHOR_DATE='\''&'\''/p
209-
210-
q
211-
}
212-
'
213237
encoding=$(git config i18n.commitencoding || echo UTF-8)
214238
git show -s --pretty=raw --encoding="$encoding" "$1" -- |
215-
LANG=C LC_ALL=C sed -ne "$pick_author_script"
239+
parse_ident_from_commit author AUTHOR
216240
}
217241
218242
# Clear repo-local GIT_* environment variables. Useful when switching to

t/t7003-filter-branch.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,11 @@ test_expect_success 'author information is preserved' '
167167
test_tick &&
168168
GIT_AUTHOR_NAME="B V Uips" git commit -m bvuips &&
169169
git branch preserved-author &&
170-
git filter-branch -f --msg-filter "cat; \
170+
(sane_unset GIT_AUTHOR_NAME &&
171+
git filter-branch -f --msg-filter "cat; \
171172
test \$GIT_COMMIT != $(git rev-parse master) || \
172173
echo Hallo" \
173-
preserved-author &&
174+
preserved-author) &&
174175
test 1 = $(git rev-list --author="B V Uips" preserved-author | wc -l)
175176
'
176177

0 commit comments

Comments
 (0)