Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions cmd/git-sync/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,18 @@ func setRepoReady() {
repoReady = true
}

// cleanupWorkTree() is used to remove a worktree and its folder
func cleanupWorkTree(ctx context.Context, gitRoot, worktree string) error {
// Clean up worktree(s)
log.V(1).Info("removing worktree", "path", worktree)
if err := os.RemoveAll(worktree); err != nil {
return fmt.Errorf("error removing directory: %v", err)
} else if _, err := runCommand(ctx, gitRoot, *flGitCmd, "worktree", "prune"); err != nil {
return err
}
return nil
}

// addWorktreeAndSwap creates a new worktree and calls updateSymlink to swap the symlink to point to the new worktree
func addWorktreeAndSwap(ctx context.Context, gitRoot, dest, branch, rev string, depth int, hash string, submoduleMode string) error {
log.V(0).Info("syncing git", "rev", rev, "hash", hash)
Expand All @@ -695,6 +707,17 @@ func addWorktreeAndSwap(ctx context.Context, gitRoot, dest, branch, rev string,

// Make a worktree for this exact git hash.
worktreePath := filepath.Join(gitRoot, hash)

// Avoid wedge cases where the worktree was created but this function error'd without cleaning the worktree.
// Next timearound, the sync loop fails to create the worktree and bails out.
// Error observed:
// " Run(git worktree add /repo/root/rev-nnnn origin/develop):
// exit status 128: { stdout: \"Preparing worktree (detached HEAD nnnn)\\n\", stderr: \"fatal: '/repo/root/rev-nnnn' already exists\\n\" }"
//. "
if err := cleanupWorkTree(ctx, gitRoot, worktreePath); err != nil {
return err
}

_, err := runCommand(ctx, gitRoot, *flGitCmd, "worktree", "add", worktreePath, "origin/"+branch, "--no-checkout")
log.V(0).Info("adding worktree", "path", worktreePath, "branch", fmt.Sprintf("origin/%s", branch))
if err != nil {
Expand Down Expand Up @@ -808,12 +831,7 @@ func addWorktreeAndSwap(ctx context.Context, gitRoot, dest, branch, rev string,
// Clean up previous worktree(s).
var cleanupErr error
if oldWorktree != "" {
log.V(1).Info("removing old worktree", "path", oldWorktree)
if err := os.RemoveAll(oldWorktree); err != nil {
cleanupErr = fmt.Errorf("error removing directory: %v", err)
} else if _, err := runCommand(ctx, gitRoot, *flGitCmd, "worktree", "prune"); err != nil {
cleanupErr = err
}
cleanupErr = cleanupWorkTree(ctx, gitRoot, oldWorktree)
}

if cleanupErr != nil {
Expand Down
35 changes: 35 additions & 0 deletions test_e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,41 @@ assert_file_eq "$ROOT"/link/file "$TESTCASE 1"
# Wrap up
pass

##############################################
# Test worktree-cleanup
##############################################
testcase "worktree-cleanup"

echo "$TESTCASE" > "$REPO"/file
git -C "$REPO" commit -qam "$TESTCASE"
GIT_SYNC \
--wait=10 \
--repo="file://$REPO" \
--branch=e2e-branch \
--rev=HEAD \
--root="$ROOT" \
--dest="link" \
> "$DIR"/log."$TESTCASE" 2>&1 &

# wait for first sync
sleep 4
assert_link_exists "$ROOT"/link
assert_file_exists "$ROOT"/link/file
assert_file_eq "$ROOT"/link/file "$TESTCASE"

# second commit
echo "$TESTCASE-ok" > "$REPO"/file2
git -C "$REPO" add file2
git -C "$REPO" commit -qam "$TESTCASE new file"
REV=$(git -C "$REPO" rev-list -n1 HEAD)
git -C "$REPO" worktree add -q "$ROOT"/"$REV" -b e2e --no-checkout
sleep 10

assert_file_exists "$ROOT"/link/file2
assert_file_eq "$ROOT"/link/file2 "$TESTCASE-ok"
# Wrap up
pass

##############################################
# Test readlink
##############################################
Expand Down