bash - Convenience script for renaming commit authors with git-filter-branch -
for convenience, in post runnable bash command.
i have following script based off of github's own:
cat <<eof > git-unite #!/usr/bin/env bash # usage: # # git-unite "user name" "new@email.com" \ # "old1@email.com" \ # "old2@email.com" \ # ... name="$1" email="$2" git config user.name "$name" git config user.email "$email" shift 2 old_email in $*; echo "changing $old_email" git filter-branch --force --env-filter ' if [ "$git_committer_email" = "$(echo $old_email)" ] export git_committer_name="$(echo $name)" export git_committer_email="$(echo $email)" fi if [ "$git_author_email" = "$(echo $old_email)" ] export git_author_name="$(echo $name)" export git_author_email="$(echo $email)" fi ' --tag-name-filter cat -- --branches --tags done eof chmod u+x git-unite
yet, when run script on test repository i've set up:
git clone https://gist.github.com/dc896ccd9a272a126436.git cd dc896ccd9a272a126436 git-unite "test author" "new@email.com" "hehe2" "hehe"
nothing changed. trouble?
changing hehe2 rewrite be8d35aca918caaa86035ab8f8011d5ff6131939 (3/3) warning: ref 'refs/heads/master' unchanged changing hehe rewrite be8d35aca918caaa86035ab8f8011d5ff6131939 (3/3) warning: ref 'refs/heads/master' unchanged
using exports, problem can solved. there way without exporting these variables?
if need "inject" $name
, $email
, can export before git filter-branch
, or can generate bash script using printf
.
notice: $(echo $old_email)
same result using "$old_email"
, fork process nothing (well, if bash fork when use builtins).
you can use printf
: idea use %q
dump different variable in quoted form (suitable use in bash script, or in eval). gain advantage split script change user name/email 1 run git command.
#action.bash: declare -r _new_name="%q" declare -r _new_email="%q" declare -r _old_email="%q" if [ "$git_committer_email" = %v ] export git_committer_name="${_new_name}" export git_committer_email="${_new_email}" fi if [ "$git_author_email" = "${_old_email}" ] export git_author_name="${_new_name}" export git_author_email="${_new_email}" fi
and in script:
git filter-branch --force --env-filter $(printf "$(<action.bash)" \ "$name" "$email" "$old_email") --tag-name-filter cat -- --branches --tags
notice:
$(<foobar)
same workcat foobar
does. when usecat
, might except bash create sub-process instead of reading filefoobar
.- i truncated
git filter-branch
(the\
) line avoid horizontal scrollbars.
this example fine, after thinking little, think should not that, in more bash way:
#action.bash: declare -r _new_name="$1" declare -r _new_email="$2" declare -r _old_email="$3" if [ "$git_committer_email" = %v ] export git_committer_name="${_new_name}" export git_committer_email="${_new_email}" fi if [ "$git_author_email" = "${_old_email}" ] export git_author_name="${_new_name}" export git_author_email="${_new_email}" fi
and instead:
git filter-branch --force --env-filter "$(printf 'action.bash "%q" "%q" "%q"' \ "$name" "$email" "$old_email")" --tag-name-filter cat -- --branches --tags
that way, if script nothing @ all, still work if needed in static way:
git filter-branch --force --env-filter 'action.bash name email old_email' \ --tag-name-filter cat -- --branches --tags
Comments
Post a Comment