Reverting to a specific commit without losing history
Asked Answered
I

5

28

I know this type of a question has a lot duplicates, but I wanted to open a new one because I didn't found in all of the other questions the explaination of the best way to do it as I want.

I know i can revert and keep the history by doing:

git reset --soft c14809fa

I want to revert the development branch and keep the history on a different branch.

If I checkout the development to a new branch before I revert the commits - For example

git checkout -b beforeRevert

Than I will checkout back to the development branch and do the reveting ( because I want to continue working on the data from the commits i had revert to )

The other branch, beforeRevert branch, will keep all the history and data of the "before reverting" that will use again someday, but won't include in the current development branch? Or the reverting on the development branch will somehow effects the beforeRevert branch?

Integrated answered 29/9, 2015 at 10:31 Comment(0)
E
31

If you're sure that neither soft reset nor creating multiple branches work for your use case, you could do

git diff HEAD commit_hash_to_go_to | git apply

This will create a diff of changes between the latest commit on your branch and the commit with the desired state and automatically apply it. That will simply change the files, it's your job to add them to staging and commit the result. Might be useful if you want to try out different solutions and keep the history of your changes WITHIN the same branch or avoid multiplying local branches.

If you encounter "cannot apply binary patch to without full index line" error, add --binary flag:

git diff HEAD commit_hash_to_go_to --binary | git apply

Before doing this ensure that you've got no uncommitted changes - otherwise the patch won't be applied (it's atomic so either all changes go through or none, so you won't end up in an inconsistent state)

NOTE: this simply changes the files and marks them as modified. It does NOT alter commit history or create new commits

HINT: If you just want undo the last commit, you can do

git diff HEAD HEAD~1 | git apply

The "~1" is how much commits you want to go back. In this case only 1 commit back.

Estimate answered 17/12, 2018 at 14:28 Comment(3)
I did this.. but I had some reverse merge to my branches in between so I could not pull those changes back since this creates a forward commit..Dumbfound
@Dumbfound That's weird since git diff only operates on local files without touching commits at all. Probably you applied a diff on files and then committed a result. If so and the commit wasn't pushed upstream, you could try git revert to undo the changesEstimate
And how would one do this on Windows, which doesn't have |?Decato
B
13

The easiest thing to do, like you say, would be to simply create a new branch where HEAD is and then revert development to the commit you want to resume work from:

git checkout development   # Make HEAD point to the 'development' branch
git branch beforeRevert    # Create a new branch reference pointing to HEAD
git reset --hard c14809fa  # Move HEAD, the index and your working copy to c14809fa

Here's a graphical representation of what will happen:

    Step 1               Step 2                  Step 3

            develop    develop, beforeRevert   develop   beforeRevert
           /                    /             /         /
A-B-C-D-E-F          A-B-C-D-E-F             A-B-C-D-E-F
          ^                    ^             ^
         HEAD                 HEAD          HEAD

The important thing here is that HEAD is always pointing to the development branch, so that's the branch that gets moved when you run git reset --hard c14809fa. The new beforeRevert branch will still point to where HEAD was before the revert.

Bangui answered 29/9, 2015 at 11:22 Comment(2)
It sounds like what I wanted to do. Let me check it and I'll approve your answer. Thanks!Integrated
Answer approved?Reginaldreginauld
S
1

Don't revert your changes, just go back to a previous commit and then checkout a new branch from there.

git checkout development
git checkout c14809fa
git checkout -b newBranch

This way you can visit the 'development' branch to see old changes and history and you can make further changes in 'newBranch'

You can rename the branches if you want the other way around using -

git branch -m <oldname> <newname>
Swigart answered 29/9, 2015 at 10:39 Comment(4)
You can do it in one go: `git checkout -b newBranch c14809fa'Mckeown
This gets the branches the wrong way around. OP wants the new branch to point to where he is currently and the development branch to point to the old commit.Craze
The simple way, as I mentioned, would be to rename the branches later using 'git branch -m <oldname> <newname>'. Just swap the branch names for both the branches.Swigart
Enrico Campidoglio's answer is more correct, I think.Swigart
B
1

Found the answer here

git reset --hard oldestCommitHash
git reset --soft mostRecentCommitHash #
git commit
  • This will preserve your history but move you back to the same state as oldestCommitHash
  • Note the # after mostRecentCommitHash is intentional and needs to be present
Burgage answered 9/8, 2023 at 0:20 Comment(0)
H
-2

git merge <old commit>

This will create a new commit (with message of your choosing) which restores your working space back to

Henslowe answered 5/10, 2021 at 20:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.