commit 9f142382a5e0fa55e6d614fdb1edc3822d3b80ba from: Stefan Sperling date: Sat Mar 21 22:06:00 2020 UTC properly lock references when 'got fetch' needs to update them commit - 0e4002cadf11b9274c4355850d55bd59bbc20d31 commit + 9f142382a5e0fa55e6d614fdb1edc3822d3b80ba blob - 4f87cf680b2db1a9e42d32ba9fff5ce4869f50f8 blob + cd12b5ed30dbe248b20f407ac20e93f91e120177 --- got/got.c +++ 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_obje 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) blob - c0ccfc9a9acb2eed45a59f61406b247bce4ce4ad blob + ff1f037375b654994fbb0552899cb13e8766cdbb --- lib/reference.c +++ lib/reference.c @@ -173,8 +173,11 @@ parse_ref_file(struct got_reference **ref, const char 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");