4

Suppose I have commits A-B-C-D-E-F. Note that all the commits have been pushed upstream.

I want to revert to commit D, but also want to keep commits E and F in the branch.

So what I want to do is to create a commit G, which will have the same contents as D. In the end my branch will look like A-B-C-D-E-F-G, with D=G.

How do I do this?

Braiam
  • 1
  • 11
  • 47
  • 78
Filipe Aleixo
  • 3,924
  • 3
  • 41
  • 74
  • You can use `git revert E F`, but it will create two commits to revert each of E and F. – choroba May 12 '21 at 09:54
  • @choroba the sequence was just for illustration. There are actually many more commits where E and F are, so this wouldn't be a solution unfortunately. – Filipe Aleixo May 12 '21 at 09:58
  • 1
    Not sure why this isn't a solution if you have more than 2 commits. You can squash all the new ones, no? – Scratte May 12 '21 at 10:00
  • Does this answer your question? [Rollback to an old Git commit in a public repo](https://stackoverflow.com/questions/2007662/rollback-to-an-old-git-commit-in-a-public-repo) – Joe May 12 '21 at 11:27

1 Answers1

4

You just have to take the exact content of D, and create a commit with that content :

# choose a. or b. :
# a. 'git restore' was added for this purpose in version 2.25,
#    and has options which are more explanatory (readable at least) :
git restore --source D --staged --worktree -- .

# b. for older gits, or for people enjoying more obscure commands, there is 'git read-tree' :
git read-tree D

# after that :
# confirm that the content you expect is staged, and commit :
git status
git commit

one word of caution: git restore with the --worktree option can delete files and discard modifications from files that aren't stored in git yet -- much like git reset --hard.

It is advised to use this command on a clean worktree, or at least check that you can throw away your current modifications.

LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • 2
    `--source` is more readable than `-s`, when mentioning explanatoriness and readability. – choroba May 12 '21 at 10:29
  • 1
    Another way with the same principle: `git checkout D; git reset --soft F; git commit -m "Reverting E and F"`. Feel free to set a branch where you are standing at that point. – eftshift0 May 12 '21 at 13:18
  • Need to get `git restore` into my toolbox. – eftshift0 May 12 '21 at 13:19
  • Are you sure? I don't think so. `git reset --soft` would just move the branch _pointer_ to `F` but the working tree and index would remain with what is in `D`. If you commit right after that you end up with `G` that follows `F` and that has the same content of `D`. – eftshift0 Feb 28 '23 at 14:25
  • Nou problemo!!! – eftshift0 Feb 28 '23 at 15:05