Skip to content

Commit

Permalink
Fix checking out a different branch while pushing a branch for the fi…
Browse files Browse the repository at this point in the history
…rst time (#4214)

- **PR Description**

When pushing a branch that didn't have an upstream yet, we use the
command line

  git push --set-upstream origin HEAD:branch-name

The HEAD: part of this is too unspecific; when checking out a different
branch while the push is still running, then git will set the upstream
branch on the newly checked out branch, not the branch that was being
pushed. This might be considered a bug in git; you might expect that it
resolves HEAD at the beginning of the operation, and uses the result at
the end.

But we can easily work around this by explicitly supplying the real
branch name instead of HEAD.

Fixes #4207.

- **Please check if the PR fulfills these requirements**

* [x] Cheatsheets are up-to-date (run `go generate ./...`)
* [x] Code has been formatted (see
[here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#code-formatting))
* [x] Tests have been added/updated (see
[here](https://github.com/jesseduffield/lazygit/blob/master/pkg/integration/README.md)
for the integration test guide)
* [ ] Text is internationalised (see
[here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#internationalisation))
* [ ] If a new UserConfig entry was added, make sure it can be
hot-reloaded (see
[here](https://github.com/jesseduffield/lazygit/blob/master/docs/dev/Codebase_Guide.md#using-userconfig))
* [ ] Docs have been updated if necessary
* [x] You've read through your own file changes for silly mistakes etc
  • Loading branch information
stefanhaller authored Jan 27, 2025
2 parents 40d6800 + 0864aff commit d768327
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 4 deletions.
5 changes: 4 additions & 1 deletion pkg/commands/git_commands/sync.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package git_commands

import (
"fmt"

"github.com/go-errors/errors"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
Expand All @@ -20,6 +22,7 @@ func NewSyncCommands(gitCommon *GitCommon) *SyncCommands {
type PushOpts struct {
Force bool
ForceWithLease bool
CurrentBranch string
UpstreamRemote string
UpstreamBranch string
SetUpstream bool
Expand All @@ -35,7 +38,7 @@ func (self *SyncCommands) PushCmdObj(task gocui.Task, opts PushOpts) (oscommands
ArgIf(opts.ForceWithLease, "--force-with-lease").
ArgIf(opts.SetUpstream, "--set-upstream").
ArgIf(opts.UpstreamRemote != "", opts.UpstreamRemote).
ArgIf(opts.UpstreamBranch != "", "HEAD:"+opts.UpstreamBranch).
ArgIf(opts.UpstreamBranch != "", fmt.Sprintf("refs/heads/%s:%s", opts.CurrentBranch, opts.UpstreamBranch)).
ToArgv()

cmdObj := self.cmd.New(cmdArgs).PromptOnCredentialRequest(task)
Expand Down
9 changes: 6 additions & 3 deletions pkg/commands/git_commands/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,37 +44,40 @@ func TestSyncPush(t *testing.T) {
testName: "Push with force disabled, upstream supplied",
opts: PushOpts{
ForceWithLease: false,
CurrentBranch: "master",
UpstreamRemote: "origin",
UpstreamBranch: "master",
},
test: func(cmdObj oscommands.ICmdObj, err error) {
assert.Equal(t, cmdObj.Args(), []string{"git", "push", "origin", "HEAD:master"})
assert.Equal(t, cmdObj.Args(), []string{"git", "push", "origin", "refs/heads/master:master"})
assert.NoError(t, err)
},
},
{
testName: "Push with force disabled, setting upstream",
opts: PushOpts{
ForceWithLease: false,
CurrentBranch: "master-local",
UpstreamRemote: "origin",
UpstreamBranch: "master",
SetUpstream: true,
},
test: func(cmdObj oscommands.ICmdObj, err error) {
assert.Equal(t, cmdObj.Args(), []string{"git", "push", "--set-upstream", "origin", "HEAD:master"})
assert.Equal(t, cmdObj.Args(), []string{"git", "push", "--set-upstream", "origin", "refs/heads/master-local:master"})
assert.NoError(t, err)
},
},
{
testName: "Push with force-with-lease enabled, setting upstream",
opts: PushOpts{
ForceWithLease: true,
CurrentBranch: "master",
UpstreamRemote: "origin",
UpstreamBranch: "master",
SetUpstream: true,
},
test: func(cmdObj oscommands.ICmdObj, err error) {
assert.Equal(t, cmdObj.Args(), []string{"git", "push", "--force-with-lease", "--set-upstream", "origin", "HEAD:master"})
assert.Equal(t, cmdObj.Args(), []string{"git", "push", "--force-with-lease", "--set-upstream", "origin", "refs/heads/master:master"})
assert.NoError(t, err)
},
},
Expand Down
1 change: 1 addition & 0 deletions pkg/gui/controllers/sync_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ func (self *SyncController) pushAux(currentBranch *models.Branch, opts pushOpts)
git_commands.PushOpts{
Force: opts.force,
ForceWithLease: opts.forceWithLease,
CurrentBranch: currentBranch.Name,
UpstreamRemote: opts.upstreamRemote,
UpstreamBranch: opts.upstreamBranch,
SetUpstream: opts.setUpstream,
Expand Down

0 comments on commit d768327

Please sign in to comment.