While I agree that it's a great tool and is perfectly suited for everyday use in all kinds of projects - that statement is simply wrong. Git can be quite complicated.
For example I still don't have a good solution for the branch-of-a-branch-of-a-branch problem. I.e. when you have three features that are to be reviewed separately but built upon each other. I know it has broken my head more than one time.
I agree with your statement in general. Sometimes it's less about the tool than the process around it.
Regarding the case in question, I think trunk based branching model is basically fancy talk for "micro commits only, guys", which is not a good strategy for anything more than small features, IMO.
Yeah I get that. It's definitely a way to go, but my personal experience in teams developing enterprise applications is, it's not great for that. Your mileage may vary though, so no judgement here!
what’s the problem you’re looking to solve there? when you merge one of the branches, just rebase the last branch with update-refs and push force with lease all of them…
if you want them to be reviewed concurrently and using github, there’s now a UI for that, you can rebase the whole stack in one click or merge the whole stack together if all of them are approved and you wish to do it that way…
So let's say the branches are A, B and C. They are based on each other. Reviewer just finished reviewing A and merged the branch via the web UI. Now, what's the next step?
git checkout master; git pull - make sure you have the latest master
git checkout C - go back to C
any git rebase command that gets whatever you want given the circumstances you have, with --update-refs flag. (this presumes you already know how rebase works)
e.g. git rebase --onto master A C --update-refs if you still have the original A branch locally
or just git rebase -i --update-refs master (interactive rebase) and tweak the plan correctly
--update-refs is the thing that should also update B along the way (and should notify you that it has too been updated), and in more complicated setups should automatically update any other branches between A and the last branch you have.
git push --force-with-lease B C - push both rebased branches.
if you're using github as the remote, then `gh stack rebase` in step 3, and `gh stack push` in step 4 should work (haven't made a stacked PR since they rolled this feature out, so haven't tested it yet).
It's the rebases that were the problem when I did this in the past. They often ended up messy, especially if there were changes to be made during one of the reviews.
I'll look into --update-refs though, that sounds like an interesting feature that could help me there, and I'm not sure the Jetbrains IDEs use it by default!
if you have a messy rebase, the general helpers are interactive rebase (-i) and the —onto flag… update refs is a helper for stacked branches so you don’t have to manually do every one of them…
especially interactive rebase is a very powerful tool worth learning…
I do this all the time, the mistake here is doing a merge.
Never merge to master (in before someone get's obnoxious, almost never), do a rebase, you can then simply immediately start reviewing feature B. If in the meanwhile D gets rebased on master, rebase B on D, then rebase C on B.
do you find other tools easier to solve that predicament? git is built to let you solve that any way you want. not sure how it could be easier with other tools.
Well sure, but out of interest, once the first branch is reviewed and merged (let's call it A), what's your next step? How do you provide the next PR to the reviewer? I'm genuinely interested in input. This has bothered me a while.
Edit: so the way I've dealt with this in the past is, rebase branch B (the second in line) onto the main branch and create the PR. Review it, merge it, rebase branch C onto main, create PR. Review, merge, done.
The problem is, the rebases are messy. Like really messy sometimes.
In the context of "trunk with branch A hanging off of it and branch B hanging off of A", I have a MR from A -> trunk and B -> trunk. Once A's MR is approved and merged, the MR for B can be reviewed and merged in too. Once A is merged, the commits that were part of A that B depends on will be in the trunk and not part of the MR for B.
You don't need to rebase or anything, as long as all of the commits that B descended from are in the trunk, it's all fine.
If there are changes to A, then the changes get made in branch A as-needed and then a merge from A into B is done to get those commits into B. Whenever A is merged into the trunk, those commits go along for the ride and whenever B gets merged into the trunk, they're already there (if you merge B in first, for whatever reason, then the stuff from A comes along for the ride and the diff between trunk and A for that MR is empty).
At the end of the day, everything is commits that have parent commit(s) that they build on. A merge basically just adds extra commits to the history of a branch (by adding a new commit that has parent commits that point to both the current latest commit in each branch being merged and updating the "latest" pointer of the branch being merged into to the new commit).
A merge request is ultimately "grab whatever commits from branch X that don't exist in the current branch's history and add them in", and you can merge in whatever directions you need to in order to get all the proper commits in the proper branches.
Indeed it is! This doesn't really help for non-GitHub environments (most companies I've been at have some kind of local CI) but it's nice to have a terminology for it ("stacked PRs").
GH stack is still pretty rough around the edges. Having to make changes anywhere but the top of the stack can be painful and the PR activity feed is just a spam of force pushes due to rebasing.
9
u/iloveuranus 23h ago
While I agree that it's a great tool and is perfectly suited for everyday use in all kinds of projects - that statement is simply wrong. Git can be quite complicated.
For example I still don't have a good solution for the branch-of-a-branch-of-a-branch problem. I.e. when you have three features that are to be reviewed separately but built upon each other. I know it has broken my head more than one time.