From 02a2b689dda4fe69491d526a8e1f4f12f5a32bdf Mon Sep 17 00:00:00 2001 From: Yu Qi Zhang Date: Thu, 23 Jun 2016 16:11:50 +0000 Subject: [PATCH] refs: resolve conflict between local/remote repos Add the functionality to use the same name for refs in local and remote repos. This helps users keep track of local refs of remote origin, much like local and remote git branches. Previously, when a local ref is specified, resolve_refspec would fall back to searching through remote repos if the ref is not found locally. This function now takes an extra flag to specify whether it should search through remote repos. Additionally, ostree_repo_resove_rev_ext was added to call resolve_refspec with fallback_remote being false, so refs --create would no longer complain when trying to create a local ref of the same name as a remote one. Fix remote repo parsing not being handled correctly on refs --create. Closes: #363 Approved by: jlebon --- apidoc/ostree-sections.txt | 1 + src/libostree/libostree.sym | 5 +- src/libostree/ostree-repo-refs.c | 84 +++++++++++++++++++++++--------- src/libostree/ostree-repo.h | 16 ++++++ src/ostree/ot-builtin-refs.c | 9 +++- tests/test-refs.sh | 12 +++++ 6 files changed, 99 insertions(+), 28 deletions(-) diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt index 6dca9ecc..cc77f15a 100644 --- a/apidoc/ostree-sections.txt +++ b/apidoc/ostree-sections.txt @@ -300,6 +300,7 @@ ostree_repo_write_content_trusted ostree_repo_write_content_async ostree_repo_write_content_finish ostree_repo_resolve_rev +ostree_repo_resolve_rev_ext ostree_repo_list_refs ostree_repo_list_refs_ext ostree_repo_remote_list_refs diff --git a/src/libostree/libostree.sym b/src/libostree/libostree.sym index 087f9879..bdfa7c3f 100644 --- a/src/libostree/libostree.sym +++ b/src/libostree/libostree.sym @@ -346,10 +346,7 @@ global: * NOTE NOTE NOTE */ -/* Uncomment this when adding a new symbol */ -/* LIBOSTREE_2016.7 { global: - someostree_some_new_symbol; + ostree_repo_resolve_rev_ext; } LIBOSTREE_2016.6; -*/ diff --git a/src/libostree/ostree-repo-refs.c b/src/libostree/ostree-repo-refs.c index b18d838e..18308d0c 100644 --- a/src/libostree/ostree-repo-refs.c +++ b/src/libostree/ostree-repo-refs.c @@ -199,6 +199,7 @@ resolve_refspec (OstreeRepo *self, const char *remote, const char *ref, gboolean allow_noent, + gboolean fallback_remote, char **out_rev, GError **error); @@ -207,6 +208,7 @@ resolve_refspec_fallback (OstreeRepo *self, const char *remote, const char *ref, gboolean allow_noent, + gboolean fallback_remote, char **out_rev, GCancellable *cancellable, GError **error) @@ -216,8 +218,8 @@ resolve_refspec_fallback (OstreeRepo *self, if (self->parent_repo) { - if (!resolve_refspec (self->parent_repo, remote, ref, - allow_noent, &ret_rev, error)) + if (!resolve_refspec (self->parent_repo, remote, ref, allow_noent, + fallback_remote, &ret_rev, error)) goto out; } else if (!allow_noent) @@ -241,6 +243,7 @@ resolve_refspec (OstreeRepo *self, const char *remote, const char *ref, gboolean allow_noent, + gboolean fallback_remote, char **out_rev, GError **error) { @@ -270,7 +273,7 @@ resolve_refspec (OstreeRepo *self, if (!ot_openat_ignore_enoent (self->repo_dir_fd, local_ref, &target_fd, error)) goto out; - if (target_fd == -1) + if (target_fd == -1 && fallback_remote) { local_ref = glnx_strjoina ("refs/remotes/", ref); @@ -300,7 +303,7 @@ resolve_refspec (OstreeRepo *self, } else { - if (!resolve_refspec_fallback (self, remote, ref, allow_noent, + if (!resolve_refspec_fallback (self, remote, ref, allow_noent, fallback_remote, &ret_rev, cancellable, error)) goto out; } @@ -388,23 +391,13 @@ ostree_repo_resolve_partial_checksum (OstreeRepo *self, return ret; } -/** - * ostree_repo_resolve_rev: - * @self: Repo - * @refspec: A refspec - * @allow_noent: Do not throw an error if refspec does not exist - * @out_rev: (out) (transfer full): A checksum,or %NULL if @allow_noent is true and it does not exist - * @error: Error - * - * Look up the given refspec, returning the checksum it references in - * the parameter @out_rev. - */ -gboolean -ostree_repo_resolve_rev (OstreeRepo *self, - const char *refspec, - gboolean allow_noent, - char **out_rev, - GError **error) +static gboolean +_ostree_repo_resolve_rev_internal (OstreeRepo *self, + const char *refspec, + gboolean allow_noent, + gboolean fallback_remote, + char **out_rev, + GError **error) { gboolean ret = FALSE; g_autofree char *ret_rev = NULL; @@ -456,7 +449,7 @@ ostree_repo_resolve_rev (OstreeRepo *self, goto out; if (!resolve_refspec (self, remote, ref, allow_noent, - &ret_rev, error)) + fallback_remote, &ret_rev, error)) goto out; } } @@ -467,6 +460,53 @@ ostree_repo_resolve_rev (OstreeRepo *self, return ret; } +/** + * ostree_repo_resolve_rev: + * @self: Repo + * @refspec: A refspec + * @allow_noent: Do not throw an error if refspec does not exist + * @out_rev: (out) (transfer full): A checksum,or %NULL if @allow_noent is true and it does not exist + * @error: Error + * + * Look up the given refspec, returning the checksum it references in + * the parameter @out_rev. Will fall back on remote directory if cannot + * find the given refspec in local. + */ +gboolean +ostree_repo_resolve_rev (OstreeRepo *self, + const char *refspec, + gboolean allow_noent, + char **out_rev, + GError **error) +{ + return _ostree_repo_resolve_rev_internal (self, refspec, allow_noent, TRUE, out_rev, error); +} + +/** + * ostree_repo_resolve_rev_ext: + * @self: Repo + * @refspec: A refspec + * @allow_noent: Do not throw an error if refspec does not exist + * @flags: Options controlling behavior + * @out_rev: (out) (transfer full): A checksum,or %NULL if @allow_noent is true and it does not exist + * @error: Error + * + * Look up the given refspec, returning the checksum it references in + * the parameter @out_rev. Differently from ostree_repo_resolve_rev(), + * this will not fall back to searching through remote repos if a + * local ref is specified but not found. + */ +gboolean +ostree_repo_resolve_rev_ext (OstreeRepo *self, + const char *refspec, + gboolean allow_noent, + OstreeRepoResolveRevExtFlags flags, + char **out_rev, + GError **error) +{ + return _ostree_repo_resolve_rev_internal (self, refspec, allow_noent, FALSE, out_rev, error); +} + static gboolean enumerate_refs_recurse (OstreeRepo *repo, const char *remote, diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index c023b4d2..2f60e633 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -382,6 +382,22 @@ gboolean ostree_repo_resolve_rev (OstreeRepo *self, char **out_rev, GError **error); +/** + * OstreeRepoResolveRevExtFlags: + * @OSTREE_REPO_RESOLVE_REV_EXT_NONE: No flags. + */ +typedef enum { + OSTREE_REPO_RESOLVE_REV_EXT_NONE = 0, +} OstreeRepoResolveRevExtFlags; + +_OSTREE_PUBLIC +gboolean ostree_repo_resolve_rev_ext (OstreeRepo *self, + const char *refspec, + gboolean allow_noent, + OstreeRepoResolveRevExtFlags flags, + char **out_rev, + GError **error); + _OSTREE_PUBLIC gboolean ostree_repo_list_refs (OstreeRepo *self, const char *refspec_prefix, diff --git a/src/ostree/ot-builtin-refs.c b/src/ostree/ot-builtin-refs.c index fbdaf1bc..017b0c74 100644 --- a/src/ostree/ot-builtin-refs.c +++ b/src/ostree/ot-builtin-refs.c @@ -72,8 +72,10 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab { g_autofree char *checksum = NULL; g_autofree char *checksum_existing = NULL; + g_autofree char *remote = NULL; + g_autofree char *ref = NULL; - if (!ostree_repo_resolve_rev (repo, opt_create, TRUE, &checksum_existing, error)) + if (!ostree_repo_resolve_rev_ext (repo, opt_create, TRUE, OSTREE_REPO_RESOLVE_REV_EXT_NONE, &checksum_existing, error)) { if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY)) { @@ -94,7 +96,10 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab if (!ostree_repo_resolve_rev (repo, refspec_prefix, FALSE, &checksum, error)) goto out; - if (!ostree_repo_set_ref_immediate (repo, NULL, opt_create, checksum, + if (!ostree_parse_refspec (opt_create, &remote, &ref, error)) + goto out; + + if (!ostree_repo_set_ref_immediate (repo, remote, ref, checksum, cancellable, error)) goto out; } diff --git a/tests/test-refs.sh b/tests/test-refs.sh index 310b586f..ee7841bd 100755 --- a/tests/test-refs.sh +++ b/tests/test-refs.sh @@ -104,4 +104,16 @@ ${CMD_PREFIX} ostree --repo=repo refs ctest --create=foo ${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create4 assert_file_has_content refscount.create4 "^6$" +#Check if a name for a ref in remote repo can be used locally, and vice versa. +${CMD_PREFIX} ostree --repo=repo commit --branch=origin:remote1 +${CMD_PREFIX} ostree --repo=repo commit --branch=local1 +${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create5 +assert_file_has_content refscount.create5 "^8$" + +${CMD_PREFIX} ostree --repo=repo refs origin:remote1 --create=remote1 +${CMD_PREFIX} ostree --repo=repo refs origin:remote1 --create=origin/remote1 +${CMD_PREFIX} ostree --repo=repo refs local1 --create=origin:local1 +${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create6 +assert_file_has_content refscount.create6 "^11$" + echo "ok refs"