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.
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.
> 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.
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.
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.
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.)
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.
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 :)
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
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.
I just don’t switch branches while coding.
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.