How to remove a commit from the middle of a branch

27,732

Solution 1

You can use interactive (-i) rebase to remove a previous commit.

$ git log                          # copy the target commit 

$ git rebase -i <target-commit>~1  # start rebase from the previous commit of target commit

An editor will open with a list of commits, one per line. Each of these lines begins with pick. Comment out your target commit's line (Put # at the start of target commit line).

OR, put drop or d instead of commenting out the line with #.

$ git rebase --continue      # repeat the command until finish rebase

Now, you need to do force (-f) push to remote since git history has been changed!

$ git push -f origin HEAD 

Solution 2

The flag --rebase-merges should be considered in answer, becasuse accepted solution will remove merge commit between HEAD and target commit~1

Example:

Before any rebase:

f3e07b4 (HEAD -> dev, origin/dev) headCommit
dd3d182 Merged PR 425: added playoutServerUsage
7ed3eb5 added playoutServerUsage
03b52af feat: add Description Series  #targetCommit
0a1217c some_older_commit

git rebase -i target-commit~1

c11fa07 (HEAD -> dev) headCommit
7ed3eb5 added playoutServerUsage
0a1217c some_older_commit

git rebase -i target-commit~1 --rebase-merge

a1943b6 (HEAD -> dev) headCommit
12411a1 Merged PR 425: added playoutServerUsage
7ed3eb5 added playoutServerUsage
0a1217c some_older_commit

Rebase with flag --rebase-merges can be harder and whole process will bo longer (bigger tree), but still we have to locate target commit and change 'pick' to 'drop'

After that I would recommend using

git push --force-with-lease origin HEAD 

instead force only.

force vs force-with-lease

PS. It is worth paying attention which commit hashes was changed

Share:
27,732
Russiancold
Author by

Russiancold

Updated on July 17, 2022

Comments

  • Russiancold
    Russiancold almost 2 years

    I've made some commits and have pushed it to my remote repo. One of those I want to remove. It includes only one binary file, which was changed only in that commit in that branch. How to remove it without harm for later commits?

    • CollinD
      CollinD about 7 years
      git rebase -i TARGET_COMMIT~1 and then don't pick TARGET_COMMIT I think would work.
    • kolejnik
      kolejnik about 7 years
      In @CollinD solution, you will have to force your push to remote repository (preferred --force-with-lease), because your changes won't be possible to fast-forward. If you want to avoid those issues, you can git revert this commit.
  • AKSHAY SHINGOTE
    AKSHAY SHINGOTE about 7 years
    What will happen after the last step i.e push -f ??
  • Sajib Khan
    Sajib Khan about 7 years
    @AKSHAYSHINGOTE your remote (origin here) will be updated (removed the commit from git history).
  • Joshua Pinter
    Joshua Pinter over 4 years
    Nailed it, thanks for this. NOTE: If you want to be more explicit, you can also use drop or d instead of commenting out the line with #.
  • Sajib Khan
    Sajib Khan over 4 years
    Yes, that's right @joshu Pinter. Updated answer. Thanks!
  • tejasvi88
    tejasvi88 over 3 years
    Is there an alternative that doesn't involve force push, and records this commit "deletion"?
  • Sajib Khan
    Sajib Khan over 3 years
    @tejasvi88 to delete a commit is like changing git history so, there is no alternative way except force push! (so far I know)
  • KJanek
    KJanek almost 3 years
    Why no one talk about flag --rebase-merges ? It should be considered in answer, becasuse this solution will remove merge commit between HEAD and target commit+1