July 14th, 2024

Working with stacked branches in Git is easier with –update-refs (2022)

The new Git feature, --update-refs in version 2.38, simplifies rebasing stacked branches by automatically updating branches pointing to rebased commits. It enhances efficiency and management of Git workflows.

Read original articleLink Icon
Working with stacked branches in Git is easier with –update-refs (2022)

The article discusses the new Git rebasing feature, --update-refs, introduced in Git 2.38, making it easier to work with "stacked" branches. Stacked branches involve creating separate branches and PRs for each unit of functionality, building on top of one another. When changes are requested during code reviews, maintaining stacked branches can become complex, requiring extensive rebasing. The --update-refs option simplifies this process by automatically updating branches that point to the rebased commits. It streamlines rebasing stacked branches, incorporating changes from the main branch efficiently. The article outlines scenarios where --update-refs can be beneficial, such as rebasing a stack of branches, incorporating changes from the main branch, and using interactive rebases. Additionally, users can enable --update-refs by default for all repositories, enhancing the rebasing experience. Overall, the feature aims to simplify the management of stacked branches in Git, improving the efficiency of rebasing workflows.

Link Icon 9 comments
By @AceJohnny2 - 4 months
Tangentially, I like to work with Gerrit [1], which approaches the core problem in a different way...

"Stacked branches" seem to be a terminology which derives from Github/etc's approach to Pull Requests, where one PR maps to one atomic change. The PR can either be integrated in the repo as a merge, in which case you maintain the history of the PR and all its changes through its reviews, or as a squash-merge, in which case you flatten the PR's review history into one commit.

But what if you want to maintain a series of separate but related commits? PRs don't really help you there, so people ended up inventing the concept of Stacked Branches, as discussed in the article.

Gerrit took a different approach, and requires you to add metadata to each commit's message, the Change-Id. This way Gerrit can track your commit through its review evolution (since its SHA will change with each iteration). This also allows Gerrit to trivially track a series of related changes through their overall evolution, since it can use git's normal branch data to track commit's relation to each other, and the Change-Id to track one commit as it evolves.

In any case, both solutions demonstrate that Git lacks a way to track the evolution of specific commits throughout their review history (a 2D branch in a way), so review tools like Github/etc and Gerrit had to create their own solution on top of it.

[1] https://www.gerritcodereview.com/

By @3np - 4 months
> To rebase the part-2 and part-3 branches, we would have to run something like this:

    # Rebase commit 4 and commit 5 on top of the part-1 branch
    git checkout andrew/feature-xyz/part-2
    git rebase HEAD~2 --onto andrew/feature-xyz/part-1

    # Rebase commit 6 on top of the (now rebased) part-2 branch
    git checkout andrew/feature-xyz/part-3
    git rebase HEAD~ --onto andrew/feature-xyz/part-2
What's the supposed benefit of this over simply the following?

    git rebase andrew/feature-xyz/part-1 andrew/feature-xyz/part-2

    git rebase andrew/feature-xyz/part-2 andrew/feature-xyz/part-3
By @eternalplatypus - 4 months
This is awesome thank you for sharing. I had almost given up on my git workflow because of how tedious the process of rebasing was getting.
By @hbogert - 4 months
When I was doing more hardcore dev instead of SRE'ing I settled on git branchless[1], was well worth the experimenting you have to do to get it into your mental model.

now that I hardly ever have 2 layer deep stacks I just settle on my go-to git client which is magit. It just takes a couple of keystrokes to do a couple of stacked rebases.

I do wish that the stacked commits approach was universally used instead of the approach that github enforced on us. It just makes everything a bit less arcane. The whole 'branch-dance' gets really old real fast. [1]: https://github.com/arxanas/git-branchless

By @tcoff91 - 4 months
Graphite makes this workflow a lot easier.
By @nosefrog - 4 months
Whoa, didn’t realize I need this. I’m constantly rebasing stacked branches.
By @randoglando - 4 months
Does this work with `git pull --rebase`?