Ejemplo n.º 1
0
Archivo: fetch.c Proyecto: 0CV0/libgit2
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;
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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 */
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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 */
}
Ejemplo n.º 7
0
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));
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
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"));
    }
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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");
}
Ejemplo n.º 15
0
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");
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
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");
}
Ejemplo n.º 18
0
/*
 *  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;
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
0
/**
 * 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);
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
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;
}
Ejemplo n.º 24
0
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));
}
Ejemplo n.º 25
0
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;
}