@@ -7,6 +7,107 @@ description: >-
77
88# Recipes
99
10+ ## Customization
11+
12+ ### Auto-track branches on checkout
13+
14+ <!-- gs:version unreleased -->
15+
16+ Git's post-checkout hook can be used
17+ to invoke git-spice automatically when a branch is checked out,
18+ and track the branch with git-spice if it is not already tracked.
19+
20+ ** Prerequisites:**
21+
22+ - git-spice <!-- gs:version unreleased -->
23+ - Git hooks are enabled
24+ (this is the default, but certain setups may disable them)
25+ - The repository is already initialized with git-spice ($$ gs repo init $$ )
26+
27+ ** Steps:**
28+
29+ 1 . Copy this script under ` .git/hooks/post-checkout ` in your repository.
30+
31+ ??? example ".git/hooks/post-checkout"
32+
33+ ```bash
34+ #!/usr/bin/env bash
35+ set -euo pipefail
36+
37+ # post-checkout is invoked with:
38+ # $1 - ref of the previous HEAD
39+ # $2 - ref of the new HEAD
40+ # $3 - 1 for a branch checkout, 0 for a file checkout
41+ shift # old SHA
42+ shift # new SHA
43+ checkout_type=$1
44+
45+ # Ignore non-branch checkouts.
46+ if [[ "$checkout_type" -eq 0 ]]; then
47+ exit 0
48+ fi
49+
50+ # Don't do anything if this was invoked during a git-spice operation;
51+ # if git-spice runs checkout, let it do what it's doing without interference.
52+ if [[ -n "${GIT_SPICE:-}" ]]; then
53+ exit 0
54+ fi
55+
56+ # post-checkout hook does not receive the branch name,
57+ # so get it from the new HEAD.
58+ branch_name=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
59+ if [[ -z "$branch_name" ]]; then
60+ exit 0 # not a branch
61+ fi
62+
63+ # ...and verify it's actually a local branch.
64+ if ! git show-ref --verify --quiet refs/heads/"$branch_name"; then
65+ exit 0
66+ fi
67+
68+ # Don't attempt to track trunk.
69+ trunk_name=$(gs trunk -n 2>/dev/null || echo "master")
70+ if [[ "$branch_name" == "$trunk_name" ]]; then
71+ exit 0
72+ fi
73+
74+ # Check if the branch is already tracked by git-spice
75+ # by poking at the internals. (gs ls --json will be slower here.)
76+ #
77+ # Warning: This may break if git-spice's internal storage format changes.
78+ if ! git rev-parse --verify --quiet refs/spice/data:branches/"$branch_name" >/dev/null; then
79+ echo >&2 "Branch not tracked with git-spice: '$branch_name'. Tracking it now..."
80+
81+ # We use 'downstack track' so that if there are any untracked branches
82+ # downstack from this one, they get tracked too.
83+ gs downstack track "$branch_name"
84+ fi
85+ ```
86+
87+ 2 . Make sure the script is executable.
88+
89+ ``` bash
90+ chmod +x .git/hooks/post-checkout
91+ ```
92+
93+ 3. Test it out by checking out an untracked branch.
94+
95+ ` ` ` bash
96+ git checkout -b my-feature main
97+ ` ` `
98+
99+ ** How this works:**
100+
101+ - The post-checkout hook is invoked by Git after a checkout operation,
102+ whether with ` git checkout` or ` git switch` .
103+ - The script checks ` GIT_SPICE` (added in < ! -- gs:version unreleased --> )
104+ to ensure it does not interfere
105+ with git-spice' s own operations (e.g. $$gs branch checkout$$).
106+ - It checks whether the new branch is already tracked by git-spice
107+ by looking inside its internal storage ([Internals](../guide/internals.md)).
108+ - If the branch is not tracked, it invokes $$gs downstack track$$
109+ to track the branch and any untracked branches downstack from it.
110+
10111## Workflows
11112
12113### Create branches without committing
0 commit comments