ideasman42
ideasman42

Reputation: 48028

How to checkout a git revision without changing working copy

Recently I've been using git with a system that applies patches as commits (Phabricator & Arcanist, but I don't think thats important for this question).

I often end up in the situation where I have a patch applied in the form of a commit, but I would like to edit that commit. Of course I can always make edits and git commit --amend, but I'd also like to be able to do git diff, use meld . and other tools which assume edits are made on-top of the last commit.

Currently I do the following.


git diff HEAD~1 > temp.diff
git reset --hard HEAD~1
git apply temp.diff
rm temp.diff

Edit patch...

git commit -a

However this seems a bit clumsy, Is there some way to set the git repository to a another sha1, but keep the current working copy intact?

Upvotes: 1

Views: 139

Answers (2)

torek
torek

Reputation: 488063

Depending on the exact behavior you want, git reset --soft and git reset --mixed will change the current commit to another commit (by rewriting the branch label if you're on a branch). Both of them do this sort of thing in terms of the commit graph:

[before `git reset`]

A - B - C - D   <-- HEAD=br1
      \
        E - F   <-- br2
          \
            G   <-- br3    [before `git reset`]

[after `git reset HEAD~1`]

            D   <-- only in reflog now
          /
A - B - C       <-- HEAD=br1
      \
        E - F   <-- br2
          \
            G   <-- br3

The difference is that git reset --soft leaves working directory and index intact, while git reset --mixed leaves working directory intact but changes the index to match the reset-to commit.

(For completeness, git reset --hard does what git reset --mixed does but also changes the work directory to match the reset-to commit. By saving the diff and then re-applying it with git apply you get the effect of git reset --mixed. If you plan to re-add everything, --soft probably makes more sense. Note that git commit --amend is essentially just git reset --soft && git commit in terms of commit-graph-and-index behavior.)

Upvotes: 2

VonC
VonC

Reputation: 1323953

You should be able to simplify your reset by using:

git reset @~

That will reset HEAD to the previous commit, and will reset the index, but not the working tree.
It used the default reset mode (like git reset --mixed)

A git diff should show you what that last patch was.
A git status should show you your last modified files, ready to be modified/added beck to the index and committed again.

Upvotes: 3

Related Questions