diff options
author | Russell Belfer <rb@github.com> | 2014-03-24 11:25:59 -0700 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2014-04-01 09:45:20 -0700 |
commit | e402d2f134ff6ac76726bedd37ac4f1c0aa5e9ab (patch) | |
tree | fa50df127e8d9cfa5a81f45758b913b8b5e5d4cc /src | |
parent | 8286300a1e2d24dfe184316c0f9798f2c69d0ef4 (diff) | |
download | libgit2-e402d2f134ff6ac76726bedd37ac4f1c0aa5e9ab.tar.gz |
Submodule sync refactoring
Turns out there was already a helper to do what I wanted to do,
so I just made it so that I could use it for sync and switched to
that instead.
Diffstat (limited to 'src')
-rw-r--r-- | src/path.h | 8 | ||||
-rw-r--r-- | src/submodule.c | 88 |
2 files changed, 49 insertions, 47 deletions
diff --git a/src/path.h b/src/path.h index f26175d15..2367d707b 100644 --- a/src/path.h +++ b/src/path.h @@ -119,6 +119,14 @@ GIT_INLINE(void) git_path_mkposix(char *path) # define git_path_mkposix(p) /* blank */ #endif +/** + * Check if string is a relative path (i.e. starts with "./" or "../") + */ +GIT_INLINE(int) git_path_is_relative(const char *p) +{ + return (p[0] == '.' && (p[1] == '/' || (p[1] == '.' && p[2] == '/'))); +} + extern int git__percent_decode(git_buf *decoded_out, const char *input); /** diff --git a/src/submodule.c b/src/submodule.c index dc0ea435e..69791ef58 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -79,6 +79,7 @@ __KHASH_IMPL( static int load_submodule_config(git_repository *repo, bool reload); static git_config_backend *open_gitmodules(git_repository *, bool, const git_oid *); +static int lookup_head_remote_key(git_buf *key, git_repository *repo); static int lookup_head_remote(git_buf *url, git_repository *repo); static int submodule_get(git_submodule **, git_repository *, const char *, const char *); static int submodule_load_from_config(const git_config_entry *, void *); @@ -271,8 +272,7 @@ int git_submodule_add_setup( } /* resolve parameters */ - error = git_submodule_resolve_url(&real_url, repo, url); - if (error) + if ((error = git_submodule_resolve_url(&real_url, repo, url)) < 0) goto cleanup; /* validate and normalize path */ @@ -576,7 +576,7 @@ int git_submodule_resolve_url(git_buf *out, git_repository *repo, const char *ur assert(url); - if (url[0] == '.' && (url[1] == '/' || (url[1] == '.' && url[2] == '/'))) { + if (git_path_is_relative(url)) { if (!(error = lookup_head_remote(out, repo))) error = git_path_apply_relative(out, url); } else if (strchr(url, ':') != NULL || url[0] == '/') { @@ -762,6 +762,7 @@ int git_submodule_sync(git_submodule *sm) int error = 0; git_config *cfg = NULL; git_buf key = GIT_BUF_INIT; + git_repository *smrepo = NULL; if (!sm->url) { giterr_set(GITERR_SUBMODULE, @@ -777,37 +778,17 @@ int git_submodule_sync(git_submodule *sm) /* if submodule exists in the working directory, update remote url */ - if (!error && (sm->flags & GIT_SUBMODULE_STATUS_IN_WD) != 0) { - git_repository *smrepo = NULL; - git_reference *smhead = NULL; - const char *remote = "origin"; - - if ((error = git_submodule_open(&smrepo, sm)) < 0 || - (error = git_repository_head(&smhead, smrepo)) < 0 || - (error = git_repository_config__weakptr(&cfg, smrepo)) < 0) - goto smcleanup; - - /* get remote for default branch and set remote.<name>.url */ - - if (git_reference_type(smhead) == GIT_REF_SYMBOLIC) { - const char *bname = git_reference_shorthand(smhead); - const git_config_entry *ce; - - git_buf_clear(&key); - if ((error = git_buf_printf(&key, "branch.%s.remote", bname)) < 0 || - (error = git_config__lookup_entry(&ce, cfg, key.ptr, 0)) < 0) - goto smcleanup; - - if (ce && ce->value) - remote = ce->value; + if (!error && + (sm->flags & GIT_SUBMODULE_STATUS_IN_WD) != 0 && + !(error = git_submodule_open(&smrepo, sm))) + { + if ((error = lookup_head_remote_key(&key, smrepo)) < 0) { + giterr_clear(); + git_buf_sets(&key, "branch.origin.remote"); } - git_buf_clear(&key); - if (!(error = git_buf_printf(&key, "remote.%s.url", remote))) - error = git_config__update_entry(cfg, key.ptr, sm->url, true, true); + error = git_config__update_entry(cfg, key.ptr, sm->url, true, true); -smcleanup: - git_reference_free(smhead); git_repository_free(smrepo); } @@ -1633,27 +1614,27 @@ cleanup: return error; } -static int lookup_head_remote(git_buf *url, git_repository *repo) +static int lookup_head_remote_key(git_buf *key, git_repository *repo) { int error; git_config *cfg; git_reference *head = NULL, *remote = NULL; const char *tgt, *scan; - git_buf key = GIT_BUF_INIT; /* 1. resolve HEAD -> refs/heads/BRANCH * 2. lookup config branch.BRANCH.remote -> ORIGIN - * 3. lookup remote.ORIGIN.url + * 3. return remote.ORIGIN.url */ + git_buf_clear(key); + if ((error = git_repository_config__weakptr(&cfg, repo)) < 0) return error; if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0) { giterr_set(GITERR_SUBMODULE, "Cannot resolve relative URL when HEAD cannot be resolved"); - error = GIT_ENOTFOUND; - goto cleanup; + return GIT_ENOTFOUND; } if (git_reference_type(head) != GIT_REF_SYMBOLIC) { @@ -1669,7 +1650,8 @@ static int lookup_head_remote(git_buf *url, git_repository *repo) /* remote should refer to something like refs/remotes/ORIGIN/BRANCH */ if (git_reference_type(remote) != GIT_REF_SYMBOLIC || - git__prefixcmp(git_reference_symbolic_target(remote), GIT_REFS_REMOTES_DIR) != 0) + git__prefixcmp( + git_reference_symbolic_target(remote), GIT_REFS_REMOTES_DIR) != 0) { giterr_set(GITERR_SUBMODULE, "Cannot resolve relative URL when HEAD is not symbolic"); @@ -1677,27 +1659,39 @@ static int lookup_head_remote(git_buf *url, git_repository *repo) goto cleanup; } - scan = tgt = git_reference_symbolic_target(remote) + strlen(GIT_REFS_REMOTES_DIR); + scan = tgt = git_reference_symbolic_target(remote) + + strlen(GIT_REFS_REMOTES_DIR); while (*scan && (*scan != '/' || (scan > tgt && scan[-1] != '\\'))) scan++; /* find non-escaped slash to end ORIGIN name */ - error = git_buf_printf(&key, "remote.%.*s.url", (int)(scan - tgt), tgt); - if (error < 0) - goto cleanup; - - if ((error = git_config_get_string(&tgt, cfg, key.ptr)) < 0) - goto cleanup; - - error = git_buf_sets(url, tgt); + error = git_buf_printf(key, "remote.%.*s.url", (int)(scan - tgt), tgt); cleanup: - git_buf_free(&key); + if (error < 0) + git_buf_clear(key); + git_reference_free(head); git_reference_free(remote); return error; } +static int lookup_head_remote(git_buf *url, git_repository *repo) +{ + int error; + git_config *cfg; + const char *tgt; + git_buf key = GIT_BUF_INIT; + + if (!(error = lookup_head_remote_key(&key, repo)) && + !(error = git_repository_config__weakptr(&cfg, repo)) && + !(error = git_config_get_string(&tgt, cfg, key.ptr))) + error = git_buf_sets(url, tgt); + + git_buf_free(&key); + return error; +} + static void submodule_get_index_status(unsigned int *status, git_submodule *sm) { const git_oid *head_oid = git_submodule_head_id(sm); |