1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#+SERIES: index.html
#+SERIES_PREV: StackedGit.html
#+TITLE: How I Keep Using Stacked Git at ~$WORK~
One year ago, I have published an article summarizing
[[./StackedGit.html][my experience using Stacked Git at ~$WORK~]]. Twelve months later,
enough has changed to motivate a spin-off piece.
* Stacked Git is /Fast/
Firstly, it is important to state that my main complain is now a
thing of the past! In particular, Stacked Git does not feel slow
anymore, and far from it. This is because
[[https://github.com/stacked-git/stgit/discussions/185][Stacked Git 2.0 has been rewritten in Rust]]. RiiR (/Rewrite it in
Rust/) is a running meme on the Internet, but in this particular
case, the result is very exciting.
Thanks to the performance boost, my Zsh prompt does not take 0.1s to
appear.
Speaking of Zsh prompt, basically what I ended up displaying is
~(<TOP PATCH NAME> <APPLIED PATCHES COUNT>/<PATCHSET SIZE> <HIDDEN
PATCHES COUNT)~. For instance, ~(fix-1337 1/2 3)~.
In case you want to take inspiration in my somewhat working
configuration, here is the snippet of interest.
#+begin_src sh
local series_top="$(stg top 2> /dev/null)"
local total="$(stg series 2> /dev/null | wc -l)"
local hidden="$(stg series --hidden 2> /dev/null | wc -l)"
if [[ "${total}" -gt 0 ]]; then
local not_applied="$(stg series | grep -E '^-' | wc -l)"
local applied="$(($total - $not_applied))"
if [[ -z "${series_top}" ]]; then
series_top="·"
fi
echo -n "(${status_color}${series_top} ${applied}/${total} ${hidden})"
echo -n " ($(current_branch))"
fi
#+end_src
* Branchless Workflow
Last year, I was using Stacked Git on top of git branches. More
precisely, I had one branch for each (stack of) Merge Request. It
worked well, because my typical MR counted 3 to 4 commits in
average.
[[mn:onecommit][This approach comes with its set of drawbacks too,
it goes without saying. During the past year, I’ve pushed fairly
large commits which could have been splitted into several smaller
ones. I have also had to manage large stacks of MRs.]]
Fast forward today, and things have changed on this front too. In a
nutshell, I have become a “one commit per MR” maximalist of sort. I
find this approach very effective to get more focused reviews, and
to reduce the time it takes for a given MR to be integrated into the
main branch. My previous approach did not scale well with this new
mindset, and during the course of the year, I stopped using branches
altogether.
I did not invent the branchless workflow, of course.
After it was first published, someone posted a link to my Stacked
Git article on Hacker News, and
[[https://news.ycombinator.com/item?id=29959224][*@arxanas* posted a comment about ~git-branchless~]]. I tried the
tool, and even if it never clicked for me, I was really compelled by
its core ideas. Similarly,
[[https://drewdevault.com/2020/04/06/My-weird-branchless-git-workflow.html][Drew DeVault has published a complete article on its own branchless
workflow in 2020]].
In my case, I proceeds as follows.
1. I name each patch after the branch to which I will push it on our
upstream Git remote.
3. I created a small git plugin I called ~git-prepare~ which allows
me to select one of the patch of my current patchset using ~fzf~,
and which pops all other patches that are currently applied.
2. 99% of the time, I push my work using ~git push -f upstream @:$(stg top)~
~git-prepare~ is really straightforward:
#+begin_src sh
#!/bin/sh
patch=$(stg series -P | fzf)
if [[ ! $? -eq 0 ]] ; then
exit $?
fi
if [ -n "$(stg series -A)" ]; then
stg pop -a
fi
stg push ${patch}
#+end_src
The main hurdle which I still need to figure out is how to deal with
stacked MRs. Currently, this is very manual. I need to remember
which commit belongs to the stack, the order and dependencies of
these commits, and I need to publish each commit individually using
~stg push; git push @:$(stg top)~.
The pragmatic answer is definitely to come back to git branches for
this use case in particular, but it's not the /fun/ answer. So from
time to time, I try to experiment new approaches. My current
intuition is that, by adopting a naming convention for my patches, I
could probably implement a thin tooling on top of Stacked Git to
deal with dependents commits.
* Conclusion
Putting aside stacked MRs for now, I am really satisfied with my
workflow. It’s very lightweight and intuitive, and working without
Stacked Git now feels backward and clunky.
So I will take this opportunity to thank one more time Stacked Git’s
authors and contributors. You all are making my professional like
easier with your project.
|