mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-12 16:46:25 -04:00
Add support for git-svn repository.
1. Can detect repository automatically. 2. Remap push/pull/fetch commands to git svn dcommit/rebase/fetch commands. 3. Command log window will show the repository type.
This commit is contained in:
parent
1d0db51caf
commit
20b268fa90
|
|
@ -1,6 +1,8 @@
|
|||
package git_commands
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
gogit "github.com/jesseduffield/go-git/v5"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/common"
|
||||
|
|
@ -16,6 +18,27 @@ type GitCommon struct {
|
|||
repo *gogit.Repository
|
||||
config *ConfigCommands
|
||||
pagerConfig *config.PagerConfig
|
||||
IsGitSvnRepo bool
|
||||
}
|
||||
|
||||
func (self *GitCommon) detectGitSvnRepo() {
|
||||
if self.Common != nil && !self.Common.UserConfig().Git.EnableGitSvnCompat {
|
||||
self.IsGitSvnRepo = false
|
||||
return
|
||||
}
|
||||
|
||||
if self.repoPaths == nil {
|
||||
self.IsGitSvnRepo = false
|
||||
return
|
||||
}
|
||||
|
||||
svnDir := filepath.Join(self.repoPaths.RepoGitDirPath(), "svn")
|
||||
if info, err := os.Stat(svnDir); err == nil && info.IsDir() {
|
||||
self.IsGitSvnRepo = true
|
||||
self.Common.Log.Info("Detected Git-SVN repository (found .git/svn)")
|
||||
} else {
|
||||
self.IsGitSvnRepo = false
|
||||
}
|
||||
}
|
||||
|
||||
func NewGitCommon(
|
||||
|
|
@ -28,7 +51,7 @@ func NewGitCommon(
|
|||
config *ConfigCommands,
|
||||
pagerConfig *config.PagerConfig,
|
||||
) *GitCommon {
|
||||
return &GitCommon{
|
||||
gitCommon := &GitCommon{
|
||||
Common: cmn,
|
||||
version: version,
|
||||
cmd: cmd,
|
||||
|
|
@ -38,4 +61,10 @@ func NewGitCommon(
|
|||
config: config,
|
||||
pagerConfig: pagerConfig,
|
||||
}
|
||||
gitCommon.detectGitSvnRepo()
|
||||
return gitCommon
|
||||
}
|
||||
|
||||
func (self *GitCommon) IsSvnRepo() bool {
|
||||
return self.IsGitSvnRepo
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ type PushOpts struct {
|
|||
}
|
||||
|
||||
func (self *SyncCommands) PushCmdObj(task gocui.Task, opts PushOpts) (*oscommands.CmdObj, error) {
|
||||
if self.IsGitSvnRepo {
|
||||
cmdArgs := NewGitCmd("svn").Arg("dcommit").ToArgv()
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task), nil
|
||||
}
|
||||
|
||||
if opts.UpstreamBranch != "" && opts.UpstreamRemote == "" {
|
||||
return nil, errors.New(self.Tr.MustSpecifyOriginError)
|
||||
}
|
||||
|
|
@ -63,6 +68,11 @@ func (self *SyncCommands) fetchCommandBuilder(fetchAll bool) *GitCommandBuilder
|
|||
}
|
||||
|
||||
func (self *SyncCommands) FetchCmdObj(task gocui.Task) *oscommands.CmdObj {
|
||||
if self.IsGitSvnRepo {
|
||||
cmdArgs := NewGitCmd("svn").Arg("fetch").ToArgv()
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task)
|
||||
}
|
||||
|
||||
cmdArgs := self.fetchCommandBuilder(self.UserConfig().Git.FetchAll).ToArgv()
|
||||
|
||||
cmdObj := self.cmd.New(cmdArgs)
|
||||
|
|
@ -96,6 +106,11 @@ type PullOptions struct {
|
|||
}
|
||||
|
||||
func (self *SyncCommands) Pull(task gocui.Task, opts PullOptions) error {
|
||||
if self.IsGitSvnRepo {
|
||||
cmdArgs := NewGitCmd("svn").Arg("rebase").ToArgv()
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).Run()
|
||||
}
|
||||
|
||||
cmdArgs := NewGitCmd("pull").
|
||||
Arg("--no-edit").
|
||||
ArgIf(opts.FastForwardOnly, "--ff-only").
|
||||
|
|
|
|||
|
|
@ -321,6 +321,8 @@ type GitConfig struct {
|
|||
RemoteBranchSortOrder string `yaml:"remoteBranchSortOrder" jsonschema:"enum=date,enum=alphabetical"`
|
||||
// When copying commit hashes to the clipboard, truncate them to this length. Set to 40 to disable truncation.
|
||||
TruncateCopiedCommitHashesTo int `yaml:"truncateCopiedCommitHashesTo"`
|
||||
// If true, will detect if git repository is created using git-svn, is so, will use git svn dcommit/rebase for push/pull operations.
|
||||
EnableGitSvnCompat bool `toml:"EnableGitSvnCompat"`
|
||||
}
|
||||
|
||||
type PagerType string
|
||||
|
|
@ -857,6 +859,7 @@ func GetDefaultConfig() *UserConfig {
|
|||
BranchPrefix: "",
|
||||
ParseEmoji: false,
|
||||
TruncateCopiedCommitHashesTo: 12,
|
||||
EnableGitSvnCompat: true,
|
||||
},
|
||||
Refresher: RefresherConfig{
|
||||
RefreshInterval: 10,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,12 @@ func (gui *Gui) printCommandLogHeader() {
|
|||
)
|
||||
fmt.Fprintln(gui.Views.Extras, style.FgCyan.Sprint(introStr))
|
||||
|
||||
if gui.git.Sync.GitCommon.IsSvnRepo() {
|
||||
fmt.Fprintln(gui.Views.Extras, "Is a Git-SVN repository: Pull=rebase | Push=dcommit")
|
||||
} else {
|
||||
fmt.Fprintln(gui.Views.Extras, "Is a Git repository")
|
||||
}
|
||||
|
||||
if gui.c.UserConfig().Gui.ShowRandomTip {
|
||||
fmt.Fprintf(
|
||||
gui.Views.Extras,
|
||||
|
|
|
|||
|
|
@ -175,6 +175,12 @@ func (self *SyncController) pullWithLock(task gocui.Task, opts PullFilesOptions)
|
|||
},
|
||||
)
|
||||
|
||||
if self.c.Git().Sync.GitCommon.IsSvnRepo() {
|
||||
if err != nil {
|
||||
return fmt.Errorf("Git-SVN rebase failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
|
||||
}
|
||||
|
||||
|
|
@ -195,6 +201,12 @@ type pushOpts struct {
|
|||
func (self *SyncController) pushAux(currentBranch *models.Branch, opts pushOpts) error {
|
||||
return self.c.WithInlineStatus(currentBranch, types.ItemOperationPushing, context.LOCAL_BRANCHES_CONTEXT_KEY, func(task gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.Push)
|
||||
|
||||
if self.c.Git().Sync.GitCommon.IsSvnRepo() {
|
||||
opts.force = false
|
||||
opts.forceWithLease = false
|
||||
}
|
||||
|
||||
err := self.c.Git().Sync.Push(
|
||||
task,
|
||||
git_commands.PushOpts{
|
||||
|
|
@ -206,6 +218,10 @@ func (self *SyncController) pushAux(currentBranch *models.Branch, opts pushOpts)
|
|||
SetUpstream: opts.setUpstream,
|
||||
})
|
||||
if err != nil {
|
||||
if self.c.Git().Sync.GitCommon.IsSvnRepo() {
|
||||
return fmt.Errorf("Git-SVN dcommit failed: %w", err)
|
||||
}
|
||||
|
||||
if !opts.force && !opts.forceWithLease && strings.Contains(err.Error(), "Updates were rejected") {
|
||||
if opts.remoteBranchStoredLocally {
|
||||
return errors.New(self.c.Tr.UpdatesRejected)
|
||||
|
|
|
|||
Loading…
Reference in a new issue