Reputation: 24015
I'm on a branch that's many commits (in a straight line of history) ahead of my develop
branch, and in each commit message is the name of the issue-tracker ticket I'm working on. Now I want to rebase through each commit and change the name of that ticket to a different ticket, conceptually something like:
perl -pi -e 's/BB-123/BB-456/' .git/COMMIT_EDITMSG
Is there a way to tell rebase's reword
action that instead of opening an interactive editor, I want to run a command on the message text instead?
The best I've come up with would be to put an exec
action after each commit that runs git commit --amend
and changes the $EDITOR
variable to the above command or something, but that's pretty horrible.
Without a good automatic solution, I usually rebase with a reword
action on every commit and edit all the messages manually.
Upvotes: 1
Views: 433
Reputation: 51169
You're probably looking for git filter-branch
. Suppose your log looks like this:
* commit 7534b4609b84b87232ad933c83d5b802adfe2814 (HEAD -> wip/T1234)
|
| More work on ticket #1234
|
* commit e23ef0941b7a52dbb46876db4c985a1c30ec5e16
|
| Some work on ticket #1234
|
* commit b660a05e4d90fc8ae61b7d39e716ee3cdcc382ec (develop)
|
| Current develop branch head
|
* commit 1b67c0b8b1b4f4c22ddc38ba78c499dde749006f
Initial commit
So, you have a straight-line history of commits from develop
to wip/T1234
. You realize the ticket should have read #1236, so you run:
$ git filter-branch --msg-filter 'sed -e s/1234/1236/g' \
> develop..wip/T1234
Rewrite 7534b4609b84b87232ad933c83d5b802adfe2814 (2/2) (0 seconds passed,
remaining 0 predicted)
Ref 'refs/heads/wip/T1234' was rewritten
$
and now the commits are rewritten:
* commit c30e8becea1221d563d2be0e5a8c048c2c5bf608 (HEAD -> wip/T1234)
|
| More work on ticket #1236
|
* commit 0417b49944b3c9311031a657bc8be3c8bf05b54d
|
| Some work on ticket #1236
|
* commit b660a05e4d90fc8ae61b7d39e716ee3cdcc382ec (develop)
|
| Current develop branch head
|
* commit 1b67c0b8b1b4f4c22ddc38ba78c499dde749006f
Initial commit
A copy of the original refs will be written to refs/original
, so you can still access the pre-filtered version:
$ git log refs/original/logs/refs/heads/wip/T1234
... version with #1234 still in place
Obviously, you want to check the rewrites carefully before removing the originals!
Upvotes: 1
Reputation: 490068
Yes: when an interactive rebase opens the editor, it opens one based on different environment settings:
GIT_SEQUENCE_EDITOR
is used for the commands to run, butGIT_EDITOR
is used for reword operations.(If one of these is not set, Git falls back to sequence.editor
or core.editor
or the built in editor as usual. You could change those settings, perhaps temporarily, but the environment variable is easier.)
Hence you can use:
GIT_SEQUENCE_EDITOR=script1 GIT_EDITOR=script2 git rebase -i <arguments>
where script1
replaces edit
with reword
, and script2
does the s/BB-123/BB-456/
you want, for instance.
Upvotes: 2