sync

package
v0.66.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var FastForwardBehindBranch = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fast-forward a branch that is behind its upstream branch, without checking it out",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")
		shell.NewBranch("feature")
		shell.EmptyCommit("two")
		shell.EmptyCommit("three")

		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("feature", "origin/feature")

		shell.HardReset("HEAD~2")
		shell.Checkout("master")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Focus().
			Lines(
				Contains("master").IsSelected(),
				Contains("feature ↓2"),
			).
			SelectNextItem().
			Press(keys.Branches.FastForward).
			Lines(
				Contains("master"),
				Contains("feature ✓").IsSelected(),
			).
			PressEnter()

		t.Views().SubCommits().
			IsFocused().
			Lines(
				Contains("three"),
				Contains("two"),
				Contains("one"),
			)
	},
})
View Source
var FastForwardBehindBranchCheckedOut = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fast-forward the checked out branch when it is behind its upstream branch",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.CreateFileAndAdd("file", "content")
		shell.Commit("one")
		shell.EmptyCommit("two")
		shell.EmptyCommit("three")

		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")

		shell.HardReset("HEAD~2")

		shell.UpdateFile("file", "changed")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Branches().
			Focus().
			Lines(
				Contains("master ↓2").IsSelected(),
			).
			Press(keys.Branches.FastForward).
			Lines(
				Contains("master ✓").IsSelected(),
			)

		t.Views().Commits().
			Lines(
				Contains("three"),
				Contains("two"),
				Contains("one"),
			)

		t.Views().Files().
			Lines(
				Contains("file"),
			)
	},
})
View Source
var FastForwardBehindBranchWithoutReflogs = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fast-forward a branch that is behind its upstream branch in a repo that keeps no reflogs",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {

		shell.SetConfig("core.logAllRefUpdates", "false")

		shell.EmptyCommit("one")
		shell.NewBranch("feature")
		shell.EmptyCommit("two")
		shell.EmptyCommit("three")

		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("feature", "origin/feature")

		shell.HardReset("HEAD~2")
		shell.Checkout("master")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Focus().
			Lines(
				Contains("master").IsSelected(),
				Contains("feature ↓2"),
			).
			SelectNextItem().
			Press(keys.Branches.FastForward).
			Lines(
				Contains("master"),
				Contains("feature ✓").IsSelected(),
			)
	},
})
View Source
var FastForwardBranchBeingRebasedInWorktree = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Try to fast-forward a branch that is being rebased in another worktree",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.CreateFileAndAdd("file", "content")
		shell.Commit("one")
		shell.EmptyCommit("two")
		shell.EmptyCommit("three")

		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")

		shell.HardReset("HEAD~1")

		shell.NewBranch("other")
		shell.AddWorktreeCheckout("master", "../linked-worktree")

		shell.RunCommandExpectError([]string{"git", "-C", "../linked-worktree", "rebase", "--exec", "false", "HEAD~1"})
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Focus().
			Lines(
				Contains("other").IsSelected(),
				Contains("master (worktree linked-worktree) ↓1"),
			).
			NavigateToLine(Contains("master")).
			Press(keys.Branches.FastForward)

		t.ExpectPopup().Alert().
			Title(Equals("Error")).
			Content(Equals("Cannot fast-forward 'master' because it is being rebased or bisected in worktree linked-worktree")).
			Confirm()

		t.Views().Worktrees().
			Focus().
			NavigateToLine(Contains("linked-worktree")).
			Press(keys.Universal.Select)

		t.Views().Information().Content(Contains("Rebasing"))

		t.Views().Commits().
			Lines(
				Contains("─── Pending rebase todos"),
				Contains("─── Commits"),
				Contains("two"),
				Contains("one"),
			)
	},
})
View Source
var FastForwardBranchesInWorktreesWithOneFailing = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fast-forward two branches checked out in other worktrees when the fast-forward fails in the first one",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		shell.CreateFileAndAdd("file", "content")
		shell.Commit("one")
		shell.NewBranch("branch-a")
		shell.CreateFileAndAdd("a-file", "a")
		shell.Commit("a")
		shell.Checkout("master")
		shell.NewBranch("branch-b")
		shell.CreateFileAndAdd("b-file", "b")
		shell.Commit("b")
		shell.Checkout("master")

		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("branch-a", "origin/branch-a")
		shell.SetBranchUpstream("branch-b", "origin/branch-b")

		shell.RunCommand([]string{"git", "branch", "-f", "branch-a", "branch-a~1"})
		shell.RunCommand([]string{"git", "branch", "-f", "branch-b", "branch-b~1"})

		shell.AddWorktreeCheckout("branch-a", "../worktree-a")
		shell.AddWorktreeCheckout("branch-b", "../worktree-b")

		shell.CreateFile("../worktree-a/a-file", "mine")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Focus().
			Lines(
				Contains("master").IsSelected(),
				Contains("branch-a (worktree worktree-a) ↓1"),
				Contains("branch-b (worktree worktree-b) ↓1"),
			).
			SelectNextItem().
			Press(keys.Universal.ToggleRangeSelect).
			SelectNextItem().
			Press(keys.Branches.FastForward)

		t.ExpectPopup().Alert().
			Title(Equals("Error")).
			Content(Contains("would be overwritten by merge")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("master"),
				Contains("branch-a (worktree worktree-a) ↓1").IsSelected(),
				Contains("branch-b (worktree worktree-b) ✓").IsSelected(),
			)
	},
})
View Source
var FastForwardRewrittenBranch = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fast-forward a branch that has diverged from its upstream because the upstream branch was rewritten",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		createBranchRewrittenOnTheRemote(shell)
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Focus().
			Lines(
				Contains("master").IsSelected(),
				Contains("feature ↓2↑2"),
			).
			SelectNextItem().
			Press(keys.Branches.FastForward).
			Lines(
				Contains("master"),
				Contains("feature ✓").IsSelected(),
			).
			PressEnter()

		t.Views().SubCommits().
			IsFocused().
			Lines(
				Contains("three-rewritten"),
				Contains("two-rewritten"),
				Contains("one"),
			)
	},
})
View Source
var FastForwardRewrittenBranchCheckedOut = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fast-forward the checked out branch after its upstream branch was rewritten",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		createBranchRewrittenOnTheRemote(shell)

		shell.Checkout("feature")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("three"),
				Contains("two"),
				Contains("one"),
			)

		t.Views().Branches().
			Focus().
			Lines(
				Contains("feature ↓2↑2").IsSelected(),
				Contains("master"),
			).
			Press(keys.Branches.FastForward).
			Lines(
				Contains("feature ✓").IsSelected(),
				Contains("master"),
			)

		t.Views().Commits().
			Lines(
				Contains("three-rewritten"),
				Contains("two-rewritten"),
				Contains("one"),
			)
	},
})
View Source
var FastForwardRewrittenBranchWithLocalCommits = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Try to fast-forward a branch that has a commit of its own on top of a rewritten upstream branch",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		createBranchRewrittenOnTheRemote(shell)

		shell.Checkout("feature")
		shell.EmptyCommit("mine")
		shell.Checkout("master")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Focus().
			Lines(
				Contains("master").IsSelected(),
				Contains("feature ↓2↑3"),
			).
			SelectNextItem().
			Press(keys.Branches.FastForward)

		t.ExpectPopup().Alert().Title(Equals("Error")).
			Content(Contains("Cannot fast-forward 'feature' because it has commits")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("master"),
				Contains("feature ↓2↑3").IsSelected(),
			)
	},
})
View Source
var FastForwardRewrittenBranchWithStaleSubmodule = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fast-forward a branch with a rewritten upstream branch while its worktree has a submodule checked out at a different commit than the one recorded",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("initial")
		shell.CloneIntoSubmodule("sub", "sub")
		createBranchRewrittenOnTheRemote(shell)

		shell.Checkout("feature")
		shell.RunCommand([]string{"git", "-C", "sub", "commit", "--allow-empty", "-m", "newer"})
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Files().
			Lines(
				Contains("sub"),
			)

		t.Views().Branches().
			Focus().
			Lines(
				Contains("feature ↓2↑2").IsSelected(),
				Contains("master"),
			).
			Press(keys.Branches.FastForward).
			Lines(
				Contains("feature ✓").IsSelected(),
				Contains("master"),
			)

		t.Views().Files().
			Lines(
				Contains("sub"),
			)
	},
})
View Source
var FastForwardRewrittenBranchWithUncommittedChanges = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Try to fast-forward a branch with a rewritten upstream branch while its worktree has uncommitted changes",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.CreateFileAndAdd("file", "content")
		createBranchRewrittenOnTheRemote(shell)

		shell.Checkout("feature")
		shell.UpdateFile("file", "changed")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Focus().
			Lines(
				Contains("feature ↓2↑2").IsSelected(),
				Contains("master"),
			).
			Press(keys.Branches.FastForward)

		t.ExpectPopup().Alert().Title(Equals("Error")).
			Content(Contains("Cannot fast-forward 'feature' because the worktree")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("feature ↓2↑2").IsSelected(),
				Contains("master"),
			)

		t.Views().Files().
			Lines(
				Contains("file"),
			)
	},
})
View Source
var FastForwardRewrittenBranchWithoutReflogs = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Try to fast-forward a branch with a rewritten upstream branch in a repo that keeps no reflogs",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {

		shell.SetConfig("core.logAllRefUpdates", "false")

		createBranchRewrittenOnTheRemote(shell)
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Focus().
			Lines(
				Contains("master").IsSelected(),
				Contains("feature ↓2↑2"),
			).
			SelectNextItem().
			Press(keys.Branches.FastForward)

		t.ExpectPopup().Alert().Title(Equals("Error")).
			Content(Contains("Cannot fast-forward 'feature' because it has commits")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("master"),
				Contains("feature ↓2↑2").IsSelected(),
			)
	},
})
View Source
var FastForwardRewrittenStackOfBranches = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fast-forward a whole stack of branches whose upstream branches were rewritten",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		createStackRewrittenOnTheRemote(shell)
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Focus().
			Lines(
				Contains("master").IsSelected(),
				Contains("branch1 ↓1↑1"),
				Contains("branch2 ↓2↑2"),
				Contains("branch3 ↓3↑3"),
			).
			SelectNextItem().
			Press(keys.Universal.ToggleRangeSelect).
			SelectNextItem().
			SelectNextItem().
			Lines(
				Contains("master"),
				Contains("branch1 ↓1↑1").IsSelected(),
				Contains("branch2 ↓2↑2").IsSelected(),
				Contains("branch3 ↓3↑3").IsSelected(),
			).
			Press(keys.Branches.FastForward).
			Lines(
				Contains("master"),
				Contains("branch1 ✓").IsSelected(),
				Contains("branch2 ✓").IsSelected(),
				Contains("branch3 ✓").IsSelected(),
			)
	},
})
View Source
var FastForwardRewrittenStackOfBranchesWithLocalCommits = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Try to fast-forward a stack of branches of which one has a commit of its own",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		createStackRewrittenOnTheRemote(shell)

		shell.Checkout("branch2")
		shell.EmptyCommit("mine")
		shell.Checkout("master")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Focus().
			Lines(
				Contains("master").IsSelected(),
				Contains("branch1 ↓1↑1"),
				Contains("branch2 ↓2↑3"),
				Contains("branch3 ↓3↑3"),
			).
			SelectNextItem().
			Press(keys.Universal.ToggleRangeSelect).
			SelectNextItem().
			SelectNextItem().
			Press(keys.Branches.FastForward)

		t.ExpectPopup().Alert().Title(Equals("Error")).
			Content(Contains("Cannot fast-forward 'branch2' because it has commits")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("master"),
				Contains("branch1 ↓1↑1").IsSelected(),
				Contains("branch2 ↓2↑3").IsSelected(),
				Contains("branch3 ↓3↑3").IsSelected(),
			)
	},
})
View Source
var FetchAndAutoForwardBranchesAllBranches = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fetch from remote and auto-forward branches with config set to 'allBranches'",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.AutoForwardBranches = "allBranches"
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		shell.CreateNCommits(3)
		shell.NewBranch("feature")
		shell.NewBranch("diverged")
		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")
		shell.SetBranchUpstream("feature", "origin/feature")
		shell.SetBranchUpstream("diverged", "origin/diverged")
		shell.Checkout("master")
		shell.HardReset("HEAD^")
		shell.Checkout("feature")
		shell.HardReset("HEAD~2")
		shell.Checkout("diverged")
		shell.HardReset("HEAD~2")
		shell.EmptyCommit("local")
		shell.NewBranch("checked-out")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Lines(
				Contains("checked-out").IsSelected(),
				Contains("diverged ↓2↑1"),
				Contains("feature ↓2").DoesNotContain("↑"),
				Contains("master ↓1").DoesNotContain("↑"),
			)

		t.Views().Files().
			IsFocused().
			Press(keys.Files.Fetch)

		t.Views().Branches().
			Lines(
				Contains("checked-out").IsSelected(),
				Contains("diverged ↓2↑1"),
				Contains("feature ✓"),
				Contains("master ✓"),
			)
	},
})
View Source
var FetchAndAutoForwardBranchesAllBranchesCheckedOutInOtherWorktree = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fetch from remote and auto-forward branches with config set to 'allBranches'; check that a branch checked out by another worktree is forwarded there, unless that worktree has changes or is mid-rebase",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.AutoForwardBranches = "allBranches"
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		shell.CreateNCommits(3)
		shell.NewBranch("feature")
		shell.NewBranch("diverged")
		shell.NewBranch("dirty")
		shell.NewBranch("rebasing")
		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")
		shell.SetBranchUpstream("feature", "origin/feature")
		shell.SetBranchUpstream("diverged", "origin/diverged")
		shell.SetBranchUpstream("dirty", "origin/dirty")
		shell.SetBranchUpstream("rebasing", "origin/rebasing")
		shell.Checkout("master")
		shell.HardReset("HEAD^")
		shell.Checkout("feature")
		shell.HardReset("HEAD~2")
		shell.Checkout("diverged")
		shell.HardReset("HEAD~2")
		shell.EmptyCommit("local")
		shell.Checkout("dirty")
		shell.HardReset("HEAD~2")
		shell.Checkout("rebasing")
		shell.HardReset("HEAD^")
		shell.NewBranch("checked-out")

		shell.AddWorktreeCheckout("master", "../linked-worktree")

		shell.AddWorktreeCheckout("dirty", "../dirty-worktree")
		shell.UpdateFile("../dirty-worktree/file01.txt", "changed")

		shell.AddWorktreeCheckout("rebasing", "../rebasing-worktree")

		shell.RunCommandExpectError([]string{"git", "-C", "../rebasing-worktree", "rebase", "--exec", "false", "HEAD^"})
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Lines(
				Contains("checked-out").IsSelected(),
				Contains("dirty (worktree dirty-worktree) ↓2").DoesNotContain("↑"),
				Contains("diverged ↓2↑1"),
				Contains("feature ↓2").DoesNotContain("↑"),
				Contains("master (worktree linked-worktree) ↓1").DoesNotContain("↑"),
				Contains("rebasing (worktree rebasing-worktree) ↓1").DoesNotContain("↑"),
			)

		t.Views().Files().
			IsFocused().
			Press(keys.Files.Fetch)

		t.Views().Branches().
			Lines(
				Contains("checked-out").IsSelected(),
				Contains("dirty (worktree dirty-worktree) ↓2"),
				Contains("diverged ↓2↑1"),
				Contains("feature ✓"),
				Contains("master (worktree linked-worktree) ✓"),
				Contains("rebasing (worktree rebasing-worktree) ↓1"),
			)

		t.Views().Worktrees().
			Focus().
			NavigateToLine(Contains("linked-worktree")).
			PressPrimaryAction()

		t.Views().Files().
			Focus().
			IsEmpty()

		t.Views().Worktrees().
			Focus().
			NavigateToLine(Contains("rebasing-worktree")).
			PressPrimaryAction()

		t.Views().Commits().
			Lines(
				Contains("─── Pending rebase todos"),
				Contains("─── Commits"),
				Contains("commit-02"),
				Contains("commit-01"),
			)
	},
})
View Source
var FetchAndAutoForwardBranchesBeingRebasedInCurrentWorktree = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Auto-forward skips a main branch that is being rebased in the current worktree",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.AutoForwardBranches = "onlyMainBranches"
	},
	SetupRepo: func(shell *Shell) {
		shell.CreateNCommits(3)
		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")
		shell.HardReset("HEAD^")

		shell.RunCommandExpectError([]string{"git", "rebase", "--exec", "false", "HEAD^"})
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Lines(
				Contains("(no branch, rebasing master)"),
				Contains("master ↓1"),
			)

		t.Views().Files().
			IsFocused().
			Press(keys.Files.Fetch)

		t.Views().Branches().
			Lines(
				Contains("(no branch, rebasing master)"),
				Contains("master ↓1"),
			)
	},
})
View Source
var FetchAndAutoForwardBranchesCheckedOutInOtherWorktreeWithStaleSubmodule = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Auto-forward a main branch that is checked out in another worktree whose submodule is checked out at a different commit than the one recorded",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.AutoForwardBranches = "onlyMainBranches"
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")
		shell.CloneIntoSubmodule("sub", "sub")
		shell.Commit("add submodule")
		shell.EmptyCommit("two")

		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")
		shell.HardReset("HEAD^")

		shell.NewBranch("other")
		shell.AddWorktreeCheckout("master", "../linked-worktree")
		shell.RunCommand([]string{"git", "-C", "../linked-worktree", "submodule", "update", "--init"})
		shell.RunCommand([]string{"git", "-C", "../linked-worktree/sub", "commit", "--allow-empty", "-m", "newer"})
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Lines(
				Contains("other").IsSelected(),
				Contains("master (worktree linked-worktree) ↓1"),
			)

		t.Views().Files().
			IsFocused().
			Press(keys.Files.Fetch)

		t.Views().Branches().
			Lines(
				Contains("other").IsSelected(),
				Contains("master (worktree linked-worktree) ✓"),
			)
	},
})
View Source
var FetchAndAutoForwardBranchesNone = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fetch from remote and auto-forward branches with config set to 'none'",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.AutoForwardBranches = "none"
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		shell.CreateNCommits(3)
		shell.NewBranch("feature")
		shell.NewBranch("diverged")
		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")
		shell.SetBranchUpstream("feature", "origin/feature")
		shell.SetBranchUpstream("diverged", "origin/diverged")
		shell.Checkout("master")
		shell.HardReset("HEAD^")
		shell.Checkout("feature")
		shell.HardReset("HEAD~2")
		shell.Checkout("diverged")
		shell.HardReset("HEAD~2")
		shell.EmptyCommit("local")
		shell.NewBranch("checked-out")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Lines(
				Contains("checked-out").IsSelected(),
				Contains("diverged ↓2↑1"),
				Contains("feature ↓2").DoesNotContain("↑"),
				Contains("master ↓1").DoesNotContain("↑"),
			)

		t.Views().Files().
			IsFocused().
			Press(keys.Files.Fetch)

		t.Views().Branches().
			Lines(
				Contains("checked-out").IsSelected(),
				Contains("diverged ↓2↑1"),
				Contains("feature ↓2").DoesNotContain("↑"),
				Contains("master ↓1").DoesNotContain("↑"),
			)
	},
})
View Source
var FetchAndAutoForwardBranchesOnlyMainBranches = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fetch from remote and auto-forward branches with config set to 'onlyMainBranches'",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.AutoForwardBranches = "onlyMainBranches"
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		shell.CreateNCommits(3)
		shell.NewBranch("feature")
		shell.NewBranch("diverged")
		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")
		shell.SetBranchUpstream("feature", "origin/feature")
		shell.SetBranchUpstream("diverged", "origin/diverged")
		shell.Checkout("master")
		shell.HardReset("HEAD^")
		shell.Checkout("feature")
		shell.HardReset("HEAD~2")
		shell.Checkout("diverged")
		shell.HardReset("HEAD~2")
		shell.EmptyCommit("local")
		shell.NewBranch("checked-out")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Lines(
				Contains("checked-out").IsSelected(),
				Contains("diverged ↓2↑1"),
				Contains("feature ↓2").DoesNotContain("↑"),
				Contains("master ↓1").DoesNotContain("↑"),
			)

		t.Views().Files().
			IsFocused().
			Press(keys.Files.Fetch)

		t.Views().Branches().
			Lines(
				Contains("checked-out").IsSelected(),
				Contains("diverged ↓2↑1"),
				Contains("feature ↓2").DoesNotContain("↑"),
				Contains("master ✓"),
			)
	},
})
View Source
var FetchAndAutoForwardBranchesWorktreeAddedAfterStartup = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Auto-forward a main branch in the linked worktree that it was externally checked out in after lazygit started",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.AutoForwardBranches = "onlyMainBranches"
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		shell.CreateNCommits(3)
		shell.NewBranch("feature")
		shell.NewBranch("wt-branch")
		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")
		shell.SetBranchUpstream("feature", "origin/feature")
		shell.Checkout("master")
		shell.HardReset("HEAD^")
		shell.Checkout("feature")
		shell.AddWorktreeCheckout("wt-branch", "../linked-worktree")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Lines(
				Contains("feature").IsSelected(),
				Contains("master ↓1").DoesNotContain("↑"),
				Contains("wt-branch (worktree linked-worktree)"),
			)

		t.Shell().RunCommand([]string{"git", "-C", "../linked-worktree", "checkout", "master"})

		t.Views().Files().
			IsFocused().
			Press(keys.Files.Fetch)

		t.Views().Branches().
			Lines(
				Contains("feature").IsSelected(),
				Contains("master (worktree linked-worktree) ✓"),
				Contains("wt-branch").DoesNotContain("worktree"),
			)

		t.Views().Worktrees().
			Focus().
			NavigateToLine(Contains("linked-worktree")).
			PressPrimaryAction()

		t.Views().Files().
			Focus().
			IsEmpty()
	},
})
View Source
var FetchPrune = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fetch from the remote with the 'prune' option set in the git config",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {

		shell.SetConfig("fetch.prune", "true")

		shell.EmptyCommit("my commit message")

		shell.NewBranch("branch_to_remove")
		shell.Checkout("master")
		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")
		shell.SetBranchUpstream("branch_to_remove", "origin/branch_to_remove")

		shell.RemoveRemoteBranch("origin", "branch_to_remove")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Lines(
				Contains("master"),
				Contains("branch_to_remove").DoesNotContain("upstream gone"),
			)

		t.Views().Files().
			IsFocused().
			Press(keys.Files.Fetch)

		t.Views().Branches().
			Lines(
				Contains("master"),
				Contains("branch_to_remove").Contains("upstream gone"),
			)
	},
})
View Source
var FetchWhenSortedByDate = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Fetch a branch while sort order is by date; verify that branch stays selected",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.
			EmptyCommitWithDate("commit", "2023-04-07 10:00:00").
			EmptyCommitWithDate("commit", "2023-04-07 12:00:00").
			NewBranch("branch1").
			EmptyCommitWithDate("commit", "2023-04-07 11:00:00").
			NewBranch("branch2").
			Checkout("master").
			CloneIntoRemote("origin").
			SetBranchUpstream("master", "origin/master").
			HardReset("HEAD^").
			Checkout("branch1")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Focus().
			Press(keys.Branches.SortOrder)

		t.ExpectPopup().Menu().Title(Equals("Sort order")).
			Select(Contains("-committerdate")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("* branch1").IsSelected(),
				Contains("branch2"),
				Contains("master ↓1"),
			).
			NavigateToLine(Contains("master")).
			Press(keys.Branches.FetchRemote).
			Lines(
				Contains("* branch1"),
				Contains("master").IsSelected(),
				Contains("branch2"),
			)
	},
})
View Source
var ForcePush = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push to a remote with new commits, requiring a force push",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")
		shell.EmptyCommit("two")

		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")

		shell.HardReset("HEAD^")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Status().Content(Equals("↓1 repo → master"))

		t.Views().Files().IsFocused().Press(keys.Universal.Push)

		t.ExpectPopup().Confirmation().
			Title(Equals("Force push")).
			Content(Equals("Your branch has diverged from the remote branch. Press <esc> to cancel, or <enter> to force push.")).
			Confirm()

		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Status().Content(Equals("✓ repo → master"))

		t.Views().Remotes().Focus().
			Lines(Contains("origin")).
			PressEnter()

		t.Views().RemoteBranches().IsFocused().
			Lines(Contains("master")).
			PressEnter()

		t.Views().SubCommits().IsFocused().
			Lines(Contains("one"))
	},
})
View Source
var ForcePushMultipleMatching = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Force push to multiple branches because the user has push.default matching",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
	},
	SetupRepo: func(shell *Shell) {
		shell.SetConfig("push.default", "matching")

		createTwoBranchesReadyToForcePush(shell)
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Status().Content(Equals("↓1 repo → master"))

		t.Views().Branches().
			Lines(
				Contains("master ↓1"),
				Contains("other_branch ↓1"),
			)

		t.Views().Files().IsFocused().Press(keys.Universal.Push)

		t.ExpectPopup().Confirmation().
			Title(Equals("Force push")).
			Content(Equals("Your branch has diverged from the remote branch. Press <esc> to cancel, or <enter> to force push.")).
			Confirm()

		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Status().Content(Equals("✓ repo → master"))

		t.Views().Branches().
			Lines(
				Contains("master ✓"),
				Contains("other_branch ✓"),
			)
	},
})
View Source
var ForcePushMultipleUpstream = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Force push to only the upstream branch of the current branch because the user has push.default upstream",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.SetConfig("push.default", "upstream")

		createTwoBranchesReadyToForcePush(shell)
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Status().Content(Equals("↓1 repo → master"))

		t.Views().Branches().
			Lines(
				Contains("master ↓1"),
				Contains("other_branch ↓1"),
			)

		t.Views().Files().IsFocused().Press(keys.Universal.Push)

		t.ExpectPopup().Confirmation().
			Title(Equals("Force push")).
			Content(Equals("Your branch has diverged from the remote branch. Press <esc> to cancel, or <enter> to force push.")).
			Confirm()

		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Status().Content(Equals("✓ repo → master"))

		t.Views().Branches().
			Lines(
				Contains("master ✓"),
				Contains("other_branch ↓1"),
			)
	},
})
View Source
var ForcePushRemoteBranchNotStoredLocally = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push a branch whose remote branch is not stored locally, requiring a force push",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")
		shell.EmptyCommit("two")

		shell.Clone("some-remote")

		shell.HardReset("HEAD^")

		shell.SetConfig("branch.master.remote", "../some-remote")
		shell.SetConfig("branch.master.pushRemote", "../some-remote")
		shell.SetConfig("branch.master.merge", "refs/heads/master")

		shell.CreateFileAndAdd("file1", "file1 content")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Status().Content(Contains("? repo → master"))

		t.Views().Files().IsFocused().Press(keys.Universal.Push)

		t.ExpectPopup().Confirmation().
			Title(Equals("Force push")).
			Content(Equals("Your branch has diverged from the remote branch. Press <esc> to cancel, or <enter> to force push.")).
			Confirm()

		t.Views().Files().IsFocused().Press(keys.Files.CommitChanges)
		t.ExpectPopup().CommitMessagePanel().Type("new").Confirm()

		t.Views().Commits().
			Lines(
				Contains("new"),
				Contains("one"),
			)

		t.Views().Files().IsFocused().Press(keys.Universal.Push)

		t.Views().Remotes().Focus().
			Press(keys.Universal.New)

		t.ExpectPopup().Prompt().
			Title(Equals("New remote name:")).Type("some-remote").Confirm()
		t.ExpectPopup().Prompt().
			Title(Equals("New remote url:")).Type("../some-remote").Confirm()
		t.Views().Remotes().Lines(
			Contains("some-remote").IsSelected(),
		).
			PressEnter()

		t.Views().RemoteBranches().IsFocused().Lines(
			Contains("master").IsSelected(),
		).
			PressEnter()

		t.Views().SubCommits().IsFocused().Lines(
			Contains("new"),
			Contains("one"),
		)
	},
})
View Source
var ForcePushTriangular = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push to a remote, requiring a force push because the branch is behind the remote push branch but not the upstream",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.SetConfig("push.default", "current")

		shell.EmptyCommit("one")

		shell.CloneIntoRemote("origin")

		shell.NewBranch("feature")
		shell.SetBranchUpstream("feature", "origin/master")
		shell.EmptyCommit("two")
		shell.PushBranch("origin", "feature")

		shell.HardReset("HEAD^")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Status().Content(Contains("✓ repo → feature"))

		t.Views().Files().IsFocused().Press(keys.Universal.Push)

		t.ExpectPopup().Confirmation().
			Title(Equals("Force push")).
			Content(Equals("Your branch has diverged from the remote branch. Press <esc> to cancel, or <enter> to force push.")).
			Confirm()

		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Status().Content(Contains("✓ repo → feature"))

		t.Views().Remotes().Focus().
			Lines(Contains("origin")).
			PressEnter()

		t.Views().RemoteBranches().IsFocused().
			Lines(
				Contains("feature"),
				Contains("master"),
			).
			PressEnter()

		t.Views().SubCommits().IsFocused().
			Lines(Contains("one"))
	},
})
View Source
var Pull = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Pull a commit from the remote",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")
		shell.EmptyCommit("two")

		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")

		shell.HardReset("HEAD^")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Status().Content(Equals("↓1 repo → master"))

		t.Views().Files().IsFocused().Press(keys.Universal.Pull)

		t.Views().Commits().
			Lines(
				Contains("two"),
				Contains("one"),
			)

		t.Views().Status().Content(Equals("✓ repo → master"))
	},
})
View Source
var PullAndSetUpstream = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Pull a commit from the remote, setting the upstream branch in the process",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")
		shell.EmptyCommit("two")

		shell.CloneIntoRemote("origin")

		shell.HardReset("HEAD^")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Status().Content(Equals("repo → master"))

		t.Views().Files().IsFocused().Press(keys.Universal.Pull)

		t.ExpectPopup().Prompt().
			Title(Equals("Enter upstream as '<remote> <branchname>'")).
			SuggestionLines(Equals("origin master")).
			ConfirmFirstSuggestion()

		t.Views().Commits().
			Lines(
				Contains("two"),
				Contains("one"),
			)

		t.Views().Status().Content(Equals("✓ repo → master"))
	},
})
View Source
var PullMerge = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Pull with a merge strategy",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.CreateFileAndAdd("file", "content1")
		shell.Commit("one")
		shell.UpdateFileAndAdd("file", "content2")
		shell.Commit("two")
		shell.EmptyCommit("three")

		shell.CloneIntoRemote("origin")

		shell.SetBranchUpstream("master", "origin/master")

		shell.HardReset("HEAD^^")
		shell.EmptyCommit("four")

		shell.SetConfig("pull.rebase", "false")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("four").IsSelected(),
				Contains("one"),
			)

		t.Views().Status().Content(Equals("↓2↑1 repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Pull)

		t.Views().Status().Content(Equals("↑2 repo → master"))

		t.Views().Commits().
			Lines(
				Contains("Merge branch 'master' of ../origin").IsSelected(),
				Contains("three"),
				Contains("two"),
				Contains("four"),
				Contains("one"),
			)
	},
})
View Source
var PullMergeConflict = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Pull with a merge strategy, where a conflict occurs",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.CreateFileAndAdd("file", "content1")
		shell.Commit("one")
		shell.UpdateFileAndAdd("file", "content2")
		shell.Commit("two")
		shell.EmptyCommit("three")

		shell.CloneIntoRemote("origin")

		shell.SetBranchUpstream("master", "origin/master")

		shell.HardReset("HEAD^^")
		shell.UpdateFileAndAdd("file", "content4")
		shell.Commit("four")

		shell.SetConfig("pull.rebase", "false")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("four"),
				Contains("one"),
			)

		t.Views().Status().Content(Equals("↓2↑1 repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Pull)

		t.Common().AcknowledgeConflicts()

		t.Views().Files().
			IsFocused().
			Lines(
				Contains("UU").Contains("file"),
			).
			PressEnter()

		t.Views().MergeConflicts().
			IsFocused().
			TopLines(
				Contains("<<<<<<< HEAD"),
				Contains("content4"),
				Contains("======="),
				Contains("content2"),
				Contains(">>>>>>>"),
			).
			PressPrimaryAction()

		t.Common().ContinueOnConflictsResolved("merge")

		t.Views().Status().Content(Equals("↑2 repo → master"))

		t.Views().Commits().
			Focus().
			Lines(
				Contains("Merge branch 'master' of ../origin").IsSelected(),
				Contains("three"),
				Contains("two"),
				Contains("four"),
				Contains("one"),
			)

		t.Views().Main().
			Content(
				Contains("- content4").
					Contains(" -content2").
					Contains("++content4"),
			)
	},
})
View Source
var PullRebase = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Pull with a rebase strategy",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.CreateFileAndAdd("file", "content1")
		shell.Commit("one")
		shell.UpdateFileAndAdd("file", "content2")
		shell.Commit("two")
		shell.CreateFileAndAdd("file3", "content3")
		shell.Commit("three")

		shell.CloneIntoRemote("origin")

		shell.SetBranchUpstream("master", "origin/master")

		shell.HardReset("HEAD^^")
		shell.CreateFileAndAdd("file4", "content4")
		shell.Commit("four")

		shell.SetConfig("pull.rebase", "true")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("four"),
				Contains("one"),
			)

		t.Views().Status().Content(Equals("↓2↑1 repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Pull)

		t.Views().Status().Content(Equals("↑1 repo → master"))

		t.Views().Commits().
			Lines(
				Contains("four"),
				Contains("three"),
				Contains("two"),
				Contains("one"),
			)
	},
})
View Source
var PullRebaseConflict = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Pull with a rebase strategy, where a conflict occurs",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.CreateFileAndAdd("file", "content1")
		shell.Commit("one")
		shell.UpdateFileAndAdd("file", "content2")
		shell.Commit("two")
		shell.EmptyCommit("three")

		shell.CloneIntoRemote("origin")

		shell.SetBranchUpstream("master", "origin/master")

		shell.HardReset("HEAD^^")
		shell.UpdateFileAndAdd("file", "content4")
		shell.Commit("four")

		shell.SetConfig("pull.rebase", "true")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("four"),
				Contains("one"),
			)

		t.Views().Status().Content(Equals("↓2↑1 repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Pull)

		t.Common().AcknowledgeConflicts()

		t.Views().Files().
			IsFocused().
			Lines(
				Contains("UU").Contains("file"),
			).
			PressEnter()

		t.Views().MergeConflicts().
			IsFocused().
			TopLines(
				Contains("<<<<<<< HEAD"),
				Contains("content2"),
				Contains("======="),
				Contains("content4"),
				Contains(">>>>>>>"),
			).
			SelectNextItem().
			PressPrimaryAction()

		t.Common().ContinueOnConflictsResolved("rebase")

		t.Views().Status().Content(Equals("↑1 repo → master"))

		t.Views().Commits().
			Focus().
			Lines(
				Contains("four").IsSelected(),
				Contains("three"),
				Contains("two"),
				Contains("one"),
			)

		t.Views().Main().
			Content(
				Contains("-content2").
					Contains("+content4"),
			)
	},
})
View Source
var PullRebaseInteractiveConflict = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Pull with an interactive rebase strategy, where a conflict occurs",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.CreateFileAndAdd("file", "content1")
		shell.Commit("one")
		shell.UpdateFileAndAdd("file", "content2")
		shell.Commit("two")
		shell.CreateFileAndAdd("file3", "content3")
		shell.Commit("three")

		shell.CloneIntoRemote("origin")

		shell.SetBranchUpstream("master", "origin/master")

		shell.HardReset("HEAD^^")
		shell.UpdateFileAndAdd("file", "content4")
		shell.Commit("four")
		shell.CreateFileAndAdd("file5", "content5")
		shell.Commit("five")

		shell.SetConfig("pull.rebase", "interactive")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("five"),
				Contains("four"),
				Contains("one"),
			)

		t.Views().Status().Content(Equals("↓2↑2 repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Pull)

		t.Common().AcknowledgeConflicts()

		t.Views().Commits().
			Lines(
				Contains("─── Pending rebase todos"),
				Contains("pick").Contains("five"),
				Contains("pick").Contains("CONFLICT").Contains("four").IsSelected(),
				Contains("─── Commits"),
				Contains("three"),
				Contains("two"),
				Contains("one"),
			)

		t.Views().Files().
			IsFocused().
			Lines(
				Contains("UU").Contains("file"),
			).
			PressEnter()

		t.Views().MergeConflicts().
			IsFocused().
			TopLines(
				Contains("<<<<<<< HEAD"),
				Contains("content2"),
				Contains("======="),
				Contains("content4"),
				Contains(">>>>>>>"),
			).
			SelectNextItem().
			PressPrimaryAction()

		t.Common().ContinueOnConflictsResolved("rebase")

		t.Views().Status().Content(Equals("↑2 repo → master"))

		t.Views().Commits().
			Focus().
			Lines(
				Contains("five"),
				Contains("four").IsSelected(),
				Contains("three"),
				Contains("two"),
				Contains("one"),
			)

		t.Views().Main().
			Content(
				Contains("-content2").
					Contains("+content4"),
			)
	},
})
View Source
var PullRebaseInteractiveConflictDrop = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Pull with an interactive rebase strategy, where a conflict occurs. Also drop a commit while rebasing",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.CreateFileAndAdd("file", "content1")
		shell.Commit("one")
		shell.UpdateFileAndAdd("file", "content2")
		shell.Commit("two")
		shell.CreateFileAndAdd("file3", "content3")
		shell.Commit("three")

		shell.CloneIntoRemote("origin")

		shell.SetBranchUpstream("master", "origin/master")

		shell.HardReset("HEAD^^")
		shell.UpdateFileAndAdd("file", "content4")
		shell.Commit("four")
		shell.CreateFileAndAdd("fil5", "content5")
		shell.Commit("five")

		shell.SetConfig("pull.rebase", "interactive")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("five"),
				Contains("four"),
				Contains("one"),
			)

		t.Views().Status().Content(Equals("↓2↑2 repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Pull)

		t.Common().AcknowledgeConflicts()

		t.Views().Commits().
			Focus().
			Lines(
				Contains("─── Pending rebase todos"),
				Contains("pick").Contains("five"),
				Contains("pick").Contains("CONFLICT").Contains("four").IsSelected(),
				Contains("─── Commits"),
				Contains("three"),
				Contains("two"),
				Contains("one"),
			).
			NavigateToLine(Contains("five")).
			Press(keys.Universal.Remove).
			Lines(
				Contains("─── Pending rebase todos"),
				Contains("drop").Contains("five").IsSelected(),
				Contains("pick").Contains("CONFLICT").Contains("four"),
				Contains("─── Commits"),
				Contains("three"),
				Contains("two"),
				Contains("one"),
			)

		t.Views().Files().
			Focus().
			Lines(
				Contains("UU").Contains("file"),
			).
			PressEnter()

		t.Views().MergeConflicts().
			IsFocused().
			TopLines(
				Contains("<<<<<<< HEAD"),
				Contains("content2"),
				Contains("======="),
				Contains("content4"),
				Contains(">>>>>>>"),
			).
			SelectNextItem().
			PressPrimaryAction()

		t.Common().ContinueOnConflictsResolved("rebase")

		t.Views().Status().Content(Equals("↑1 repo → master"))

		t.Views().Commits().
			Focus().
			Lines(
				Contains("four").IsSelected(),
				Contains("three"),
				Contains("two"),
				Contains("one"),
			)

		t.Views().Main().
			Content(
				Contains("-content2").
					Contains("+content4"),
			)
	},
})
View Source
var PullStackedBranches = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Pull a stack of branches that was rebased on the remote, updating the branches below the current one too",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		createStackRewrittenOnTheRemote(shell)
		shell.Checkout("branch3")
		shell.SetConfig("pull.rebase", "true")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Lines(
				Contains("branch3 ↓3↑3"),
				Contains("branch1 ↓1↑1"),
				Contains("branch2 ↓2↑2"),
				Contains("master"),
			)

		t.Views().Files().IsFocused().Press(keys.Universal.Pull)

		t.ExpectPopup().Menu().
			Title(Equals("Pull")).
			ContainsLines(
				Contains("  branch2 ↓2↑2"),
				Contains("  branch1 ↓1↑1"),
			).
			Select(Contains("Pull all these branches in addition to the current one")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("branch3 ✓"),
				Contains("branch1 ✓"),
				Contains("branch2 ✓"),
				Contains("master"),
			)

		t.Views().Commits().
			Lines(
				Contains("three-rewritten"),
				Contains("two-rewritten"),
				Contains("one-rewritten"),
				Contains("base"),
			)
	},
})
View Source
var PullStackedBranchesCheckedOutInOtherWorktree = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Pull a stack that was rebased on the remote; a branch below the current one that is checked out in another worktree is not offered for updating",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		createStackRewrittenOnTheRemote(shell)
		shell.Checkout("branch3")
		shell.SetConfig("pull.rebase", "true")

		shell.AddWorktreeCheckout("branch1", "../linked-worktree")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Files().IsFocused().Press(keys.Universal.Pull)

		t.ExpectPopup().Menu().
			Title(Equals("Pull")).
			Lines(
				Contains("The following branches stacked below 'branch3' have also changed on the remote:"),
				Equals(""),
				Equals("  branch2 ↓2↑2"),
				Equals(""),
				Contains("Pull all these branches in addition to the current one"),
				Contains("Pull only 'branch3'"),
				Contains("Cancel"),
			).
			Select(Contains("Pull all these branches in addition to the current one")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("branch3 ✓"),
				Contains("branch1 (worktree linked-worktree) ↓1↑1"),
				Contains("branch2 ✓"),
				Contains("master"),
			)
	},
})
View Source
var PullStackedBranchesOnlyCurrent = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Decline updating the branches below the current one in a stack that was rebased on the remote, pulling only the current branch",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		createStackRewrittenOnTheRemote(shell)
		shell.Checkout("branch3")
		shell.SetConfig("pull.rebase", "true")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Files().IsFocused().Press(keys.Universal.Pull)

		t.ExpectPopup().Menu().
			Title(Equals("Pull")).
			Select(Contains("Pull only 'branch3'")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("branch3 ✓"),
				Contains("branch1 ↓1↑1"),
				Contains("branch2 ↓2↑2"),
				Contains("master"),
			)
	},
})
View Source
var PullStackedBranchesUpdateFails = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Pull a stack that was rebased on the remote, when updating the branches below the current one fails; the current branch is not pulled then",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		createStackRewrittenOnTheRemote(shell)
		shell.Checkout("branch3")
		shell.SetConfig("pull.rebase", "true")

		shell.RunCommand([]string{"git", "-C", "../origin", "branch", "-D", "branch1"})
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Files().IsFocused().Press(keys.Universal.Pull)

		t.ExpectPopup().Menu().
			Title(Equals("Pull")).
			Select(Contains("Pull all these branches in addition to the current one")).
			Confirm()

		t.ExpectPopup().Alert().
			Title(Equals("Error")).
			Content(Contains("couldn't find remote ref")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("branch3 ↓3↑3"),
				Contains("branch1 ↓1↑1"),
				Contains("branch2 ↓2↑2"),
				Contains("master"),
			)
	},
})
View Source
var PullStackedBranchesWithLocalCommits = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Pull a stack that was rebased on the remote; a branch below the current one that has a commit of its own is not offered for updating",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		createStackRewrittenOnTheRemote(shell)

		shell.Checkout("branch2")
		shell.EmptyCommit("mine")
		shell.Checkout("branch3")
		shell.RunCommand([]string{"git", "rebase", "--onto", "branch2", "branch2~1"})
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Lines(
				Contains("branch3 ↓3↑4"),
				Contains("branch1 ↓1↑1"),
				Contains("branch2 ↓2↑3"),
				Contains("master"),
			)

		t.Views().Files().IsFocused().Press(keys.Universal.Pull)

		t.ExpectPopup().Menu().
			Title(Equals("Pull")).
			Lines(
				Contains("The following branches stacked below 'branch3' have also changed on the remote:"),
				Equals(""),
				Equals("  branch1 ↓1↑1"),
				Equals(""),
				Contains("Pull all these branches in addition to the current one"),
				Contains("Pull only 'branch3'"),
				Contains("Cancel"),
			).
			Cancel()
	},
})
View Source
var Push = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push a commit to a pre-configured upstream",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
	},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")

		shell.CloneIntoRemote("origin")

		shell.SetBranchUpstream("master", "origin/master")

		shell.EmptyCommit("two")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Status().Content(Equals("↑1 repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Push)

		assertSuccessfullyPushed(t)
	},
})
View Source
var PushAndAutoSetUpstream = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push a commit and set the upstream automatically as configured by git",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
	},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")

		shell.CloneIntoRemote("origin")

		shell.EmptyCommit("two")

		shell.SetConfig("push.default", "current")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {

		t.Views().Status().Content(Equals("repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Push)

		assertSuccessfullyPushed(t)
	},
})
View Source
var PushAndSetUpstream = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push a commit and set the upstream via a prompt",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")

		shell.CloneIntoRemote("origin")

		shell.EmptyCommit("two")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {

		t.Views().Status().Content(Equals("repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Push)

		t.ExpectPopup().Prompt().
			Title(Equals("Enter upstream as '<remote> <branchname>'")).
			SuggestionLines(Equals("origin master")).
			ConfirmFirstSuggestion()

		assertSuccessfullyPushed(t)
	},
})
View Source
var PushFollowTags = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push with --follow-tags configured in git config",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
	},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")

		shell.CloneIntoRemote("origin")

		shell.SetBranchUpstream("master", "origin/master")

		shell.EmptyCommit("two")
		shell.CreateAnnotatedTag("mytag", "message", "HEAD")

		shell.SetConfig("push.followTags", "true")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Status().Content(Equals("↑1 repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Push)

		t.Views().Status().Content(Equals("✓ repo → master"))

		t.Views().Remotes().
			Focus().
			Lines(
				Contains("origin"),
			).
			PressEnter()

		t.Views().RemoteBranches().
			IsFocused().
			Lines(
				Contains("master"),
			).
			PressEnter()

		t.Views().SubCommits().
			IsFocused().
			Lines(
				Contains("two").Contains("mytag"),
				Contains("one"),
			)
	},
})
View Source
var PushNoFollowTags = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push with --follow-tags NOT configured in git config",
	ExtraCmdArgs: []string{},
	Skip:         true,
	SetupConfig: func(config *config.AppConfig) {
	},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")
		shell.EmptyCommit("two")

		shell.CloneIntoRemote("origin")

		shell.SetBranchUpstream("master", "origin/master")

		shell.CreateAnnotatedTag("mytag", "message", "HEAD")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Status().Content(Equals("✓ repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Push)

		t.Views().Status().Content(Equals("✓ repo → master"))

		t.Views().Remotes().
			Focus().
			Lines(
				Contains("origin"),
			).
			PressEnter()

		t.Views().RemoteBranches().
			IsFocused().
			Lines(
				Contains("master"),
			).
			PressEnter()

		t.Views().SubCommits().
			IsFocused().
			Lines(

				Contains("two").DoesNotContain("mytag"),
				Contains("one"),
			)
	},
})
View Source
var PushStackedBranches = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push a rebased stack of branches in one go, force-pushing all of them after a single confirmation",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		createRebasedStackOfBranches(shell)
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Lines(
				Contains("branch3 ↓3↑3"),
				Contains("branch1 ↓1↑1"),
				Contains("branch2 ↓2↑2"),
				Contains("local-only").DoesNotContain("↑"),
				Contains("master ✓"),
			)

		t.Views().Files().IsFocused().Press(keys.Universal.Push)

		t.ExpectPopup().Menu().
			Title(Equals("Push")).
			ContainsLines(
				Contains("  branch2 ↓2↑2"),
				Contains("  branch1 ↓1↑1"),
			).
			Select(Contains("Push all these branches in addition to the current one")).
			Confirm()

		t.ExpectPopup().Confirmation().
			Title(Equals("Force push")).
			Content(Contains("The following branches have diverged from their remote branches:").
				Contains("branch3").Contains("branch2").Contains("branch1")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("branch3 ✓"),
				Contains("branch1 ✓"),
				Contains("branch2 ✓"),
				Contains("local-only").DoesNotContain("✓"),
				Contains("master ✓"),
			)

		t.Views().Remotes().
			Focus().
			Lines(
				Contains("origin"),
			).
			PressEnter()

		t.Views().RemoteBranches().
			IsFocused().
			NavigateToLine(Contains("branch1")).
			PressEnter()

		t.Views().SubCommits().
			IsFocused().
			Lines(
				Contains("one-rebased"),
				Contains("base"),
			)
	},
})
View Source
var PushStackedBranchesCurrentWithoutUpstream = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push a rebased stack of branches whose topmost branch has no upstream yet; the prompt for its upstream comes before the force-push confirmation",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		createRebasedStackOfBranches(shell)
		shell.NewBranch("branch4")
		shell.EmptyCommit("four")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Files().IsFocused().Press(keys.Universal.Push)

		t.ExpectPopup().Menu().
			Title(Equals("Push")).
			ContainsLines(
				Contains("  branch3 ↓3↑3"),
				Contains("  branch2 ↓2↑2"),
				Contains("  branch1 ↓1↑1"),
			).
			Select(Contains("Push all these branches in addition to the current one")).
			Confirm()

		t.ExpectPopup().Prompt().
			Title(Equals("Enter upstream as '<remote> <branchname>'")).
			InitialText(Equals("origin branch4")).
			Confirm()

		t.ExpectPopup().Confirmation().
			Title(Equals("Force push")).
			Content(Contains("The following branches have diverged from their remote branches:").
				Contains("branch3").Contains("branch2").Contains("branch1").DoesNotContain("branch4")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("branch4 ✓"),
				Contains("branch1 ✓"),
				Contains("branch2 ✓"),
				Contains("branch3 ✓"),
				Contains("local-only"),
				Contains("master ✓"),
			)
	},
})
View Source
var PushStackedBranchesNoForce = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push a stack of branches that are only ahead of their remote branches, without being asked to force push",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("base")
		shell.NewBranch("branch1")
		shell.NewBranch("branch2")
		shell.NewBranch("branch3")

		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")
		shell.SetBranchUpstream("branch1", "origin/branch1")
		shell.SetBranchUpstream("branch2", "origin/branch2")
		shell.SetBranchUpstream("branch3", "origin/branch3")

		shell.Checkout("branch1")
		shell.EmptyCommit("one")
		shell.Checkout("branch2")
		shell.HardReset("branch1")
		shell.EmptyCommit("two")
		shell.Checkout("branch3")
		shell.HardReset("branch2")
		shell.EmptyCommit("three")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Branches().
			Lines(
				Contains("branch3 ↑3"),
				Contains("branch1 ↑1"),
				Contains("branch2 ↑2"),
				Contains("master ✓"),
			)

		t.Views().Files().IsFocused().Press(keys.Universal.Push)

		t.ExpectPopup().Menu().
			Title(Equals("Push")).
			ContainsLines(
				Contains("  branch2 ↑2"),
				Contains("  branch1 ↑1"),
			).
			Select(Contains("Push all these branches in addition to the current one")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("branch3 ✓"),
				Contains("branch1 ✓"),
				Contains("branch2 ✓"),
				Contains("master ✓"),
			)
	},
})
View Source
var PushStackedBranchesOnlyCurrent = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Decline pushing the branches below the current one in a rebased stack, pushing only the current branch",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical"
	},
	SetupRepo: func(shell *Shell) {
		createRebasedStackOfBranches(shell)
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Files().IsFocused().Press(keys.Universal.Push)

		t.ExpectPopup().Menu().
			Title(Equals("Push")).
			Select(Contains("Push only 'branch3'")).
			Confirm()

		t.ExpectPopup().Confirmation().
			Title(Equals("Force push")).
			Content(Equals("Your branch has diverged from the remote branch. Press <esc> to cancel, or <enter> to force push.")).
			Confirm()

		t.Views().Branches().
			Lines(
				Contains("branch3 ✓"),
				Contains("branch1 ↓1↑1"),
				Contains("branch2 ↓2↑2"),
				Contains("local-only"),
				Contains("master ✓"),
			)
	},
})
View Source
var PushTag = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push a specific tag",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
	},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")
		shell.EmptyCommit("two")

		shell.CloneIntoRemote("origin")

		shell.CreateAnnotatedTag("mytag", "message", "HEAD")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Tags().
			Focus().
			Lines(
				Contains("mytag"),
			).
			Press(keys.Branches.PushTag)

		t.ExpectPopup().Prompt().
			Title(Equals("Remote to push tag 'mytag' to:")).
			InitialText(Equals("origin")).
			SuggestionLines(
				Contains("origin"),
			).
			Confirm()

		t.Views().Remotes().
			Focus().
			Lines(
				Contains("origin"),
			).
			PressEnter()

		t.Views().RemoteBranches().
			IsFocused().
			Lines(
				Contains("master"),
			).
			PressEnter()

		t.Views().SubCommits().
			IsFocused().
			Lines(
				Contains("two").Contains("mytag"),
				Contains("one"),
			)
	},
})
View Source
var PushWithCredentialPrompt = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Push a commit to a pre-configured upstream, where credentials are required",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
	},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")

		shell.CloneIntoRemote("origin")

		shell.SetBranchUpstream("master", "origin/master")

		shell.EmptyCommit("two")

		shell.CopyHelpFile("pre-push", ".git/hooks/pre-push")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Status().Content(Equals("↑1 repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Push)

		t.ExpectPopup().Prompt().
			Title(Equals("Username")).
			Type("username").
			Confirm()

		t.ExpectPopup().Prompt().
			Title(Equals("Password")).
			Type("incorrect password").
			Confirm()

		t.ExpectPopup().Alert().
			Title(Equals("Error")).
			Content(Contains("incorrect username/password")).
			Confirm()

		t.Views().Status().Content(Equals("↑1 repo → master"))

		t.Views().Files().
			IsFocused().
			Press(keys.Universal.Push)

		t.ExpectPopup().Prompt().
			Title(Equals("Username")).
			Type("username").
			Confirm()

		t.ExpectPopup().Prompt().
			Title(Equals("Password")).
			Type("password").
			Confirm()

		t.Views().Status().Content(Equals("✓ repo → master"))

		assertSuccessfullyPushed(t)
	},
})
View Source
var RenameBranchAndPull = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Rename a branch to no longer match its upstream, then pull from the upstream",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig:  func(config *config.AppConfig) {},
	SetupRepo: func(shell *Shell) {
		shell.EmptyCommit("one")
		shell.EmptyCommit("two")

		shell.CloneIntoRemote("origin")
		shell.SetBranchUpstream("master", "origin/master")

		shell.HardReset("HEAD^")
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		t.Views().Commits().
			Lines(
				Contains("one"),
			)

		t.Views().Branches().
			Focus().
			Lines(
				Contains("master"),
			).
			Press(keys.Branches.RenameBranch).
			Tap(func() {
				t.ExpectPopup().Confirmation().
					Title(Equals("Rename branch")).
					Content(Equals("This branch is tracking a remote. This action will only rename the local branch name, not the name of the remote branch. Continue?")).
					Confirm()

				t.ExpectPopup().Prompt().
					Title(Contains("Enter new branch name")).
					InitialText(Equals("master")).
					Type("-local").
					Confirm()
			}).
			Press(keys.Universal.Pull)

		t.Views().Commits().
			Lines(
				Contains("two"),
				Contains("one"),
			)
	},
})

Functions

This section is empty.

Types

This section is empty.

Source Files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL