Commit 3e84aa506d8f3160aa8cda77f97e27a463c778b0

Patrick Steinhardt 2017-04-05T13:47:09

repository: get worktree HEAD via `git_reference__read_head` The functions `git_repository_head_for_worktree` and `git_repository_detached_head_for_worktree` both implement their own logic to read the HEAD reference file. Use the new function `git_reference__read_head` instead to unify the code paths.

diff --git a/src/repository.c b/src/repository.c
index f14eaf9..7eb5bed 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -2069,38 +2069,21 @@ static int get_worktree_file_path(git_buf *out, git_repository *repo, const char
 	return git_buf_printf(out, "%s/worktrees/%s/%s", repo->commondir, worktree, file);
 }
 
-static int read_worktree_head(git_buf *out, git_repository *repo, const char *name)
-{
-	git_buf path = GIT_BUF_INIT;
-	int err;
-
-	assert(out && repo && name);
-
-	if ((err = get_worktree_file_path(&path, repo, name, "HEAD")) < 0 ||
-	    (err = git_futils_readbuffer(out, path.ptr)) < 0)
-		goto out;
-	git_buf_rtrim(out);
-
-out:
-	git_buf_free(&path);
-
-	return err;
-}
-
 int git_repository_head_detached_for_worktree(git_repository *repo, const char *name)
 {
-	git_buf buf = GIT_BUF_INIT;
-	int ret;
+	git_reference *ref = NULL;
+	int error;
 
 	assert(repo && name);
 
-	if (read_worktree_head(&buf, repo, name) < 0)
-		return -1;
+	if ((error = git_repository_head_for_worktree(&ref, repo, name)) < 0)
+		goto out;
 
-	ret = git__strncmp(buf.ptr, GIT_SYMREF, strlen(GIT_SYMREF)) != 0;
-	git_buf_free(&buf);
+	error = (git_reference_type(ref) != GIT_REF_SYMBOLIC);
+out:
+	git_reference_free(ref);
 
-	return ret;
+	return error;
 }
 
 int git_repository_head(git_reference **head_out, git_repository *repo)
@@ -2124,44 +2107,34 @@ int git_repository_head(git_reference **head_out, git_repository *repo)
 
 int git_repository_head_for_worktree(git_reference **out, git_repository *repo, const char *name)
 {
-	git_buf buf = GIT_BUF_INIT;
-	git_reference *head;
-	int err;
+	git_buf path = GIT_BUF_INIT;
+	git_reference *head = NULL;
+	int error;
 
 	assert(out && repo && name);
 
 	*out = NULL;
 
-	if (git_repository_head_detached_for_worktree(repo, name))
-		return -1;
-	if ((err = read_worktree_head(&buf, repo, name)) < 0)
+	if ((error = get_worktree_file_path(&path, repo, name, GIT_HEAD_FILE)) < 0 ||
+	    (error = git_reference__read_head(&head, repo, path.ptr)) < 0)
 		goto out;
 
-	/* We can only resolve symbolic references */
-	if (git__strncmp(buf.ptr, GIT_SYMREF, strlen(GIT_SYMREF)))
-	{
-		err = -1;
-		goto out;
-	}
-	git_buf_consume(&buf, buf.ptr + strlen(GIT_SYMREF));
+	if (git_reference_type(head) != GIT_REF_OID) {
+		git_reference *resolved;
 
-	if ((err = git_reference_lookup(&head, repo, buf.ptr)) < 0)
-		goto out;
-	if (git_reference_type(head) == GIT_REF_OID)
-	{
-		*out = head;
-		err = 0;
-		goto out;
+		error = git_reference_lookup_resolved(&resolved, repo, git_reference_symbolic_target(head), -1);
+		git_reference_free(head);
+		head = resolved;
 	}
 
-	err = git_reference_lookup_resolved(
-		out, repo, git_reference_symbolic_target(head), -1);
-	git_reference_free(head);
+	*out = head;
 
 out:
-	git_buf_free(&buf);
+	if (error)
+		git_reference_free(head);
+	git_buf_clear(&path);
 
-	return err;
+	return error;
 }
 
 int git_repository_head_unborn(git_repository *repo)