mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-06-04 23:37:41 +02:00
Visualize local branch heads in commits panel, 2nd approach (#2775)
This commit is contained in:
commit
a6af31a4cb
@ -62,7 +62,6 @@ gui:
|
|||||||
showListFooter: true # for seeing the '5 of 20' message in list panels
|
showListFooter: true # for seeing the '5 of 20' message in list panels
|
||||||
showRandomTip: true
|
showRandomTip: true
|
||||||
showBranchCommitHash: false # show commit hashes alongside branch names
|
showBranchCommitHash: false # show commit hashes alongside branch names
|
||||||
experimentalShowBranchHeads: false # visualize branch heads with (*) in commits list
|
|
||||||
showBottomLine: true # for hiding the bottom information line (unless it has important information to tell you)
|
showBottomLine: true # for hiding the bottom information line (unless it has important information to tell you)
|
||||||
showCommandLog: true
|
showCommandLog: true
|
||||||
showIcons: false # deprecated: use nerdFontsVersion instead
|
showIcons: false # deprecated: use nerdFontsVersion instead
|
||||||
|
@ -6,4 +6,5 @@
|
|||||||
* [Keybindings](./keybindings)
|
* [Keybindings](./keybindings)
|
||||||
* [Undo/Redo](./Undoing.md)
|
* [Undo/Redo](./Undoing.md)
|
||||||
* [Searching/Filtering](./Searching.md)
|
* [Searching/Filtering](./Searching.md)
|
||||||
|
* [Stacked Branches](./Stacked_Branches.md)
|
||||||
* [Dev docs](./dev)
|
* [Dev docs](./dev)
|
||||||
|
18
docs/Stacked_Branches.md
Normal file
18
docs/Stacked_Branches.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Working with stacked branches
|
||||||
|
|
||||||
|
When working on a large branch it can often be useful to break it down into
|
||||||
|
smaller pieces, and it can help to create separate branches for each independent
|
||||||
|
chunk of changes. For example, you could have one branch for preparatory
|
||||||
|
refactorings, one for backend changes, and one for frontend changes. Those
|
||||||
|
branches would then all be stacked onto each other.
|
||||||
|
|
||||||
|
Git has support for rebasing such a stack as a whole; you can enable it by
|
||||||
|
setting the git config `rebase.updateRfs` to true. If you then rebase the
|
||||||
|
topmost branch of the stack, the other ones in the stack will follow. This
|
||||||
|
includes interactive rebases, so for example amending a commit in the first
|
||||||
|
branch of the stack will "just work" in the sense that it keeps the other
|
||||||
|
branches properly stacked onto it.
|
||||||
|
|
||||||
|
Lazygit visualizes the invidual branch heads in the stack by marking them with a
|
||||||
|
cyan asterisk (or a cyan branch symbol if you are using [nerd
|
||||||
|
fonts](Config.md#display-nerd-fonts-icons)).
|
@ -70,6 +70,21 @@ func (self *BranchCommands) CurrentBranchInfo() (BranchInfo, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurrentBranchName get name of current branch
|
||||||
|
func (self *BranchCommands) CurrentBranchName() (string, error) {
|
||||||
|
cmdArgs := NewGitCmd("rev-parse").
|
||||||
|
Arg("--abbrev-ref").
|
||||||
|
Arg("--verify").
|
||||||
|
Arg("HEAD").
|
||||||
|
ToArgv()
|
||||||
|
|
||||||
|
output, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
|
||||||
|
if err == nil {
|
||||||
|
return strings.TrimSpace(output), nil
|
||||||
|
}
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
// Delete delete branch
|
// Delete delete branch
|
||||||
func (self *BranchCommands) Delete(branch string, force bool) error {
|
func (self *BranchCommands) Delete(branch string, force bool) error {
|
||||||
cmdArgs := NewGitCmd("branch").
|
cmdArgs := NewGitCmd("branch").
|
||||||
|
@ -171,7 +171,7 @@ var branchFields = []string{
|
|||||||
"upstream:short",
|
"upstream:short",
|
||||||
"upstream:track",
|
"upstream:track",
|
||||||
"subject",
|
"subject",
|
||||||
fmt.Sprintf("objectname:short=%d", utils.COMMIT_HASH_SHORT_SIZE),
|
"objectname",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain branch information from parsed line output of getRawBranches()
|
// Obtain branch information from parsed line output of getRawBranches()
|
||||||
|
@ -107,3 +107,7 @@ func (self *ConfigCommands) GetCoreCommentChar() byte {
|
|||||||
|
|
||||||
return '#'
|
return '#'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *ConfigCommands) GetRebaseUpdateRefs() bool {
|
||||||
|
return self.gitConfig.GetBool("rebase.updateRefs")
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package git_commands
|
package git_commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -71,3 +72,14 @@ func IsBareRepo(osCommand *oscommands.OSCommand) (bool, error) {
|
|||||||
func (self *StatusCommands) IsInMergeState() (bool, error) {
|
func (self *StatusCommands) IsInMergeState() (bool, error) {
|
||||||
return self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "MERGE_HEAD"))
|
return self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "MERGE_HEAD"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Full ref (e.g. "refs/heads/mybranch") of the branch that is currently
|
||||||
|
// being rebased, or empty string when we're not in a rebase
|
||||||
|
func (self *StatusCommands) BranchBeingRebased() string {
|
||||||
|
for _, dir := range []string{"rebase-merge", "rebase-apply"} {
|
||||||
|
if bytesContent, err := os.ReadFile(filepath.Join(self.repoPaths.WorktreeGitDirPath(), dir, "head-name")); err == nil {
|
||||||
|
return strings.TrimSpace(string(bytesContent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
@ -27,36 +27,35 @@ type RefresherConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GuiConfig struct {
|
type GuiConfig struct {
|
||||||
AuthorColors map[string]string `yaml:"authorColors"`
|
AuthorColors map[string]string `yaml:"authorColors"`
|
||||||
BranchColors map[string]string `yaml:"branchColors"`
|
BranchColors map[string]string `yaml:"branchColors"`
|
||||||
ScrollHeight int `yaml:"scrollHeight"`
|
ScrollHeight int `yaml:"scrollHeight"`
|
||||||
ScrollPastBottom bool `yaml:"scrollPastBottom"`
|
ScrollPastBottom bool `yaml:"scrollPastBottom"`
|
||||||
MouseEvents bool `yaml:"mouseEvents"`
|
MouseEvents bool `yaml:"mouseEvents"`
|
||||||
SkipDiscardChangeWarning bool `yaml:"skipDiscardChangeWarning"`
|
SkipDiscardChangeWarning bool `yaml:"skipDiscardChangeWarning"`
|
||||||
SkipStashWarning bool `yaml:"skipStashWarning"`
|
SkipStashWarning bool `yaml:"skipStashWarning"`
|
||||||
SidePanelWidth float64 `yaml:"sidePanelWidth"`
|
SidePanelWidth float64 `yaml:"sidePanelWidth"`
|
||||||
ExpandFocusedSidePanel bool `yaml:"expandFocusedSidePanel"`
|
ExpandFocusedSidePanel bool `yaml:"expandFocusedSidePanel"`
|
||||||
MainPanelSplitMode string `yaml:"mainPanelSplitMode"`
|
MainPanelSplitMode string `yaml:"mainPanelSplitMode"`
|
||||||
Language string `yaml:"language"`
|
Language string `yaml:"language"`
|
||||||
TimeFormat string `yaml:"timeFormat"`
|
TimeFormat string `yaml:"timeFormat"`
|
||||||
ShortTimeFormat string `yaml:"shortTimeFormat"`
|
ShortTimeFormat string `yaml:"shortTimeFormat"`
|
||||||
Theme ThemeConfig `yaml:"theme"`
|
Theme ThemeConfig `yaml:"theme"`
|
||||||
CommitLength CommitLengthConfig `yaml:"commitLength"`
|
CommitLength CommitLengthConfig `yaml:"commitLength"`
|
||||||
SkipNoStagedFilesWarning bool `yaml:"skipNoStagedFilesWarning"`
|
SkipNoStagedFilesWarning bool `yaml:"skipNoStagedFilesWarning"`
|
||||||
ShowListFooter bool `yaml:"showListFooter"`
|
ShowListFooter bool `yaml:"showListFooter"`
|
||||||
ShowFileTree bool `yaml:"showFileTree"`
|
ShowFileTree bool `yaml:"showFileTree"`
|
||||||
ShowRandomTip bool `yaml:"showRandomTip"`
|
ShowRandomTip bool `yaml:"showRandomTip"`
|
||||||
ShowCommandLog bool `yaml:"showCommandLog"`
|
ShowCommandLog bool `yaml:"showCommandLog"`
|
||||||
ShowBottomLine bool `yaml:"showBottomLine"`
|
ShowBottomLine bool `yaml:"showBottomLine"`
|
||||||
ShowIcons bool `yaml:"showIcons"`
|
ShowIcons bool `yaml:"showIcons"`
|
||||||
NerdFontsVersion string `yaml:"nerdFontsVersion"`
|
NerdFontsVersion string `yaml:"nerdFontsVersion"`
|
||||||
ShowBranchCommitHash bool `yaml:"showBranchCommitHash"`
|
ShowBranchCommitHash bool `yaml:"showBranchCommitHash"`
|
||||||
ExperimentalShowBranchHeads bool `yaml:"experimentalShowBranchHeads"`
|
CommandLogSize int `yaml:"commandLogSize"`
|
||||||
CommandLogSize int `yaml:"commandLogSize"`
|
SplitDiff string `yaml:"splitDiff"`
|
||||||
SplitDiff string `yaml:"splitDiff"`
|
SkipRewordInEditorWarning bool `yaml:"skipRewordInEditorWarning"`
|
||||||
SkipRewordInEditorWarning bool `yaml:"skipRewordInEditorWarning"`
|
WindowSize string `yaml:"windowSize"`
|
||||||
WindowSize string `yaml:"windowSize"`
|
Border string `yaml:"border"`
|
||||||
Border string `yaml:"border"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ThemeConfig struct {
|
type ThemeConfig struct {
|
||||||
@ -436,21 +435,20 @@ func GetDefaultConfig() *UserConfig {
|
|||||||
UnstagedChangesColor: []string{"red"},
|
UnstagedChangesColor: []string{"red"},
|
||||||
DefaultFgColor: []string{"default"},
|
DefaultFgColor: []string{"default"},
|
||||||
},
|
},
|
||||||
CommitLength: CommitLengthConfig{Show: true},
|
CommitLength: CommitLengthConfig{Show: true},
|
||||||
SkipNoStagedFilesWarning: false,
|
SkipNoStagedFilesWarning: false,
|
||||||
ShowListFooter: true,
|
ShowListFooter: true,
|
||||||
ShowCommandLog: true,
|
ShowCommandLog: true,
|
||||||
ShowBottomLine: true,
|
ShowBottomLine: true,
|
||||||
ShowFileTree: true,
|
ShowFileTree: true,
|
||||||
ShowRandomTip: true,
|
ShowRandomTip: true,
|
||||||
ShowIcons: false,
|
ShowIcons: false,
|
||||||
NerdFontsVersion: "",
|
NerdFontsVersion: "",
|
||||||
ExperimentalShowBranchHeads: false,
|
ShowBranchCommitHash: false,
|
||||||
ShowBranchCommitHash: false,
|
CommandLogSize: 8,
|
||||||
CommandLogSize: 8,
|
SplitDiff: "auto",
|
||||||
SplitDiff: "auto",
|
SkipRewordInEditorWarning: false,
|
||||||
SkipRewordInEditorWarning: false,
|
Border: "single",
|
||||||
Border: "single",
|
|
||||||
},
|
},
|
||||||
Git: GitConfig{
|
Git: GitConfig{
|
||||||
Paging: PagingConfig{
|
Paging: PagingConfig{
|
||||||
|
@ -83,3 +83,7 @@ func (self *BranchesContext) GetDiffTerminals() []string {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *BranchesContext) ShowBranchHeadsInSubCommits() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
@ -38,10 +38,14 @@ func NewLocalCommitsContext(c *ContextCommon) *LocalCommitsContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showYouAreHereLabel := c.Model().WorkingTreeStateAtLastCommitRefresh == enums.REBASE_MODE_REBASING
|
showYouAreHereLabel := c.Model().WorkingTreeStateAtLastCommitRefresh == enums.REBASE_MODE_REBASING
|
||||||
|
showBranchMarkerForHeadCommit := c.Git().Config.GetRebaseUpdateRefs()
|
||||||
|
|
||||||
return presentation.GetCommitListDisplayStrings(
|
return presentation.GetCommitListDisplayStrings(
|
||||||
c.Common,
|
c.Common,
|
||||||
c.Model().Commits,
|
c.Model().Commits,
|
||||||
|
c.Model().Branches,
|
||||||
|
c.Model().CheckedOutBranch,
|
||||||
|
showBranchMarkerForHeadCommit,
|
||||||
c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL,
|
c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL,
|
||||||
c.Modes().CherryPicking.SelectedShaSet(),
|
c.Modes().CherryPicking.SelectedShaSet(),
|
||||||
c.Modes().Diffing.Ref,
|
c.Modes().Diffing.Ref,
|
||||||
|
@ -86,3 +86,7 @@ func (self *ReflogCommitsContext) GetDiffTerminals() []string {
|
|||||||
|
|
||||||
return []string{itemId}
|
return []string{itemId}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *ReflogCommitsContext) ShowBranchHeadsInSubCommits() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -72,3 +72,7 @@ func (self *RemoteBranchesContext) GetDiffTerminals() []string {
|
|||||||
|
|
||||||
return []string{itemId}
|
return []string{itemId}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *RemoteBranchesContext) ShowBranchHeadsInSubCommits() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
@ -37,6 +37,13 @@ func NewSubCommitsContext(
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDisplayStrings := func(startIdx int, length int) [][]string {
|
getDisplayStrings := func(startIdx int, length int) [][]string {
|
||||||
|
// This can happen if a sub-commits view is asked to be rerendered while
|
||||||
|
// it is invisble; for example when switching screen modes, which
|
||||||
|
// rerenders all views.
|
||||||
|
if viewModel.GetRef() == nil {
|
||||||
|
return [][]string{}
|
||||||
|
}
|
||||||
|
|
||||||
selectedCommitSha := ""
|
selectedCommitSha := ""
|
||||||
if c.CurrentContext().GetKey() == SUB_COMMITS_CONTEXT_KEY {
|
if c.CurrentContext().GetKey() == SUB_COMMITS_CONTEXT_KEY {
|
||||||
selectedCommit := viewModel.GetSelected()
|
selectedCommit := viewModel.GetSelected()
|
||||||
@ -44,9 +51,17 @@ func NewSubCommitsContext(
|
|||||||
selectedCommitSha = selectedCommit.Sha
|
selectedCommitSha = selectedCommit.Sha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
branches := []*models.Branch{}
|
||||||
|
if viewModel.GetShowBranchHeads() {
|
||||||
|
branches = c.Model().Branches
|
||||||
|
}
|
||||||
|
showBranchMarkerForHeadCommit := c.Git().Config.GetRebaseUpdateRefs()
|
||||||
return presentation.GetCommitListDisplayStrings(
|
return presentation.GetCommitListDisplayStrings(
|
||||||
c.Common,
|
c.Common,
|
||||||
c.Model().SubCommits,
|
c.Model().SubCommits,
|
||||||
|
branches,
|
||||||
|
viewModel.GetRef().RefName(),
|
||||||
|
showBranchMarkerForHeadCommit,
|
||||||
c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL,
|
c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL,
|
||||||
c.Modes().CherryPicking.SelectedShaSet(),
|
c.Modes().CherryPicking.SelectedShaSet(),
|
||||||
c.Modes().Diffing.Ref,
|
c.Modes().Diffing.Ref,
|
||||||
@ -97,7 +112,8 @@ type SubCommitsViewModel struct {
|
|||||||
ref types.Ref
|
ref types.Ref
|
||||||
*ListViewModel[*models.Commit]
|
*ListViewModel[*models.Commit]
|
||||||
|
|
||||||
limitCommits bool
|
limitCommits bool
|
||||||
|
showBranchHeads bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SubCommitsViewModel) SetRef(ref types.Ref) {
|
func (self *SubCommitsViewModel) SetRef(ref types.Ref) {
|
||||||
@ -108,6 +124,14 @@ func (self *SubCommitsViewModel) GetRef() types.Ref {
|
|||||||
return self.ref
|
return self.ref
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *SubCommitsViewModel) SetShowBranchHeads(value bool) {
|
||||||
|
self.showBranchHeads = value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *SubCommitsViewModel) GetShowBranchHeads() bool {
|
||||||
|
return self.showBranchHeads
|
||||||
|
}
|
||||||
|
|
||||||
func (self *SubCommitsContext) GetSelectedItemId() string {
|
func (self *SubCommitsContext) GetSelectedItemId() string {
|
||||||
item := self.GetSelected()
|
item := self.GetSelected()
|
||||||
if item == nil {
|
if item == nil {
|
||||||
|
@ -69,3 +69,7 @@ func (self *TagsContext) GetDiffTerminals() []string {
|
|||||||
|
|
||||||
return []string{itemId}
|
return []string{itemId}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *TagsContext) ShowBranchHeadsInSubCommits() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
@ -272,6 +272,32 @@ func (self *RefreshHelper) refreshCommitsAndCommitFiles() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *RefreshHelper) determineCheckedOutBranchName() string {
|
||||||
|
if rebasedBranch := self.c.Git().Status.BranchBeingRebased(); rebasedBranch != "" {
|
||||||
|
// During a rebase we're on a detached head, so cannot determine the
|
||||||
|
// branch name in the usual way. We need to read it from the
|
||||||
|
// ".git/rebase-merge/head-name" file instead.
|
||||||
|
return strings.TrimPrefix(rebasedBranch, "refs/heads/")
|
||||||
|
}
|
||||||
|
|
||||||
|
if bisectInfo := self.c.Git().Bisect.GetInfo(); bisectInfo.Bisecting() && bisectInfo.GetStartSha() != "" {
|
||||||
|
// Likewise, when we're bisecting we're on a detached head as well. In
|
||||||
|
// this case we read the branch name from the ".git/BISECT_START" file.
|
||||||
|
return bisectInfo.GetStartSha()
|
||||||
|
}
|
||||||
|
|
||||||
|
// In all other cases, get the branch name by asking git what branch is
|
||||||
|
// checked out. Note that if we're on a detached head (for reasons other
|
||||||
|
// than rebasing or bisecting, i.e. it was explicitly checked out), then
|
||||||
|
// this will return its sha.
|
||||||
|
if branchName, err := self.c.Git().Branch.CurrentBranchName(); err == nil {
|
||||||
|
return branchName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should never get here unless the working copy is corrupt
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (self *RefreshHelper) refreshCommitsWithLimit() error {
|
func (self *RefreshHelper) refreshCommitsWithLimit() error {
|
||||||
self.c.Mutexes().LocalCommitsMutex.Lock()
|
self.c.Mutexes().LocalCommitsMutex.Lock()
|
||||||
defer self.c.Mutexes().LocalCommitsMutex.Unlock()
|
defer self.c.Mutexes().LocalCommitsMutex.Unlock()
|
||||||
@ -291,6 +317,7 @@ func (self *RefreshHelper) refreshCommitsWithLimit() error {
|
|||||||
self.c.Model().Commits = commits
|
self.c.Model().Commits = commits
|
||||||
self.RefreshAuthors(commits)
|
self.RefreshAuthors(commits)
|
||||||
self.c.Model().WorkingTreeStateAtLastCommitRefresh = self.c.Git().Status.WorkingTreeState()
|
self.c.Model().WorkingTreeStateAtLastCommitRefresh = self.c.Git().Status.WorkingTreeState()
|
||||||
|
self.c.Model().CheckedOutBranch = self.determineCheckedOutBranchName()
|
||||||
|
|
||||||
return self.c.PostRefreshUpdate(self.c.Contexts().LocalCommits)
|
return self.c.PostRefreshUpdate(self.c.Contexts().LocalCommits)
|
||||||
}
|
}
|
||||||
@ -412,6 +439,12 @@ func (self *RefreshHelper) refreshBranches() {
|
|||||||
self.c.Log.Error(err)
|
self.c.Log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Need to re-render the commits view because the visualization of local
|
||||||
|
// branch heads might have changed
|
||||||
|
if err := self.c.Contexts().LocalCommits.HandleRender(); err != nil {
|
||||||
|
self.c.Log.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
self.refreshStatus()
|
self.refreshStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ var _ types.IController = &SwitchToSubCommitsController{}
|
|||||||
type CanSwitchToSubCommits interface {
|
type CanSwitchToSubCommits interface {
|
||||||
types.Context
|
types.Context
|
||||||
GetSelectedRef() types.Ref
|
GetSelectedRef() types.Ref
|
||||||
|
ShowBranchHeadsInSubCommits() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type SwitchToSubCommitsController struct {
|
type SwitchToSubCommitsController struct {
|
||||||
@ -79,6 +80,7 @@ func (self *SwitchToSubCommitsController) viewCommits() error {
|
|||||||
subCommitsContext.SetTitleRef(ref.Description())
|
subCommitsContext.SetTitleRef(ref.Description())
|
||||||
subCommitsContext.SetRef(ref)
|
subCommitsContext.SetRef(ref)
|
||||||
subCommitsContext.SetLimitCommits(true)
|
subCommitsContext.SetLimitCommits(true)
|
||||||
|
subCommitsContext.SetShowBranchHeads(self.context.ShowBranchHeadsInSubCommits())
|
||||||
subCommitsContext.ClearSearchString()
|
subCommitsContext.ClearSearchString()
|
||||||
subCommitsContext.GetView().ClearSearch()
|
subCommitsContext.GetView().ClearSearch()
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ func getBranchDisplayStrings(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if fullDescription || userConfig.Gui.ShowBranchCommitHash {
|
if fullDescription || userConfig.Gui.ShowBranchCommitHash {
|
||||||
res = append(res, b.CommitHash)
|
res = append(res, utils.ShortSha(b.CommitHash))
|
||||||
}
|
}
|
||||||
|
|
||||||
res = append(res, coloredName)
|
res = append(res, coloredName)
|
||||||
|
@ -39,6 +39,9 @@ type bisectBounds struct {
|
|||||||
func GetCommitListDisplayStrings(
|
func GetCommitListDisplayStrings(
|
||||||
common *common.Common,
|
common *common.Common,
|
||||||
commits []*models.Commit,
|
commits []*models.Commit,
|
||||||
|
branches []*models.Branch,
|
||||||
|
currentBranchName string,
|
||||||
|
showBranchMarkerForHeadCommit bool,
|
||||||
fullDescription bool,
|
fullDescription bool,
|
||||||
cherryPickedCommitShaSet *set.Set[string],
|
cherryPickedCommitShaSet *set.Set[string],
|
||||||
diffName string,
|
diffName string,
|
||||||
@ -99,6 +102,30 @@ func GetCommitListDisplayStrings(
|
|||||||
getGraphLine = func(idx int) string { return "" }
|
getGraphLine = func(idx int) string { return "" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine the hashes of the local branches for which we want to show a
|
||||||
|
// branch marker in the commits list. We only want to do this for branches
|
||||||
|
// that are not the current branch, and not any of the main branches. The
|
||||||
|
// goal is to visualize stacks of local branches, so anything that doesn't
|
||||||
|
// contribute to a branch stack shouldn't show a marker.
|
||||||
|
//
|
||||||
|
// If there are other branches pointing to the current head commit, we only
|
||||||
|
// want to show the marker if the rebase.updateRefs config is on.
|
||||||
|
branchHeadsToVisualize := set.NewFromSlice(lo.FilterMap(branches,
|
||||||
|
func(b *models.Branch, index int) (string, bool) {
|
||||||
|
return b.CommitHash,
|
||||||
|
// Don't consider branches that don't have a commit hash. As far
|
||||||
|
// as I can see, this happens for a detached head, so filter
|
||||||
|
// these out
|
||||||
|
b.CommitHash != "" &&
|
||||||
|
// Don't show a marker for the current branch
|
||||||
|
b.Name != currentBranchName &&
|
||||||
|
// Don't show a marker for main branches
|
||||||
|
!lo.Contains(common.UserConfig.Git.MainBranches, b.Name) &&
|
||||||
|
// Don't show a marker for the head commit unless the
|
||||||
|
// rebase.updateRefs config is on
|
||||||
|
(showBranchMarkerForHeadCommit || b.CommitHash != commits[0].Sha)
|
||||||
|
}))
|
||||||
|
|
||||||
lines := make([][]string, 0, len(filteredCommits))
|
lines := make([][]string, 0, len(filteredCommits))
|
||||||
var bisectStatus BisectStatus
|
var bisectStatus BisectStatus
|
||||||
for i, commit := range filteredCommits {
|
for i, commit := range filteredCommits {
|
||||||
@ -112,6 +139,7 @@ func GetCommitListDisplayStrings(
|
|||||||
lines = append(lines, displayCommit(
|
lines = append(lines, displayCommit(
|
||||||
common,
|
common,
|
||||||
commit,
|
commit,
|
||||||
|
branchHeadsToVisualize,
|
||||||
cherryPickedCommitShaSet,
|
cherryPickedCommitShaSet,
|
||||||
diffName,
|
diffName,
|
||||||
timeFormat,
|
timeFormat,
|
||||||
@ -260,6 +288,7 @@ func getBisectStatusText(bisectStatus BisectStatus, bisectInfo *git_commands.Bis
|
|||||||
func displayCommit(
|
func displayCommit(
|
||||||
common *common.Common,
|
common *common.Common,
|
||||||
commit *models.Commit,
|
commit *models.Commit,
|
||||||
|
branchHeadsToVisualize *set.Set[string],
|
||||||
cherryPickedCommitShaSet *set.Set[string],
|
cherryPickedCommitShaSet *set.Set[string],
|
||||||
diffName string,
|
diffName string,
|
||||||
timeFormat string,
|
timeFormat string,
|
||||||
@ -289,8 +318,11 @@ func displayCommit(
|
|||||||
} else {
|
} else {
|
||||||
if len(commit.Tags) > 0 {
|
if len(commit.Tags) > 0 {
|
||||||
tagString = theme.DiffTerminalColor.SetBold().Sprint(strings.Join(commit.Tags, " ")) + " "
|
tagString = theme.DiffTerminalColor.SetBold().Sprint(strings.Join(commit.Tags, " ")) + " "
|
||||||
} else if common.UserConfig.Gui.ExperimentalShowBranchHeads && commit.ExtraInfo != "" {
|
}
|
||||||
tagString = style.FgMagenta.SetBold().Sprint("(*)") + " "
|
|
||||||
|
if branchHeadsToVisualize.Includes(commit.Sha) && commit.Status != models.StatusMerged {
|
||||||
|
tagString = style.FgCyan.SetBold().Sprint(
|
||||||
|
lo.Ternary(icons.IsIconEnabled(), icons.BRANCH_ICON, "*") + " " + tagString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,9 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
|||||||
scenarios := []struct {
|
scenarios := []struct {
|
||||||
testName string
|
testName string
|
||||||
commits []*models.Commit
|
commits []*models.Commit
|
||||||
|
branches []*models.Branch
|
||||||
|
currentBranchName string
|
||||||
|
hasUpdateRefConfig bool
|
||||||
fullDescription bool
|
fullDescription bool
|
||||||
cherryPickedCommitShaSet *set.Set[string]
|
cherryPickedCommitShaSet *set.Set[string]
|
||||||
diffName string
|
diffName string
|
||||||
@ -72,6 +75,120 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
|||||||
sha2 commit2
|
sha2 commit2
|
||||||
`),
|
`),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
testName: "commit with tags",
|
||||||
|
commits: []*models.Commit{
|
||||||
|
{Name: "commit1", Sha: "sha1", Tags: []string{"tag1", "tag2"}},
|
||||||
|
{Name: "commit2", Sha: "sha2"},
|
||||||
|
},
|
||||||
|
startIdx: 0,
|
||||||
|
length: 2,
|
||||||
|
showGraph: false,
|
||||||
|
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||||
|
cherryPickedCommitShaSet: set.New[string](),
|
||||||
|
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
expected: formatExpected(`
|
||||||
|
sha1 tag1 tag2 commit1
|
||||||
|
sha2 commit2
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "show local branch head, except the current branch, main branches, or merged branches",
|
||||||
|
commits: []*models.Commit{
|
||||||
|
{Name: "commit1", Sha: "sha1"},
|
||||||
|
{Name: "commit2", Sha: "sha2"},
|
||||||
|
{Name: "commit3", Sha: "sha3"},
|
||||||
|
{Name: "commit4", Sha: "sha4", Status: models.StatusMerged},
|
||||||
|
},
|
||||||
|
branches: []*models.Branch{
|
||||||
|
{Name: "current-branch", CommitHash: "sha1", Head: true},
|
||||||
|
{Name: "other-branch", CommitHash: "sha2", Head: false},
|
||||||
|
{Name: "master", CommitHash: "sha3", Head: false},
|
||||||
|
{Name: "old-branch", CommitHash: "sha4", Head: false},
|
||||||
|
},
|
||||||
|
currentBranchName: "current-branch",
|
||||||
|
hasUpdateRefConfig: true,
|
||||||
|
startIdx: 0,
|
||||||
|
length: 4,
|
||||||
|
showGraph: false,
|
||||||
|
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||||
|
cherryPickedCommitShaSet: set.New[string](),
|
||||||
|
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
expected: formatExpected(`
|
||||||
|
sha1 commit1
|
||||||
|
sha2 * commit2
|
||||||
|
sha3 commit3
|
||||||
|
sha4 commit4
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "show local branch head for head commit if updateRefs is on",
|
||||||
|
commits: []*models.Commit{
|
||||||
|
{Name: "commit1", Sha: "sha1"},
|
||||||
|
{Name: "commit2", Sha: "sha2"},
|
||||||
|
},
|
||||||
|
branches: []*models.Branch{
|
||||||
|
{Name: "current-branch", CommitHash: "sha1", Head: true},
|
||||||
|
{Name: "other-branch", CommitHash: "sha1", Head: false},
|
||||||
|
},
|
||||||
|
currentBranchName: "current-branch",
|
||||||
|
hasUpdateRefConfig: true,
|
||||||
|
startIdx: 0,
|
||||||
|
length: 2,
|
||||||
|
showGraph: false,
|
||||||
|
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||||
|
cherryPickedCommitShaSet: set.New[string](),
|
||||||
|
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
expected: formatExpected(`
|
||||||
|
sha1 * commit1
|
||||||
|
sha2 commit2
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "don't show local branch head for head commit if updateRefs is off",
|
||||||
|
commits: []*models.Commit{
|
||||||
|
{Name: "commit1", Sha: "sha1"},
|
||||||
|
{Name: "commit2", Sha: "sha2"},
|
||||||
|
},
|
||||||
|
branches: []*models.Branch{
|
||||||
|
{Name: "current-branch", CommitHash: "sha1", Head: true},
|
||||||
|
{Name: "other-branch", CommitHash: "sha1", Head: false},
|
||||||
|
},
|
||||||
|
currentBranchName: "current-branch",
|
||||||
|
hasUpdateRefConfig: false,
|
||||||
|
startIdx: 0,
|
||||||
|
length: 2,
|
||||||
|
showGraph: false,
|
||||||
|
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||||
|
cherryPickedCommitShaSet: set.New[string](),
|
||||||
|
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
expected: formatExpected(`
|
||||||
|
sha1 commit1
|
||||||
|
sha2 commit2
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "show local branch head and tag if both exist",
|
||||||
|
commits: []*models.Commit{
|
||||||
|
{Name: "commit1", Sha: "sha1"},
|
||||||
|
{Name: "commit2", Sha: "sha2", Tags: []string{"some-tag"}},
|
||||||
|
{Name: "commit3", Sha: "sha3"},
|
||||||
|
},
|
||||||
|
branches: []*models.Branch{
|
||||||
|
{Name: "some-branch", CommitHash: "sha2"},
|
||||||
|
},
|
||||||
|
startIdx: 0,
|
||||||
|
length: 3,
|
||||||
|
showGraph: false,
|
||||||
|
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||||
|
cherryPickedCommitShaSet: set.New[string](),
|
||||||
|
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
expected: formatExpected(`
|
||||||
|
sha1 commit1
|
||||||
|
sha2 * some-tag commit2
|
||||||
|
sha3 commit3
|
||||||
|
`),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
testName: "showing graph",
|
testName: "showing graph",
|
||||||
commits: []*models.Commit{
|
commits: []*models.Commit{
|
||||||
@ -285,6 +402,9 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
|||||||
result := GetCommitListDisplayStrings(
|
result := GetCommitListDisplayStrings(
|
||||||
common,
|
common,
|
||||||
s.commits,
|
s.commits,
|
||||||
|
s.branches,
|
||||||
|
s.currentBranchName,
|
||||||
|
s.hasUpdateRefConfig,
|
||||||
s.fullDescription,
|
s.fullDescription,
|
||||||
s.cherryPickedCommitShaSet,
|
s.cherryPickedCommitShaSet,
|
||||||
s.diffName,
|
s.diffName,
|
||||||
|
@ -217,6 +217,10 @@ type Model struct {
|
|||||||
RemoteBranches []*models.RemoteBranch
|
RemoteBranches []*models.RemoteBranch
|
||||||
Tags []*models.Tag
|
Tags []*models.Tag
|
||||||
|
|
||||||
|
// Name of the currently checked out branch. This will be set even when
|
||||||
|
// we're on a detached head because we're rebasing or bisecting.
|
||||||
|
CheckedOutBranch string
|
||||||
|
|
||||||
// for displaying suggestions while typing in a file name
|
// for displaying suggestions while typing in a file name
|
||||||
FilesTrie *patricia.Trie
|
FilesTrie *patricia.Trie
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
Skip: false,
|
Skip: false,
|
||||||
SetupRepo: func(shell *Shell) {
|
SetupRepo: func(shell *Shell) {
|
||||||
shell.
|
shell.
|
||||||
|
NewBranch("mybranch").
|
||||||
CreateNCommits(10)
|
CreateNCommits(10)
|
||||||
},
|
},
|
||||||
SetupConfig: func(cfg *config.AppConfig) {},
|
SetupConfig: func(cfg *config.AppConfig) {},
|
||||||
@ -31,20 +32,21 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
|
|
||||||
t.Views().Commits().
|
t.Views().Commits().
|
||||||
Focus().
|
Focus().
|
||||||
SelectedLine(Contains("commit 10")).
|
SelectedLine(Contains("CI commit 10")).
|
||||||
NavigateToLine(Contains("commit 09")).
|
NavigateToLine(Contains("CI commit 09")).
|
||||||
Tap(func() {
|
Tap(func() {
|
||||||
markCommitAsBad()
|
markCommitAsBad()
|
||||||
|
|
||||||
t.Views().Information().Content(Contains("Bisecting"))
|
t.Views().Information().Content(Contains("Bisecting"))
|
||||||
}).
|
}).
|
||||||
SelectedLine(Contains("<-- bad")).
|
SelectedLine(Contains("<-- bad")).
|
||||||
NavigateToLine(Contains("commit 02")).
|
NavigateToLine(Contains("CI commit 02")).
|
||||||
Tap(markCommitAsGood).
|
Tap(markCommitAsGood).
|
||||||
|
TopLines(Contains("CI commit 10")).
|
||||||
// lazygit will land us in the commit between our good and bad commits.
|
// lazygit will land us in the commit between our good and bad commits.
|
||||||
SelectedLine(Contains("commit 05").Contains("<-- current")).
|
SelectedLine(Contains("CI commit 05").Contains("<-- current")).
|
||||||
Tap(markCommitAsBad).
|
Tap(markCommitAsBad).
|
||||||
SelectedLine(Contains("commit 04").Contains("<-- current")).
|
SelectedLine(Contains("CI commit 04").Contains("<-- current")).
|
||||||
Tap(func() {
|
Tap(func() {
|
||||||
markCommitAsGood()
|
markCommitAsGood()
|
||||||
|
|
||||||
@ -52,7 +54,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
t.ExpectPopup().Alert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 05.*Do you want to reset")).Confirm()
|
t.ExpectPopup().Alert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 05.*Do you want to reset")).Confirm()
|
||||||
}).
|
}).
|
||||||
IsFocused().
|
IsFocused().
|
||||||
Content(Contains("commit 04"))
|
Content(Contains("CI commit 04"))
|
||||||
|
|
||||||
t.Views().Information().Content(DoesNotContain("Bisecting"))
|
t.Views().Information().Content(DoesNotContain("Bisecting"))
|
||||||
},
|
},
|
||||||
|
@ -10,12 +10,16 @@ var DropTodoCommitWithUpdateRef = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
ExtraCmdArgs: []string{},
|
ExtraCmdArgs: []string{},
|
||||||
Skip: false,
|
Skip: false,
|
||||||
GitVersion: AtLeast("2.38.0"),
|
GitVersion: AtLeast("2.38.0"),
|
||||||
SetupConfig: func(config *config.AppConfig) {},
|
SetupConfig: func(config *config.AppConfig) {
|
||||||
|
config.GetUserConfig().Git.MainBranches = []string{"master"}
|
||||||
|
},
|
||||||
SetupRepo: func(shell *Shell) {
|
SetupRepo: func(shell *Shell) {
|
||||||
shell.
|
shell.
|
||||||
CreateNCommits(3).
|
CreateNCommits(1).
|
||||||
NewBranch("mybranch").
|
NewBranch("branch1").
|
||||||
CreateNCommitsStartingAt(3, 4)
|
CreateNCommitsStartingAt(3, 2).
|
||||||
|
NewBranch("branch2").
|
||||||
|
CreateNCommitsStartingAt(3, 5)
|
||||||
|
|
||||||
shell.SetConfig("rebase.updateRefs", "true")
|
shell.SetConfig("rebase.updateRefs", "true")
|
||||||
},
|
},
|
||||||
@ -23,26 +27,28 @@ var DropTodoCommitWithUpdateRef = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
t.Views().Commits().
|
t.Views().Commits().
|
||||||
Focus().
|
Focus().
|
||||||
Lines(
|
Lines(
|
||||||
Contains("commit 06").IsSelected(),
|
Contains("CI commit 07").IsSelected(),
|
||||||
Contains("commit 05"),
|
Contains("CI commit 06"),
|
||||||
Contains("commit 04"),
|
Contains("CI commit 05"),
|
||||||
Contains("commit 03"),
|
Contains("CI * commit 04"),
|
||||||
Contains("commit 02"),
|
Contains("CI commit 03"),
|
||||||
Contains("commit 01"),
|
Contains("CI commit 02"),
|
||||||
|
Contains("CI commit 01"),
|
||||||
).
|
).
|
||||||
NavigateToLine(Contains("commit 01")).
|
NavigateToLine(Contains("commit 02")).
|
||||||
Press(keys.Universal.Edit).
|
Press(keys.Universal.Edit).
|
||||||
Focus().
|
Focus().
|
||||||
Lines(
|
Lines(
|
||||||
Contains("pick").Contains("commit 06"),
|
Contains("pick").Contains("CI commit 07"),
|
||||||
Contains("pick").Contains("commit 05"),
|
Contains("pick").Contains("CI commit 06"),
|
||||||
Contains("pick").Contains("commit 04"),
|
Contains("pick").Contains("CI commit 05"),
|
||||||
Contains("update-ref").Contains("master"),
|
Contains("update-ref").Contains("branch1").DoesNotContain("*"),
|
||||||
Contains("pick").Contains("commit 03"),
|
Contains("pick").Contains("CI * commit 04"),
|
||||||
Contains("pick").Contains("commit 02"),
|
Contains("pick").Contains("CI commit 03"),
|
||||||
Contains("<-- YOU ARE HERE --- commit 01"),
|
Contains("<-- YOU ARE HERE --- commit 02"),
|
||||||
|
Contains("CI commit 01"),
|
||||||
).
|
).
|
||||||
NavigateToLine(Contains("commit 05")).
|
NavigateToLine(Contains("commit 06")).
|
||||||
Press(keys.Universal.Remove)
|
Press(keys.Universal.Remove)
|
||||||
|
|
||||||
t.Common().ContinueRebase()
|
t.Common().ContinueRebase()
|
||||||
@ -50,11 +56,12 @@ var DropTodoCommitWithUpdateRef = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
t.Views().Commits().
|
t.Views().Commits().
|
||||||
IsFocused().
|
IsFocused().
|
||||||
Lines(
|
Lines(
|
||||||
Contains("commit 06"),
|
Contains("CI commit 07"),
|
||||||
Contains("commit 04"),
|
Contains("CI commit 05"),
|
||||||
Contains("commit 03"),
|
Contains("CI * commit 04"),
|
||||||
Contains("commit 02"),
|
Contains("CI commit 03"),
|
||||||
Contains("commit 01"),
|
Contains("CI commit 02"),
|
||||||
|
Contains("CI commit 01"),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
package interactive_rebase
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/config"
|
|
||||||
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
|
||||||
)
|
|
||||||
|
|
||||||
var DropTodoCommitWithUpdateRefShowBranchHeads = NewIntegrationTest(NewIntegrationTestArgs{
|
|
||||||
Description: "Drops a commit during interactive rebase when there is an update-ref in the git-rebase-todo file (with experimentalShowBranchHeads on)",
|
|
||||||
ExtraCmdArgs: []string{},
|
|
||||||
Skip: false,
|
|
||||||
GitVersion: AtLeast("2.38.0"),
|
|
||||||
SetupConfig: func(config *config.AppConfig) {
|
|
||||||
config.UserConfig.Gui.ExperimentalShowBranchHeads = true
|
|
||||||
},
|
|
||||||
SetupRepo: func(shell *Shell) {
|
|
||||||
shell.
|
|
||||||
CreateNCommits(3).
|
|
||||||
NewBranch("mybranch").
|
|
||||||
CreateNCommitsStartingAt(3, 4)
|
|
||||||
|
|
||||||
shell.SetConfig("rebase.updateRefs", "true")
|
|
||||||
},
|
|
||||||
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
|
||||||
t.Views().Commits().
|
|
||||||
Focus().
|
|
||||||
Lines(
|
|
||||||
Contains("(*) commit 06").IsSelected(),
|
|
||||||
Contains("commit 05"),
|
|
||||||
Contains("commit 04"),
|
|
||||||
Contains("(*) commit 03"),
|
|
||||||
Contains("commit 02"),
|
|
||||||
Contains("commit 01"),
|
|
||||||
).
|
|
||||||
NavigateToLine(Contains("commit 01")).
|
|
||||||
Press(keys.Universal.Edit).
|
|
||||||
Focus().
|
|
||||||
Lines(
|
|
||||||
Contains("pick").Contains("(*) commit 06"),
|
|
||||||
Contains("pick").Contains("commit 05"),
|
|
||||||
Contains("pick").Contains("commit 04"),
|
|
||||||
Contains("update-ref").Contains("master"),
|
|
||||||
Contains("pick").Contains("(*) commit 03"),
|
|
||||||
Contains("pick").Contains("commit 02"),
|
|
||||||
Contains("<-- YOU ARE HERE --- commit 01"),
|
|
||||||
).
|
|
||||||
NavigateToLine(Contains("commit 05")).
|
|
||||||
Press(keys.Universal.Remove)
|
|
||||||
|
|
||||||
t.Common().ContinueRebase()
|
|
||||||
|
|
||||||
t.Views().Commits().
|
|
||||||
IsFocused().
|
|
||||||
Lines(
|
|
||||||
Contains("(*) commit 06"),
|
|
||||||
Contains("commit 04"),
|
|
||||||
Contains("(*) commit 03"),
|
|
||||||
Contains("commit 02"),
|
|
||||||
Contains("commit 01"),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
})
|
|
@ -0,0 +1,71 @@
|
|||||||
|
package reflog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
|
)
|
||||||
|
|
||||||
|
var DoNotShowBranchMarkersInReflogSubcommits = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
|
Description: "Verify that no branch heads are shown in the subcommits view of a reflog entry",
|
||||||
|
ExtraCmdArgs: []string{},
|
||||||
|
Skip: false,
|
||||||
|
SetupConfig: func(config *config.AppConfig) {},
|
||||||
|
SetupRepo: func(shell *Shell) {
|
||||||
|
shell.NewBranch("branch1")
|
||||||
|
shell.EmptyCommit("one")
|
||||||
|
shell.EmptyCommit("two")
|
||||||
|
shell.NewBranch("branch2")
|
||||||
|
shell.EmptyCommit("three")
|
||||||
|
},
|
||||||
|
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||||
|
// Check that the local commits view does show a branch marker for branch1
|
||||||
|
t.Views().Commits().
|
||||||
|
Lines(
|
||||||
|
Contains("CI three"),
|
||||||
|
Contains("CI * two"),
|
||||||
|
Contains("CI one"),
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Views().Branches().
|
||||||
|
Focus().
|
||||||
|
// Check out branch1
|
||||||
|
NavigateToLine(Contains("branch1")).
|
||||||
|
PressPrimaryAction().
|
||||||
|
// Look at the subcommits of branch2
|
||||||
|
NavigateToLine(Contains("branch2")).
|
||||||
|
PressEnter().
|
||||||
|
// Check that we see a marker for branch1 here (but not for
|
||||||
|
// branch2), even though branch1 is checked out
|
||||||
|
Tap(func() {
|
||||||
|
t.Views().SubCommits().
|
||||||
|
IsFocused().
|
||||||
|
Lines(
|
||||||
|
Contains("CI three"),
|
||||||
|
Contains("CI * two"),
|
||||||
|
Contains("CI one"),
|
||||||
|
).
|
||||||
|
PressEscape()
|
||||||
|
}).
|
||||||
|
// Check out branch2 again
|
||||||
|
NavigateToLine(Contains("branch2")).
|
||||||
|
PressPrimaryAction()
|
||||||
|
|
||||||
|
t.Views().ReflogCommits().
|
||||||
|
Focus().
|
||||||
|
TopLines(
|
||||||
|
Contains("checkout: moving from branch1 to branch2").IsSelected(),
|
||||||
|
).
|
||||||
|
PressEnter().
|
||||||
|
// Check that the subcommits view for a reflog entry doesn't show
|
||||||
|
// any branch markers
|
||||||
|
Tap(func() {
|
||||||
|
t.Views().SubCommits().
|
||||||
|
IsFocused().
|
||||||
|
Lines(
|
||||||
|
Contains("CI three"),
|
||||||
|
Contains("CI two"),
|
||||||
|
Contains("CI one"),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
@ -117,7 +117,6 @@ var tests = []*components.IntegrationTest{
|
|||||||
interactive_rebase.AmendMerge,
|
interactive_rebase.AmendMerge,
|
||||||
interactive_rebase.AmendNonHeadCommitDuringRebase,
|
interactive_rebase.AmendNonHeadCommitDuringRebase,
|
||||||
interactive_rebase.DropTodoCommitWithUpdateRef,
|
interactive_rebase.DropTodoCommitWithUpdateRef,
|
||||||
interactive_rebase.DropTodoCommitWithUpdateRefShowBranchHeads,
|
|
||||||
interactive_rebase.DropWithCustomCommentChar,
|
interactive_rebase.DropWithCustomCommentChar,
|
||||||
interactive_rebase.EditFirstCommit,
|
interactive_rebase.EditFirstCommit,
|
||||||
interactive_rebase.EditNonTodoCommitDuringRebase,
|
interactive_rebase.EditNonTodoCommitDuringRebase,
|
||||||
@ -164,6 +163,7 @@ var tests = []*components.IntegrationTest{
|
|||||||
patch_building.StartNewPatch,
|
patch_building.StartNewPatch,
|
||||||
reflog.Checkout,
|
reflog.Checkout,
|
||||||
reflog.CherryPick,
|
reflog.CherryPick,
|
||||||
|
reflog.DoNotShowBranchMarkersInReflogSubcommits,
|
||||||
reflog.Patch,
|
reflog.Patch,
|
||||||
reflog.Reset,
|
reflog.Reset,
|
||||||
staging.DiffContextChange,
|
staging.DiffContextChange,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user