Commit 698eae1392e0b9ec8d7f3e47b0a7206e8c5fc14d

Patrick Steinhardt 2019-02-14T12:52:25

worktree: error out early if given ref is not valid When adding a new worktree, we only verify that an optionally given reference is valid half-way through the function. At this point, some data structures have already been created on-disk. If we bail out due to an invalid reference, these will be left behind and need to be manually cleaned up by the user. Improve the situation by moving the reference checks to the function's preamble. Like this, we error out as early as possible and will not leave behind any files.

diff --git a/src/worktree.c b/src/worktree.c
index 174a107..fdaa905 100644
--- a/src/worktree.c
+++ b/src/worktree.c
@@ -290,6 +290,20 @@ int git_worktree_add(git_worktree **out, git_repository *repo,
 
 	*out = NULL;
 
+	if (wtopts.ref) {
+		if (!git_reference_is_branch(wtopts.ref)) {
+			git_error_set(GIT_ERROR_WORKTREE, "reference is not a branch");
+			err = -1;
+			goto out;
+		}
+
+		if (git_branch_is_checked_out(wtopts.ref)) {
+			git_error_set(GIT_ERROR_WORKTREE, "reference is already checked out");
+			err = -1;
+			goto out;
+		}
+	}
+
 	/* Create gitdir directory ".git/worktrees/<name>" */
 	if ((err = git_buf_joinpath(&gitdir, repo->commondir, "worktrees")) < 0)
 		goto out;
@@ -342,18 +356,6 @@ int git_worktree_add(git_worktree **out, git_repository *repo,
 
 	/* Set up worktree reference */
 	if (wtopts.ref) {
-		if (!git_reference_is_branch(wtopts.ref)) {
-			git_error_set(GIT_ERROR_WORKTREE, "reference is not a branch");
-			err = -1;
-			goto out;
-		}
-
-		if (git_branch_is_checked_out(wtopts.ref)) {
-			git_error_set(GIT_ERROR_WORKTREE, "reference is already checked out");
-			err = -1;
-			goto out;
-		}
-
 		if ((err = git_reference_dup(&ref, wtopts.ref)) < 0)
 			goto out;
 	} else {