properly lock references when 'got fetch' needs to update them
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
diff --git a/got/got.c b/got/got.c
index 4f87cf6..cd12b5e 100644
--- a/got/got.c
+++ b/got/got.c
@@ -1527,7 +1527,7 @@ static const struct got_error *
update_wanted_ref(const char *refname, struct got_object_id *id,
const char *remote_repo_name, int verbosity, struct got_repository *repo)
{
- const struct got_error *err;
+ const struct got_error *err, *unlock_err;
char *remote_refname;
struct got_reference *ref;
@@ -1538,13 +1538,16 @@ update_wanted_ref(const char *refname, struct got_object_id *id,
remote_repo_name, refname) == -1)
return got_error_from_errno("asprintf");
- err = got_ref_open(&ref, repo, remote_refname, 0);
+ err = got_ref_open(&ref, repo, remote_refname, 1);
if (err) {
if (err->code != GOT_ERR_NOT_REF)
goto done;
err = create_ref(remote_refname, id, verbosity, repo);
} else {
err = update_ref(ref, id, 0, verbosity, repo);
+ unlock_err = got_ref_unlock(ref);
+ if (unlock_err && err == NULL)
+ err = unlock_err;
got_ref_close(ref);
}
done:
@@ -1555,7 +1558,7 @@ done:
static const struct got_error *
cmd_fetch(int argc, char *argv[])
{
- const struct got_error *error = NULL;
+ const struct got_error *error = NULL, *unlock_err;
char *cwd = NULL, *repo_path = NULL;
const char *remote_name;
char *proto = NULL, *host = NULL, *port = NULL;
@@ -1790,7 +1793,7 @@ cmd_fetch(int argc, char *argv[])
if (remote->mirror_references ||
strncmp("refs/tags/", refname, 10) == 0) {
- error = got_ref_open(&ref, repo, refname, 0);
+ error = got_ref_open(&ref, repo, refname, 1);
if (error) {
if (error->code != GOT_ERR_NOT_REF)
goto done;
@@ -1801,6 +1804,9 @@ cmd_fetch(int argc, char *argv[])
} else {
error = update_ref(ref, id, replace_tags,
verbosity, repo);
+ unlock_err = got_ref_unlock(ref);
+ if (unlock_err && error == NULL)
+ error = unlock_err;
got_ref_close(ref);
if (error)
goto done;
@@ -1812,7 +1818,7 @@ cmd_fetch(int argc, char *argv[])
goto done;
}
- error = got_ref_open(&ref, repo, remote_refname, 0);
+ error = got_ref_open(&ref, repo, remote_refname, 1);
if (error) {
if (error->code != GOT_ERR_NOT_REF)
goto done;
@@ -1823,13 +1829,16 @@ cmd_fetch(int argc, char *argv[])
} else {
error = update_ref(ref, id, replace_tags,
verbosity, repo);
+ unlock_err = got_ref_unlock(ref);
+ if (unlock_err && error == NULL)
+ error = unlock_err;
got_ref_close(ref);
if (error)
goto done;
}
/* Also create a local branch if none exists yet. */
- error = got_ref_open(&ref, repo, refname, 0);
+ error = got_ref_open(&ref, repo, refname, 1);
if (error) {
if (error->code != GOT_ERR_NOT_REF)
goto done;
@@ -1837,8 +1846,12 @@ cmd_fetch(int argc, char *argv[])
repo);
if (error)
goto done;
- } else
+ } else {
+ unlock_err = got_ref_unlock(ref);
+ if (unlock_err && error == NULL)
+ error = unlock_err;
got_ref_close(ref);
+ }
}
}
if (delete_refs)
diff --git a/lib/reference.c b/lib/reference.c
index c0ccfc9..ff1f037 100644
--- a/lib/reference.c
+++ b/lib/reference.c
@@ -173,8 +173,11 @@ parse_ref_file(struct got_reference **ref, const char *name,
if (lock) {
err = got_lockfile_lock(&lf, abspath);
- if (err)
- return (err);
+ if (err) {
+ if (err->code == GOT_ERR_ERRNO && errno == ENOENT)
+ err = got_error(GOT_ERR_NOT_REF);
+ return err;
+ }
}
f = fopen(abspath, "rb");