Remove Specific Files from Old Git Commit
tldr; Skip to solution »
Last week, I encountered a merge conflict while trying to sync my git working branch to latest remote
master. Merge conflicts is not a serious problem to me, I am used to resolving conflicts. But the conflict that I encountered is from an auto generated typings file from
Apollo Codegen file is
TypeScript typings for the schema and queries in project that uses GraphQL. The generated file often has >10k lines of code. Trying to resolve conflict in that file will make the text editor unresponsive (even with Vim!).
So I aborted the sync master (
git rebase --abort), then attempt to remove the changes for the auto-generated codegen file using lazygit
. Afterwards, I do sync remote
master branch and the conflict don’t happen. Last thing I do is regenerate the codegen file before posting a Pull Request.
Back to the post’s main topic, to remove specific file using plain old shell command.
First, checkout to temporary branch with the afore mentioned commit as
HEAD using the commit’s hash:
git checkout <commit-hash>
Then do a soft reset to uncommit with all files in staged status:
git reset --soft HEAD^
Make the desired file(s) unstaged using reset command, and then commit with
-c ORIG_HEAD flag to use the previous commit message. The
--no-edit flag is optional.
git reset <path/to/file>
git commit -c ORIG_HEAD --no-edit
Discard the changes of the file you want to remove from unstaged area:
git checkout -- .
rebase this temporary branch to your branch, from the commit of
git rebase --onto HEAD <commit-hash> <destination-branch-name>
If you do this for already merged Pull Request, you need to
push <remote> <branch> --force. Mind you, doing this will be inconvenient for other people working on same project.
As I mentioned above, I use lazygit
. The process is more straight forward. For the following example, I accidentally committed build file, far before I
build/ folder. What I do is:
Do this way if you want to install lazygit before doing your intention.
lazygit way is easier. I also use tig
as a TUI for
git, but I don’t know the command to do the steps wit