147

In last hour or so i have modified files

A
ATest
B
BTest

In order to make sure my commit messages line up with the actual change, committed A with a description. Unfortunately i have not included ATest into that commit.

Meanwhile, still not committed are B and BTest.

What is the best way to proceed at this point? I'd like to either:

  1. Revert previous commit without affecting my currently uncommitted files?
  2. Add another file under the same description to the previous commit?
James Raitsev
  • 92,517
  • 154
  • 335
  • 470

3 Answers3

249

To add a new file to the previous commit:

$ git add new-file
$ git commit --amend

You can use git commit --amend --no-edit if you don't want to change the commit message.

pyrmont
  • 225
  • 5
  • 12
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • 4
    Thank you. Out of the curiosity, if commit's sha1 was known and commit was not 'last' how would it have been possible to amend to *that* commit? – James Raitsev Dec 31 '12 at 02:19
  • 9
    @Jam I'd say try really hard not to do that ;-) But if you must, one way (not sure if it's the best) is to commit the new file as its own commit and then use `git rebase -i` to reorder the commits and merge the new-file commit with the other commit. That might be material for a separate question. – David Z Dec 31 '12 at 02:21
  • 5
    When doing `git rebase -i` as @DavidZ suggests, all you have to do is move the new commit up to just below the one you want to combine it with, and change the new commit's word to `squash` instead of `pick` – M.M Nov 05 '14 at 00:28
  • What if I staged lots of files, but I only want to add a single one to the amended commit? – dfrankow Sep 06 '15 at 16:08
  • Unstage all of the staged files (eg, `git reset`), then stage the one you want to add, amend the commit, then stage all of the files again. – William Pursell Sep 06 '15 at 18:21
  • If you've already pushed it to remote, you can `git push -f` to force the update through. Be mindful that this can cause issues if you have other collaborators that have already pulled your changes. – Llama D'Attore Feb 14 '23 at 07:38
83

Here's an amusing flowchart1 which is also surprisingly handy: it gives the correct recommendation both for the original question and for the amended "What if it weren't the last commit?" question.

Git-pretty flowchart

1 Taken from http://justinhileman.info/article/git-pretty/

geisterfurz007
  • 5,292
  • 5
  • 33
  • 54
amalloy
  • 89,153
  • 8
  • 140
  • 205
37

Add a file to a previous commit

If you have already pushed the branch you are working on, please see the man pages first. In particular, please note:

Rebasing (or any other form of rewriting) a branch that others have based work on is a bad idea: anyone downstream of it is forced to manually fix their history.

However, if you haven't pushed your branch, prepare to enter the danger zone.

Find the commit hash

First, you need to know the commit hash of the commit that you want to add to. This is shown by git log. You actually want to specify the commit prior to the one you want to add to. (You can think of it as the start index to the slice of commits you want to alter.) You can make sure you have the right commit by running git log -1 HEAD~n. Where 'n' is an integer you increment until you have the right commit. Or you could count, no really.

But, if you do count, at least confirm you have the right commit with git log -1 HEAD~5 or whatever your count was. You should NOT see the commit you want to add to.

DANGER, heh

Now you are ready to run git rebase -i HEAD~5, or use a commit hash instead git rebase -i hash^. This will bring up your favorite text editor and a file to edit. The file is the todo list for the rebase command. The comments in the file tell you what options you have. Simply find the line with the commit you want to add to, and on that line change 'pick' to 'edit'. Now save and close the file.

The rebase will stop once it reaches the commit you told it to edit. Run a git status to see the extra information it provides. Stage your files to add to the commit with git add . or whatever the filenames are.

Then, do git commit --amend or git commit --amend --no-edit (if you don't want to edit the commit message). This will amend the commit you chose to edit.

Finally, run git rebase --continue.

If in doubt, on Linux you can find out more by reading through the docs output by man git-rebase or git --help rebase.

Juan Marco
  • 3,081
  • 2
  • 28
  • 32
  • 4
    Regarding "find the commit hash". No need to start counting. Just use `git log` to find your commit and copy its hash, then use `git rebase -i hash^` to rebase on the commit previous to yours. – Viktor Sep 30 '19 at 15:32
  • man this was such a gem of an answer. wish i could give you reddit gold. thank you for your help – vampiire Jan 24 '22 at 21:02
  • To edit an initial commit, use [`rebase`'s `--root` option](https://stackoverflow.com/a/21048552/1429450): `git rebase -i --root`. – Geremia Apr 30 '22 at 21:47
  • Argh, don't forget that if you're doing this from `cmd.exe` that `^` [is an escape character](https://stackoverflow.com/a/20344034/1028230). So ***`cmd.exe` only***: `git rebase -i hash^^`. If you don't include two `^` (escaped escape), `cmd` will ask `More?`. – ruffin May 01 '23 at 15:48