stop caching head ref's value in struct got_worktree; may become stale
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 146 147 148
diff --git a/got/got.c b/got/got.c
index 1b87fc9..c82e0bf 100644
--- a/got/got.c
+++ b/got/got.c
@@ -252,9 +252,10 @@ check_ancestry(struct got_worktree *worktree, struct got_object_id *commit_id,
struct got_object_id *head_commit_id = NULL;
struct got_commit_graph *graph = NULL;
- head_ref = got_worktree_get_head_ref(worktree);
- if (head_ref == NULL)
- return got_error_from_errno();
+ err = got_ref_open(&head_ref, repo,
+ got_worktree_get_head_ref_name(worktree));
+ if (err)
+ return err;
/* TODO: Check the reflog. The head ref may have been rebased. */
err = got_ref_resolve(&head_commit_id, repo, head_ref);
diff --git a/include/got_worktree.h b/include/got_worktree.h
index 6986c3a..0261d10 100644
--- a/include/got_worktree.h
+++ b/include/got_worktree.h
@@ -77,12 +77,6 @@ const struct got_error *got_worktree_match_path_prefix(int *,
const char *got_worktree_get_head_ref_name(struct got_worktree *);
/*
- * Get the work tree's HEAD reference.
- * The caller must dispose of it with free(3).
- */
-struct got_reference *got_worktree_get_head_ref(struct got_worktree *);
-
-/*
* Get the current base commit ID of a worktree.
*/
struct got_object_id *got_worktree_get_base_commit_id(struct got_worktree *);
diff --git a/lib/got_lib_worktree.h b/lib/got_lib_worktree.h
index 9bfa860..222d5b8 100644
--- a/lib/got_lib_worktree.h
+++ b/lib/got_lib_worktree.h
@@ -19,7 +19,7 @@ struct got_worktree {
char *repo_path;
char *path_prefix;
struct got_object_id *base_commit_id;
- struct got_reference *head_ref;
+ char *head_ref_name;
uuid_t uuid;
/*
diff --git a/lib/worktree.c b/lib/worktree.c
index a4c605a..5b2aa32 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -330,7 +330,6 @@ open_worktree(struct got_worktree **worktree, const char *path)
char *uuidstr = NULL;
char *path_lock = NULL;
char *base_commit_id_str = NULL;
- char *head_ref_str = NULL;
int version, fd = -1;
const char *errstr;
struct got_repository *repo = NULL;
@@ -416,17 +415,13 @@ open_worktree(struct got_worktree **worktree, const char *path)
if (err)
goto done;
- err = read_meta_file(&head_ref_str, path_got, GOT_WORKTREE_HEAD_REF);
- if (err)
- goto done;
-
- err = got_ref_open(&(*worktree)->head_ref, repo, head_ref_str);
+ err = read_meta_file(&(*worktree)->head_ref_name, path_got,
+ GOT_WORKTREE_HEAD_REF);
done:
if (repo)
got_repo_close(repo);
free(path_got);
free(path_lock);
- free(head_ref_str);
free(base_commit_id_str);
free(uuidstr);
free(formatstr);
@@ -469,8 +464,7 @@ got_worktree_close(struct got_worktree *worktree)
free(worktree->repo_path);
free(worktree->path_prefix);
free(worktree->base_commit_id);
- if (worktree->head_ref)
- got_ref_close(worktree->head_ref);
+ free(worktree->head_ref_name);
if (worktree->lockfd != -1)
if (close(worktree->lockfd) != 0)
err = got_error_from_errno();
@@ -515,13 +509,7 @@ got_worktree_match_path_prefix(int *match, struct got_worktree *worktree,
const char *
got_worktree_get_head_ref_name(struct got_worktree *worktree)
{
- return got_ref_get_name(worktree->head_ref);
-}
-
-struct got_reference *
-got_worktree_get_head_ref(struct got_worktree *worktree)
-{
- return got_ref_dup(worktree->head_ref);
+ return worktree->head_ref_name;
}
struct got_object_id *
@@ -2824,6 +2812,7 @@ got_worktree_commit(struct got_object_id **new_commit_id,
struct got_pathlist_entry *pe;
char *relpath = NULL;
const char *head_ref_name = NULL;
+ struct got_reference *head_ref = NULL;
struct got_commit_object *head_commit = NULL;
struct got_object_id *head_commit_id = NULL;
struct got_reference *head_ref2 = NULL;
@@ -2849,8 +2838,10 @@ got_worktree_commit(struct got_object_id **new_commit_id,
if (err)
goto done;
- /* XXX should re-read head ref here now that work tree is locked */
- err = got_ref_resolve(&head_commit_id, repo, worktree->head_ref);
+ err = got_ref_open(&head_ref, repo, worktree->head_ref_name);
+ if (err)
+ goto done;
+ err = got_ref_resolve(&head_commit_id, repo, head_ref);
if (err)
goto done;
@@ -2933,10 +2924,10 @@ got_worktree_commit(struct got_object_id **new_commit_id,
goto done;
}
/* Update branch head in repository. */
- err = got_ref_change_ref(worktree->head_ref, *new_commit_id);
+ err = got_ref_change_ref(head_ref, *new_commit_id);
if (err)
goto done;
- err = got_ref_write(worktree->head_ref, repo);
+ err = got_ref_write(head_ref, repo);
if (err)
goto done;
/* XXX race has ended here */
@@ -2969,6 +2960,8 @@ done:
free(relpath);
free(head_commit_id);
free(head_commit_id2);
+ if (head_ref)
+ got_ref_close(head_ref);
if (head_ref2)
got_ref_close(head_ref2);
return err;