mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-10-06 14:06:32 -04:00
After rebasing a stack of branches, every branch of the stack has to be force-pushed, and so far the only way to do that in lazygit was to check out each branch in turn and push it. For a stack of a dozen branches that is a lot of work for a routine task. When the current branch is pushed and there are branches below it in the stack that have commits to push, show a menu that offers to push them along with it. The menu lists the branches and how far each of them has diverged from its remote branch, so that the user can see what is about to happen. It doesn't show where each branch goes; the branches panel doesn't show that for a normal push either. Pushing only the current branch is the second entry. If any of the branches has diverged from its remote branch, a single confirmation covers force-pushing all of them. A branch is offered if its tip is a commit of the current branch that isn't merged yet, it has an upstream that is stored locally, that upstream is not gone, and it is ahead of its push destination. Branches without an upstream are left out because a branch that was never pushed can't be told apart from one that is meant to stay local. A branch that is only behind is left out because pushing it would move the remote branch back to an older commit; the lease doesn't catch that when the remote-tracking branch is up to date. Each branch is pushed to where `git push` would push it if it were checked out, using the destination git reports in the %(push) field. This honors push.default, remote.pushDefault and branch.<name>.pushRemote without lazygit having to interpret them. Branches going to the same remote are pushed in one command, with --force-with-lease when the user confirmed force-pushing; the lease checks each ref against its remote-tracking branch, so a coworker's unseen push is still rejected. The current branch joins that command when its remote-tracking branch is stored locally. Otherwise it needs a plain push first, for example with --set-upstream, and that option would apply to every refspec of a combined command; so in that case it is pushed on its own as before, and the other branches follow in a second command. Pushing the current branch on its own still runs a bare `git push`, so users who rely on push.default or remote.<name>.push for it see no change. The push is non-atomic, as git defaults to; if one branch's lease fails, the others still go through and the error names the one to look at. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>