1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
package git_commands
import (
"fmt"
"github.com/go-errors/errors"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
)
type SyncCommands struct {
*GitCommon
}
func NewSyncCommands(gitCommon *GitCommon) *SyncCommands {
return &SyncCommands{
GitCommon: gitCommon,
}
}
// Push pushes to a branch
type PushOpts struct {
Force bool
ForceWithLease bool
CurrentBranch string
UpstreamRemote string
UpstreamBranch string
SetUpstream bool
}
func (self *SyncCommands) PushCmdObj(task gocui.Task, opts PushOpts) (oscommands.ICmdObj, error) {
if opts.UpstreamBranch != "" && opts.UpstreamRemote == "" {
return nil, errors.New(self.Tr.MustSpecifyOriginError)
}
cmdArgs := NewGitCmd("push").
ArgIf(opts.Force, "--force").
ArgIf(opts.ForceWithLease, "--force-with-lease").
ArgIf(opts.SetUpstream, "--set-upstream").
ArgIf(opts.UpstreamRemote != "", opts.UpstreamRemote).
ArgIf(opts.UpstreamBranch != "", fmt.Sprintf("refs/heads/%s:%s", opts.CurrentBranch, opts.UpstreamBranch)).
ToArgv()
cmdObj := self.cmd.New(cmdArgs).PromptOnCredentialRequest(task)
return cmdObj, nil
}
func (self *SyncCommands) Push(task gocui.Task, opts PushOpts) error {
cmdObj, err := self.PushCmdObj(task, opts)
if err != nil {
return err
}
return cmdObj.Run()
}
func (self *SyncCommands) fetchCommandBuilder(fetchAll bool) *GitCommandBuilder {
return NewGitCmd("fetch").
ArgIf(fetchAll, "--all").
// avoid writing to .git/FETCH_HEAD; this allows running a pull
// concurrently without getting errors
ArgIf(self.version.IsAtLeast(2, 29, 0), "--no-write-fetch-head")
}
func (self *SyncCommands) FetchCmdObj(task gocui.Task) oscommands.ICmdObj {
cmdArgs := self.fetchCommandBuilder(self.UserConfig().Git.FetchAll).ToArgv()
cmdObj := self.cmd.New(cmdArgs)
cmdObj.PromptOnCredentialRequest(task)
return cmdObj
}
func (self *SyncCommands) Fetch(task gocui.Task) error {
return self.FetchCmdObj(task).Run()
}
func (self *SyncCommands) FetchBackgroundCmdObj() oscommands.ICmdObj {
cmdArgs := self.fetchCommandBuilder(self.UserConfig().Git.FetchAll).ToArgv()
cmdObj := self.cmd.New(cmdArgs)
cmdObj.DontLog().FailOnCredentialRequest()
return cmdObj
}
func (self *SyncCommands) FetchBackground() error {
return self.FetchBackgroundCmdObj().Run()
}
type PullOptions struct {
RemoteName string
BranchName string
FastForwardOnly bool
WorktreeGitDir string
WorktreePath string
}
func (self *SyncCommands) Pull(task gocui.Task, opts PullOptions) error {
cmdArgs := NewGitCmd("pull").
Arg("--no-edit").
ArgIf(opts.FastForwardOnly, "--ff-only").
ArgIf(opts.RemoteName != "", opts.RemoteName).
ArgIf(opts.BranchName != "", "refs/heads/"+opts.BranchName).
GitDirIf(opts.WorktreeGitDir != "", opts.WorktreeGitDir).
WorktreePathIf(opts.WorktreePath != "", opts.WorktreePath).
ToArgv()
// setting GIT_SEQUENCE_EDITOR to ':' as a way of skipping it, in case the user
// has 'pull.rebase = interactive' configured.
return self.cmd.New(cmdArgs).AddEnvVars("GIT_SEQUENCE_EDITOR=:").PromptOnCredentialRequest(task).Run()
}
func (self *SyncCommands) FastForward(
task gocui.Task,
branchName string,
remoteName string,
remoteBranchName string,
) error {
cmdArgs := self.fetchCommandBuilder(false).
Arg(remoteName).
Arg("refs/heads/" + remoteBranchName + ":" + branchName).
ToArgv()
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).Run()
}
func (self *SyncCommands) FetchRemote(task gocui.Task, remoteName string) error {
cmdArgs := self.fetchCommandBuilder(false).
Arg(remoteName).
ToArgv()
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).Run()
}
|