Skip to content

Commit 0ee5454

Browse files
committed
feat: add graphite
1 parent 5dbd6c4 commit 0ee5454

4 files changed

Lines changed: 370 additions & 263 deletions

File tree

links/git/.config/git/stoke.gitconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ name = Kyle Davis
33
email = kad-gh@stoke.com
44

55
[core]
6-
sshCommand = ssh -i ~/.ssh/id_kad_stoke
6+
sshCommand = ssh -i ~/.ssh/id_kad_stoke_ed25519

links/zsh/.graphite.zsh

Lines changed: 366 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
1+
#!/bin/zsh
2+
3+
# =============================================================================
4+
# Helper Functions
5+
# =============================================================================
6+
7+
8+
# Function to print an error message.
9+
alias print_err=">&2 echo Error: "
10+
11+
# Gets a string representation for the kind of repository we are in.
12+
#
13+
# Git repos print: "git"
14+
# Graphite prints: "graphite"
15+
# Anything else prints: "none"
16+
#
17+
function vcs_kind() {
18+
GIT_DIR=$(git rev-parse --git-dir 2> /dev/null)
19+
if [ -n "$GIT_DIR" ]; then
20+
GRAPHITE_CONFIG="$GIT_DIR/.graphite_repo_config"
21+
if [[ -f "$GRAPHITE_CONFIG" ]]; then
22+
echo "graphite"
23+
return 1
24+
else
25+
echo "git"
26+
return 1
27+
fi
28+
fi
29+
echo "none"
30+
}
31+
32+
# Prints a generic error message for an unknown vcs then exits.
33+
#
34+
# Note: Always return 1 after calling this function so the method will break
35+
# logical chains properly. (TODO: Can this be done automatically somehow?)
36+
function vcs_none() {
37+
print_err "$(pwd) is not managed by a known version control system"
38+
return 1
39+
}
40+
41+
# =============================================================================
42+
# Commands
43+
# =============================================================================
44+
45+
# Prints the current status of the repository.
46+
#
47+
# Accepts no arguments.
48+
function st() {
49+
if [ -n "$1" ]; then
50+
print_err "There should be no arguments, too many arguments provided."
51+
return 1
52+
fi
53+
54+
case $(vcs_kind) in
55+
git)
56+
git status
57+
return 0
58+
;;
59+
graphite)
60+
git status
61+
return 0
62+
;;
63+
*)
64+
vcs_none
65+
return 1
66+
;;
67+
esac
68+
}
69+
70+
# Prints a short graph of the current repository's commit structure. Alias
71+
# to force the git version even in graphite.
72+
function gsl() {
73+
if [ -n "$1" ]; then
74+
print_err "There should be no arguments, too many arguments provided."
75+
return 1
76+
fi
77+
78+
case $(vcs_kind) in
79+
git)
80+
git log \
81+
-10 \
82+
--graph \
83+
--abbrev-commit \
84+
--decorate \
85+
--format=format:'%C(bold blue)%h%C(reset) %C(bold green)(%ar)%C(reset)%C(auto)%d%C(reset)%n'' %C(white)%s%C(reset)%n'' %C(dim white)- %an%C(reset)'
86+
return 0
87+
;;
88+
graphite)
89+
git log \
90+
-10 \
91+
--graph \
92+
--abbrev-commit \
93+
--decorate \
94+
--format=format:'%C(bold blue)%h%C(reset) %C(bold green)(%ar)%C(reset)%C(auto)%d%C(reset)%n'' %C(white)%s%C(reset)%n'' %C(dim white)- %an%C(reset)'
95+
return 0
96+
;;
97+
*)
98+
vcs_none
99+
return 1
100+
;;
101+
esac
102+
}
103+
104+
# Prints a short graph of the current repository's commit structure.
105+
#
106+
# Accepts no arguments.
107+
function sl() {
108+
if [ -n "$1" ]; then
109+
print_err "There should be no arguments, too many arguments provided."
110+
return 1
111+
fi
112+
113+
case $(vcs_kind) in
114+
git)
115+
git log \
116+
-10 \
117+
--graph \
118+
--abbrev-commit \
119+
--decorate \
120+
--format=format:'%C(bold blue)%h%C(reset) %C(bold green)(%ar)%C(reset)%C(auto)%d%C(reset)%n'' %C(white)%s%C(reset)%n'' %C(dim white)- %an%C(reset)'
121+
return 0
122+
;;
123+
graphite)
124+
gt log short
125+
return 0
126+
;;
127+
*)
128+
vcs_none
129+
return 1
130+
;;
131+
esac
132+
}
133+
134+
# Prints a more detailed graph of the current repository's commit structure.
135+
#
136+
# Accepts no arguments.
137+
function sll() {
138+
if [ -n "$1" ]; then
139+
print_err "There should be no arguments, too many arguments provided."
140+
return 1
141+
fi
142+
143+
case $(vcs_kind) in
144+
git)
145+
# Git has no special handling here, reuse sl.
146+
sl
147+
return 0
148+
;;
149+
graphite)
150+
gt log -n 2
151+
return 0
152+
;;
153+
*)
154+
vcs_none
155+
return 1
156+
;;
157+
esac
158+
}
159+
160+
# Checkout a particular place in the repository.
161+
#
162+
# Passes all arguments to underlying command.
163+
function co() {
164+
case $(vcs_kind) in
165+
git)
166+
git checkout "$@"
167+
return 0
168+
;;
169+
graphite)
170+
git checkout "$@"
171+
return 0
172+
;;
173+
*)
174+
vcs_none
175+
return 1
176+
;;
177+
esac
178+
}
179+
180+
# Submit Stack: Submits all changes in the stack.
181+
function ss() {
182+
case $(vcs_kind) in
183+
git)
184+
print_err "Cannot submit diffs from git repos, only graphite."
185+
return 1
186+
;;
187+
graphite)
188+
gt submit
189+
return 0
190+
;;
191+
*)
192+
vcs_none
193+
return 1
194+
;;
195+
esac
196+
}
197+
198+
# Create a new commit with the given message.
199+
#
200+
# Accepts a single string argument that is the message.
201+
function cm() {
202+
if [ -z "$1" ]; then
203+
print_err "Must provide a single message argument, no arguments provided."
204+
return 1
205+
fi
206+
207+
if [ -n "$2" ]; then
208+
print_err "Must provide a single message argument, too many arguments provided."
209+
return 1
210+
fi
211+
212+
case $(vcs_kind) in
213+
git)
214+
# Have to git add first in order to capture untracked files.
215+
git add -A && git commit -am "$1"
216+
return 0
217+
;;
218+
graphite)
219+
git add -A && git commit -am "$1"
220+
return 0
221+
;;
222+
*)
223+
vcs_none
224+
return 1
225+
;;
226+
esac
227+
}
228+
229+
# Ammends the commit with the current changes.
230+
function ca() {
231+
if [ -n "$1" ]; then
232+
print_err "There should be no arguments, too many arguments provided."
233+
return 1
234+
fi
235+
236+
case $(vcs_kind) in
237+
git)
238+
git add -A && git commit --amend --no-edit
239+
return 0
240+
;;
241+
graphite)
242+
git add -A && git commit --amend --no-edit
243+
return 0
244+
;;
245+
*)
246+
vcs_none
247+
return 1
248+
;;
249+
esac
250+
}
251+
252+
# Creates a new graphite branch with the given branch name and message.
253+
function cn() {
254+
case $(vcs_kind) in
255+
git)
256+
print_err "Not implemented for plain git repos."
257+
return 1
258+
;;
259+
graphite)
260+
graphite_cn "$@"
261+
# Return whatever the last function did
262+
return $?
263+
;;
264+
*)
265+
vcs_none
266+
return 1
267+
;;
268+
esac
269+
}
270+
271+
# Helper function for cn that has already ensured we're in a graphite repo.
272+
function graphite_cn() {
273+
BRANCH=""
274+
MESSAGE=""
275+
276+
# No arguments provided.
277+
if [ -z "$1" ]; then
278+
print_err "Expecting branch or message as first argument, no arguments provided."
279+
return 1
280+
fi
281+
282+
# Only one argument provided.
283+
if [ -z "$2" ]; then
284+
# Check if the current branch ends in a digit.
285+
CURR_BRANCH=$(graphite_curr_branch)
286+
CURR_BRANCH_ENDS_IN_DIGIT="$(echo "$CURR_BRANCH" | grep -E '[0-9]$')"
287+
if [ -z "$CURR_BRANCH_ENDS_IN_DIGIT" ]; then
288+
print_err "Current branch does not end in a digit, cannot infer next branch name."
289+
print_err "Please provide both a branch name and message arguments."
290+
return 1
291+
fi
292+
293+
# Increment the branch by 1.
294+
NEXT_BRANCH_NAME="$(echo "$CURR_BRANCH" | perl -pe 's/(\d+)$/$1+1/e')"
295+
296+
# Save the inferred branch and messages.
297+
BRANCH="$NEXT_BRANCH_NAME"
298+
MESSAGE="$1"
299+
else
300+
# At least two arguments provided here.
301+
BRANCH="$1"
302+
MESSAGE="$2"
303+
fi
304+
305+
# More than two arguments provided.
306+
if [ -n "$3" ]; then
307+
print_err "Expecting branch or message as first argument, and at most 2 arguments. Too many arguments provided."
308+
return 1
309+
fi
310+
311+
# Check if the message looks like a conventional commit message. That means
312+
# it starts with a word character, can have optional parenthesis, and ends
313+
# with a colon.
314+
if ! echo "$MESSAGE" | grep -qE '^[a-zA-Z0-9_]+(\([a-zA-Z0-9_]+\))?:'; then
315+
print_err "Message does not look like a conventional commit message, please use a message like 'feat: description'"
316+
return 1
317+
fi
318+
319+
# Check if the git repo is clean, if so then they probably don't mean to
320+
# create a new branch and commit just yet.
321+
if [ -z "$(git status --porcelain)" ]; then
322+
print_err "Git repo has no changes, prefer to make changes before creating a new branch via graphite."
323+
return 1
324+
fi
325+
326+
# Create the new branch and message for graphite.
327+
gt create "$BRANCH" -m "$MESSAGE" --all
328+
}
329+
330+
# Gets the current commit hash in the repository.
331+
#
332+
# Accepts no arguments.
333+
function curr_hash() {
334+
if [ -n "$1" ]; then
335+
print_err "There should be no arguments, too many arguments provided."
336+
return 1
337+
fi
338+
339+
case $(vcs_kind) in
340+
git)
341+
git log -1 --pretty=format:"%h"
342+
return 0
343+
;;
344+
graphite)
345+
git log -1 --pretty=format:"%h"
346+
return 0
347+
;;
348+
*)
349+
vcs_none
350+
return 1
351+
;;
352+
esac
353+
}
354+
355+
# Gets the current branch in a graphite repo.
356+
#
357+
# Accepts no arguments.
358+
function graphite_curr_branch() {
359+
if [ -n "$1" ]; then
360+
print_err "There should be no arguments, too many arguments provided."
361+
return 1
362+
fi
363+
364+
git branch --show-current
365+
return $?
366+
}

0 commit comments

Comments
 (0)