2

I can't seem to get the "git filter-branch" to work inside bash:

  fix_commit_date() { 
   git filter-branch --env-filter \
     'if [ $GIT_COMMIT = "${1}" ]
      then
        export GIT_AUTHOR_DATE="${2}"
        export GIT_COMMITTER_DATE="${2}"
      fi' -f
   }

This is the error message I get:

fix_commit_date b62178fd4d40e1e52a7bfef64ff2f269c3aff7f8 "Mon Aug 12 13:03:00 2019"
Rewrite b62178fd4d40e1e52a7bfef64ff2f269c3aff7f8 (8/8) (0 seconds passed, remaining 0 predicted)    
WARNING: Ref 'refs/heads/master' is unchanged

It works fine in bash if I just type it out and not use fix_commit_date. Any ideas how I can get the fix_commit_date bash command to work? Thanks.

Linh Phan
  • 37
  • 5
  • What exactly do you mean by "*I just type it out*"? What's the actual command? – melpomene Aug 12 '19 at 23:56
  • git filter-branch --env-filter \ 'if [ $GIT_COMMIT = b62178fd4d40e1e52a7bfef64ff2f269c3aff7f8 ] then export GIT_AUTHOR_DATE="Mon Aug 12 13:03:00 2019" export GIT_COMMITTER_DATE="Mon Aug 12 13:03:00 2019" fi' -f – Linh Phan Aug 13 '19 at 00:18
  • Possible duplicate of [Difference between single and double quotes in Bash](https://stackoverflow.com/questions/6697753/difference-between-single-and-double-quotes-in-bash) – melpomene Aug 13 '19 at 00:22

1 Answers1

4

Your shell function uses inappropriate quoting.

Try prefixing git filter-branch with echo:

echo git filter-branch --env-filter \
  'if [ $GIT_COMMIT = b62178fd4d40e1e52a7bfef64ff2f269c3aff7f8 ]
  then
    export GIT_AUTHOR_DATE="Mon Aug 12 13:03:00 2019"
    export GIT_COMMITTER_DATE="Mon Aug 12 13:03:00 2019"
  fi' -

Observe the output. What do you see for the test for the commit hash ID?

Then try your shell function as written, again inserting echo in front of git:

fix_commit_date() { 
   echo git filter-branch --env-filter \
     'if [ $GIT_COMMIT = "${1}" ]
      then
        export GIT_AUTHOR_DATE="${2}"
        export GIT_COMMITTER_DATE="${2}"
      fi' -f
}

fix_commit_date b62178fd4d40e1e52a7bfef64ff2f269c3aff7f8 "Mon Aug 12 13:03:00 2019"

What output do you see?

The trick here is to expand the arguments $1 and $2, yet still provide the entire expression as a single word to the command. There are numerous ways to do this; here's one:

fix_commit_date() { 
   git filter-branch --env-filter \
     'if [ $GIT_COMMIT = "'"${1}"'" ]
      then
        export GIT_AUTHOR_DATE="'"${2}"'"
        export GIT_COMMITTER_DATE="'"${2}"'"
      fi' -f
}

Try this variant with the echo inserted first.


Incidentally, one of my favorite tricks for encoding this sort of thing in a more readable manner is to set a shell variable to contain a double quote:

DQ='"'
echo "John told me to say ${DQ}hello${DQ}"

Each of the shell-expanded metacharacters can be put in a variable:

DOL='$'
BQ='`'
SQ="'"  # not technically needed

Otherwise "invisible" characters can be set up as well:

TAB=$'\t'
NL=$'\n'

Now you can write things like:

echo "This has some ${DOL}weird ${BQ}ch${TAB}ara${NL}cters in it, doesn't it?"
torek
  • 448,244
  • 59
  • 642
  • 775