Parm
Parm

Reputation: 578

How to save current changes in repo, go back to an old commit, go back to most recent commit, and restore changes?

Scenario

Long story short, I need to go back to an old commit to run some code, but I eventually want to come back to the most recent commit. However, I've made some changes that I'm not ready to commit.

For this reason, I want to stash my current changes, then go back to the old commit, do what I need to do, then come back to the most recent commit, and restore the changes I originally made.

Note: This is all on one branch

Question

What's the best way to go about doing this?

My ideas

I was think of doing something like:

git stash push
git checkout <old_commit_hash>
#Do some stuff
git checkout <most_recent_commit>
git stash pop

Another idea is to commit my current changes. Eventually when I return to this commit, I could create another commit to finalize my work, and then use git rebase to squash them into one new commit.

Upvotes: 1

Views: 1178

Answers (1)

torek
torek

Reputation: 490068

You could do either of the two things you mentioned (modulo the correction eftshift0 mentioned in a comment). I personally recommend avoiding git stash as much as possible, though; it has too many corner cases and tricky bits. Committing now has a lot to recommend it.

What I would do, though, regardless of whether I made a commit right now, is use git worktree add to create a detached-HEAD working tree at the old commit. This leaves your existing work undisturbed. The new working tree is just as good as having made a separate git clone and run git checkout hash, with two things being different:

  • you didn't have to make a separate git clone, and
  • the added working tree actually uses the current Git repository, so Git forbids it from being on the same branch as the main working tree, but other Git items are shared.

In particular, things like git stash push (to create a new stash) or git checkout -b (to create a new branch) work in the shared repository, creating a stash or branch name that you can see from either working tree. This has various positives and negatives, but overall it's pretty minor. The extra working tree, though, lets you build and run the old commits—in detached-HEAD mode—and accomplish things you need to, without messing with your current working tree, so you can leave in-progress stuff, temporary files, inputs, outputs, and so on cluttering it up if that's useful. You can also clutter up the added working tree with inputs and outputs, if that's useful: these are separate working trees (different directory trees on your local file system) so they do not interfere with each other.

One caveat: before using git worktree add, make sure your Git is at least version 2.15. If your Git predates 2.5, you don't have git worktree at all and you would need to upgrade your Git. If you have a Git version of 2.14 or lower, be sure you get everything done in an added working tree within two weeks, then remove it.

For details on git worktree, see its documentation. A simple git worktree add --detach ../old-commit a123456 would work to check out old commit a123456. (Technically, you don't need the --detach, but I like the idea of being explicit here.)

Upvotes: 2

Related Questions