Add a simple hook that will run before checkouts. Signed-off-by: Sam Vilain <sam.vilain@xxxxxxxxxxxxxxx> --- Documentation/githooks.txt | 20 +++++++++++++++----- builtin-checkout.c | 25 ++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index 06e0f31..8dc3fbf 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -143,21 +143,31 @@ pre-rebase This hook is called by 'git-rebase' and can be used to prevent a branch from getting rebased. +pre-checkout +----------- -post-checkout -~~~~~~~~~~~~~ - -This hook is invoked when a 'git-checkout' is run after having updated the +This hook is invoked when a 'git-checkout' is run after before updating the worktree. The hook is given three parameters: the ref of the previous HEAD, the ref of the new HEAD (which may or may not have changed), and a flag indicating whether the checkout was a branch checkout (changing branches, flag=1) or a file checkout (retrieving a file from the index, flag=0). -This hook cannot affect the outcome of 'git-checkout'. +This hook can prevent the checkout from proceeding by exiting with an +error code. It is also run after 'git-clone', unless the --no-checkout (-n) option is used. The first parameter given to the hook is the null-ref, the second the ref of the new HEAD and the flag is always 1. +This hook can be used to perform any clean-up deemed necessary before +checking out the new branch/files. + +post-checkout +----------- + +This hook is invoked when a 'git-checkout' is run after having updated the +worktree. It takes the same arguments as the 'pre-checkout' hook. +This hook cannot affect the outcome of 'git-checkout'. + This hook can be used to perform repository validity checks, auto-display differences from the previous HEAD if different, or set working dir metadata properties. diff --git a/builtin-checkout.c b/builtin-checkout.c index d050c37..b72a3cb 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -36,6 +36,17 @@ struct checkout_opts { enum branch_track track; }; +static int pre_checkout_hook(struct commit *old, struct commit *new, + int changed) +{ + return run_hook(NULL, "pre-checkout", + sha1_to_hex(old ? old->object.sha1 : null_sha1), + sha1_to_hex(new ? new->object.sha1 : null_sha1), + changed ? "1" : "0", NULL); + /* "new" can be NULL when checking out from the index before + a commit exists. */ +} + static int post_checkout_hook(struct commit *old, struct commit *new, int changed) { @@ -256,6 +267,13 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec, if (errs) return 1; + /* Run the pre-checkout hook */ + resolve_ref("HEAD", rev, 0, &flag); + head = lookup_commit_reference_gently(rev, 1); + errs = pre_checkout_hook(head, head, 0); + if (errs) + return 1; + /* Now we are committed to check them out */ memset(&state, 0, sizeof(state)); state.force = 1; @@ -279,9 +297,6 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec, commit_locked_index(lock_file)) die("unable to write new index file"); - resolve_ref("HEAD", rev, 0, &flag); - head = lookup_commit_reference_gently(rev, 1); - errs |= post_checkout_hook(head, head, 0); return errs; } @@ -543,6 +558,10 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new) parse_commit(new->commit); } + ret = pre_checkout_hook(old.commit, new->commit, 1); + if (ret) + return ret; + ret = merge_working_tree(opts, &old, new); if (ret) return ret; -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html