static int filter_ref__cb(git_remote_head *head, void *payload) { struct filter_payload *p = payload; int error; if (!p->found_head && strcmp(head->name, GIT_HEAD_FILE) == 0) { p->found_head = 1; } else { /* If it doesn't match the refpec, we don't want it */ error = git_refspec_src_match(p->spec, head->name); if (error == GIT_ENOMATCH) return GIT_SUCCESS; if (error < GIT_SUCCESS) return git__rethrow(error, "Error matching remote ref name"); } /* If we have the object, mark it so we don't ask for it */ if (git_odb_exists(p->odb, &head->oid)) head->local = 1; else p->remote->need_pack = 1; return git_vector_insert(&p->remote->refs, head); }
static int filter_wants(git_remote *remote) { git_vector list; git_headarray refs; git_transport *t = remote->transport; git_repository *repo = remote->repo; const git_refspec *spec; int error; unsigned int i; error = git_vector_init(&list, 16, NULL); if (error < GIT_SUCCESS) return error; error = t->ls(t, &refs); if (error < GIT_SUCCESS) { error = git__rethrow(error, "Failed to get remote ref list"); goto cleanup; } spec = git_remote_fetchspec(remote); if (spec == NULL) { error = git__throw(GIT_ERROR, "The remote has no fetchspec"); goto cleanup; } for (i = 0; i < refs.len; ++i) { git_remote_head *head = refs.heads[i]; /* If it doesn't match the refpec, we don't want it */ error = git_refspec_src_match(spec, head->name); if (error == GIT_ENOMATCH) continue; if (error < GIT_SUCCESS) { error = git__rethrow(error, "Error matching remote ref name"); goto cleanup; } /* If we have the object, mark it so we don't ask for it */ if (git_odb_exists(repo->db, &head->oid)) head->local = 1; else remote->need_pack = 1; error = git_vector_insert(&list, head); if (error < GIT_SUCCESS) goto cleanup; } remote->refs.len = list.length; remote->refs.heads = (git_remote_head **) list.contents; return GIT_SUCCESS; cleanup: git_vector_free(&list); return error; }
void test_network_remotes__fnmatch(void) { cl_git_pass(git_refspec_src_match(refspec, "refs/heads/master")); cl_git_pass(git_refspec_src_match(refspec, "refs/heads/multi/level/branch")); }
DEFAPI(void) defGitRefspec(CTX ctx, kclass_t cid, kclassdef_t *cdef) { cdef->name = "GitRefspec"; cdef->init = kGitRefspec_init; cdef->free = kGitRefspec_free; } /* ------------------------------------------------------------------------ */ /* Match a refspec's source descriptor with a reference name */ //## @Native void GitRefspec.srcMatch(String refname); KMETHOD GitRefspec_srcMatch(CTX ctx, ksfp_t *sfp _RIX) { const git_refspec *refspec = RawPtr_to(const git_refspec *, sfp[0]); const char *refname = String_to(const char *, sfp[1]); int error = git_refspec_src_match(refspec, refname); if (error < GIT_SUCCESS) { TRACE_ERROR(ctx, "git_refspec_src_match", error); } RETURNvoid_(); } /* Transform a reference to its target following the refspec's rules */ //## @Native void GitRefspec.transform(Bytes out, String name); KMETHOD GitRefspec_transform(CTX ctx, ksfp_t *sfp _RIX) { const git_refspec *spec = RawPtr_to(const git_refspec *, sfp[0]); char *out = BA_tobytes(sfp[1].ba).buf; size_t outlen = BA_size(sfp[1].ba); const char *name = String_to(const char *, sfp[2]); int error = git_refspec_transform(out, outlen, spec, name);
git_config_free(cfg); git_repository_free(repo); END_TEST BEGIN_TEST(refspec1, "remote fnmatch works as expected") git_remote *remote; git_repository *repo; git_config *cfg; const git_refspec *refspec = NULL; must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); must_pass(git_repository_config(&cfg, repo, NULL, NULL)); must_pass(git_remote_get(&remote, cfg, "test")); refspec = git_remote_fetchspec(remote); must_be_true(refspec != NULL); must_pass(git_refspec_src_match(refspec, "refs/heads/master")); must_pass(git_refspec_src_match(refspec, "refs/heads/multi/level/branch")); git_remote_free(remote); git_config_free(cfg); git_repository_free(repo); END_TEST BEGIN_TEST(refspec2, "refspec transform") git_remote *remote; git_repository *repo; git_config *cfg; const git_refspec *refspec = NULL; char ref[1024] = {0}; must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); must_pass(git_repository_config(&cfg, repo, NULL, NULL));