From 7775193d1a7f01ebf93a28b361b10be47d146563 Mon Sep 17 00:00:00 2001 From: Timofey Kirillov Date: Fri, 24 Jun 2022 11:06:47 +0300 Subject: [PATCH] fix(git-worktree): ignore existing locked service worktree when re-adding * Use git worktree add with double `--force` argument. From git docs: > To add a missing but locked working tree path, specify --force twice. * Added test for locked worktree case. Signed-off-by: Timofey Kirillov --- pkg/true_git/git_cmd_test.go | 6 +++ pkg/true_git/service_branch_test.go | 7 +++ pkg/true_git/work_tree.go | 2 +- pkg/true_git/work_tree_test.go | 73 +++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/pkg/true_git/git_cmd_test.go b/pkg/true_git/git_cmd_test.go index 8e0f6ad771..dff5b4358e 100644 --- a/pkg/true_git/git_cmd_test.go +++ b/pkg/true_git/git_cmd_test.go @@ -25,6 +25,12 @@ var _ = Describe("Git command", func() { "init", ) + utils.RunSucceedCommand( + gitRepoPath, + "git", + "checkout", "-b", "main", + ) + utils.RunSucceedCommand( gitRepoPath, "git", diff --git a/pkg/true_git/service_branch_test.go b/pkg/true_git/service_branch_test.go index 2a24f18037..4119d9aa47 100644 --- a/pkg/true_git/service_branch_test.go +++ b/pkg/true_git/service_branch_test.go @@ -31,6 +31,13 @@ var _ = Describe("SyncSourceWorktreeWithServiceBranch", func() { "-c", "init.defaultBranch=main", "init", ) + + utils.RunSucceedCommand( + sourceWorkTreeDir, + "git", + "checkout", "-b", "main", + ) + gitDir = filepath.Join(sourceWorkTreeDir, ".git") utils.RunSucceedCommand( diff --git a/pkg/true_git/work_tree.go b/pkg/true_git/work_tree.go index 484c47661d..6033a26bb4 100644 --- a/pkg/true_git/work_tree.go +++ b/pkg/true_git/work_tree.go @@ -212,7 +212,7 @@ func switchWorkTree(ctx context.Context, repoDir, workTreeDir, commit string, wi _, err := os.Stat(workTreeDir) switch { case os.IsNotExist(err): - wtAddCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: repoDir}, "worktree", "add", "--force", "--detach", workTreeDir, commit) + wtAddCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: repoDir}, "worktree", "add", "--force", "--force", "--detach", workTreeDir, commit) if err = wtAddCmd.Run(ctx); err != nil { return fmt.Errorf("git worktree add command failed: %w", err) } diff --git a/pkg/true_git/work_tree_test.go b/pkg/true_git/work_tree_test.go index ca7d60ab7f..752094f648 100644 --- a/pkg/true_git/work_tree_test.go +++ b/pkg/true_git/work_tree_test.go @@ -39,6 +39,59 @@ var _ = Describe("Work tree helpers", func() { }) }) + When("side worktree was previously added and locked", func() { + When("no submodules are used", func() { + var mainWtDir, sideWtDir string + + BeforeEach(func() { + mainWtDir = filepath.Join(SuiteData.TestDirPath, "main-wt") + sideWtDir = filepath.Join(SuiteData.TestDirPath, "side-wt") + + Expect(os.MkdirAll(mainWtDir, os.ModePerm)).To(Succeed()) + + utils.RunSucceedCommand( + mainWtDir, + "git", + "-c", "init.defaultBranch=main", + "init", + ) + + utils.RunSucceedCommand( + mainWtDir, + "git", + "checkout", "-b", "main", + ) + + utils.RunSucceedCommand( + mainWtDir, + "git", + "commit", "--allow-empty", "-m", "Initial commit", + ) + + utils.RunSucceedCommand( + mainWtDir, + "git", "worktree", "add", sideWtDir, + ) + + utils.RunSucceedCommand( + mainWtDir, + "git", "worktree", "lock", sideWtDir, + ) + + err := os.RemoveAll(sideWtDir) + Expect(err).To(Succeed()) + }) + + It("should replace worktree without errors", func() { + ctx := context.Background() + + commit := getHeadCommit(ctx, mainWtDir) + + Expect(switchWorkTree(ctx, mainWtDir, sideWtDir, commit, false)).To(Succeed()) + }) + }) + }) + Describe("verifyWorkTreeConsistency", func() { var mainWtDir, sideWtDir string BeforeEach(func() { @@ -54,6 +107,12 @@ var _ = Describe("Work tree helpers", func() { "init", ) + utils.RunSucceedCommand( + mainWtDir, + "git", + "checkout", "-b", "main", + ) + utils.RunSucceedCommand( mainWtDir, "git", @@ -84,3 +143,17 @@ var _ = Describe("Work tree helpers", func() { }) }) }) + +func getHeadCommit(ctx context.Context, repoDir string) string { + refs, err := ShowRef(ctx, repoDir) + Expect(err).To(Succeed()) + + for _, ref := range refs.Refs { + if ref.IsHEAD { + return ref.Commit + } + } + + Expect(fmt.Errorf("head commit not found")).NotTo(HaveOccurred()) + return "" +}