In my day-to-day git workflow, I have many topic branches, like so:
o--o--o (t2) / o--o (t1) / o--o--o (master) \ o--o--o (t3)
When I pull from upstream,
o--o--o (t2) / o--o (t1) / o--o--o--n--n--n (master) \ o--o--o (t3)
I want to rebase all my topic branches on top of the new master:
o'--o'--o' (t2) / o'--o' (t1) / o--o--o--n--n--n (master) \ o'--o'--o' (t3)
Currently I do this by hand, using git rebase --onto
. In this scenario, the whole update process would be:
$ git checkout master $ git pull $ git rebase master t1 $ git rebase --onto t1 t2~3 t2 $ git rebase master t3
This gets even hairier when jumping between various topic branches and adding commits.
Dependencies between topic branches in my case are purely tree-like: no branch depends on more than a single other branch. (I have to eventually upstream dependent patches in some particular order, so I choose that order a priori.)
Are there any tools that can help me manage this workflow? I've seen TopGit, but it seems to be tied quite heavily to the tg patch
email-based workflow, which isn't relevant to me.
What is git rebase? From a content perspective, rebasing is changing the base of your branch from one commit to another making it appear as if you'd created your branch from a different commit. Internally, Git accomplishes this by creating new commits and applying them to the specified base.
Git Merge Vs Git Rebase:Git merge is a command that allows you to merge branches from Git. Git rebase is a command that allows developers to integrate changes from one branch to another. In Git Merge logs will be showing the complete history of the merging of commits.
Pretty much the same question was asked on the git mailing list: Rebasing Multiple branches at once... The linked response has a perl script attached that generates the commands you would need.
If you want this script to be fast and avoid having it tread on your toes, also consider using git-new-workdir
to set up a working copy just for automatic rebasing.
If you find yourself resolving the same conflicts over and over, consider enabling git rerere.
Having said all that, here is an alternate recipe:
# Construct a placeholder commit that has all topics as parent. HEADS="$(git for-each-ref refs/heads/\*)" && MAGIC_COMMIT=$(echo "Magic Octopus"$'\n\n'"$HEADS" | git commit-tree \ $(git merge-base $(echo "$HEADS" | sed 's/ .*//' ))^{tree} \ $(echo "$HEADS" | sed 's/ .*//;s/^/-p /')) && git update-ref refs/hidden/all $MAGIC_COMMIT # Rebase the whole lot at once. git rebase --preserve-merges master refs/hidden/all # Resolve conflicts and all that jazz. # Update topic refs from the rebased placeholder. PARENT= echo "$HEADS" | while read HASH TYPE REF do let ++PARENT git update-ref -m 'Mass rebase' "$REF" refs/hidden/all^$PARENT "$HASH" done
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With