Remove files from Git commit

GitGit Commit

Git Problem Overview


I am using Git and I have committed few files using

git commit -a

Later, I found that a file had mistakenly been added to the commit.

How can I remove a file from the last commit?

Git Solutions


Solution 1 - Git

I think other answers here are wrong, because this is a question of moving the mistakenly committed files back to the staging area from the previous commit, without cancelling the changes done to them. This can be done like Paritosh Singh suggested:

git reset --soft HEAD^ 

or

git reset --soft HEAD~1

Then reset the unwanted files in order to leave them out from the commit (the old way):

git reset HEAD path/to/unwanted_file

Note, that since Git 2.23.0 one can (the new way):

git restore --staged path/to/unwanted_file

Now commit again, you can even re-use the same commit message:

git commit -c ORIG_HEAD  

Solution 2 - Git

ATTENTION! If you only want to remove a file from your previous commit, and keep it on disk, read juzzlin's answer just above.

If this is your last commit and you want to completely delete the file from your local and the remote repository, you can:

  1. remove the file git rm <file>
  2. commit with amend flag: git commit --amend

The amend flag tells git to commit again, but "merge" (not in the sense of merging two branches) this commit with the last commit.

As stated in the comments, using git rm here is like using the rm command itself!

Solution 3 - Git

Existing answers are all talking about removing the unwanted files from the last commit.

If you want to remove unwanted files from an old commit (even pushed) and don't want to create a new commit, which is unnecessary, because of the action:

  1. Find the commit that you want the file to conform to using ;

git log --graph --decorate --oneline

  1. Checkout that commit using

git checkout <commit_id> <path_to_file>

you can do this multiple times if you want to remove many files.

git commit -am "remove unwanted files"

Find the commit_id of the commit on which the files were added mistakenly, let's say "35c23c2" here

git rebase 35c23c2~1 -i // notice: "~1" is necessary

This command opens the editor according to your settings. The default one is vim. If you want to change the global git editor, use;

git config --global core.editor <editor_name>

Move the last commit, which should be "remove unwanted files", to the next line of the incorrect commit("35c23c2" in our case), and set the command as fixup:

pick 35c23c2 the first commit
fixup 0d78b28 remove unwanted files

You should be good after saving the file.

To finish :

git push -f

If you unfortunately get conflicts, you have to solve them manually.

Solution 4 - Git

As the accepted answer indicates, you can do this by resetting the entire commit. But this is a rather heavy handed approach.
A cleaner way to do this would be to keep the commit, and simply remove the changed files from it.

git reset HEAD^ -- path/to/file
git commit --amend --no-edit

The git reset will take the file as it was in the previous commit, and stage it in the index. The file in the working directory is untouched.
The git commit will then commit and squash the index into the current commit.

This essentially takes the version of the file that was in the previous commit and adds it to the current commit. This results in no net change, and so the file is effectively removed from the commit.

Solution 5 - Git

If you have not pushed the changes on the server you can use

git reset --soft HEAD~1

It will reset all the changes and revert to one commit back

If you have pushed your changes then follow steps as answered by @CharlesB

Solution 6 - Git

Removing the file using rm will delete it!

You're always adding to a commit in git rather than removing, so in this instance return the file to the state it was in prior to the first commit (this may be a delete 'rm' action if the file is new) and then re-commit and the file will go.

To return the file to some previous state:

    git checkout <commit_id> <path_to_file>

or to return it to the state at the remote HEAD:

    git checkout origin/master <path_to_file>

then amend the commit and you should find the file has disappeared from the list (and not deleted from your disk!)

Solution 7 - Git

I will explain to you with example.
Let A, B, C be 3 successive commits. Commit B contains a file that should not have been committed.

git log  # take A commit_id
git rebase -i "A_commit_ID" # do an interactive rebase
change commit to 'e' in rebase vim # means commit will be edited
git rm unwanted_file
git rebase --continue
git push --force-with-lease <branchName>	

Solution 8 - Git

git checkout HEAD~ path/to/file
git commit --amend

Solution 9 - Git

The following will unstage just the file you intended, which is what the OP asked.

git reset HEAD^ /path/to/file

You'll see something like the following...

> Changes to be committed: (use "git reset HEAD ..." to unstage) > > modified: /path/to/file > > Changes not staged for commit: (use "git add ..." to update > what will be committed) (use "git checkout -- ..." to discard > changes in working directory) > > modified: /path/to/file

  • "Changes to be committed" is the previous version of the file before the commit. This will look like a deletion if the file never existed. If you commit this change, there will be a revision that reverts the change to the file in your branch.
  • "Changes not staged for commit" is the change you committed, and the current state of the file

At this point, you can do whatever you like to the file, such as resetting to a different version.

When you're ready to commit:

git commit --amend -a

or (if you've got some other changes going on that you don't want to commit, yet)

git commit add /path/to/file
git commit --amend

Solution 10 - Git

You can simply try.

git reset --soft HEAD~1

and create a new commit.

