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
This commit is contained in:
Yu Qi Zhang 2016-06-23 16:11:50 +00:00 committed by Atomic Bot
parent fc4a7ec35e
commit 02a2b689dd
6 changed files with 99 additions and 28 deletions

View File

@ -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

View File

@ -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;
*/

View File

@ -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,

View File

@ -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,

View File

@ -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;
}

View File

@ -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"