Reputation: 36452
How do I remove a file from the latest commit?
Upvotes: 2338
Views: 2342384
Reputation: 230
Already quiet a few have tried to solve the issue, here is what worked for me
git revert -n <commit hash>
-n flag is used to revert the changes from the specified commit without creating a new commit immediately. Then, remove the file(s) you don't want using the next command
git reset HEAD <file names to keep>
git commit -m "removed files form commit"
git push origin branch-name
Upvotes: -2
Reputation: 2169
For those of you who are not as nerdy as all the other answers require, and you like to use the desktop app, this answer is for you.
Using the GitHub Desktop app for Windows, you can click on the History tab. Then right click on the commit you messed up, and select "Undo commit...". This will bring all the files back to your staging area and you can start over.
Upvotes: 0
Reputation: 47945
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
EDIT: The easiest way to do this is to use e.g. git gui
. Just select Commit => Amend Last Commit
and simply uncheck the desired file from the commit and click Commit
.
Upvotes: 4297
Reputation: 574
The best way is to use a SourceTree (or you can do it from Command Line also, as you want) and:
git reset --soft
to the commit before the commit you want to changestage
/unstage
) the files you don't want :) Upvotes: 0
Reputation: 574
git rm -r ./* --cached
this will remove all cached/staged files
Upvotes: 2
Reputation: 18860
If you want to keep the file you can use --cached
like so:
git rm --cached filename
else if you want to delete the file just use:
git rm filename
Upvotes: 20
Reputation: 14338
git reset --soft HEAD~1
git reset HEAD /file/to/delete
git rm --cached /file/to/delete
git commit --amend -m "your message"
then can:
git push -u origin master
Upvotes: 7
Reputation: 1435
From git 2.23 onwards, you can simply use this command:
git restore --staged <file>
Upvotes: 1
Reputation: 31302
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:
git log --graph --decorate --oneline
git checkout <commit_id> <path_to_file>
you can do this multiple times if you want to remove many files.
3.
git commit -am "remove unwanted files"
4.
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>
5.
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.
6.
To finish :
git push -f
If you unfortunately get conflicts, you have to solve them manually.
Upvotes: 234
Reputation: 493
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
Upvotes: 0
Reputation: 2305
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.
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.
Upvotes: 1
Reputation: 935
Another approach that we can do is to :
Upvotes: 3
Reputation: 2201
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.
Upvotes: 6
Reputation: 1683
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)
Upvotes: 0
Reputation: 1850
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.
Upvotes: 31
Reputation: 953
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.
Upvotes: -1
Reputation: 1864
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.
Upvotes: 2
Reputation: 2445
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
Upvotes: 3
Reputation: 529
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
Upvotes: 6
Reputation: 1075
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>
Upvotes: 47
Reputation: 31
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
Upvotes: 1
Reputation: 7441
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)
Upvotes: 4
Reputation: 1998
If you're using GitHub and haven't yet pushed the commit, GitHub Desktop solves this problem easily:
Upvotes: 1
Reputation: 90496
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:
git rm <file>
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!
Upvotes: 446
Reputation: 547
If you dont need that file anymore, you could do
git rm file
git commit --amend
git push origin branch
Upvotes: 3
Reputation: 8846
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.
Upvotes: 321
Reputation: 41
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)
Create a local branch from my origin/feature/target_branch - called it feature/staging
Merged my working local branch feature/target_branch to the feature/staging branch
Checked out feature/staging then git reset --soft ORIG_HEAD (Now all changes from the feature/staging' will be staged but uncommitted.)
Unstaged the file which I have previously checked in with unnecessary changes
Changed the upstream branch for feature/staging to origin/feature/target_branch
Committed the rest of the staged changes and pushed upstream to my remote origin/feature/target_branch
Upvotes: 3
Reputation: 7881
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'
Upvotes: 6
Reputation: 455
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.
Upvotes: 3
Reputation: 71
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!
Upvotes: 6