Fast rebases with git-move
blog.waleedkhan.name
blog.waleedkhan.name
When I make a fix on the 6 month old branch, I have to manually cherry pick it to the current release and develop branch, and by cherry picking I lose all association between those three commits now ostensibly containing the same changes (though not really, because conflict resolution makes all of them different).
There must be a better way.
If you decide that the way things were done way back when on the release branch isn't quite how you want to proceed in the future, you just amend the message to reflect the additional changes. The SHA is still there to reach back and see how things were done in the first place.
Start a feature branch off from the last common ancestor between your branches of interest. Make your commit against that. Then merge that feature branch into the old release branch, current release branch and feature branch.
You might still have to do lots of conflict resolution, but at least this way you can preserve the associations in a form legible to git.
This works a bit better, if you can regularly merge your release branches back into your development branch, since then the last common ancestor will be exactly the release branch.
It works fine locally, when you just run merge and fix conflicts in one action.
But I need to push my branches to bitbucket/github to go through a review process, so you can’t stay with one branch.
I guess I could run the merge, and resolve the conflicts locally, then push a separate branch to make a PR with for each target with the original+merge commit inside.
In BitBucket, you can make multiple PRs from the same branch.
> I guess I could run the merge, and resolve the conflicts locally, then push a separate branch to make a PR with for each target with the original+merge commit inside.
Yes, that's basically what I do. Though most of the time, I don't need to bother with the merge commit, because I only do this dance to get something into both master and release, but they haven't diverged too far, yet.
If you can still merge the same changes to both branches you are home free.
Checking today and there’s differences in 2.5k files (out of 3.5k maybe?).
To be fair, a lot of that is cleanup, but still.
My biggest burn is when I am rebasing and addressing conflicts and I do the wrong thing like a pull or a commit or something and then it’s just completely unclear to me what I’ve broken and why my conflicts are getting far worse every stage of the rebase.
Visualize current tree:
$ git stack
Show what the ideal tree will be post-pull:
$ git stack --pull --dry-run
Perform pull and show the actual tree (e.g. we don't handle merge-conflicts):
$ git stack --pull
In addition, the above command snapshots the state of all of your branches and prints out the command to undo everything in case something is off
But the switch to TBD is not just a dev change, it's as much a change for the organization.
But it certainly opens up some great new possibilities to make the switch.
That said, this is only a problem at my work. Even the largest of open source repos I have worked on have been mostly fine with Git’s slow rebase implementation.
More interested in hearing more about the use case for this tool. AFAIK Git was created for use with Linux, which is a large codes base with lots of churn. One would asume rebase would work with a large codebase like that
(And to be exact, then possibly branch -f and checkout, depending what was rebased.)
I heartily approve of rebase-first development methodology.
But rebasing is not something that has ever been slow for me. Even in huge monolithic repos with frequent changes, it takes at most a couple seconds to reconcile my work branch against master.
Maybe this will help some team with specific needs, but I highly advise against just adopting it because “heard rebasing was slow”.
What I find useful is not the performance but this line
> For example, it can move entire subtrees, not just branches
The referenced docs mention other great quality of life improvements that streamline standard workflows (e.g. deleting local PR branches when merged into upstream)
When performance does matter is when the rebase operation is a small part of a larger operation. In my related tool, git-stack [0], I rebase all branches on top of their latest upstream branches along with re-arranging and squashing fixup commits and soon other features. When automating entire workflows, having each part be fast is important for the whole to still have decent performance.
So I decided to focus primarily on features which everyone understands, such as performance. (Of course, many people then say "why do we need this? git rebase is already plenty fast", but they get the principle.)
I also maintain a comparison of related tools [1] that might interest you. Of them I would probably recommend looking at git-branchless [2]
[0] https://github.com/epage/git-stack
[1] https://github.com/epage/git-stack/blob/main/docs/comparison...
Once a patch set looks good to the maintainer, it's merged. Email clients do enforce looking at the changes as a series of diffs on a per commit basis.
1. analyze your work properly
2. Break down work to smaller parts
3. prioritize what comes after what
$ git checkout <commit>
$ git commit --amend
$ git restack
It will properly rebase descendant commits and branches for you.> It moves branches on any intermediate commits. git rebase only moves the branch pointing to the commit which was checked out at the time of the rebase.
Many times I've had a chain of branches that I want to send out as PRs in sequence (smaller PRs are easier to review), but rebasing can result in some of this branches pointing at the wrong (pre-rebase) commits.
I also recommend that you try out a solution like git-stack to manage stacked PRs: https://github.com/epage/git-stack
Tooling for Hg regarding merges and conflict handling is a little bit better, but where Git wins is the vast amount of info and help available.
Another issue is that Pull Requests are uncommon with Hg, so instead bundles are shared using email, this is not a good workflow.
No, I didn't. Can you please point out to us where I did that?
> If HG truly shines I don’t know why people would choose Git over it
Git had a head start because Torvalds invented it and it became the SCM of Linux kernel, then other free software developers on linux ecosystem followed that (GNOME etc.). Github became hip and took of among open source developers few years after that. Rest is network effect.
> yet bitbucket based on Hg didn’t take off
Because bitbucket UI was more clunky and corparate-y looking compared to Github. Is it really surprising Github was more popular among Silicon Valley crowd? That's totally unrelated to it using hg instead of git.
Git has its pros and cons like Hg but it managed to outshine whatever benefits hg offered.
Yes bitbucket and Github are related because, bitbucket was one of the main companies to offer it, which sucked, in turn dropped Hg adoption.
How many people do you think work on Linux kernel, for it to drive git adoption? There are 10000x more php developers than Linux kernel developers. If Hg was able to entice them, it would’ve been different may be, which it couldn’t.
But I agree with your point git was seen more favourable for open-source due to Github.
You say hg sucked thus bitbucket dropped it. I say bitbucket sucked, regardless of hg, thus nobody adopted bitbucket, went with Github instead, indirectly adopting git.
> How many people do you think work on Linux kernel, for it to drive git adoption? There are 10000x more php developers than Linux kernel developers. If Hg was able to entice them, it would’ve been different may be, which it couldn’t.
If hg would be able to entice them, they'd be stuck with using subpar hosts like bitbucket, or hosting repos themselves (and having to figure out different solutions to other features github offered, like bug reports). Which is actually what a lot of large open source projects did in late 2000's/early 2010's, but even those eventually moved to Github because of network effect. (See for example discussions for Python project moving to Github)
But Git adoption has grown over the years to become the default system, helping teams of all sizes work faster as they become more distributed.
As we surpass 10 million registered users on the platform, we're at a point in our growth where we are conducting a deeper evaluation of the market and how we can best support our users going forward.
After much consideration, we've decided to remove Mercurial support from Bitbucket Cloud and its API.