Commit 517bab732f80f5ecc6af2ffcfe6fe1e363303c01

Stefan Sperling 2019-03-11T19:06:13

deduplicate code for constructing a worktree's base ref name

diff --git a/lib/got_lib_worktree.h b/lib/got_lib_worktree.h
index 44e57df..867714c 100644
--- a/lib/got_lib_worktree.h
+++ b/lib/got_lib_worktree.h
@@ -49,3 +49,6 @@ struct got_worktree {
 #define GOT_WORKTREE_INVALID_COMMIT_ID	GOT_SHA1_STRING_ZERO
 
 #define GOT_WORKTREE_BASE_REF_PREFIX "got/worktree-base"
+
+const struct got_error *got_worktree_get_base_ref_name(char **,
+    struct got_worktree *worktree);
diff --git a/lib/worktree.c b/lib/worktree.c
index 352980f..c80536c 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -1176,19 +1176,16 @@ diff_new(void *arg, struct got_tree_entry *te, const char *parent_path)
 	return err;
 }
 
-/*
- * Prevent Git's garbage collector from deleting our base commit by
- * setting a reference to our base commit's ID.
- */
-static const struct got_error *
-ref_base_commit(struct got_worktree *worktree, struct got_repository *repo)
+const struct got_error *
+got_worktree_get_base_ref_name(char **refname, struct got_worktree *worktree)
 {
 	const struct got_error *err = NULL;
-	struct got_reference *ref = NULL;
 	const char *root_path;
-	char *refname = NULL, *uuidstr = NULL, *s;
+	char *uuidstr = NULL, *s;
 	uint32_t uuid_status;
 
+	*refname = NULL;
+
 	uuid_to_string(&worktree->uuid, &uuidstr, &uuid_status);
 	if (uuid_status != uuid_s_ok)
 		return got_error_uuid(uuid_status);
@@ -1196,19 +1193,38 @@ ref_base_commit(struct got_worktree *worktree, struct got_repository *repo)
 	root_path = got_worktree_get_root_path(worktree);
 	while (root_path[0] == '/')
 		root_path++;
-	if (asprintf(&refname, "%s-%s-%s", GOT_WORKTREE_BASE_REF_PREFIX,
+	if (asprintf(refname, "%s-%s-%s", GOT_WORKTREE_BASE_REF_PREFIX,
 	    root_path, uuidstr) == -1) {
 		err = got_error_from_errno();
 		goto done;
 	}
 
 	/* Replace slashes from worktree's on-disk path with dashes. */
-	s = refname + sizeof(GOT_WORKTREE_BASE_REF_PREFIX) - 1;
+	s = *refname + sizeof(GOT_WORKTREE_BASE_REF_PREFIX) - 1;
 	while (*s) {
 		if (*s == '/')
 			*s = '-';
 		s++;
 	}
+done:
+	free(uuidstr);
+	return err;
+}
+
+/*
+ * Prevent Git's garbage collector from deleting our base commit by
+ * setting a reference to our base commit's ID.
+ */
+static const struct got_error *
+ref_base_commit(struct got_worktree *worktree, struct got_repository *repo)
+{
+	const struct got_error *err = NULL;
+	struct got_reference *ref = NULL;
+	char *refname;
+
+	err = got_worktree_get_base_ref_name(&refname, worktree);
+	if (err)
+		return err;
 
 	err = got_ref_alloc(&ref, refname, worktree->base_commit_id);
 	if (err)
@@ -1216,7 +1232,6 @@ ref_base_commit(struct got_worktree *worktree, struct got_repository *repo)
 
 	err = got_ref_write(ref, repo);
 done:
-	free(uuidstr);
 	free(refname);
 	if (ref)
 		got_ref_close(ref);
diff --git a/regress/worktree/worktree_test.c b/regress/worktree/worktree_test.c
index 7c5d377..bd0774b 100644
--- a/regress/worktree/worktree_test.c
+++ b/regress/worktree/worktree_test.c
@@ -88,30 +88,18 @@ remove_worktree_base_ref(struct got_worktree *worktree,
     struct got_repository *repo)
 {
 	const struct got_error *err = NULL;
-	const char *root_path;
-	struct got_reference *base_ref;
-	char *refname = NULL, *uuidstr = NULL, *s;
-	uint32_t uuid_status;
-
-	uuid_to_string(&worktree->uuid, &uuidstr, &uuid_status);
-	if (uuid_status != uuid_s_ok)
-		return got_error_uuid(uuid_status);
-	root_path = got_worktree_get_root_path(worktree);
-	while (*root_path == '/')
-		root_path++;
-	if (asprintf(&refname, "refs/%s-%s-%s", GOT_WORKTREE_BASE_REF_PREFIX,
-	    root_path, uuidstr) == -1)
-		return got_error_from_errno();
-
-	/* Replace slashes from worktree's on-disk path with dashes. */
-	s = refname + sizeof(GOT_WORKTREE_BASE_REF_PREFIX) - 1;
-	while (*s) {
-		if (*s == '/')
-			*s = '-';
-		s++;
-	}
+	struct got_reference *base_ref = NULL;
+	char *refname = NULL, *absrefname = NULL;
+
+	err = got_worktree_get_base_ref_name(&refname, worktree);
+	if (err)
+		return err;
 
-	err = got_ref_open(&base_ref, repo, refname);
+	if (asprintf(&absrefname, "refs/%s", refname) == -1) {
+		err = got_error_from_errno();
+		goto done;
+	}
+	err = got_ref_open(&base_ref, repo, absrefname);
 	if (err)
 		goto done;
 
@@ -119,8 +107,8 @@ remove_worktree_base_ref(struct got_worktree *worktree,
 done:
 	if (base_ref)
 		got_ref_close(base_ref);
-	free(uuidstr);
 	free(refname);
+	free(absrefname);
 	return err;
 
 }