11

I ran an interactive rebase up to commit abcdef.

git rebase -i abcdef

In the editor - Vim I changed all pick hash lines to

reword hash PREFIX: Original commit message using this vim command

%s/pick \(\w\{7}\)/reword \1 PREFIX:/

but then git goes on to prompt me to edit the message for every commit. Is there a simple way to batch this process?

Peter Chaula
  • 3,456
  • 2
  • 28
  • 32

2 Answers2

9
GIT_EDITOR='sed -i "1s/^/PREFIX: /"' GIT_SEQUENCE_EDITOR=vim \
        git rebase -i abcdef

or alternately you could

git -c core.editor='sed -i "1s/^/PREFIX: /"' \
        -c sequence.editor=vim \
        rebase -i abcdef

if you don't want to use the environment overrides.

If you know you're going to reword them all you could even sed the sequence, GIT_SEQUENCE_EDITOR='sed -i "s/^pick/reword/"'.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • @jtill What do you think about https://davidwalsh.name/update-git-commit-messages? – Peter Chaula Apr 11 '17 at 16:22
  • filter-branch works too, it's just a question of what's most convenient at the moment. Sometimes you need a screwdriver, sometimes you need a crowbar, sometimes a dime would do, sometimes all of them would do the job eventually and it's just a question of what's handiest at the moment. `git commit --amend` for the checked-out commit, `git rebase -i` for hunk-shuffling and merge elision and light-duty rewords, `git filter-branch` for wholesale batch work where what you're doing isn't hunk-shuffling and the rebase overhead starts mattering. – jthill Apr 11 '17 at 16:31
  • The second example has a minor typo - missing slash in the sed command. It should be `sed -i "1s/^/PREFIX: /"` as above. – jthodges Jan 02 '18 at 00:10
4

Alternative answer using only git:

git rebase -i --exec 'git commit --amend -m "PREFIX: $(git show -s --format=%s)"' origin/master

You can also do this non-interactively (without the -i flag). Afterwards in the interactive window you can remove the exec directive after every commit where the prefix shouldn't be applied.

Explanation:

  1. Using rebase --exec you can execute a command for every commit, this is quite generally useful.

  2. Using git commit --amend -m <MESSAGE> you can change the message of the current commit.

  3. Using git show -s --format=%s you can display the current commit message.

Putting it all together:

  1. To prefix the message we must get the current message (3), and change the current message with amend (2), i.e. git commit --amend -m "PREFIX: $(git show -s --format=%s)". The double quotes are important so that the command gets executed inside the message string.

  2. To do this for every commit in the rebase (based on your origin/master branch here) you execute (4) on every commit, using single quotes otherwise every commit will get your last commit's message, and voilà you get the command above.

CodeMonkey
  • 4,067
  • 1
  • 31
  • 43