0

While changing my code I have made several commits to my Git repo (and pushing each set of changes). As I now need to reinstate an earlier commit to make unrelated changes, I want to save the current code as a branch that I can later return to.

Here is what I want to do. Let's take the commit I want to reinstate as repo_v6. Since then I have made various changes (repo_v6, repo_v7 etc), so that I now have repo_v9:

  1. repo_v6 <--- I want to go back to this
  2. make changes, commit as repo_v7
  3. make changes, commit as repo_v8
  4. make changes, commit as repo_v9 <--- my current tip

I want to go back to repo_v6, but keep the changes I made between repo_v6 and repo_v9 in a safe place in case I want to use them later.

My repo contains just the master branch, as - not expecting to need branches - I did not create a branch earlier. Though I have read several help topics, I cannot see how to go back - and put aside but keep the changes - without having cretaed a branch earlier. Having never created branches in the past, I do not know what to do. Please can you advise?

I am the only developer who uses the repo, so do not need to consider changes made by others.

finch
  • 549
  • 1
  • 6
  • 18
  • 2
    did you try `git branch myNewBranchName` and then `git checkout myNewBranchName` ? then you can go back to `master` by `git checkout master` – Ahmad Sep 10 '20 at 10:19
  • Please read this: https://www.atlassian.com/git/tutorials/using-branches#:~:text=A%20branch%20represents%20an%20independent%20line%20of%20development.&text=The%20git%20branch%20command%20lets,checkout%20and%20git%20merge%20commands. – Ahmad Sep 10 '20 at 10:22
  • @Ahmad Thanks, but I am still not clear what to do.I have edited my question to make clearer what I want to do. I suspect the challenge is that I did not create a branch earlier. I now realise I need to go back to an earlier point, but want to preserve my changes for possible later use, then go back to an earlier commit without the changes. – finch Sep 10 '20 at 12:58
  • Does this answer your question? [Move the most recent commit(s) to a new branch with Git](https://stackoverflow.com/questions/1628563/move-the-most-recent-commits-to-a-new-branch-with-git) Assuming you don't want to keep your commits v6 to v9 on the current branch and just branch out from an older point like explained [here](https://stackoverflow.com/questions/2816715/branch-from-a-previous-commit-using-git) – Daemon Painter Sep 10 '20 at 13:22
  • Just to be clear: you want newBranchName to point to repo_v9, and you want master to essentially the same code as repo_v6, correct? – John Szakmeister Sep 11 '20 at 01:04
  • @John, yes, exactly. I want newBranchName to point to repo_v9, and I want master to essentially the same code as repo_v6. – finch Sep 11 '20 at 08:44
  • @finch See my answer below. This is another way (via rewriting history) but I don't like to introduce that to folks new to Git because it's easy to lose your work and can be difficult getting it back when you don't know where to look. :-) – John Szakmeister Sep 11 '20 at 09:07

2 Answers2

2

The easy way to create a branch from a specific commit is via git branch. In this case, you have two options. You can use:

git branch newBranchName repo_v9

where you explicitly create a branch from repo_v9, or since it's the current tip of master, and that's what you have checked out, you can drop the repo_v9 and run:

git branch newBranchName

In this case, it'll infer the commit (HEAD), which points to the tip of master, since that's the current branch you are on.

From there you really have two options: 1) forcibly roll back the commits as though they never happened, 2) essentially revert the commits introduced since repo_v6. Since 1) involves rewriting history and is not conducive to working with a team, and since master tends to be the development branch of choice for teams, we'll look at option 2).

Revert the individual commits

You can use the git revert command to "undo" commits. In this case, you can revert the whole series of them with:

git revert repo_v7..master

This will undo all the commits starting with repo_v7 going to the tip of master. This isn't a great option for lots of commits because it's create a new commit for every commit that is being reverted. And it will pop up the editor for each of them. You can avoid that with the --no-edit option, but there is another way too.

Revert the tree

When many commits are involved, this is the option I use. You simply checkout the files from the version you want, and then commit the result:

git checkout repo_v6 .
git commit

The git checkout will make your working tree look like the contents at repo_v6. Everything will be staged and ready to go as the index is updated to match as well. Then you just commit the result.

John Szakmeister
  • 44,691
  • 9
  • 89
  • 79
  • Thanks. I did what you suggested, but find that HEAD is detached. What do you suggest? I did `git branch newBranchName`, then `git checkout `. I then realised I missed out the ending period, so redid this as `git checkout .`. But `git status` and now `git commit` show the HEAD detached. – finch Oct 01 '20 at 14:31
  • 1
    @finch Right, so `git checkout ` switches the tree away from the branch and checks out that specific commit, putting you in a detached head state. You'll want to be on the branch you want to roll back (say master) using `git checkout`: `git checkout master`. Then run `git checkout .`. This latter form says "make the current working tree (for the current branch) look as it did in ``". At that point, you should be able to commit again. Hope that helps! – John Szakmeister Oct 02 '20 at 08:44
  • Thanks John, your explanation seems to have fixed it. HEAD is no longer detached. – finch Oct 11 '20 at 16:02
0

Step 1 (optional): If you have any uncommitted changes, stash them

git stash

Step 2: Checkout the commit you want to go back to

git checkout repo_v6

Now do what it is you need to do with this version. Note that you are in a detached-head state (not on a branch). If you need to make new commits on top of this one (and not the tip of master), you will need to make a new branch here. git checkout -b new_branch When you are done:

Step 3: Checkout master again

git checkout master

Step 4 (optional): If you stored a stash. restore it

git stash pop
David Sugar
  • 1,042
  • 6
  • 8