1

I saw the solutions on undo the last / last x commits in Git.
What I want to know is how to undo the commits that are pushed 2 months ago. I want to undo just the commits in the middle of the commits, but want to keep the other commits.

for example:

commit 1  ----  2 mins ago
commit 2  ----  1 day ago
....
commit 105  ---  2 months ago
commit 106  ---  2 months ago
commit 107  ---  3 months ago
....

In the example, I want to reverse commits 105 and 106, but keep the other commits as they are.

JShobbyist
  • 532
  • 3
  • 9
  • 23

2 Answers2

2

git revert will create a new commit that undoes the changes that made in the target commit. So in your example, you would run git revert 105 106 and this will make 2 new commits that remove the changes that were made in those commits.

If you only wanted to undo the changes from only one file in the those commits, you can do git reset HEAD~2 (This assumes that you have 2 reverted commits). Then you can git checkout the files that you don't want to have the changes undone. Once that is done, you can git add and git commit to undo the changes to only the specific files.

Schleis
  • 41,516
  • 7
  • 68
  • 87
1

You have two options:

revert the commits

This will create new commits on top of the current commits removing the changes applied in commits 105 and 106 and the commits will still be present in the git log.

git revert 106 105

drop the commits with rebase

This will completely remove the commits from the history as they have never existed, but all of the following commits will be re-applied on top of commit 104 and they'll have different hashes

git rebase 105~1 --interactive

Git will open your $EDITOR with list of commits followed by a long comment with all of the options

pick 105 Commit message
pick 106 Commit message
pick 107 Commit message
pick 108 Commit message

# Rebase 7fd6a37..9141cc2 onto 7fd6a37 (4 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
#         create a merge commit using the original merge commit's
#         message (or the oneline, if no original merge commit was
#         specified); use -c <commit> to reword the commit message
# u, update-ref <ref> = track a placeholder for the <ref> to be updated
#                       to this position in the new commits. The <ref> is
#                       updated at the end of the rebase
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#

to remove the commits you can either change pick top drop on the first two lines, or delete the first two lines.

If you remove a line here THAT COMMIT WILL BE LOST.

Once saving the opened file and exiting the $EDITOR git will remove the commits and re-apply the rest on top. Then you should force push the changes (assuming you have the privileges, as it's probably a protected branch)


presuming the commit numbers are their hashes

Teneff
  • 30,564
  • 13
  • 72
  • 103