From 47d422bb8a210cfb300ae7f5050de3ef791a4ca2 Mon Sep 17 00:00:00 2001 From: AzraelSec Date: Sun, 27 Aug 2023 14:02:13 +0200 Subject: [PATCH 1/2] chore: rename "Set/Unset upstream" menu to "Upstream Options" This should already have been done when adding the "View divergence from upstream" command, but now we're going to add yet another item to the menu that is unrelated to setting or unsetting the upstream. --- docs/keybindings/Keybindings_en.md | 2 +- docs/keybindings/Keybindings_ja.md | 2 +- docs/keybindings/Keybindings_ko.md | 2 +- docs/keybindings/Keybindings_nl.md | 2 +- docs/keybindings/Keybindings_pl.md | 2 +- docs/keybindings/Keybindings_ru.md | 2 +- docs/keybindings/Keybindings_zh-CN.md | 2 +- docs/keybindings/Keybindings_zh-TW.md | 2 +- pkg/gui/controllers/branches_controller.go | 5 +- pkg/i18n/english.go | 98 ++++++++++--------- pkg/i18n/korean.go | 1 - pkg/i18n/russian.go | 2 - pkg/i18n/traditional_chinese.go | 2 - .../tests/branch/reset_upstream.go | 2 +- pkg/integration/tests/branch/set_upstream.go | 2 +- .../branch/show_divergence_from_upstream.go | 2 +- 16 files changed, 64 insertions(+), 66 deletions(-) diff --git a/docs/keybindings/Keybindings_en.md b/docs/keybindings/Keybindings_en.md index 718c2d2be..976ea8193 100644 --- a/docs/keybindings/Keybindings_en.md +++ b/docs/keybindings/Keybindings_en.md @@ -155,7 +155,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ T: Create tag g: View reset options R: Rename branch - u: Set/Unset upstream + u: View upstream options w: View worktree options <enter>: View commits /: Filter the current view by text diff --git a/docs/keybindings/Keybindings_ja.md b/docs/keybindings/Keybindings_ja.md index 02e6af23f..419beb5dd 100644 --- a/docs/keybindings/Keybindings_ja.md +++ b/docs/keybindings/Keybindings_ja.md @@ -227,7 +227,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ T: タグを作成 g: View reset options R: ブランチ名を変更 - u: Set/Unset upstream + u: View upstream options w: View worktree options <enter>: コミットを閲覧 /: Filter the current view by text diff --git a/docs/keybindings/Keybindings_ko.md b/docs/keybindings/Keybindings_ko.md index 4af5fb1a3..71c57714e 100644 --- a/docs/keybindings/Keybindings_ko.md +++ b/docs/keybindings/Keybindings_ko.md @@ -190,7 +190,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ T: 태그를 생성 g: View reset options R: 브랜치 이름 변경 - u: Set/Unset upstream + u: View upstream options w: View worktree options <enter>: 커밋 보기 /: Filter the current view by text diff --git a/docs/keybindings/Keybindings_nl.md b/docs/keybindings/Keybindings_nl.md index 7d366fcda..13a868817 100644 --- a/docs/keybindings/Keybindings_nl.md +++ b/docs/keybindings/Keybindings_nl.md @@ -97,7 +97,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ T: Creëer tag g: Bekijk reset opties R: Hernoem branch - u: Set/Unset upstream + u: View upstream options w: View worktree options <enter>: Bekijk commits /: Filter the current view by text diff --git a/docs/keybindings/Keybindings_pl.md b/docs/keybindings/Keybindings_pl.md index f4f59228e..eae095115 100644 --- a/docs/keybindings/Keybindings_pl.md +++ b/docs/keybindings/Keybindings_pl.md @@ -113,7 +113,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ T: Create tag g: Wyświetl opcje resetu R: Rename branch - u: Set/Unset upstream + u: View upstream options w: View worktree options <enter>: View commits /: Filter the current view by text diff --git a/docs/keybindings/Keybindings_ru.md b/docs/keybindings/Keybindings_ru.md index 9a03d2935..ff533b605 100644 --- a/docs/keybindings/Keybindings_ru.md +++ b/docs/keybindings/Keybindings_ru.md @@ -188,7 +188,7 @@ _Связки клавиш_ T: Создать тег g: Просмотреть параметры сброса R: Переименовать ветку - u: Установить/убрать upstream-ветку + u: View upstream options w: View worktree options <enter>: Просмотреть коммиты /: Filter the current view by text diff --git a/docs/keybindings/Keybindings_zh-CN.md b/docs/keybindings/Keybindings_zh-CN.md index 6f60cb644..620c77495 100644 --- a/docs/keybindings/Keybindings_zh-CN.md +++ b/docs/keybindings/Keybindings_zh-CN.md @@ -91,7 +91,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ T: 创建标签 g: 查看重置选项 R: 重命名分支 - u: Set/Unset upstream + u: View upstream options w: View worktree options <enter>: 查看提交 /: Filter the current view by text diff --git a/docs/keybindings/Keybindings_zh-TW.md b/docs/keybindings/Keybindings_zh-TW.md index eb82367b5..186d02864 100644 --- a/docs/keybindings/Keybindings_zh-TW.md +++ b/docs/keybindings/Keybindings_zh-TW.md @@ -263,7 +263,7 @@ _說明:`` 表示 Ctrl+B、`` 表示 Alt+B,`B`表示 Shift+B_ T: 建立標籤 g: 檢視重設選項 R: 重新命名分支 - u: 設定/取消設定上游 + u: View upstream options w: View worktree options <enter>: 檢視提交 /: Filter the current view by text diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index 67174439c..8fc621e76 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -108,7 +108,8 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty { Key: opts.GetKey(opts.Config.Branches.SetUpstream), Handler: self.checkSelected(self.setUpstream), - Description: self.c.Tr.SetUnsetUpstream, + Description: self.c.Tr.ViewBranchUpstreamOptions, + Tooltip: self.c.Tr.ViewBranchUpstreamOptionsTooltip, OpensMenu: true, }, } @@ -140,7 +141,7 @@ func (self *BranchesController) GetOnRenderToMain() func() error { func (self *BranchesController) setUpstream(selectedBranch *models.Branch) error { return self.c.Menu(types.CreateMenuOptions{ - Title: self.c.Tr.Actions.SetUnsetUpstream, + Title: self.c.Tr.BranchUpstreamOptionsTitle, Items: []*types.MenuItem{ { LabelColumns: []string{self.c.Tr.ViewDivergenceFromUpstream}, diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 5c7f99b55..32825a272 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -396,7 +396,9 @@ type TranslationSet struct { KeybindingsMenuSectionGlobal string KeybindingsMenuSectionNavigation string RenameBranch string - SetUnsetUpstream string + ViewBranchUpstreamOptions string + BranchUpstreamOptionsTitle string + ViewBranchUpstreamOptionsTooltip string NewGitFlowBranchPrompt string RenameBranchWarning string OpenMenu string @@ -654,7 +656,6 @@ type Actions struct { Merge string RebaseBranch string RenameBranch string - SetUnsetUpstream string CreateBranch string FastForwardBranch string CherryPick string @@ -1166,51 +1167,53 @@ func EnglishTranslationSet() TranslationSet { NotAGitFlowBranch: "This does not seem to be a git flow branch", NewGitFlowBranchPrompt: "New {{.branchType}} name:", - IgnoreTracked: "Ignore tracked file", - IgnoreTrackedPrompt: "Are you sure you want to ignore a tracked file?", - ExcludeTracked: "Exclude tracked file", - ExcludeTrackedPrompt: "Are you sure you want to exclude a tracked file?", - ViewResetToUpstreamOptions: "View upstream reset options", - NextScreenMode: "Next screen mode (normal/half/fullscreen)", - PrevScreenMode: "Prev screen mode", - StartSearch: "Search the current view by text", - StartFilter: "Filter the current view by text", - Panel: "Panel", - KeybindingsLegend: "Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b", - RenameBranch: "Rename branch", - SetUnsetUpstream: "Set/Unset upstream", - NewBranchNamePrompt: "Enter new branch name for branch", - RenameBranchWarning: "This branch is tracking a remote. This action will only rename the local branch name, not the name of the remote branch. Continue?", - OpenMenu: "Open menu", - ResetCherryPick: "Reset cherry-picked (copied) commits selection", - NextTab: "Next tab", - PrevTab: "Previous tab", - CantUndoWhileRebasing: "Can't undo while rebasing", - CantRedoWhileRebasing: "Can't redo while rebasing", - MustStashWarning: "Pulling a patch out into the index requires stashing and unstashing your changes. If something goes wrong, you'll be able to access your files from the stash. Continue?", - MustStashTitle: "Must stash", - ConfirmationTitle: "Confirmation panel", - PrevPage: "Previous page", - NextPage: "Next page", - GotoTop: "Scroll to top", - GotoBottom: "Scroll to bottom", - FilteringBy: "Filtering by", - ResetInParentheses: "(Reset)", - OpenFilteringMenu: "View filter-by-path options", - FilterBy: "Filter by", - ExitFilterMode: "Stop filtering by path", - FilterPathOption: "Enter path to filter by", - EnterFileName: "Enter path:", - FilteringMenuTitle: "Filtering", - MustExitFilterModeTitle: "Command not available", - MustExitFilterModePrompt: "Command not available in filter-by-path mode. Exit filter-by-path mode?", - Diff: "Diff", - EnterRefToDiff: "Enter ref to diff", - EnterRefName: "Enter ref:", - ExitDiffMode: "Exit diff mode", - DiffingMenuTitle: "Diffing", - SwapDiff: "Reverse diff direction", - OpenDiffingMenu: "Open diff menu", + IgnoreTracked: "Ignore tracked file", + IgnoreTrackedPrompt: "Are you sure you want to ignore a tracked file?", + ExcludeTracked: "Exclude tracked file", + ExcludeTrackedPrompt: "Are you sure you want to exclude a tracked file?", + ViewResetToUpstreamOptions: "View upstream reset options", + NextScreenMode: "Next screen mode (normal/half/fullscreen)", + PrevScreenMode: "Prev screen mode", + StartSearch: "Search the current view by text", + StartFilter: "Filter the current view by text", + Panel: "Panel", + KeybindingsLegend: "Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b", + RenameBranch: "Rename branch", + BranchUpstreamOptionsTitle: "Upstream options", + ViewBranchUpstreamOptionsTooltip: "View options relating to the branch's upstream e.g. setting/unsetting the upstream and resetting to the upstream", + ViewBranchUpstreamOptions: "View upstream options", + NewBranchNamePrompt: "Enter new branch name for branch", + RenameBranchWarning: "This branch is tracking a remote. This action will only rename the local branch name, not the name of the remote branch. Continue?", + OpenMenu: "Open menu", + ResetCherryPick: "Reset cherry-picked (copied) commits selection", + NextTab: "Next tab", + PrevTab: "Previous tab", + CantUndoWhileRebasing: "Can't undo while rebasing", + CantRedoWhileRebasing: "Can't redo while rebasing", + MustStashWarning: "Pulling a patch out into the index requires stashing and unstashing your changes. If something goes wrong, you'll be able to access your files from the stash. Continue?", + MustStashTitle: "Must stash", + ConfirmationTitle: "Confirmation panel", + PrevPage: "Previous page", + NextPage: "Next page", + GotoTop: "Scroll to top", + GotoBottom: "Scroll to bottom", + FilteringBy: "Filtering by", + ResetInParentheses: "(Reset)", + OpenFilteringMenu: "View filter-by-path options", + FilterBy: "Filter by", + ExitFilterMode: "Stop filtering by path", + FilterPathOption: "Enter path to filter by", + EnterFileName: "Enter path:", + FilteringMenuTitle: "Filtering", + MustExitFilterModeTitle: "Command not available", + MustExitFilterModePrompt: "Command not available in filter-by-path mode. Exit filter-by-path mode?", + Diff: "Diff", + EnterRefToDiff: "Enter ref to diff", + EnterRefName: "Enter ref:", + ExitDiffMode: "Exit diff mode", + DiffingMenuTitle: "Diffing", + SwapDiff: "Reverse diff direction", + OpenDiffingMenu: "Open diff menu", // the actual view is the extras view which I intend to give more tabs in future but for now we'll only mention the command log part OpenExtrasMenu: "Open command log menu", ShowingGitDiff: "Showing output for:", @@ -1394,7 +1397,6 @@ func EnglishTranslationSet() TranslationSet { Merge: "Merge", RebaseBranch: "Rebase branch", RenameBranch: "Rename branch", - SetUnsetUpstream: "Set/Unset upstream", CreateBranch: "Create branch", CherryPick: "(Cherry-pick) paste commits", CheckoutFile: "Checkout file", diff --git a/pkg/i18n/korean.go b/pkg/i18n/korean.go index 32c29db14..9c859ec60 100644 --- a/pkg/i18n/korean.go +++ b/pkg/i18n/korean.go @@ -476,7 +476,6 @@ func koreanTranslationSet() TranslationSet { Merge: "병합", RebaseBranch: "브랜치 리베이스", RenameBranch: "브랜치 이름 변경", - SetUnsetUpstream: "Set/Unset upstream", CreateBranch: "브랜치 생성", CherryPick: "(Cherry-pick) 커밋 붙여넣기", CheckoutFile: "체크아웃 파일", diff --git a/pkg/i18n/russian.go b/pkg/i18n/russian.go index fc8806e73..967e91c12 100644 --- a/pkg/i18n/russian.go +++ b/pkg/i18n/russian.go @@ -395,7 +395,6 @@ func RussianTranslationSet() TranslationSet { Panel: "Панель", KeybindingsLegend: "Связки клавиш", RenameBranch: "Переименовать ветку", - SetUnsetUpstream: "Установить/убрать upstream-ветку", NewBranchNamePrompt: "Введите новое название ветки", RenameBranchWarning: "Эта ветвь отслеживает удалённый репозитории. Это действие переименует только имя локальной ветки, а не имя удалённой ветки. Продолжать?", OpenMenu: "Открыть меню", @@ -566,7 +565,6 @@ func RussianTranslationSet() TranslationSet { Merge: "Слить", RebaseBranch: "Перебазировать ветку", RenameBranch: "Переименовать ветку", - SetUnsetUpstream: "Установить/убрать upstream-ветку", CreateBranch: "Создать ветку", CherryPick: "(Cherry-pick) Вставить коммиты", CheckoutFile: "Переключить файл", diff --git a/pkg/i18n/traditional_chinese.go b/pkg/i18n/traditional_chinese.go index 8c5dc9599..896441784 100644 --- a/pkg/i18n/traditional_chinese.go +++ b/pkg/i18n/traditional_chinese.go @@ -421,7 +421,6 @@ func traditionalChineseTranslationSet() TranslationSet { Panel: "面板", KeybindingsLegend: "說明:`` 表示 Ctrl+B、`` 表示 Alt+B,`B`表示 Shift+B", RenameBranch: "重新命名分支", - SetUnsetUpstream: "設定/取消設定上游", NewBranchNamePrompt: "為分支輸入新名稱", RenameBranchWarning: "此分支正在追蹤遠端分支。此操作僅會重新命名本地分支名稱,而不是遠端分支的名稱。是否繼續?", OpenMenu: "開啟選單", @@ -592,7 +591,6 @@ func traditionalChineseTranslationSet() TranslationSet { Merge: "合併", RebaseBranch: "變基分支", RenameBranch: "重新命名分支", - SetUnsetUpstream: "設置/取消上游", CreateBranch: "建立分支", CherryPick: "(Cherry-pick)粘貼提交", CheckoutFile: "檢出檔案", diff --git a/pkg/integration/tests/branch/reset_upstream.go b/pkg/integration/tests/branch/reset_upstream.go index 0fe11767d..70300c312 100644 --- a/pkg/integration/tests/branch/reset_upstream.go +++ b/pkg/integration/tests/branch/reset_upstream.go @@ -25,7 +25,7 @@ var ResetUpstream = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.SetUpstream). Tap(func() { t.ExpectPopup().Menu(). - Title(Equals("Set/Unset upstream")). + Title(Equals("Upstream options")). Select(Contains("Unset upstream of selected branch")). Confirm() }). diff --git a/pkg/integration/tests/branch/set_upstream.go b/pkg/integration/tests/branch/set_upstream.go index 37117b0d7..16faeb7e3 100644 --- a/pkg/integration/tests/branch/set_upstream.go +++ b/pkg/integration/tests/branch/set_upstream.go @@ -24,7 +24,7 @@ var SetUpstream = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.SetUpstream). Tap(func() { t.ExpectPopup().Menu(). - Title(Equals("Set/Unset upstream")). + Title(Equals("Upstream options")). Select(Contains(" Set upstream of selected branch")). // using leading space to disambiguate from the 'reset' option Confirm() diff --git a/pkg/integration/tests/branch/show_divergence_from_upstream.go b/pkg/integration/tests/branch/show_divergence_from_upstream.go index 10fc29986..8aff21ca9 100644 --- a/pkg/integration/tests/branch/show_divergence_from_upstream.go +++ b/pkg/integration/tests/branch/show_divergence_from_upstream.go @@ -38,7 +38,7 @@ var ShowDivergenceFromUpstream = NewIntegrationTest(NewIntegrationTestArgs{ Lines(Contains("master")). Press(keys.Branches.SetUpstream) - t.ExpectPopup().Menu().Title(Contains("upstream")).Select(Contains("View divergence from upstream")).Confirm() + t.ExpectPopup().Menu().Title(Contains("Upstream")).Select(Contains("View divergence from upstream")).Confirm() t.Views().SubCommits(). IsFocused(). From 2b7b6f71eea41f0d33a3212bb759aa6f47c8d50e Mon Sep 17 00:00:00 2001 From: AzraelSec Date: Wed, 16 Aug 2023 16:19:29 +0200 Subject: [PATCH 2/2] feat: add a menu to reset current branch to a target branch upstream --- pkg/gui/controllers/branches_controller.go | 150 +++++++++++------- pkg/i18n/english.go | 10 ++ .../tests/branch/reset_to_upstream.go | 102 ++++++++++++ pkg/integration/tests/test_list.go | 1 + 4 files changed, 209 insertions(+), 54 deletions(-) create mode 100644 pkg/integration/tests/branch/reset_to_upstream.go diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index 8fc621e76..99cb3d63f 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -140,34 +140,57 @@ func (self *BranchesController) GetOnRenderToMain() func() error { } func (self *BranchesController) setUpstream(selectedBranch *models.Branch) error { - return self.c.Menu(types.CreateMenuOptions{ - Title: self.c.Tr.BranchUpstreamOptionsTitle, - Items: []*types.MenuItem{ - { - LabelColumns: []string{self.c.Tr.ViewDivergenceFromUpstream}, - OnPress: func() error { - branch := self.context().GetSelected() - if branch == nil { - return nil + options := []*types.MenuItem{ + { + LabelColumns: []string{self.c.Tr.ViewDivergenceFromUpstream}, + OnPress: func() error { + branch := self.context().GetSelected() + if branch == nil { + return nil + } + + if !branch.RemoteBranchStoredLocally() { + return self.c.ErrorMsg(self.c.Tr.DivergenceNoUpstream) + } + return self.c.Helpers().SubCommits.ViewSubCommits(helpers.ViewSubCommitsOpts{ + Ref: branch, + TitleRef: fmt.Sprintf("%s <-> %s", branch.RefName(), branch.ShortUpstreamRefName()), + RefToShowDivergenceFrom: branch.FullUpstreamRefName(), + Context: self.context(), + ShowBranchHeads: false, + }) + }, + Key: 'v', + }, + { + LabelColumns: []string{self.c.Tr.UnsetUpstream}, + OnPress: func() error { + if err := self.c.Git().Branch.UnsetUpstream(selectedBranch.Name); err != nil { + return self.c.Error(err) + } + if err := self.c.Refresh(types.RefreshOptions{ + Mode: types.SYNC, + Scope: []types.RefreshableView{ + types.BRANCHES, + types.COMMITS, + }, + }); err != nil { + return self.c.Error(err) + } + return nil + }, + Key: 'u', + }, + { + LabelColumns: []string{self.c.Tr.SetUpstream}, + OnPress: func() error { + return self.c.Helpers().Upstream.PromptForUpstreamWithoutInitialContent(selectedBranch, func(upstream string) error { + upstreamRemote, upstreamBranch, err := self.c.Helpers().Upstream.ParseUpstream(upstream) + if err != nil { + return self.c.Error(err) } - if !branch.RemoteBranchStoredLocally() { - return self.c.ErrorMsg(self.c.Tr.DivergenceNoUpstream) - } - return self.c.Helpers().SubCommits.ViewSubCommits(helpers.ViewSubCommitsOpts{ - Ref: branch, - TitleRef: fmt.Sprintf("%s <-> %s", branch.RefName(), branch.ShortUpstreamRefName()), - RefToShowDivergenceFrom: branch.FullUpstreamRefName(), - Context: self.context(), - ShowBranchHeads: false, - }) - }, - Key: 'v', - }, - { - LabelColumns: []string{self.c.Tr.UnsetUpstream}, - OnPress: func() error { - if err := self.c.Git().Branch.UnsetUpstream(selectedBranch.Name); err != nil { + if err := self.c.Git().Branch.SetUpstream(upstreamRemote, upstreamBranch, selectedBranch.Name); err != nil { return self.c.Error(err) } if err := self.c.Refresh(types.RefreshOptions{ @@ -180,36 +203,55 @@ func (self *BranchesController) setUpstream(selectedBranch *models.Branch) error return self.c.Error(err) } return nil - }, - Key: 'u', - }, - { - LabelColumns: []string{self.c.Tr.SetUpstream}, - OnPress: func() error { - return self.c.Helpers().Upstream.PromptForUpstreamWithoutInitialContent(selectedBranch, func(upstream string) error { - upstreamRemote, upstreamBranch, err := self.c.Helpers().Upstream.ParseUpstream(upstream) - if err != nil { - return self.c.Error(err) - } - - if err := self.c.Git().Branch.SetUpstream(upstreamRemote, upstreamBranch, selectedBranch.Name); err != nil { - return self.c.Error(err) - } - if err := self.c.Refresh(types.RefreshOptions{ - Mode: types.SYNC, - Scope: []types.RefreshableView{ - types.BRANCHES, - types.COMMITS, - }, - }); err != nil { - return self.c.Error(err) - } - return nil - }) - }, - Key: 's', + }) }, + Key: 's', }, + } + + if selectedBranch.IsTrackingRemote() { + upstream := fmt.Sprintf("%s/%s", selectedBranch.UpstreamRemote, selectedBranch.Name) + upstreamResetOptions := utils.ResolvePlaceholderString( + self.c.Tr.ViewUpstreamResetOptions, + map[string]string{"upstream": upstream}, + ) + upstreamResetTooltip := utils.ResolvePlaceholderString( + self.c.Tr.ViewUpstreamResetOptionsTooltip, + map[string]string{"upstream": upstream}, + ) + + options = append(options, &types.MenuItem{ + LabelColumns: []string{upstreamResetOptions}, + OpensMenu: true, + OnPress: func() error { + if selectedBranch.RemoteBranchNotStoredLocally() { + return self.c.ErrorMsg(self.c.Tr.UpstreamNotStoredLocallyError) + } + + err := self.c.Helpers().Refs.CreateGitResetMenu(upstream) + if err != nil { + return self.c.Error(err) + } + return nil + }, + Tooltip: upstreamResetTooltip, + Key: 'g', + }) + } else { + options = append(options, &types.MenuItem{ + LabelColumns: []string{self.c.Tr.ViewUpstreamDisabledResetOptions}, + OpensMenu: true, + OnPress: func() error { + return self.c.ErrorMsg(self.c.Tr.UpstreamNotSetError) + }, + Tooltip: self.c.Tr.UpstreamNotSetError, + Key: 'g', + }) + } + + return self.c.Menu(types.CreateMenuOptions{ + Title: self.c.Tr.BranchUpstreamOptionsTitle, + Items: options, }) } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 32825a272..87ca8c8ca 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -352,6 +352,9 @@ type TranslationSet struct { DivergenceNoUpstream string DivergenceSectionHeaderLocal string DivergenceSectionHeaderRemote string + ViewUpstreamResetOptions string + ViewUpstreamResetOptionsTooltip string + ViewUpstreamDisabledResetOptions string SetUpstreamTitle string SetUpstreamMessage string EditRemote string @@ -399,6 +402,8 @@ type TranslationSet struct { ViewBranchUpstreamOptions string BranchUpstreamOptionsTitle string ViewBranchUpstreamOptionsTooltip string + UpstreamNotStoredLocallyError string + UpstreamNotSetError string NewGitFlowBranchPrompt string RenameBranchWarning string OpenMenu string @@ -1138,6 +1143,9 @@ func EnglishTranslationSet() TranslationSet { DivergenceNoUpstream: "Cannot show divergence of a branch that has no (locally tracked) upstream", DivergenceSectionHeaderLocal: "Local", DivergenceSectionHeaderRemote: "Remote", + ViewUpstreamResetOptions: "Reset checked-out branch onto {{.upstream}}", + ViewUpstreamResetOptionsTooltip: "View options for resetting the checked-out branch onto {{upstream}}. Note: this will not reset the selected branch onto the upstream, it will reset the checked-out branch onto the upstream", + ViewUpstreamDisabledResetOptions: "Reset checked-out branch onto upstream of selected branch", SetUpstreamTitle: "Set upstream branch", SetUpstreamMessage: "Are you sure you want to set the upstream branch of '{{.checkedOut}}' to '{{.selected}}'", EditRemote: "Edit remote", @@ -1181,6 +1189,8 @@ func EnglishTranslationSet() TranslationSet { RenameBranch: "Rename branch", BranchUpstreamOptionsTitle: "Upstream options", ViewBranchUpstreamOptionsTooltip: "View options relating to the branch's upstream e.g. setting/unsetting the upstream and resetting to the upstream", + UpstreamNotStoredLocallyError: "Cannot reset to upstream branch because it is not stored locally", + UpstreamNotSetError: "The selected branch has no upstream", ViewBranchUpstreamOptions: "View upstream options", NewBranchNamePrompt: "Enter new branch name for branch", RenameBranchWarning: "This branch is tracking a remote. This action will only rename the local branch name, not the name of the remote branch. Continue?", diff --git a/pkg/integration/tests/branch/reset_to_upstream.go b/pkg/integration/tests/branch/reset_to_upstream.go new file mode 100644 index 000000000..0c749ee2d --- /dev/null +++ b/pkg/integration/tests/branch/reset_to_upstream.go @@ -0,0 +1,102 @@ +package branch + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var ResetToUpstream = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Hard reset the current branch to the selected branch upstream", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell. + CloneIntoRemote("origin"). + NewBranch("hard-branch"). + EmptyCommit("hard commit"). + PushBranch("origin", "hard-branch"). + NewBranch("soft-branch"). + EmptyCommit("soft commit"). + PushBranch("origin", "soft-branch"). + NewBranch("base"). + EmptyCommit("base-branch commit"). + CreateFile("file-1", "content"). + GitAdd("file-1"). + Commit("commit with file"). + CreateFile("file-2", "content"). + GitAdd("file-2") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + // soft reset + t.Views().Branches(). + Focus(). + Lines( + Contains("base").IsSelected(), + Contains("soft-branch"), + Contains("hard-branch"), + ). + Press(keys.Branches.SetUpstream). + Tap(func() { + t.ExpectPopup().Menu(). + Title(Equals("Upstream options")). + Select(Contains("Reset checked-out branch onto upstream of selected branch")). + Tooltip(Contains("The selected branch has no upstream")). + Confirm() + t.ExpectPopup().Alert(). + Title(Equals("Error")). + Content(Equals("The selected branch has no upstream")). + Confirm() + }). + SelectNextItem(). + Lines( + Contains("base"), + Contains("soft-branch").IsSelected(), + Contains("hard-branch"), + ). + Press(keys.Branches.SetUpstream). + Tap(func() { + t.ExpectPopup().Menu(). + Title(Equals("Upstream options")). + Select(Contains("Reset checked-out branch onto origin/soft-branch...")). + Confirm() + + t.ExpectPopup().Menu(). + Title(Equals("Reset to origin/soft-branch")). + Select(Contains("Soft reset")). + Confirm() + }) + t.Views().Commits().Lines( + Contains("soft commit"), + Contains("hard commit"), + ) + t.Views().Files().Lines( + Contains("file-1").Contains("A"), + Contains("file-2").Contains("A"), + ) + + // hard reset + t.Views().Branches(). + Focus(). + Lines( + Contains("base"), + Contains("soft-branch").IsSelected(), + Contains("hard-branch"), + ). + NavigateToLine(Contains("hard-branch")). + Press(keys.Branches.SetUpstream). + Tap(func() { + t.ExpectPopup().Menu(). + Title(Equals("Upstream options")). + Select(Contains("Reset checked-out branch onto origin/hard-branch...")). + Confirm() + + t.ExpectPopup().Menu(). + Title(Equals("Reset to origin/hard-branch")). + Select(Contains("Hard reset")). + Confirm() + }) + t.Views().Commits().Lines(Contains("hard commit")) + t.Views().Files().IsEmpty() + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index c669bbae3..19447b6a1 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -47,6 +47,7 @@ var tests = []*components.IntegrationTest{ branch.RebaseDoesNotAutosquash, branch.RebaseFromMarkedBase, branch.Reset, + branch.ResetToUpstream, branch.ResetUpstream, branch.SetUpstream, branch.ShowDivergenceFromUpstream,