Hacker News new | past | comments | ask | show | jobs | submit login

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.




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.


> 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.


So it's basically a slightly nicer interface to interactive rebase? Would be nice if the Readme explained that!


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.


Describing a patch queue development workflow as a "slightly nicer interface to interactive rebase" does it a tremendous disservice. It's like saying "a database is a slightly nicer interface to a filesystem" — technically true, but a disservice.


I tried StGit recently, having used rebases for a while now. In practice, StGit operations are much more intuitive and easy to learn than rebasing. Conflicts are much easier to track down and resolve compared to rebases. Personally, I find rebase operations so confusing that I often do multiple rebases on the same branch, a few operations at a time. It's easier for me to track down rebase conflicts that way.

Rebases and merges use diffs behind the scenes, although git stores the commits as snapshots. There is always a conflict of the two mental models while rebasing. With StGit, it's explicitly just patches that you can inspect anytime. I assume that this is the reason why StGit operations make more sense than rebasing.

Another important fact is that you don't need to wait till a feature-branch is complete to edit the history. With StGit, you can craft the ideal commit history along the way while you develop. I treat a stack of patches as multiple staging areas - each with specific purpose/feature and a predefined commit message. That way, you can develop code hunks in whatever order that makes sense, and then check them into (refresh the patch) the appropriate patch. It's even possible to edit or reorder these patches as we progress. Finally, the patches can be committed when the series of features are complete.


> Another important fact is that you don't need to wait till a feature-branch is complete to edit the history.

Why would you need to wait until it's complete?

I don't feel any need to do that, and I'm constantly rebasing. I guess I must be something about your workflow here.


You miss the important point here. With rebases, crafting the history is a separate step that can be done only after you've made a few commits. Whether you do it continuously or as one batch makes no difference. With StGit, crafting the history can start at the very beginning of the feature development. It goes hand in hand with the development and can be refactored any time.


I'm afraid I still don't understand the workflow. I continually rebase my branch(es) on top of upstream.

At any time, I can choose to consolidate a few of my WIP commits into a more (logically) cohesive commit and keep that around for further rebasing.

I must be missing something here, but I'm not sure what.

(If it helps understanding, we work with Gerrit which basically expects a 'list of patches' on top of the branch you want to commit your changes to. So that's already part of our mentality, but we just use plain git.)


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.


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.


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?


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


I used to use kiln from fogcreek and found that it's code review feature was much better suited for commit by commit style reviewing than either GitHub/gitlab.

On GitHub it tends to push you towards smaller and smaller PRs, which is generally good, however I kinda miss the "full context" of having a larger change on a single PR with well thought out commits


It seems like Phabricator supports this type of workflow, and I really wish there was wider popularity so I could push for it at work. The lab|hub style PR ends up with people falling into giant PRs that are difficult to review.


which is fine as long as the diffs don't overlap and you start moving them around


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.


Yeah but for me, playing around with SHA1 is a pain. So if I can simplify that, I am all for it.


That sounds quite complicated to me. Why not just have your patches in their own branches?


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.


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.


Convenient for you, but not for anyone else who has to review your work


Before I even push anything, I squash and re-order my commits, then cherry-pick into appropriate branches.

I just don’t switch branches while coding.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: