6

Git 2.38 introduced the --update-refs flag to the rebase command. If you have a chain of branches, it will update all the branches in the chain. I've found this incredibly useful when breaking a large PR down into more easily reviewed PRs.

However, after git rebase --update-refs dev, I need to push all the refs to GitHub to update the PRs. This requires a set of git checkout branch1 && git push --force-with-lease && git checkout branch2 && git push --force-with-lease && ....

Is there a way built into git to handle this automatically? I basically want to push --force-with-lease automatically for any branches updated during a rebase --update-refs.

Andrew Hampton
  • 1,632
  • 3
  • 20
  • 29

4 Answers4

3

I'm not sure that you can do this "automatically", but you can get pretty close.

When you use the --update-refs option with rebase, the output will tell you all of your local branches that were updated:

$ git rebase origin/main my-branch --update-refs

Successfully rebased and updated refs/heads/my-branch.
Updated the following refs with --update-refs:
        refs/heads/some-branch-1
        refs/heads/some-branch-2

From there you can use that output to build a single command to force push all of your modified branches:

git push --force-with-lease origin my-branch some-branch-1 some-branch-2

Tip: when using the --update-refs option and there is at least one branch to update, you'll notice that the number of actions in the output is higher than the number of commits you are rebasing. This is because every instruction line is counted (including blank lines). You can add the -i option (for interactive rebase) to see exactly what instructions are used. This is also a good way to see what branches will be updated when you run the command, if you wish to know that beforehand.

TTT
  • 22,611
  • 8
  • 63
  • 69
2

To save from copy/pasting, if you have a branch naming convention, such as fix/a-bug or project/beta, it's possible to target all branches branched from a target using git branch --contains:

git branch --list --format='%(refname:lstrip=2)' --contains=project/beta | xargs -I "{}" git push origin {}
MattyRad
  • 173
  • 1
  • 10
1

You can push all matching branches at once.

git push origin :

The special refspec : (or +: to allow non-fast-forward updates) directs Git to push "matching" branches: for every branch that exists on the local side, the remote side is updated if a branch of the same name already exists on the remote side. git-push.

joke
  • 654
  • 9
  • 11
  • 3
    In the context of this question you would need to use force push. If you are force pushing every branch you have locally, then please use this command with extreme caution! – TTT Oct 10 '22 at 16:00
0

After trying @MattyRad solution without success I got to polish it to the following working solution:

git branch --list "*jony*" | xargs -I "{}" git push origin {} --force-with-lease

This will force push (with lease) all your local branches. If you are using a naming convention, you can place it on the list pattern.

Jonatan Kruszewski
  • 1,027
  • 3
  • 23