diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 7cae59953..ccbbcb219 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -35,7 +35,7 @@ type GitCommand struct { Tag *git_commands.TagCommands WorkingTree *git_commands.WorkingTreeCommands Bisect *git_commands.BisectCommands - Svn *git_commands.SvnCommands + Svn *git_commands.SvnCommands Worktree *git_commands.WorktreeCommands Version *git_commands.GitVersion RepoPaths *git_commands.RepoPaths diff --git a/pkg/commands/git_commands/branch_loader.go b/pkg/commands/git_commands/branch_loader.go index 4dd099649..17a48ac69 100644 --- a/pkg/commands/git_commands/branch_loader.go +++ b/pkg/commands/git_commands/branch_loader.go @@ -140,6 +140,7 @@ func (self *BranchLoader) Load(reflogCommits []*models.Commit, revOutput, revErr := self.cmd.New( NewGitCmd("rev-list"). Arg("--left-right"). + Arg("--count"). Arg(fmt.Sprintf("%s...%s", branch.FullRefName(), upstreamRef)). ToArgv(), ).DontLog().RunWithOutput() diff --git a/pkg/commands/git_commands/svn_commands.go b/pkg/commands/git_commands/svn_commands.go index 2e2a59780..ce8942dc5 100644 --- a/pkg/commands/git_commands/svn_commands.go +++ b/pkg/commands/git_commands/svn_commands.go @@ -4,10 +4,9 @@ import ( "fmt" "strings" "time" - "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/gocui" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" - "github.com/jesseduffield/lazygit/pkg/common" ) // SvnRefMapping 表示git-svn配置中的一组路径映射 @@ -23,7 +22,7 @@ type SvnCommands struct { *GitCommon cmd oscommands.ICmdObjBuilder // 缓存 SVN ref 映射,避免重复解析git config - svnRefMappingsCache *[] SvnRefMapping + svnRefMappingsCache *[]SvnRefMapping svnUrlCache string svnUrlCacheExpiry time.Time } @@ -179,13 +178,13 @@ func (self *SvnCommands) GetSvnUpstream(branchName string) (string, string, erro for _, m := range mappings { if relPath == m.SvnPath { - upstreamBranch := strings.TrimPrefix(m.RefsPath, "refs/remotes/git-svn") + upstreamBranch := strings.TrimPrefix(m.RefsPath, "refs/remotes/git-svn/") return "git-svn", upstreamBranch, nil } if strings.HasPrefix(relPath, m.SvnPath+"/") { remaining := strings.TrimPrefix(relPath, m.SvnPath) fullRef := m.RefsPath + remaining - upstreamBranch := strings.TrimPrefix(fullRef, "refs/remotes/git-svn") + upstreamBranch := strings.TrimPrefix(fullRef, "refs/remotes/git-svn/") return "git-svn", upstreamBranch, nil } } @@ -197,7 +196,7 @@ func (self *SvnCommands) parseSvnIdLine(commitMessage string) (string, bool) { for _, line := range strings.Split(commitMessage, "\n") { line = strings.TrimSpace(line) if strings.HasPrefix(line, "git-svn-id: ") { - rest := string.TrimPrefix(line, "git-svn-id: ") + rest := strings.TrimPrefix(line, "git-svn-id: ") parts := strings.SplitN(rest, " ", 2) urlWithRev := parts[0] atIdx := strings.LastIndex(urlWithRev, "@") @@ -239,7 +238,7 @@ func (self *SvnCommands) DeleteLocalRef(refName string) error { // Fetch 执行 git svn fetch -all 获取 SVN 更新 func (self *SvnCommands) Fetch() error { - cmdArgs := NewGitCmd("svn").Arg("fetch").Arg("-all").ToArgv() + cmdArgs := NewGitCmd("svn").Arg("fetch").Arg("--all").ToArgv() return self.cmd.New(cmdArgs).Run() } @@ -248,17 +247,17 @@ func (self *SvnCommands) Fetch() error { // 返回值:map[branchPath]models.SvnBranchStatus, branchPath 如 "branches/proj1/xxx" // SVN list 使用 --non-interactive 防止网络阻塞,结果不缓存(每次进入时重新检测) func (self *SvnCommands) CheckBranchStatus(task gocui.Task, refType string) (map[string]models.SvnBranchStatus, error) { - svnUrl, err != self.GetSvnUrl() + svnUrl, err := self.GetSvnUrl() if err != nil { return nil, err } // 1. 获取本地 refs localRefs := make(map[string]bool) - refsPath := "refs/remotes/git-svn" + refType + refsPath := "refs/remotes/git-svn/" + refType output, err := self.cmd.New( NewGitCmd("for-each-ref").Arg("--format=%(refname)").Arg(refsPath).ToArgv(), - ).DontLog.RunWithOutput() + ).DontLog().RunWithOutput() if err == nil { for _, line := range strings.Split(strings.TrimSpace(output), "\n") { if line := strings.TrimSpace(line); line != "" { diff --git a/pkg/commands/git_commands/tag_loader.go b/pkg/commands/git_commands/tag_loader.go index 75ff580a7..a3d390772 100644 --- a/pkg/commands/git_commands/tag_loader.go +++ b/pkg/commands/git_commands/tag_loader.go @@ -2,6 +2,7 @@ package git_commands import ( "regexp" + "strings" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" @@ -55,7 +56,7 @@ func (self *TagLoader) GetTags() ([]*models.Tag, error) { } }) - // SVN 仓库:追究扫描 refs/remotes/git-svn/tags/* 下的引用 + // SVN 仓库:追加扫描 refs/remotes/git-svn/tags/* 下的引用 if self.gitCommon != nil && self.gitCommon.IsSvnRepo() { tagsPaths, err := self.gitCommon.Svn.GetTagsRefsPaths() if err == nil && len(tagsPaths) > 0 { @@ -79,7 +80,7 @@ func (self *TagLoader) getTagsFromPath(basePath string) ([]*models.Tag, error) { Arg(basePath). ToArgv() - err := self.cmd.New(cmdArgs).DontLog().RunAndProcessLines(func(line, string) (bool, error){ + err := self.cmd.New(cmdArgs).DontLog().RunAndProcessLines(func(line string) (bool, error){ line = strings.TrimSpace(line) if line == "" { return false, nil diff --git a/pkg/commands/models/svn_branch_status.go b/pkg/commands/models/svn_branch_status.go index 095fc8c77..7f64131e6 100644 --- a/pkg/commands/models/svn_branch_status.go +++ b/pkg/commands/models/svn_branch_status.go @@ -4,7 +4,7 @@ package models type SvnBranchStatus int const ( - SvnBranchStatusUnknown SvnBranchStatus = itoa + SvnBranchStatusUnknown SvnBranchStatus = iota SvnBranchStatusOk // 正常: 本地和 SVN 服务器都存在 SvnBranchStatusStale // Stale:本地有引用但 SVN 服务器已删除 SvnBranchStatusMissing // Missing:本地未 fetch 但 SVN 服务器上有 diff --git a/pkg/commands/models/tag.go b/pkg/commands/models/tag.go index e2ff5aa39..51675d6ce 100644 --- a/pkg/commands/models/tag.go +++ b/pkg/commands/models/tag.go @@ -18,7 +18,10 @@ type Tag struct { } func (t *Tag) FullRefName() string { - return "refs/tags/" + t.RefName() + if t.FullRefNameOverride != "" { + return "refs/tags/" + t.RefName() + } + return "" } func (t *Tag) RefName() string { diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index e3936ee35..de3c40a8c 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -359,7 +359,7 @@ type GitConfig struct { // 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 `yaml:"EnableGitSvnCompat" jsonschema:"default=true"` + EnableGitSvnCompat bool `yaml:"enableGitSvnCompat" jsonschema:"default=true"` } type DiffRendererCommandType string diff --git a/pkg/gui/controllers/remote_branches_controller.go b/pkg/gui/controllers/remote_branches_controller.go index 38a766ebf..4ffa12c7d 100644 --- a/pkg/gui/controllers/remote_branches_controller.go +++ b/pkg/gui/controllers/remote_branches_controller.go @@ -225,7 +225,7 @@ func (self *RemoteBranchesController) deleteSvnRemoteBranches(selectedBranches [ return self.c.Menu(types.CreateMenuOptions{ Title: menuTitle, - Items: []*types.menuTitle{ + Items: []*types.MenuTitle{ { LabelColumns: []string{self.c.Tr.DeleteSvnLocalRef}, Key: 'l', @@ -248,7 +248,7 @@ func (self *RemoteBranchesController) deleteSvnLocalRefs(selectedBranches []*mod return self.c.WithWaitingStatus(self.c.Tr.DeletingStatus, func(task gocui.Task) error { for _, branch := range selectedBranches { refName := branch.RemoteName + "/" + branch.Name - if err := self.c.Git().Svn.DeleteSvnLocalRef(refName); err != nil { + if err := self.c.Git().Svn.DeleteLocalRef(refName); err != nil { return err } } @@ -261,7 +261,7 @@ func (self *RemoteBranchesController) deleteSvnLocalRefs(selectedBranches []*mod }) } -func (self *RemoteBranchesController) confirmDeleteSvnBoth(selectedBranches []models.RemoteBranch) error { +func (self *RemoteBranchesController) confirmDeleteSvnBoth(selectedBranches []*models.RemoteBranch) error { var prompt string if len(selectedBranches) == 1 { prompt = utils.ResolvePlaceholderString( diff --git a/pkg/gui/presentation/remote_branches.go b/pkg/gui/presentation/remote_branches.go index 1261403fa..bacc93d9a 100644 --- a/pkg/gui/presentation/remote_branches.go +++ b/pkg/gui/presentation/remote_branches.go @@ -37,6 +37,6 @@ func getRemoteBranchDisplayStrings(b *models.RemoteBranch, diffed bool) []string if icons.IsIconEnabled() { res = append(res, textStyle.Sprint(icons.IconForRemoteBranch(b))) } - res = append(res, textStyle.Sprint(b.Name)) + res = append(res, textStyle.Sprint(name)) return res } diff --git a/pkg/gui/presentation/tags.go b/pkg/gui/presentation/tags.go index 61e1f6e9a..c9cf238a5 100644 --- a/pkg/gui/presentation/tags.go +++ b/pkg/gui/presentation/tags.go @@ -48,10 +48,10 @@ func getTagDisplayStrings( if t.IsSvnTag() { switch t.StaleStatus { case models.SvnBranchStatusStale: - name = b.Name + "⚠" + name = t.Name + "⚠" textStyle = style.FgRed case models.SvnBranchStatusMissing: - name = b.Name + "(not fetched)" + name = t.Name + "(not fetched)" textStyle = style.FgWhite } } @@ -62,6 +62,6 @@ func getTagDisplayStrings( if itemOperationStr != "" { descriptionStr = style.FgCyan.Sprint(itemOperationStr+" "+Loader(time.Now(), userConfig.Gui.Spinner)) + " " + descriptionStr } - res = append(res, textStyle.Sprint(t.Name), descriptionStr) + res = append(res, textStyle.Sprint(name), descriptionStr) return res } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 74ad4ec91..950d46ee6 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -2143,22 +2143,22 @@ func EnglishTranslationSet() *TranslationSet { UseBothChanges: "Use both", // --- SVN 相关 --- - NewSvnBranch "New SVN remote branch", - NewSvnBranchPrompt "SVN branch name (relative to --branches config, e.g. my-feature", - SvnBranchCreateSuccess "SVN branch created. Fetching from SVN ...", - SvnFetchFailed "SVN branch created but fetch failed. Run 'git svn fetch' manually.", + NewSvnBranch: "New SVN remote branch", + NewSvnBranchPrompt: "SVN branch name (relative to --branches config, e.g. my-feature", + SvnBranchCreateSuccess: "SVN branch created. Fetching from SVN ...", + SvnFetchFailed: "SVN branch created but fetch failed. Run 'git svn fetch' manually.", - DeleteSvnLocalRef "Delete local ref only (safe)", - DeleteSvnBoth "Delete from SVN server and local ref (dangerous)", - DeleteSvnBothConfirm "This will PERMANENTLY delete '{{.branchPath}}' from both local refs and SVN server. Continue?", - SvnDeleteLocalRefSuccess "Local ref deleted.", - SvnDeleteBothSuccess "SVN branch deleted from both local and SVN server.", - SvnOperationFailed "SVN operation failed: {{.error}}", + DeleteSvnLocalRef: "Delete local ref only (safe)", + DeleteSvnBoth: "Delete from SVN server and local ref (dangerous)", + DeleteSvnBothConfirm: "This will PERMANENTLY delete '{{.branchPath}}' from both local refs and SVN server. Continue?", + SvnDeleteLocalRefSuccess: "Local ref deleted.", + SvnDeleteBothSuccess: "SVN branch deleted from both local and SVN server.", + SvnOperationFailed: "SVN operation failed: {{.error}}", - SvnCreateBranchTitle "Create SVN Remote Branch", - SvnDeleteBranchTitle "Delete SVN Remote Branch", - SvnFetchingStatus "Fetching from SVN ...", - CheckingSvnStatus "Checking SVN branch status ...", + SvnCreateBranchTitle: "Create SVN Remote Branch", + SvnDeleteBranchTitle: "Delete SVN Remote Branch", + SvnFetchingStatus: "Fetching from SVN ...", + CheckingSvnStatus: "Checking SVN branch status ...", Actions: Actions{ // TODO: combine this with the original keybinding descriptions (those are all in lowercase atm)