[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)