Skip to content

Pass through the exit code of post-checkout #385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

dscho
Copy link
Member

@dscho dscho commented Oct 10, 2019

This is my attempt to revive an old discussion (related to this StackOverflow thread).

[...] is this the right behavior for "git checkout" to have? I.e. is it useful for "git checkout" to fail when the post-checkout hook fails, or would it be better for it to e.g. simply print a message and exit with status 0?

To answer Jonathan's question, at long last, yes, it is useful. A hook is not only an opportunity to run code at given points in Git's life cycle, but also an opportunity to stop Git in its tracks. Further, if you script the operation, it may very well be useful to discern between an exit code from Git's operation from an exit code produced by your hook.

If you don't want your git checkout/git switch/git restore to fail due to a post-checkout failure, just make sure that that hook does not fail ;-) (This could easily be achieved by trap EXIT { exit 0; }, I believe.

I discovered, however, that the original patch contribution missed that a git checkout -b <branch> will not pass through the exit code, but instead return exit code 1. As part of my contribution, I fix this, and also introduce a regression test to document the now-consistent behavior.

Cc: Jonathan Nieder [email protected], Magne Land [email protected]

Currently, the exit code of the `post-checkout` hook becomes the exit
code of the `git restore` (or the equivalent `git checkout`) command,
_iff_ no error occurred during the `restore` operation.

That allows versatile scripting where the `post-checkout` failure modes
can be discerned from the `git restore` failure modes.

There is a problem, though: if that `git restore` operation fails
_before_ the `post-checkout` hook is run, -1 is returned from the
`checkout_paths()` function, which yields the misleading exit code 127
(which is reserved to indicate "command not found").

Another problem: a non-zero exit code of the `post-checkout` hook as run
at the end of a `git switch` run will always causes that command to exit
with exit code 1.

This is inconsistent. Let's pass through the exit code of the
`post-checkout` hook verbatim (unless the Git operation fails, in which
case we want to exit with code 1, even if the hook returns another exit
code).

Document this, and add a regression test for this behavior, too.

Inspired-by-a-patch-by: Magne Land <[email protected]>
Signed-off-by: Johannes Schindelin <[email protected]>
@dscho
Copy link
Member Author

dscho commented Oct 10, 2019

/submit

@gitgitgadget
Copy link

gitgitgadget bot commented Oct 10, 2019

Submitted as [email protected]

@gitgitgadget
Copy link

gitgitgadget bot commented Oct 11, 2019

On the Git mailing list, Junio C Hamano wrote (reply to this):

"Johannes Schindelin via GitGitGadget" <[email protected]>
writes:

> To answer Jonathan's question, at long last, yes, it is useful. A hook is
> not only an opportunity to run code at given points in Git's life cycle, but
> also an opportunity to stop Git in its tracks.

In general that is correct, and especially so for pre_$git_action
hooks, which are about interfering and vetoing an action that is
being carried out.

On the other hand, post_$git_action hooks are specifically defined
as a way to trigger an extra action and documented that they cannot
affect the outcome of the operation (in other words, they trigger at
a point in the operation flow that is too late to affect the
outcome).

Now, it is somewhat debatable how the "outcome" should be defined.
A post-rebase hook that drops the last commit in the sequence, for
example, should not be allowed (the rebase has rebuilt a sequence
and that final sequence of commits should be left), but should it be
allowed to signal back to "git rebase" and affect its exit status?

I am not 100% sure if it is a good idea to allow post-checkout to
affect the exit status of "git checkout" or its friends.  If one
codepath in "git checkout" or its friends lets post-checkout to
influence the exit status while another codepath ignores, it makes
sense to discuss if the inconsistency needs to be removed, but in
such a case, I think it would make sense to unify in the direction
of ignoring (i.e. not allowing post-* hook to affect the outcome).


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant