Reputation: 4345
Sometimes it is useful to modify a commit by editing a patch file rather than by changing files directly, adding them to the working set and then amending a commit.
To make this easy, it would be useful to have a command in git that opens the most recent commit in $EDITOR
as a patch file, in the same way that issuing git commit --amend
(without any changes staged) immediately allows editing of the commit message in an editor.
Is this possible in git
Upvotes: 10
Views: 4349
Reputation: 11
In case you need more than one commit edited, you can use git format-patch
git am
git format-patch ${commit_hash}^ --stdout > patch
# edit the patch file accordingly
git reset --hard ${commit_hash}^
git am < patch
Upvotes: 0
Reputation: 37812
I'm not sure if it is possible in a single command, but almost:
git reset -N HEAD~
git add --edit
git commit --reuse-message=ORIG_HEAD
some explanations:
git reset -N HEAD~
: destroy last commit but keep the changesgit add --edit
allows you to edit your changes in patch formatgit commit --reuse-message=ORIG_HEAD
: commit your staged changes with the commit message from ORIG_HEAD which is the pointer to the commit you made before git reset
.NOTE: since only git add --edit
needs for interaction, you could even just chain the commands on one line and create a bash or git alias for it if desired:
git reset -N HEAD~ && git add --edit && git commit --reuse-message=ORIG_HEAD
NOTE2 if you edit your commit, some changes will remain in your git repository after this command. You must choose to throw them all away (git checkout -- :/
) or commit them or...
If you don't do anything with these changes; then calling the above commands twice will always show you the changes from your very first commit:
git commit -am "very first commit"
git reset -N HEAD~
git add --edit # edit very first commit as patch
git commit --reuse-message=ORIG_HEAD
# you now have some unstaged changes lying around.
git reset HEAD~ # undo second commit
# the unstaged changes that are lying around now
# are a combination of second commit and the unstaged changes
# that were still lying around.
# That combination = content of very first commit
git add --edit # edit that combination
git commit --reuse-message=ORIG_HEAD
If you would like a full command that you can continue applying; you could include the throwing away of changes:
git reset -N HEAD~ && git add --edit && git commit --reuse-message=ORIG_HEAD && git checkout -- :/
Note that this is dangerous because you might be throwing away changes...
you might save this script as /usr/bin/git-edit-last-commit
, then you can run it as git edit-last-commit
:
#!/bin/bash
set -e # exit on first error
if ! git diff-files --quiet
then
echo "Your git repository is not clean: you have unstaged changes."
exit 1
fi
if ! git diff-index --quiet --cached HEAD --
then
echo "Your git repository is not clean: you have staged changes."
exit 1
fi
git reset -N HEAD~
git add --edit
git commit --reuse-message=ORIG_HEAD
# supposing that this edit is really what you wanted, we can throw away leftovers
# if work was lost, in can be recovered using git reflog
git checkout -- :/
Upvotes: 10