[HN Gopher] Stacked Git - manage commits as a stack of patches
       ___________________________________________________________________
        
       Stacked Git - manage commits as a stack of patches
        
       Author : pcr910303
       Score  : 90 points
       Date   : 2021-05-27 17:17 UTC (5 hours ago)
        
 (HTM) web link (stacked-git.github.io)
 (TXT) w3m dump (stacked-git.github.io)
        
       | smcameron wrote:
       | Cool. I've been using this for many years. Before that, I used
       | quilt[1], and before that, Andrew Morton's patch scripts[2].
       | 
       | It's a great workflow that makes you look like a genius who
       | rarely makes mistakes. Absolutely vital if you need to maintain a
       | set of patches against a bunch of branched source code (e.g.
       | maintaining an open source driver with variants upstream (linus's
       | plus stable kernels) and also for various distro kernels.) This
       | was my main use case for years, but I still use it even for
       | things that don't fit that pattern, just because it's convenient
       | to do so.
       | 
       | Sure everything that stgit does can be done with git by itself
       | (duh, that's what stgit is doing under the hood), but I find it's
       | a lot easier with stgit.
       | 
       | [1] http://savannah.nongnu.org/projects/quilt [2]
       | https://lwn.net/Articles/13518/
        
       | fpoling wrote:
       | I still occasionally use quilt,
       | http://savannah.nongnu.org/projects/quilt , as it properly works
       | across arbitrary submodule tree.
       | 
       | StGit does not support that as I understand.
        
         | zserge wrote:
         | I have been using quilt a lot a few years ago. We have been
         | working on some embedded systems,and were receiving the base
         | firmware sources of questionable quality from some shady
         | Chinese manufacturer as a zip (or sometimes rar) archive on a
         | flash drive sent by mail. We had to maintain our own "overlay"
         | of changes applied on top of it. The discovery of quilt back
         | then was such a relief!
        
       | cryptonector wrote:
       | Isn't that what rebase is?
        
       | jayd16 wrote:
       | Wait, they name mangled "push"?
        
         | jpgrayson wrote:
         | Obviously `stg push` and `git push` are different commands, but
         | to your point, yes, they have very different meanings and the
         | overlap is somewhat unfortunate.
         | 
         | StGit uses push/pop in the sense of pushing and popping patches
         | to/from the patch stack. An alternative such as apply/unapply
         | would be valid and could be aliased, but this ship sailed 16
         | years ago (StGit has been around almost as long as Git) and so
         | is unlikely to change.
        
       | eevilspock wrote:
       | Somewhat (or possibly greatly) related:
       | 
       | Are tools like _git-absorb_ safe /reliable? Git-absorb is a port
       | of _hg absorb_ :
       | 
       |  _" Essentially, when your working directory has uncommitted
       | changes on top of draft changesets, you can run `hg absorb` and
       | the uncommitted modifications are automagically folded
       | ("absorbed") into the appropriate draft ancestor changesets. This
       | is essentially doing `hg histedit` + "roll" actions without
       | having to make a commit or manually make history modification
       | rules."_
       | 
       | I haven't (yet) wrapped my head around the algorithm. I get that
       | an algorithm can "recollate" a series of commits in a way that
       | yields no commit conflicts, but that's not the same as
       | rearranging and combining commits into a sequence of semantically
       | coherent _atomic_ commits.
       | 
       | ---
       | 
       | https://github.com/tummychow/git-absorb
       | 
       | https://github.com/torbiak/git-autofixup
        
         | andrewshadura wrote:
         | I use git-absorb a lot, it's been my daily driver since I
         | discovered it. It is very conservative in what it does: if it
         | doesn't know what to do, it does nothing. And in any case, each
         | of the changes it introduces is a separate commit, so you can
         | reorder or amend them however you like.
         | 
         | Also, what a shameless plug I am, have a look at git-crecord to
         | interactively commit files line by line.
        
       | choeger wrote:
       | That sounds extremely useful, indeed. What are the caveats/corner
       | cases? I assume it does a lot of debasing behind the scenes, what
       | happens in case if conflicts?
        
         | jpgrayson wrote:
         | StGit maintainer here.
         | 
         | You are correct that conflicts can occur when pushing or
         | reordering patches. These conflicts are resolved with the
         | regular git mechanisms. I.e. conflict markers in files, use
         | `git add` to mark conflicts as resolved, and then `stg refresh`
         | to update the patch with conflicts resolved.
        
       | Hackbraten wrote:
       | Why would I use Stacked Git rather than Git's fixup/interactive
       | rebase dance?
       | 
       | For example:                   git commit -m "one thing"
       | # commit hash: deadbeef              git commit -m "other thing"
       | # commit hash: badf00d
       | 
       | (working on one thing) then:                   git commit --fixup
       | deadbeef
       | 
       | (working on the other thing again) then:                   git
       | commit --fixup badf00d
       | 
       | And in the end, when I'm ready to roll each patch into one
       | commit, respectively:                   git rebase -i
       | --autosquash
       | 
       | I do realize that Stacked Git allows me to switch between
       | patches. Which is nice because regular Git wants me to type in
       | SHAs for --fixup.
       | 
       | But I'm not sure I'd take on a new tool dependency just for that.
       | What are other benefits of Stacked Git? Just wondering if I'm
       | missing something.
        
         | jpgrayson wrote:
         | With the kind of git workflow you describe, bringing StGit into
         | your tooling/workflow may not be worthwhile.
         | 
         | I'd say if you wanted to do these kinds of stack manipulations
         | a little bit faster or with a little less cognitive overhead
         | (e.g. named patches vs SHA1 hashes), then investing in StGit
         | might pay off.
         | 
         | I generally would agree that using StGit isn't going to be a
         | slam-dunk win for someone who already has a capable workflow
         | using interactive git rebase.
        
           | juped wrote:
           | Can you explain what your tool does to someone who knows what
           | an interactive rebase is? I don't get much more from your
           | blurb than "we reimplemented interactive rebase for some
           | reason", but I'm sure you do something different or unique...
        
           | Hackbraten wrote:
           | Got it. Thank you for clarifying.
        
         | juped wrote:
         | if the commit name is more readily at hand, just name the
         | commit "fixup! whatever". --fixup just does this for you since
         | references are shorter and easier to type (it doesn't have to
         | be a hash, it can be --fixup HEAD~2 or something).
        
         | epage wrote:
         | The main reason I've heard of people using tools like this is
         | so people can review a commit at a time (a lot of review tools
         | don't handle this well) and CI runs on each commit.
         | 
         | Generally, it sounds like people are simulated Phab with these
         | tools which is trying to simulate the email patch workflow.
        
           | gorset wrote:
           | We use gitlab and review a commit at a time and do CI runs on
           | each commit in the MR branch. Just plain git with the
           | fixup/interactive rebase dance. Gitlab is not optimized for
           | this workflow, but it's liveable.
           | 
           | Gitlab-runner can execute any shell commands, so it's easy to
           | just loop through all the commits and run bazel test.
           | 
           | Gitlab has improved lately and it's now easier to review each
           | commit in a MR, but you can sense that most of the PM
           | attention is on the single commit/squash everything MR
           | workflow.
        
       | bayindirh wrote:
       | So it's basically Quilt + git. No?
        
       | zzzeek wrote:
       | correct me if I'm wrong this seems like what Gerrit does?
        
         | e40 wrote:
         | And Gerrit as (IMO) a really nice UI for managing and
         | commenting.
        
           | RyJones wrote:
           | I wish Gerrit had won out over GitHub.
        
       | topher200 wrote:
       | @jpgrayson (since I see you lurking around here) Thanks for
       | maintaining stgit! I've been a recent convert and it's a great
       | workflow improvement. I used to be a big `git rebase -i` user and
       | stgit works so much more fluidly and fits great with my mental
       | model of how I want git to behave. Thanks!
       | 
       | I'd love to add functionality that mimics `git rebase -i`. That
       | is, you would open an editor and be able to select which patches
       | you want on your stack as well as possibly designate patches as
       | 'squash' or 'fix' from your editor. Think of it as `stg sink`,
       | but able to operate on multiple patches at once.
       | 
       | Prior art: this script[1] already performs a re-ordering of
       | commits but in a pretty hacky way. I'd like to productize it!
       | 
       | I'd love to have this new `stg rebase --interactive` be part of
       | the main repo to enjoy the benefits of the existing test suite.
       | My question for you is around how to include the new command with
       | the rest of the tools. Would you want it to integrate with the
       | existing rebase command (`stg rebase --interactive`) or is it
       | something more appropriate for `contrib` (so a new independent
       | command like `stg-rebase-interactive`)?
       | 
       | [1] https://github.com/da-x/misc-gitology/blob/master/stg-
       | rebase...
        
         | jpgrayson wrote:
         | Thanks for the recognition!
         | 
         | I think I get the gist of what this interactive script does and
         | how you propose to extend it. A PR for such a script to go into
         | StGit's contrib directory would be non-controversial. Maybe a
         | little higher bar to have this capability as a first-class
         | StGit command.
        
         | dorian-graph wrote:
         | > stgit works so much more fluidly and fits great with my
         | mental model of how I want git to behave
         | 
         | Would you mind expanding upon this? I'm really curious.
         | 
         | Have you tried Pijul too?
        
       | veilrap wrote:
       | I read through the getting started guide and I have a hard time
       | seeing how this differs from an existing workflow I use with just
       | pure git.
       | 
       | Basically, having a stack of patches as commits in my local
       | branch. Edits to older commits saved via fixup commits, and
       | occasionally merging in the fixups and/or rearranging the commits
       | with rebase when its convenient to have a different commit on top
       | of the stack or when I'm pushing a patch out from the bottom of
       | the stack.
        
         | [deleted]
        
         | skywal_l wrote:
         | Yeah but for me, playing around with SHA1 is a pain. So if I
         | can simplify that, I am all for it.
        
         | TranquilMarmot wrote:
         | This is mostly what I do as well; I make a branch, make a ton
         | of little tiny commits, and then squash and merge them on
         | GitHub with a better commit message. Best part is the series of
         | commits are preserved on the PR in GitHub if I ever want to go
         | back and look at the process.
        
           | alexeldeib wrote:
           | I actually think the value add with stacks is a bit
           | different. It makes pieces of code far too large to review in
           | one PR manageable.
           | 
           | To compare: I often use the workflow you described. But large
           | PRs, I might rebase, and then rewrite my entire history as a
           | clean series of commits, each incremental and easily
           | reviewable.
           | 
           | Most often, the commits while working and the commits at the
           | end look different, but the final presentation of a series of
           | clean commits makes life easy for reviewers.
        
             | lacksconfidence wrote:
             | This is my way as well, but in part it's because we use
             | gerrit instead of git(hub|lab) which explicitly allows for
             | this workflow of separately reviewed patches that build
             | atop each other. I'm curious, if you are using
             | git(hub|lab), how does it work with their workflow?
        
               | alexeldeib wrote:
               | It's okay on github, if somewhat implicit. You can click
               | the "commits" tab of a PR, and then clicking any
               | individual commit brings up the usual github diff view
               | (like you'd see for the whole PR). It's not immediately
               | obvious but you can leave comments in that view, unlike
               | the other view for a single commit on branch history.
               | 
               | But I find most people on github end up reviewing the
               | whole PR as one unless we all are on the same page ahead
               | of time. So despite supporting the functionality it's not
               | all that highly used compared to, say, the way individual
               | patches in a set might be reviewed on the Linux mailing
               | lists during later revisions. I feel like on github it's
               | more common to see asks to break up PRs (maybe just as a
               | result of the projects I've seen? both approaches have
               | valid usecases imo, and there are good reasons to break
               | up PRs which can be done in single commits anyway).
               | 
               | I still feel it's good hygiene even if reviewers don't
               | look :)
        
         | jpgrayson wrote:
         | Probably the main value-add of StGit versus the git-only
         | workflow described is that StGit makes operations on its stack
         | of patches fast and fluid.
         | 
         | Reordering patches with StGit is trivial with `stg push` and
         | `stg pop`. Arbitrary patches can be combined with `stg squash`.
         | A modification in the work tree can be incorporated into the
         | top-most patch with `stg refresh` or an arbitrary patch in the
         | stack with `stg refresh --patch <patchname>`.
         | 
         | In other words, StGit provides a command vocabulary for
         | performing these kind of patch-stack manipulations in a first-
         | class manner.
         | 
         | But as you note, everything StGit does can be accomplished with
         | plain git--albeit with more or less difficulty depending on the
         | particular stack manipulation goal.
        
           | IshKebab wrote:
           | So it's basically a slightly nicer interface to interactive
           | rebase? Would be nice if the Readme explained that!
        
             | jpgrayson wrote:
             | Good point that StGit's docs could benefit from a
             | compare/contrast with interactive rebase workflows. Thanks!
             | 
             | > slightly nicer interface to interactive rebase
             | 
             | More accurate to say StGit is an alternative interface that
             | does some of the same things as interactive rebase (and
             | more). For me, part of StGit's value proposition is that it
             | _is not_ interactive. A single imperative StGit command may
             | accomplish as much as an interactive rebase session.
             | 
             | Workflows using `git rebase --autosquash` feel more similar
             | to StGit because of their non-interactivity.
        
           | philsnow wrote:
           | > command vocubulary
           | 
           | A sibling comment mentions interactive rebase. I had never
           | thought about it this way but if stacked got gives you a
           | command vocabulary / imperative interface to adjusting your
           | local commits, I would say `git rebase -i` gives you a
           | declarative interface.
           | 
           | I prefer the latter; it's easier for me to prepare a bunch of
           | modifications in an emacs buffer / vim tab and then have git
           | go and do them all at once rather than try to maintain the
           | state of the commits in my head and plan out the commands one
           | at a time to achieve the same result.
        
         | secondcoming wrote:
         | That sounds quite complicated to me. Why not just have your
         | patches in their own branches?
        
           | Hackbraten wrote:
           | I'd say that highly depends on your habits and how your brain
           | works. Some people prefer to focus on one topic at a time,
           | have their current branch open, and choose not to give in to
           | opportunistic edits if unrelated to the task at hand.
           | 
           | Others prefer to work their way through a piece of code for
           | example from top to bottom, making opportunistic edits along
           | the way, even if unrelated to the task. Not having to switch
           | branches can be convenient in that case.
           | 
           | I'm 100% in the latter team. Near the end of a coding
           | session, my `git diff` often shows three or four completely
           | unrelated sets of changes. Some might call that a rather
           | unproductive and annoying way to work. But I really love it
           | that way. My brain just _craves_ to fix that typo or convert
           | that tab to spaces right away, even when I'm supposed to fix
           | a bug right now. I love dealing with those things right away
           | so I get them out of my mind and don't have to put them on a
           | mental stack -- even if that means a little more chaos later
           | when it's time to bin my edits into different commits.
           | 
           | Arguably, I _could_ switch branches for such edits. But
           | frankly, I'm used to opportunistic editing, and sticking with
           | that approach feels just super convenient.
        
             | [deleted]
        
             | xyzzy_plugh wrote:
             | This is me. Commits closer to upstream (older in the
             | branch) are usually more stable, easier to merge, probably
             | already out for review. The newest commits at the tip of
             | the branch are the crazy WIP changes I'm considering, and
             | not ready for prime-time.
        
         | globular-toast wrote:
         | Same. With magit's "instant fixup" it's quite easy to maintain
         | a stack of patches on your branch. I didn't realise this was
         | considered anything special really.
        
       | tyhoff wrote:
       | Preface: I love Stacked Git and have convinced many co-workers to
       | use it and they all love it. It's really great, especially when
       | used with Phabricator!
       | 
       | ---
       | 
       | A question for the maintainers...I was enjoying the command `stg
       | publish` to allow myself to keep refreshing patches locally but
       | every so often push to a branch that others non-stg users were
       | pulling and pushing to. The command was removed in 1.0.
       | 
       | I'm curious why it was deprecated and removed and if there is a
       | good replacement flow for working with non-stg users on branches
       | I can't force push to.
        
         | jpgrayson wrote:
         | Ah ha, someone did use `stg publish`!
         | 
         | I removed it because it was challenging to test and maintain,
         | its semantics are somewhat complex, and it wasn't clear that it
         | provided value to anyone.
         | 
         | If you wouldn't mind making your case on the issue tracker [1],
         | I will reconsider the fate of `stg publish`.
         | 
         | [1] https://github.com/stacked-git/stgit/issues
        
           | pm215 wrote:
           | I'm not using it any more, but for a while I used stg publish
           | as a way of working with a stack of patches but also
           | providing other people with a "this branch doesn't rebase,
           | you can pull it" interface. It was also nice when working
           | continuously with the same stack of patches (periodically
           | rebasing them onto a moving upstream, cleaning them up, etc)
           | to have the publish view's commits as a record of "this is
           | the delta since the last publish". But it's been years since
           | I had a need for the functionality...
        
       | stinos wrote:
       | Can someone who has used this comment on whether learning the
       | newish terminology and workflow pays off, vs doing what I do now
       | in situations which this seems tailored for: multiple branches,
       | cherry-picking here and there and/or interactive rebasing when
       | features have been tested and are ok to put into master, likewise
       | when one feature needs changes from another branch?
        
         | pm215 wrote:
         | I use it all day every day, and I really like it for the
         | workflows I have, which are basically contributing to open
         | source projects that use the "send patches by email for review,
         | features should be sent as patch series with each commit doing
         | one thing for ease of code review" workflow. If the thing you
         | want to send off for code review is not "a commit" but "a
         | series of maybe 10 to 30 carefully crafted commits", stgit just
         | makes it very easy to create that series of commits and work
         | with it, putting code changes into the right patches,
         | reshuffling the patch order, etc, as you go along. It's
         | possible to do all that with interactive rebase, but I never
         | got the hang of that and find the stgit interface much more
         | intuitive. In particular, the 'git rebase' manual suggests that
         | the typical rebase workflow is "create a lot of commits, and
         | some fixup commits, and then occasionally tidy up with
         | interactive rebase". The stgit workflow is much more "keep your
         | patchseries tidy as you go along" because it's trivially easy
         | to say "actually this little change should go in the patch 15
         | commits before the one I'm currently at", or "actually let me
         | unstack these last 5 commits and spend the next day creating
         | patches that logically belong before them, and then tomorrow
         | push those last 5 commits back on again". I use separate
         | branches for different topics/features, but basically every
         | branch is an stgit patchseries.
        
         | jpgrayson wrote:
         | I originally used mercurial and its queues (mq) extension and
         | then found StGit when switching to an organization using git
         | for version control. Thus I got used to the patch-stack model
         | prior to really being exposed to git's interactive rebase.
         | 
         | Some days I wonder if an interactive rebase oriented workflow
         | would be good enough for me, but manipulating the patch-stack
         | with StGit has become so second-nature that even the small
         | amount of extra friction of `git rebase -i` sends me right back
         | to StGit.
        
       | bentcorner wrote:
       | Interesting. I usually manage this workflow via rebasing my
       | commits, re-ordering commits (can be moderately painful depending
       | on merge conflicts), then squashing fixups together.
       | 
       | Although I imagine you'd still run into problems when you push a
       | commit you've popped and there's a merge conflict.
        
       ___________________________________________________________________
       (page generated 2021-05-27 23:01 UTC)