So here’s the scenario. I’ve got a script that runs some tests. I need to make another script that accepts as a parameter a git commit name and then does the following:
- Saves the current commit state – branch name or unnamed commit.
- Switches to a detached HEAD at the specified commit
- Runs the test script against that commit
- Switches back so HEAD is the same as it was before this business
I need to make sure this script is robust so that it’s never destructive no matter the state of the repository. It should work when it’s run from a detached HEAD or from a regular branch, and preferably it should work even when there are uncommitted or unstaged changes around.
I feel like this should be an easy question to answer, since running a test script against a previous commit seems like a really common task to want to automate. But I can’t seem to find any simple series of commands to do it.
(Similar to what pushd / cd / popd do for current working directory).
If it’s in a script, for only this one use case, you don’t need to do anything super-fancy, just store where HEAD was before, and check it out again after:
This has the advantage of working no matter what you do in the middle – in particular you could do a lot of git operations there – perhaps a test merge, or cherry-pick a commit for testing (maybe testing that commit, maybe it contains some build configuration settings purely for testing). Since those operations create commits, they’d cause the
HEAD@{1}approach to fail (you’d wantHEAD@{2}instead). Even better, if your testing actually involves creating temporary branches, this will still work, while the@{-1}approach would not.(Plus, as far as I can tell,
HEAD@{1}always checks out the commit referred to by HEAD at that point, not the branch that was then pointing to that commit. That kind of makes sense, as the branch could’ve conceivably changed since then.)