127

I have modified two files a, b in the last commit. But file b should not be commited, what's the workflow to amend this?

5 Answers 5

121

Update (couple of years later)

Jan Hudec

It's trivial to remove it from index only.

True: you can reset a file to its index content easily enough, as the more recent answer (written by Matt Connolly) suggests:

git reset HEAD^ path/to/file/to/revert

HEAD^ allows the file to access its content in the previous commit before the last one.

Then you can git commit --amend, as I originally wrote below.


With Git 2.23 (August 2019), you might use the new git restore command

 git restore --source=HEAD^ --staged  -- path/to/file/to/revert

shorter:

 git restore -s@^ -S -- path/to/file/to/revert

Again, you then can git commit --amend, as I originally wrote below.


Original answer (January 2011)

If this is your last commit (and you haven't pushed it anywhere), you can amend it:
(first stash or save b)

 git commit --amend

Then delete b, re-commit. Restore b and you're done.

--amend

Used to amend the tip of the current branch.
Prepare the tree object you would want to replace the latest commit as usual (this includes the usual -i/-o and explicit paths), and the commit log editor is seeded with the commit message from the tip of the current branch.
The commit you create replaces the current tip — if it was a merge, it will have the parents of the current tip as parents — so the current top commit is discarded.

4
  • ... Then stash/delete b, re-commit.., here shouldn't the word Then be after? -- --amend after stach/delete b, ...
    – Lenik
    Jan 5, 2011 at 10:17
  • @谢继雷: in other words, save b first, then commit --amend, then restore? True. I have updated the answer.
    – VonC
    Jan 5, 2011 at 11:21
  • With the power of git index, telling anybody to stash/save the file is just plain silly (-1). It's trivial to remove it from index only.
    – Jan Hudec
    May 6, 2014 at 7:44
  • 1
    @JanHudec True, I have edited the answer accordingly. I didn't follow that old answer as closely as I do on Stack Overflow. 99% of git questions on SU should be migrated on SO anyway.
    – VonC
    May 6, 2014 at 7:51
74
  1. git diff --name-only HEAD^ - (optional) use to list the files that changed in the last commit.
  2. git reset HEAD^ path/to/file/to/revert - to reset the index to that last version, leaving the working copy untouched.
  3. git commit --amend - to amend that last commit to include the index changes
4
  • 11
    Imho it's a much better answer then the accepted one.
    – mik01aj
    Jun 8, 2013 at 7:11
  • 1
    Note that you shouldn't use git commit -a --amend (i.e. don't add files) for step 3, or you'll commit your working copy changes which are the edits you are trying to remove. An optional step 2.5 could be git checkout path/to/file/to/revert to clean up your working copy too.
    – dmnd
    Oct 16, 2013 at 17:56
  • 1
    Alternatively git rm --cached path/to/file/to/revert to un-add file without deleting it from the tree.
    – Jan Hudec
    May 6, 2014 at 7:45
  • Note that this will add all currently staged changes into the commit as well, so you might want to run git restore --staged -- $(git rev-parse --git-dir) beforehand. See also stackoverflow.com/a/70197343
    – xeruf
    Dec 2, 2021 at 17:22
13

Alternatively if you are using git gui, you just select the "Amend last commit" option, the added file appears in the "Staged" list, click on it's icon to move it to the "Unstaged" list and commit.

2
  • 1
    @VonC: Editing and splitting patches is quite common operation for heavy git users, so the gui was designed to make it easy and is IMO best tool for it.
    – Jan Hudec
    May 6, 2014 at 7:58
  • That one works! I didn't have succes with other options for that particular task. Thanks for the tip!
    – Serguzest
    Aug 21, 2016 at 21:41
9

If you want to delete b from your last commit

git rm --cached b (will preserve the file in the working tree but remove it from the index)
git commit --amend

If you want to remove all changes to b in your last commit

(backup b)
(modify b to state before incorrect commit)
git commit --amend
(restore b)
3
  • git rm --cached and do away with the backup/restore dance (-1).
    – Jan Hudec
    May 6, 2014 at 7:46
  • Thanks for pointing that out. I wanted to share how I did this because this was the approach I felt most comfortable with even after reading the whole thread.
    – pingo
    May 6, 2014 at 10:57
  • Yes, but this removes/deletes the file b which was very possibly in index in previous commit. So it changes the b in the commit which is not what OP wants.
    – yurtesen
    Sep 26, 2021 at 17:40
6

An alternative that doesn't require index hackery, but nonetheless preserves the old commit message:

$ git reset HEAD^
$ git add <all the files you want, excluding the one you don't want>
$ git commit -C HEAD@{1}

I like this because (a) it uses commands I regularly use, and (b) I can do git add -p to figure out exactly what it is I want to commit.

2
  • what does this part do git commit -C HEAD@{1} in particular the HEAD@{1} part?
    – gMale
    Dec 19, 2020 at 0:57
  • 1
    Commit using the commit message from the previous commit in the reflog, namely the commit we just undid.
    – Justin L.
    Dec 20, 2020 at 1:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.