← Back to context

Comment by jenadine

11 hours ago

I might be missing something, but what I need is not "stacked PR" but a proper UI and interface to manage single commit:

- merge some commits independently when partial work is ready.

- mark some commit as reviewed.

- UI to do interactive rebase and and squash and edit individual commits. (I can do that well from the command line, but not when using the GitHub interface, and somehow not everyone from my team is familiar with that)

- ability to attach a comment to a specific commit, or to the commit message.

- better way to visualize what change over time in each forced push/revision (diff of diff)

Git itself already has the concept of commit. Why put this "stacked PR" abstraction on top of it?

Or is there a difference I don't see?

It's basically trying to bring the stacked diff workflow pioneered by Phabricator to GitHub.

The idea is that it allows you to better handle working on top of stuff that's not merged yet, and makes it easier for reviewers to review pieces of a larger stack of work independently.

It's really useful in larger corporate environments.

I've used stacked PRs when doing things like upgrading react-native in a monorepo. It required a massive amount of changes, and would be really hard to review as a single pull request. It has to be landed all at once, it's all or nothing. But being able to review it as smaller independent PRs is helpful.

Stacking PRs is also useful even when you don't need to merge the entire stack at once.

Constantly rewriting git history with squashes, rebases, manual changes, and force pushes has always seemed like leaving a loaded gun pointed at your foot to me.

Especially since you get all of the same advantages with plain old stream on consciousness commits and merges using:

git merge --no-ff

git log --first-parent

git bisect --first-parent

  • I find rebases are only a footgun because the standard git cli is so bad at representing them - things like --force being easier to write than --force-with-lease, there being no way to easily absorb quick fixes into existing commits, interdiffs not really being possible without guesswork, rebases halting the entire workflow if they don't succeed, etc.

    I've switched over pretty much entirely to Jujutsu (or JJ), which is an alternative VCS that can use Git as its backend so it's still compatible with Github and other git repos. My colleagues can all use git, and I can use JJ without them noticing or needing to care. JJ has merges, and I still use them when I merge a set of changes into the main branch once I've finished working on it, but it also makes rebases really simple and eliminates most of the footguns. So while I'm working on my branch, I can iteratively make a change, and then squash it into the commit I'm working on. If I refactor something, I can split the refactor out so it's in a separate commit and therefore easiest to review and test. When I get review feedback, I can squash it directly into the relevant commit rather than create a new commit for it, which means git blame tends to be much more accurate and helpful - the commit I see in the git blame readout is always the commit that did the change I'm interested in, rather than maybe the commit that was fixing some minor review details, or the commit that had some typo in it that was fixed in a later commit after review but that relationship isn't clear any more.

    And while I'm working on a branch, I still have access to the full history of each commit and how it's changed over time, so I can easily make a change and then undo it, or see how a particular commit has evolved and maybe restore a previous state. It's just that the end result that gets merged doesn't contain all those details once they're no longer relevant.

    • +1 on this, I also switched to jj when working with any git repo.

      What's funny is how much better I understand git now, and despite using jj full time, I have been explaining concepts like rebasing, squashing, and stacked PRs to colleagues who exclusively use git tooling

    • The magic of the git cli is that it gives you control. Meaning whatever you want to do can be done. But it only gives you the raw tools. You'll need to craft your own workflow on top of that. Everyone's workflow is different.

      > So while I'm working on my branch, I can iteratively make a[...]which means git blame tends to be much more accurate and helpful

      Everything here I can do easily with Magit with a few keystroke. And magit sits directly on top of git, just with interactivity. Which means if I wanted to I could write a few scripts with fzf (to helps with selection) and they would be quite short.

      > And while I'm working on a branch, I still have access to the full history of each commit...

      Not sure why I would want the history for a specific commit. But there's the reflog in git which is the ultimate undo tool. My transient workspace is only a few branches (a single one in most cases). And that's the few commits I worry about. Rebase and Revert has always been all I needed to alter them.

  • Until someone merges master into their feature branch rather than rebasing it. (And then that branch later gets merged.)

    • This shouldn't be a problem if you stick to commits and merges. --first-parent will skip past commits, including merge commits, in merged branches.

      1 reply →

  • I agree. PR merges for me are bisect points. That's when changes are introduced. Individual commits don't even always build.

    And I don't rebase or squash because I need provenance in my job.

Workflows can vary, but what I like:

PR/MR is an "atomic" change (ideally the smallest change that can be landed separately - smallest makes it easier to review, bisect and revert)

Individual commits (or what "versions" are in Phabricator) are used for the evolution of the PR/MR to achieve that change.

But really I have 2 use cases for the commits:

1. the PR/MR is still too big, so I split it into individual commits (I know they will land together)

2. I keep the history of the evolution of the PR/MR in the commits ("changed foo to bar cause its a better approach")

yeah interdiffing and being able to cherrypick in a review just there and getting it done is nice.

Perhaps a future iteration of this feature will at least allow us to do something like merge just steps of it if they can be reordered.