static int filter_wants(git_remote *remote) { struct filter_payload p; git_refspec tagspec; int error = -1; git_vector_clear(&remote->refs); if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0) return error; /* * The fetch refspec can be NULL, and what this means is that the * user didn't specify one. This is fine, as it means that we're * not interested in any particular branch but just the remote's * HEAD, which will be stored in FETCH_HEAD after the fetch. */ p.tagspec = &tagspec; p.found_head = 0; p.remote = remote; if (git_repository_odb__weakptr(&p.odb, remote->repo) < 0) goto cleanup; error = git_remote_ls(remote, filter_ref__cb, &p); cleanup: git_refspec__free(&tagspec); return error; }
void test_online_fetch__ls_disconnected(void) { git_remote *remote; int nr_before = 0, nr_after = 0; cl_git_pass(git_remote_create(&remote, _repo, "test", "http://github.com/libgit2/TestGitRepository.git")); cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); cl_git_pass(git_remote_ls(remote, ls_cb, &nr_before)); git_remote_disconnect(remote); cl_git_pass(git_remote_ls(remote, ls_cb, &nr_after)); cl_assert_equal_i(nr_before, nr_after); git_remote_free(remote); }
static int use_remote(git_repository *repo, char *name) { git_remote *remote = NULL; int error; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; // Find the remote by name error = git_remote_load(&remote, repo, name); if (error < 0) { error = git_remote_create_inmemory(&remote, repo, NULL, name); if (error < 0) goto cleanup; } callbacks.credentials = cred_acquire_cb; git_remote_set_callbacks(remote, &callbacks); error = git_remote_connect(remote, GIT_DIRECTION_FETCH); if (error < 0) goto cleanup; error = git_remote_ls(remote, &show_ref__cb, NULL); cleanup: git_remote_free(remote); return error; }
void test_network_remotelocal__retrieve_advertised_references(void) { int how_many_refs = 0; cl_git_pass(git_remote_ls(remote, &count_ref__cb, &how_many_refs)); cl_assert(how_many_refs == 12); /* 1 HEAD + 9 refs + 2 peeled tags */ }
void test_online_fetch__ls_disconnected(void) { const git_remote_head **refs; size_t refs_len_before, refs_len_after; git_remote *remote; cl_git_pass(git_remote_create(&remote, _repo, "test", "http://github.com/libgit2/TestGitRepository.git")); cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); cl_git_pass(git_remote_ls(&refs, &refs_len_before, remote)); git_remote_disconnect(remote); cl_git_pass(git_remote_ls(&refs, &refs_len_after, remote)); cl_assert_equal_i(refs_len_before, refs_len_after); git_remote_free(remote); }
void test_network_remotelocal__retrieve_advertised_references(void) { int how_many_refs = 0; connect_to_local_repository(cl_fixture("testrepo.git")); cl_git_pass(git_remote_ls(remote, &count_ref__cb, &how_many_refs)); cl_assert(how_many_refs == 14); /* 1 HEAD + 6 heads + 1 lightweight tag + 3 annotated tags + 3 peeled target */ }
void test_network_remote_local__retrieve_advertised_before_connect(void) { const git_remote_head **refs; size_t refs_len = 0; git_buf_sets(&file_path_buf, cl_git_path_url(cl_fixture("testrepo.git"))); cl_git_pass(git_remote_create_anonymous(&remote, repo, git_buf_cstr(&file_path_buf))); cl_git_fail(git_remote_ls(&refs, &refs_len, remote)); }
void test_network_remotelocal__retrieve_advertised_references(void) { int how_many_refs = 0; connect_to_local_repository(cl_fixture("testrepo.git")); cl_git_pass(git_remote_ls(remote, &count_ref__cb, &how_many_refs)); cl_assert_equal_i(how_many_refs, 26); }
void test_network_remote_local__retrieve_advertised_references(void) { const git_remote_head **refs; size_t refs_len; connect_to_local_repository(cl_fixture("testrepo.git")); cl_git_pass(git_remote_ls(&refs, &refs_len, remote)); cl_assert_equal_i(refs_len, 28); }
void test_network_remote_local__nested_tags_are_completely_peeled(void) { const git_remote_head **refs; size_t refs_len, i; connect_to_local_repository(cl_fixture("testrepo.git")); cl_git_pass(git_remote_ls(&refs, &refs_len, remote)); for (i = 0; i < refs_len; i++) { if (!strcmp(refs[i]->name, "refs/tags/test^{}")) cl_git_pass(git_oid_streq(&refs[i]->oid, "e90810b8df3e80c413d903f631643c716887138d")); } }
void test_network_remote_defaultbranch__no_default_branch(void) { git_remote *remote_b; const git_remote_head **heads; size_t len; git_buf buf = GIT_BUF_INIT; cl_git_pass(git_remote_create(&remote_b, g_repo_b, "self", git_repository_path(g_repo_b))); cl_git_pass(git_remote_connect(remote_b, GIT_DIRECTION_FETCH)); cl_git_pass(git_remote_ls(&heads, &len, remote_b)); cl_assert_equal_i(0, len); cl_git_fail_with(GIT_ENOTFOUND, git_remote_default_branch(&buf, remote_b)); git_remote_free(remote_b); }
void test_online_fetch__remote_symrefs(void) { const git_remote_head **refs; size_t refs_len; git_remote *remote; cl_git_pass(git_remote_create(&remote, _repo, "test", "http://github.com/libgit2/TestGitRepository.git")); cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); git_remote_disconnect(remote); cl_git_pass(git_remote_ls(&refs, &refs_len, remote)); cl_assert_equal_s("HEAD", refs[0]->name); cl_assert_equal_s("refs/heads/master", refs[0]->symref_target); git_remote_free(remote); }
static int filter_wants(git_remote *remote) { git_remote_head **heads; git_refspec tagspec, head; int error = 0; git_odb *odb; size_t i, heads_len; git_vector_clear(&remote->refs); if ((error = git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true)) < 0) return error; /* * The fetch refspec can be NULL, and what this means is that the * user didn't specify one. This is fine, as it means that we're * not interested in any particular branch but just the remote's * HEAD, which will be stored in FETCH_HEAD after the fetch. */ if (remote->active_refspecs.length == 0) { if ((error = git_refspec__parse(&head, "HEAD", true)) < 0) goto cleanup; error = git_refspec__dwim_one(&remote->active_refspecs, &head, &remote->refs); git_refspec__free(&head); if (error < 0) goto cleanup; } if (git_repository_odb__weakptr(&odb, remote->repo) < 0) goto cleanup; if (git_remote_ls((const git_remote_head ***)&heads, &heads_len, remote) < 0) goto cleanup; for (i = 0; i < heads_len; i++) { if ((error = maybe_want(remote, heads[i], odb, &tagspec)) < 0) break; } cleanup: git_refspec__free(&tagspec); return error; }
void test_network_remotelocal__retrieve_advertised_references_from_spaced_repository(void) { int how_many_refs = 0; cl_fixture_sandbox("testrepo.git"); cl_git_pass(p_rename("testrepo.git", "spaced testrepo.git")); connect_to_local_repository("spaced testrepo.git"); cl_git_pass(git_remote_ls(remote, &count_ref__cb, &how_many_refs)); cl_assert(how_many_refs == 14); /* 1 HEAD + 6 heads + 1 lightweight tag + 3 annotated tags + 3 peeled target */ git_remote_free(remote); /* Disconnect from the "spaced repo" before the cleanup */ remote = NULL; cl_fixture_cleanup("spaced testrepo.git"); }
void test_network_remotelocal__retrieve_advertised_references_from_spaced_repository(void) { int how_many_refs = 0; cl_fixture_sandbox("testrepo.git"); cl_git_pass(p_rename("testrepo.git", "spaced testrepo.git")); connect_to_local_repository("spaced testrepo.git"); cl_git_pass(git_remote_ls(remote, &count_ref__cb, &how_many_refs)); cl_assert_equal_i(how_many_refs, 26); git_remote_free(remote); /* Disconnect from the "spaced repo" before the cleanup */ remote = NULL; cl_fixture_cleanup("spaced testrepo.git"); }
static int use_remote(git_repository *repo, char *name) { git_remote *remote = NULL; int error; const git_remote_head **refs; size_t refs_len, i; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; // Find the remote by name error = git_remote_lookup(&remote, repo, name); if (error < 0) { error = git_remote_create_anonymous(&remote, repo, name); if (error < 0) goto cleanup; } /** * Connect to the remote and call the printing function for * each of the remote references. */ callbacks.credentials = cred_acquire_cb; callbacks.certificate_check = certificate_check; error = git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks, NULL); if (error < 0) goto cleanup; /** * Get the list of references on the remote and print out * their name next to what they point to. */ if (git_remote_ls(&refs, &refs_len, remote) < 0) goto cleanup; for (i = 0; i < refs_len; i++) { char oid[GIT_OID_HEXSZ + 1] = {0}; git_oid_fmt(oid, &refs[i]->oid); printf("%s\t%s\n", oid, refs[i]->name); } cleanup: git_remote_free(remote); return error; }
void test_network_remote_local__retrieve_advertised_references_from_spaced_repository(void) { const git_remote_head **refs; size_t refs_len; cl_fixture_sandbox("testrepo.git"); cl_git_pass(p_rename("testrepo.git", "spaced testrepo.git")); connect_to_local_repository("spaced testrepo.git"); cl_git_pass(git_remote_ls(&refs, &refs_len, remote)); cl_assert_equal_i(refs_len, 28); git_remote_free(remote); /* Disconnect from the "spaced repo" before the cleanup */ remote = NULL; cl_fixture_cleanup("spaced testrepo.git"); }
/* * call-seq: * remote.ls(options = {}) -> an_enumerator * remote.ls(options = {}) { |remote_head_hash| block } * * Connects +remote+ to list all references available along with their * associated commit ids. * * The given block is called once for each remote head with a Hash containing the * following keys: * * :local? :: * +true+ if the remote head is available locally, +false+ otherwise. * * :oid :: * The id of the object the remote head is currently pointing to. * * :loid :: * The id of the object the local copy of the remote head is currently * pointing to. Set to +nil+ if there is no local copy of the remote head. * * :name :: * The fully qualified reference name of the remote head. * * If no block is given, an enumerator will be returned. * * The following options can be passed in the +options+ Hash: * * :credentials :: * The credentials to use for the ls operation. Can be either an instance of one * of the Rugged::Credentials types, or a proc returning one of the former. * The proc will be called with the +url+, the +username+ from the url (if applicable) and * a list of applicable credential types. * * :headers :: * Extra HTTP headers to include with the request (only applies to http:// or https:// remotes) */ static VALUE rb_git_remote_ls(int argc, VALUE *argv, VALUE self) { git_remote *remote; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; git_strarray custom_headers = {0}; const git_remote_head **heads; struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 }; VALUE rb_options; int error; size_t heads_len, i; Data_Get_Struct(self, git_remote, remote); rb_scan_args(argc, argv, ":", &rb_options); if (!rb_block_given_p()) return rb_funcall(self, rb_intern("to_enum"), 2, CSTR2SYM("ls"), rb_options); rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload); init_custom_headers(rb_options, &custom_headers); if ((error = git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks, NULL, &custom_headers)) || (error = git_remote_ls(&heads, &heads_len, remote))) goto cleanup; for (i = 0; i < heads_len && !payload.exception; i++) rb_protect(rb_yield, rugged_rhead_new(heads[i]), &payload.exception); cleanup: git_remote_disconnect(remote); git_strarray_free(&custom_headers); if (payload.exception) rb_jump_tag(payload.exception); rugged_exception_check(error); return Qnil; }
int use_remote(git_repository *repo, char *name) { git_remote *remote = NULL; int error; // Find the remote by name error = git_remote_load(&remote, repo, name); if (error < GIT_SUCCESS) goto cleanup; error = git_remote_connect(remote, GIT_DIR_FETCH); if (error < GIT_SUCCESS) goto cleanup; error = git_remote_ls(remote, &show_ref__cb, NULL); cleanup: git_remote_free(remote); return error; }
int use_unnamed(git_repository *repo, const char *url) { git_remote *remote = NULL; int error; // Create an instance of a remote from the URL. The transport to use // is detected from the URL error = git_remote_new(&remote, repo, url, NULL); if (error < GIT_SUCCESS) goto cleanup; // When connecting, the underlying code needs to know wether we // want to push or fetch error = git_remote_connect(remote, GIT_DIR_FETCH); if (error < GIT_SUCCESS) goto cleanup; // With git_remote_ls we can retrieve the advertised heads error = git_remote_ls(remote, &show_ref__cb, NULL); cleanup: git_remote_free(remote); return error; }
/** * Get the remote's url * * Based on https://github.com/libgit2/libgit2/blob/babdc376c7/examples/network/ls-remote.c * @param repo S4 class git_repository * @param name Character vector with URL of remote. * @return Character vector for each reference with the associated commit IDs. */ SEXP git2r_remote_ls(SEXP name, SEXP repo, SEXP credentials) { const char *name_ = NULL; SEXP result = R_NilValue; SEXP names = R_NilValue; git_remote *remote = NULL; int err; const git_remote_head **refs; size_t refs_len, i; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; git2r_transfer_data payload = GIT2R_TRANSFER_DATA_INIT; git_repository *repository = NULL; if (git2r_arg_check_string(name)) git2r_error(__func__, NULL, "'name'", git2r_err_string_arg); if (git2r_arg_check_credentials(credentials)) git2r_error(__func__, NULL, "'credentials'", git2r_err_credentials_arg); repository = git2r_repository_open(repo); if (!repository) git2r_error(__func__, NULL, git2r_err_invalid_repository, NULL); name_ = CHAR(STRING_ELT(name, 0)); err = git_remote_lookup(&remote, repository, name_); if (err) { err = git_remote_create_anonymous(&remote, repository, name_); if (err) goto cleanup; } payload.credentials = credentials; callbacks.payload = &payload; callbacks.credentials = &git2r_cred_acquire_cb; err = git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks, NULL, NULL); if (err) goto cleanup; err = git_remote_ls(&refs, &refs_len, remote); if (err) goto cleanup; PROTECT(result = allocVector(STRSXP, refs_len)); setAttrib(result, R_NamesSymbol, names = allocVector(STRSXP, refs_len)); for (i = 0; i < refs_len; i++) { char oid[GIT_OID_HEXSZ + 1] = {0}; git_oid_fmt(oid, &refs[i]->oid); SET_STRING_ELT(result, i, mkChar(oid)); SET_STRING_ELT(names, i, mkChar(refs[i]->name)); } cleanup: if (repository) git_repository_free(repository); if (result != R_NilValue) UNPROTECT(1); if (err) git2r_error(__func__, giterr_last(), NULL, NULL); return(result); }
int NotesModel::pull() { git_repository *repo = NULL; git_remote *remote = NULL; git_merge_head *merge_head = NULL; if (!QSettings().value("gitRemoteUrl").isValid()) { qDebug() << "gitRemoteUrl setting invalid"; return false; } if (QSettings().value("gitRemoteUrl") == "") return false; try { //Open Repo e(git_repository_open(&repo, notesFolder().absolutePath().toUtf8().constData())); //List repository and add one from Settings if none exists or doesn t have same URI than settings git_strarray remotes = {0}; git_remote_list(&remotes, repo); if (remotes.count >= 1) { for (size_t i = 0; i < remotes.count; i++) { e(git_remote_load(&remote, repo, remotes.strings[i])); qDebug() << git_remote_url(remote); if (QSettings().value("gitRemoteUrl").isValid() && git_remote_url(remote)) { if (strcmp(git_remote_url(remote),QSettings().value("gitRemoteUrl").toString().toUtf8().constData()) != 0) { e(git_remote_delete(remote)); e(git_remote_create(&remote, repo, "upstream", QSettings().value("gitRemoteUrl").toString().toUtf8().constData())); e(git_remote_save(remote)); } } } } else if (remotes.count == 0) { e(git_remote_create(&remote, repo, "upstream", QSettings().value("gitRemoteUrl").toString().toUtf8().constData())); e(git_remote_save(remote)); } e(git_remote_load(&remote, repo, "upstream")); git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; callbacks.credentials = cred_acquire_cb; e(git_remote_set_callbacks(remote, &callbacks)); e(git_remote_connect(remote, GIT_DIRECTION_FETCH)); int connected = git_remote_connected(remote); if (connected) e(git_remote_fetch(remote, NULL, NULL)); git_checkout_options checkout_opt = GIT_CHECKOUT_OPTIONS_INIT; checkout_opt.checkout_strategy = GIT_CHECKOUT_FORCE; checkout_opt.file_mode = 0644; git_merge_options merge_opt = GIT_MERGE_OPTIONS_INIT; merge_opt.file_favor = GIT_MERGE_FILE_FAVOR_UNION; const git_remote_head **head = NULL; size_t size = 0; e(git_remote_ls(&head, &size, remote)); if (size <= 0) e(-1); git_oid oid = head[0]->oid; e(git_merge_head_from_fetchhead(&merge_head, repo, "master", git_remote_url(remote), &oid)); e(git_merge(repo, (const git_merge_head **)(&merge_head), 1, &merge_opt, &checkout_opt)); //TRY TO COMMIT /* Create signature */ git_signature *me = NULL; e(git_signature_now(&me, "sparkleNotes", "*****@*****.**")); //Tree Lookup git_object *tree_obj; e(git_revparse_single(&tree_obj, repo, "HEAD^{tree}")); // Get parent commit git_oid parentCommitId; git_commit *parent; git_oid remoteParentCommitId; git_commit *remoteParent; e(git_reference_name_to_id( &parentCommitId, repo, "ORIG_HEAD" )); e(git_commit_lookup( &parent, repo, &parentCommitId )); e(git_reference_name_to_id( &remoteParentCommitId, repo, "MERGE_HEAD" )); e(git_commit_lookup( &remoteParent, repo, &remoteParentCommitId )); if (remoteParent == parent) { //Same commit ... nothing to merge e(git_repository_state_cleanup(repo)); git_merge_head_free(merge_head); git_remote_free(remote); git_repository_free(repo); return false; } const git_commit *parents [2] = { parent, remoteParent }; git_oid new_commit_id; e(git_commit_create( &new_commit_id, repo, "HEAD", /* name of ref to update */ me, /* author */ me, /* committer */ "UTF-8", /* message encoding */ "Merge remote upstream/master", /* message */ (git_tree *) tree_obj, /* root tree */ 2, /* parent count */ parents)); /* parents */ git_merge_head_free(merge_head); git_remote_free(remote); e(git_repository_state_cleanup(repo)); git_repository_free(repo); } catch (int error) { const git_error *err = giterr_last(); if (err != NULL) qDebug() << QString::number(err->klass) + "\t" + QString(err->message); emit this->error(QString(err->message)); giterr_clear(); git_merge_head_free(merge_head); git_remote_free(remote); git_repository_free(repo); } return true; }
static int update_head_to_remote( git_repository *repo, git_remote *remote, const git_signature *signature, const char *reflog_message) { int error = 0, found_branch = 0; size_t refs_len; git_refspec dummy_spec, *refspec; const git_remote_head *remote_head, **refs; const git_oid *remote_head_id; git_buf remote_master_name = GIT_BUF_INIT; git_buf branch = GIT_BUF_INIT; if ((error = git_remote_ls(&refs, &refs_len, remote)) < 0) return error; /* Did we just clone an empty repository? */ if (refs_len == 0) return setup_tracking_config( repo, "master", GIT_REMOTE_ORIGIN, GIT_REFS_HEADS_MASTER_FILE); error = git_remote_default_branch(&branch, remote); if (error == GIT_ENOTFOUND) { git_buf_puts(&branch, GIT_REFS_HEADS_MASTER_FILE); } else { found_branch = 1; } /* Get the remote's HEAD. This is always the first ref in the list. */ remote_head = refs[0]; assert(remote_head); remote_head_id = &remote_head->oid; refspec = git_remote__matching_refspec(remote, git_buf_cstr(&branch)); if (refspec == NULL) { memset(&dummy_spec, 0, sizeof(git_refspec)); refspec = &dummy_spec; } /* Determine the remote tracking reference name from the local master */ if ((error = git_refspec_transform( &remote_master_name, refspec, git_buf_cstr(&branch))) < 0) return error; if (found_branch) { error = update_head_to_new_branch( repo, remote_head_id, git_buf_cstr(&branch), signature, reflog_message); } else { error = git_repository_set_head_detached( repo, remote_head_id, signature, reflog_message); } git_buf_free(&remote_master_name); git_buf_free(&branch); return error; }
void test_network_remotelocal__nested_tags_are_completely_peeled(void) { connect_to_local_repository(cl_fixture("testrepo.git")); cl_git_pass(git_remote_ls(remote, &ensure_peeled__cb, NULL)); }
static int update_head_to_remote( git_repository *repo, git_remote *remote, const char *reflog_message) { int error = 0; size_t refs_len; git_refspec *refspec; const git_remote_head *remote_head, **refs; const git_oid *remote_head_id; git_buf remote_master_name = GIT_BUF_INIT; git_buf branch = GIT_BUF_INIT; if ((error = git_remote_ls(&refs, &refs_len, remote)) < 0) return error; /* We cloned an empty repository or one with an unborn HEAD */ if (refs_len == 0 || strcmp(refs[0]->name, GIT_HEAD_FILE)) return setup_tracking_config( repo, "master", GIT_REMOTE_ORIGIN, GIT_REFS_HEADS_MASTER_FILE); /* We know we have HEAD, let's see where it points */ remote_head = refs[0]; assert(remote_head); remote_head_id = &remote_head->oid; error = git_remote_default_branch(&branch, remote); if (error == GIT_ENOTFOUND) { error = git_repository_set_head_detached( repo, remote_head_id); goto cleanup; } refspec = git_remote__matching_refspec(remote, git_buf_cstr(&branch)); if (refspec == NULL) { git_error_set(GIT_ERROR_NET, "the remote's default branch does not fit the refspec configuration"); error = GIT_EINVALIDSPEC; goto cleanup; } /* Determine the remote tracking reference name from the local master */ if ((error = git_refspec_transform( &remote_master_name, refspec, git_buf_cstr(&branch))) < 0) goto cleanup; error = update_head_to_new_branch( repo, remote_head_id, git_buf_cstr(&branch), reflog_message); cleanup: git_buf_dispose(&remote_master_name); git_buf_dispose(&branch); return error; }