deduplicate code for constructing a worktree's base ref name
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
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;
}