However, there is an awesome software "gitkraken". which makes it easy to work with git.

Solution 11 - Git

git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit -m "removed unwanted file from git"

will leave you the local file still. If you don't want the file locally either, you can skip the --cached option.

If all work is on your local branch, you need to keep the file in a later commit, and like having a clean history, I think a simpler way to do this could be:

git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit --squash <commit_id>
git add <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit -m "brand new file!"
git rebase --interactive <commit_id>^

and you can then finish the rebase with ease without having to remember more complex commands or commit message or type as much.

Solution 12 - Git

Using git GUI can simplify removing a file from the prior commit.

Assuming that this isn't a shared branch and you don't mind rewriting history, then run:

git gui citool --amend

You can un-check the file that was mistakenly committed and then click "Commit".

enter image description here

The file is removed from the commit, but will be kept on disk. So if you un-checked the file after mistakenly adding it, it will show in your untracked files list (and if you un-checked the file after mistakenly modifying it it will show in your changes not staged for commit list).

Solution 13 - Git

If you want to preserve your commit (maybe you already spent some time writing a detailed commit message and don't want to lose it), and you only want to remove the file from the commit, but not from the repository entirely:

git checkout origin/<remote-branch> <filename>
git commit --amend

Solution 14 - Git

Do a sequence of the following commands:

//to remove the last commit, but preserve changes  
git reset --soft HEAD~1

//to remove unneded file from the staging area  
git reset HEAD `<your file>` 

//finally make a new commit  
git commit -m 'Your message'

Solution 15 - Git

Just wanted to complement the top answer as I had to run an extra command:

git reset --soft HEAD^
git checkout origin/master <filepath>

Cheers!

Solution 16 - Git

If you want to remove files from previous commits use filters

git filter-branch --prune-empty --index-filter 'git rm --ignore-unmatch --cached "file_to_be_removed.dmg"'

If you see this error:

Cannot create a new backup. A previous backup already exists in refs/original/ Force overwriting the backup with -f

Just remove refs backups on your local repo

$ rm -rf .git/refs/original/refs

Solution 17 - Git

git reset --soft HEAD~1. 

This will undo the last commit in local repos and move everything back to stage area like before doing the commit. Then just use any Git UI tool as normal (like TortoiseGit, Git UI, Git Extensions...) to unstage the files that we do not want to commit then do the commit again.

Solution 18 - Git

Something that worked for me, but still think there should be a better solution:

$ git revert <commit_id>
$ git reset HEAD~1 --hard

Just leave the change you want to discard in the other commit, check others out

$ git commit --amend // or stash and rebase to <commit_id> to amend changes

Solution 19 - Git

git reset --soft HEAD^ winds back your commit, and when you type git status, it tells you what to do:

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

Solution 20 - Git

Had the same issue where I have changes in a local branch where I wanted to revert just one file. What worked for me was -

(feature/target_branch below is where I have all my changes including those I wanted to undo for a specific file)

(origin/feature/target_branch is the remote branch where I want to push my changes to)

(feature/staging is my temporary staging branch where I will be pushing from all my wanted changes excluding the change to that one file)

  1. Create a local branch from my origin/feature/target_branch - called it feature/staging

  2. Merged my working local branch feature/target_branch to the feature/staging branch

  3. Checked out feature/staging then git reset --soft ORIG_HEAD (Now all changes from the feature/staging' will be staged but uncommitted.)

  4. Unstaged the file which I have previously checked in with unnecessary changes

  5. Changed the upstream branch for feature/staging to origin/feature/target_branch

  6. Committed the rest of the staged changes and pushed upstream to my remote origin/feature/target_branch

Solution 21 - Git

if you dont push your changes to git yet

git reset --soft HEAD~1

It will reset all the changes and revert to one commit back

If this is the last commit you made and you want to delete the file from local and remote repository try this :

git rm <file>
 git commit --amend

or even better :

reset first

git reset --soft HEAD~1

reset the unwanted file

git reset HEAD path/to/unwanted_file

commit again

git commit -c ORIG_HEAD  

Solution 22 - Git

Actually, I think a quicker and easier way is to use git rebase interactive mode.

git rebase -i head~1  

(or head~4, how ever far you want to go)

and then, instead of 'pick', use 'edit'. I did not realize how powerful 'edit' is.

https://www.youtube.com/watch?v=2dQosJaLN18

Hope you will find it helpful.

Solution 23 - Git

If you dont need that file anymore, you could do

git rm file
git commit --amend
git push origin branch

Solution 24 - Git

If you're using GitHub and haven't yet pushed the commit, GitHub Desktop solves this problem easily:

  1. Choose Repository -> Undo Most Recent Commit
  2. Unselect the file that you mistakenly added. Your previous commit message will be in the dialog box already.
  3. Press the Commit button!

Solution 25 - Git

This is worked for me to remove the file from bit bucket repo which I pushed the file to branch initially.

git checkout origin/develop <path-to-file>
git add <path-to-file>
git commit -m "Message"
git push

Solution 26 - Git

I copied the current files in a different folder, then get rid of all unpushed changes by:

git reset --hard @{u}

Then copy things back. Commit, Push.

Solution 27 - Git

From git 2.23 onwards, you can simply use this command:

git restore --staged <file>

Solution 28 - Git

Another approach that we can do is to :

  1. Delete the file
  2. Make a new commit with the deleted file
  3. Do an interactive rebase and squash both commits
  4. Push

Solution 29 - Git

If for any reason (as it was in my case) you'll have trouble reseting all files from the last commit - as in git reset --soft HEAD^ - and your case mets the following conditions, you can do as I explain below.

  1. the file you are trying to remove already existed in repository before the last commit
  2. you can undo all changes in the file since the previous commit (HEAD~2 - the commit just before the last commit)

You can then undo all the changes since the previous commit (HEAD~2), save the file, stage it (git add filename) and then run git commit --amend --no-edit. This will commit the "new changes" - which is actually recommitting the file to the last commit as it was before the last commit.

Solution 30 - Git

Keep the file locally (remove from git)

If you want to keep the file you can use --catch like so:

git rm --cached filename

enter image description here

Delete local file (and remove from git)

else if you want to delete the file just use:

git rm filename

enter image description here

Solution 31 - Git

  1. git reset --soft HEAD~1
  2. git reset HEAD /file/to/delete
  3. git rm --cached /file/to/delete
  4. git commit --amend -m "your message"
  • key point is the --amend

then can:

git push -u origin master

Solution 32 - Git

Here is the step to remove files from Git Commit.

>git reset --soft HEAD^1(either commitid ) -- now files moved to the staging area.
>git rm --cached filename(it will removed the file from staging area)
>git commit -m 'meaningfull message'(Now commit the required files)

Solution 33 - Git

Now that Apple has non-cosensually updated all MacOS users to zsh, the correct answer doesn't work anymore.

git reset --soft HEAD^
zsh: no matches found: HEAD^

You can prevent the shell from treating the ^ as a special character by single quoting it.

git reset --soft 'HEAD^'

Alternatively you can disable this behavior in your shell. by updating your ~/.zshrc with

unsetopt nomatch

Solution 34 - Git

None of the answers at this time are reasonable. Sounds like there is enough demand that a real solution should be proposed: https://github.com/git/git/blob/master/Documentation/SubmittingPatches

> git --uncommit <file name>

would be nice. I get that we do not want to modify history, but if I am local and accidentally added local "hack" file and want to remove it from the commit this would be super helpful.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLollyView Question on Stackoverflow
Solution 1 - GitjuzzlinView Answer on Stackoverflow
Solution 2 - GitCharlesBView Answer on Stackoverflow
Solution 3 - GitBrianView Answer on Stackoverflow
Solution 4 - GitphemmerView Answer on Stackoverflow
Solution 5 - GitParitosh SinghView Answer on Stackoverflow
Solution 6 - GitBob FlannigonView Answer on Stackoverflow
Solution 7 - GitMoaz RashadView Answer on Stackoverflow
Solution 8 - GitDenis ShchepetovView Answer on Stackoverflow
Solution 9 - GitThatsAMoraisView Answer on Stackoverflow
Solution 10 - GitHamzaMushtaqView Answer on Stackoverflow
Solution 11 - GitBryan BuckleyView Answer on Stackoverflow
Solution 12 - GitJDiMatteoView Answer on Stackoverflow
Solution 13 - GitmattexxView Answer on Stackoverflow
Solution 14 - GitSergey OnishchenkoView Answer on Stackoverflow
Solution 15 - GitandrepoView Answer on Stackoverflow
Solution 16 - Gitwilo087View Answer on Stackoverflow
Solution 17 - GitMinh NguyenView Answer on Stackoverflow
Solution 18 - GitsaiyancoderView Answer on Stackoverflow
Solution 19 - GitcardamomView Answer on Stackoverflow
Solution 20 - Gituser1201303View Answer on Stackoverflow
Solution 21 - GitTanvirChowdhuryView Answer on Stackoverflow
Solution 22 - GitMattView Answer on Stackoverflow
Solution 23 - GittvenView Answer on Stackoverflow
Solution 24 - GitRonView Answer on Stackoverflow
Solution 25 - GitswathiView Answer on Stackoverflow
Solution 26 - GitMzqView Answer on Stackoverflow
Solution 27 - GitsuulisinView Answer on Stackoverflow
Solution 28 - GitYeikelView Answer on Stackoverflow
Solution 29 - GitWesley GonçalvesView Answer on Stackoverflow
Solution 30 - GitDevWLView Answer on Stackoverflow
Solution 31 - GitcrifanView Answer on Stackoverflow
Solution 32 - GitSheo Dayal SinghView Answer on Stackoverflow
Solution 33 - GitjoarView Answer on Stackoverflow
Solution 34 - GitBob9630View Answer on Stackoverflow