Exemplo n.º 1
0
void test_rebase_merge__finish(void)
{
	git_rebase *rebase;
	git_reference *branch_ref, *upstream_ref, *head_ref;
	git_annotated_commit *branch_head, *upstream_head;
	git_rebase_operation *rebase_operation;
	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
	git_oid commit_id;
	git_reflog *reflog;
	const git_reflog_entry *reflog_entry;
	int error;

	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;

	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/gravy"));
	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/veal"));

	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));

	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));

	cl_git_pass(git_rebase_next(&rebase_operation, rebase, &checkout_opts));
	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
		NULL, NULL));

	cl_git_fail(error = git_rebase_next(&rebase_operation, rebase, &checkout_opts));
	cl_assert_equal_i(GIT_ITEROVER, error);

	cl_git_pass(git_rebase_finish(rebase, signature, NULL));

	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));

	cl_git_pass(git_reference_lookup(&head_ref, repo, "HEAD"));
	cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head_ref));
	cl_assert_equal_s("refs/heads/gravy", git_reference_symbolic_target(head_ref));

	/* Make sure the reflogs are updated appropriately */
	cl_git_pass(git_reflog_read(&reflog, repo, "HEAD"));
	cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0));
	cl_assert_equal_oid(&commit_id, git_reflog_entry_id_old(reflog_entry));
	cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry));
	cl_assert_equal_s("rebase finished: returning to refs/heads/gravy", git_reflog_entry_message(reflog_entry));
	git_reflog_free(reflog);

	cl_git_pass(git_reflog_read(&reflog, repo, "refs/heads/gravy"));
	cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0));
	cl_assert_equal_oid(git_annotated_commit_id(branch_head), git_reflog_entry_id_old(reflog_entry));
	cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry));
	cl_assert_equal_s("rebase finished: refs/heads/gravy onto f87d14a4a236582a0278a916340a793714256864", git_reflog_entry_message(reflog_entry));

	git_reflog_free(reflog);
	git_annotated_commit_free(branch_head);
	git_annotated_commit_free(upstream_head);
	git_reference_free(head_ref);
	git_reference_free(branch_ref);
	git_reference_free(upstream_ref);
	git_rebase_free(rebase);
}
Exemplo n.º 2
0
static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, size_t identifier)
{
	git_reflog *reflog;
	int error = -1;
	size_t numentries;
	const git_reflog_entry *entry;
	bool search_by_pos = (identifier <= 100000000);

	if (git_reflog_read(&reflog, git_reference_owner(ref), git_reference_name(ref)) < 0)
		return -1;

	numentries = git_reflog_entrycount(reflog);

	if (search_by_pos) {
		if (numentries < identifier + 1) {
			giterr_set(
				GITERR_REFERENCE,
				"Reflog for '%s' has only %"PRIuZ" entries, asked for %"PRIuZ,
				git_reference_name(ref), numentries, identifier);

			error = GIT_ENOTFOUND;
			goto cleanup;
		}

		entry = git_reflog_entry_byindex(reflog, identifier);
		git_oid_cpy(oid, git_reflog_entry_id_new(entry));
		error = 0;
		goto cleanup;

	} else {
		size_t i;
		git_time commit_time;

		for (i = 0; i < numentries; i++) {
			entry = git_reflog_entry_byindex(reflog, i);
			commit_time = git_reflog_entry_committer(entry)->when;

			if (commit_time.time > (git_time_t)identifier)
				continue;

			git_oid_cpy(oid, git_reflog_entry_id_new(entry));
			error = 0;
			goto cleanup;
		}

		error = GIT_ENOTFOUND;
	}

cleanup:
	git_reflog_free(reflog);
	return error;
}
Exemplo n.º 3
0
static void test_reflog(git_repository *repo, size_t idx,
                        const char *old_spec, const char *new_spec,
                        const char *email, const char *message)
{
    git_reflog *log;
    const git_reflog_entry *entry;

    cl_git_pass(git_reflog_read(&log, repo, "HEAD"));
    entry = git_reflog_entry_byindex(log, idx);

    if (old_spec) {
        git_object *obj;
        cl_git_pass(git_revparse_single(&obj, repo, old_spec));
        cl_assert_equal_oid(git_object_id(obj), git_reflog_entry_id_old(entry));
        git_object_free(obj);
    }
    if (new_spec) {
        git_object *obj;
        cl_git_pass(git_revparse_single(&obj, repo, new_spec));
        cl_assert_equal_oid(git_object_id(obj), git_reflog_entry_id_new(entry));
        git_object_free(obj);
    }

    if (email) {
        cl_assert_equal_s(email, git_reflog_entry_committer(entry)->email);
    }
    if (message) {
        cl_assert_equal_s(message, git_reflog_entry_message(entry));
    }

    git_reflog_free(log);
}
Exemplo n.º 4
0
/**
 * Init slots in S4 class git_reflog_entry
 *
 * @param source The source reflog entry
 * @param index The entry index
 * @param repo S4 class git_repository
 * @param ref Reference to read from
 * @param dest S4 class git_reflog_entry to initialize
 * @return void
 */
void git2r_reflog_entry_init(
    const git_reflog_entry *source,
    size_t index,
    SEXP repo,
    SEXP ref,
    SEXP dest)
{
    SEXP i;
    const char *message;
    const git_signature *committer;
    char sha[GIT_OID_HEXSZ + 1];

    git_oid_fmt(sha, git_reflog_entry_id_new(source));
    sha[GIT_OID_HEXSZ] = '\0';
    SET_SLOT(dest, Rf_install("sha"), mkString(sha));

    SET_SLOT(dest, Rf_install("index"), i = allocVector(INTSXP, 1));
    INTEGER(i)[0] = index;

    committer = git_reflog_entry_committer(source);
    if (committer)
        git2r_signature_init(committer, GET_SLOT(dest, Rf_install("committer")));

    message = git_reflog_entry_message(source);
    if (message)
        SET_SLOT(dest, Rf_install("message"), mkString(message));
    else
        SET_SLOT(dest, Rf_install("message"), ScalarString(NA_STRING));

    SET_SLOT(dest, Rf_install("refname"), ref);
    SET_SLOT(dest, Rf_install("repo"), repo);
}
Exemplo n.º 5
0
PyObject *
RefLogIter_iternext(RefLogIter *self)
{
    const git_reflog_entry *entry;
    RefLogEntry *py_entry;
    int err;

    if (self->i < self->size) {
        entry = git_reflog_entry_byindex(self->reflog, self->i);
        py_entry = PyObject_New(RefLogEntry, &RefLogEntryType);

        py_entry->oid_old = git_oid_to_python(git_reflog_entry_id_old(entry));
        py_entry->oid_new = git_oid_to_python(git_reflog_entry_id_new(entry));
        py_entry->message = strdup(git_reflog_entry_message(entry));
        err = git_signature_dup(&py_entry->signature,
                                git_reflog_entry_committer(entry));
        if (err < 0)
            return Error_set(err);

        ++(self->i);

        return (PyObject*) py_entry;
    }

    PyErr_SetNone(PyExc_StopIteration);
    return NULL;
}
Exemplo n.º 6
0
static VALUE reflog_entry_new(const git_reflog_entry *entry)
{
	VALUE rb_entry = rb_hash_new();
	const char *message;

	rb_hash_aset(rb_entry,
		CSTR2SYM("id_old"),
		rugged_create_oid(git_reflog_entry_id_old(entry))
	);

	rb_hash_aset(rb_entry,
		CSTR2SYM("id_new"),
		rugged_create_oid(git_reflog_entry_id_new(entry))
	);

	rb_hash_aset(rb_entry,
		CSTR2SYM("committer"),
		rugged_signature_new(git_reflog_entry_committer(entry), NULL)
	);

	if ((message = git_reflog_entry_message(entry)) != NULL) {
		rb_hash_aset(rb_entry, CSTR2SYM("message"), rb_str_new_utf8(message));
	}

	return rb_entry;
}
Exemplo n.º 7
0
ERL_NIF_TERM
geef_reflog_read(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
	git_reflog *reflog;
	geef_repository *repo;
	ErlNifBinary bin;
	int error;
	size_t count, i;
	ERL_NIF_TERM list;

	if (!enif_get_resource(env, argv[0], geef_repository_type, (void **) &repo))
		return enif_make_badarg(env);

	if (!enif_inspect_iolist_as_binary(env, argv[1], &bin))
		return enif_make_badarg(env);

	if (!geef_terminate_binary(&bin))
		return geef_oom(env);

	if ((error = git_reflog_read(&reflog, repo->repo, (char *)bin.data)) < 0)
		return geef_error(env);

	count = git_reflog_entrycount(reflog);
	list = enif_make_list(env, 0);

	for (i = count; i > 0; i--) {
		ErlNifBinary id_old, id_new, message;
		ERL_NIF_TERM tentry, name, email, time, offset;
		const git_reflog_entry *entry;

		entry = git_reflog_entry_byindex(reflog, i-1);

		if (geef_oid_bin(&id_old, git_reflog_entry_id_old(entry)))
			goto on_oom;

		if (geef_oid_bin(&id_new, git_reflog_entry_id_new(entry)))
			goto on_oom;

		if (geef_signature_to_erl(&name, &email, &time, &offset,
					  env, git_reflog_entry_committer(entry)))
			goto on_oom;

		if (geef_string_to_bin(&message, git_reflog_entry_message(entry)))
			goto on_oom;

		tentry = enif_make_tuple7(env, name, email, time, offset,
					  enif_make_binary(env, &id_old),
					  enif_make_binary(env, &id_new),
					  enif_make_binary(env, &message));
		list = enif_make_list_cell(env, tentry, list);
	}

	git_reflog_free(reflog);
	return enif_make_tuple2(env, atoms.ok, list);

on_oom:
	git_reflog_free(reflog);
	return geef_oom(env);
}
Exemplo n.º 8
0
void test_rebase_merge__commit(void)
{
	git_rebase *rebase;
	git_reference *branch_ref, *upstream_ref;
	git_annotated_commit *branch_head, *upstream_head;
	git_rebase_operation *rebase_operation;
	git_oid commit_id, tree_id, parent_id;
	git_signature *author;
	git_commit *commit;
	git_reflog *reflog;
	const git_reflog_entry *reflog_entry;

	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));

	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));

	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));

	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
		NULL, NULL));

	cl_git_pass(git_commit_lookup(&commit, repo, &commit_id));

	git_oid_fromstr(&parent_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
	cl_assert_equal_i(1, git_commit_parentcount(commit));
	cl_assert_equal_oid(&parent_id, git_commit_parent_id(commit, 0));

	git_oid_fromstr(&tree_id, "4461379789c777d2a6c1f2ee0e9d6c86731b9992");
	cl_assert_equal_oid(&tree_id, git_commit_tree_id(commit));

	cl_assert_equal_s(NULL, git_commit_message_encoding(commit));
	cl_assert_equal_s("Modification 1 to beef\n", git_commit_message(commit));

	cl_git_pass(git_signature_new(&author,
		"Edward Thomson", "*****@*****.**", 1405621769, 0-(4*60)));
	cl_assert(git_signature__equal(author, git_commit_author(commit)));

	cl_assert(git_signature__equal(signature, git_commit_committer(commit)));

	/* Make sure the reflogs are updated appropriately */
	cl_git_pass(git_reflog_read(&reflog, repo, "HEAD"));
	cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0));
	cl_assert_equal_oid(&parent_id, git_reflog_entry_id_old(reflog_entry));
	cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry));
	cl_assert_equal_s("rebase: Modification 1 to beef", git_reflog_entry_message(reflog_entry));

	git_reflog_free(reflog);
	git_signature_free(author);
	git_commit_free(commit);
	git_annotated_commit_free(branch_head);
	git_annotated_commit_free(upstream_head);
	git_reference_free(branch_ref);
	git_reference_free(upstream_ref);
	git_rebase_free(rebase);
}
Exemplo n.º 9
0
/**
 * ggit_reflog_entry_get_new_id:
 * @reflog_entry: a #GgitReflogEntry.
 *
 * Gets the new #GgitOId.
 *
 * Returns: (transfer full) (nullable): the new oid or %NULL.
 */
GgitOId *
ggit_reflog_entry_get_new_id (GgitReflogEntry *reflog_entry)
{
	const git_oid *oid;

	g_return_val_if_fail (reflog_entry != NULL, NULL);

	oid = git_reflog_entry_id_new (reflog_entry->reflog_entry);

	return _ggit_oid_wrap (oid);
}
Exemplo n.º 10
0
void test_rebase_merge__finish_with_ids(void)
{
	git_rebase *rebase;
	git_reference *head_ref;
	git_oid branch_id, upstream_id;
	git_annotated_commit *branch_head, *upstream_head;
	git_rebase_operation *rebase_operation;
	git_oid commit_id;
	git_reflog *reflog;
	const git_reflog_entry *reflog_entry;
	int error;

	cl_git_pass(git_oid_fromstr(&branch_id, "d616d97082eb7bb2dc6f180a7cca940993b7a56f"));
	cl_git_pass(git_oid_fromstr(&upstream_id, "f87d14a4a236582a0278a916340a793714256864"));

	cl_git_pass(git_annotated_commit_lookup(&branch_head, repo, &branch_id));
	cl_git_pass(git_annotated_commit_lookup(&upstream_head, repo, &upstream_id));

	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));

	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
		NULL, NULL));

	cl_git_fail(error = git_rebase_next(&rebase_operation, rebase));
	cl_assert_equal_i(GIT_ITEROVER, error);

	cl_git_pass(git_rebase_finish(rebase, signature));

	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));

	cl_git_pass(git_reference_lookup(&head_ref, repo, "HEAD"));
	cl_assert_equal_i(GIT_REF_OID, git_reference_type(head_ref));
	cl_assert_equal_oid(&commit_id, git_reference_target(head_ref));

	/* reflogs are not updated as if we were operating on proper
	 * branches.  check that the last reflog entry is the rebase.
	 */
	cl_git_pass(git_reflog_read(&reflog, repo, "HEAD"));
	cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0));
	cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry));
	cl_assert_equal_s("rebase: Modification 3 to gravy", git_reflog_entry_message(reflog_entry));
	git_reflog_free(reflog);

	git_annotated_commit_free(branch_head);
	git_annotated_commit_free(upstream_head);
	git_reference_free(head_ref);
	git_rebase_free(rebase);
}
Exemplo n.º 11
0
static void test_abort(git_annotated_commit *branch, git_annotated_commit *onto)
{
	git_rebase *rebase;
	git_reference *head_ref, *branch_ref = NULL;
	git_signature *signature;
	git_status_list *statuslist;
	git_reflog *reflog;
	const git_reflog_entry *reflog_entry;

	cl_git_pass(git_rebase_open(&rebase, repo));
	cl_git_pass(git_signature_new(&signature, "Rebaser", "*****@*****.**", 1404157834, -400));
	cl_git_pass(git_rebase_abort(rebase, signature));

	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));

	/* Make sure the refs are updated appropriately */
	cl_git_pass(git_reference_lookup(&head_ref, repo, "HEAD"));

	if (branch->ref_name == NULL)
		cl_assert_equal_oid(git_annotated_commit_id(branch), git_reference_target(head_ref));
	else {
		cl_assert_equal_s("refs/heads/beef", git_reference_symbolic_target(head_ref));
		cl_git_pass(git_reference_lookup(&branch_ref, repo, git_reference_symbolic_target(head_ref)));
		cl_assert_equal_oid(git_annotated_commit_id(branch), git_reference_target(branch_ref));
	}

	git_status_list_new(&statuslist, repo, NULL);
	cl_assert_equal_i(0, git_status_list_entrycount(statuslist));
	git_status_list_free(statuslist);

	/* Make sure the reflogs are updated appropriately */
	cl_git_pass(git_reflog_read(&reflog, repo, "HEAD"));

	cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0));
	cl_assert_equal_oid(git_annotated_commit_id(onto), git_reflog_entry_id_old(reflog_entry));
	cl_assert_equal_oid(git_annotated_commit_id(branch), git_reflog_entry_id_new(reflog_entry));
	cl_assert_equal_s("rebase: aborting", git_reflog_entry_message(reflog_entry));

	git_reflog_free(reflog);
	git_reference_free(head_ref);
	git_reference_free(branch_ref);
	git_signature_free(signature);
	git_rebase_free(rebase);
}
Exemplo n.º 12
0
static void assert_head_reflog(git_repository *repo, size_t idx,
                               const char *old_id, const char *new_id, const char *message)
{
    git_reflog *log;
    const git_reflog_entry *entry;
    char id_str[GIT_OID_HEXSZ + 1] = {0};

    cl_git_pass(git_reflog_read(&log, repo, GIT_HEAD_FILE));
    entry = git_reflog_entry_byindex(log, idx);

    git_oid_fmt(id_str, git_reflog_entry_id_old(entry));
    cl_assert_equal_s(old_id, id_str);

    git_oid_fmt(id_str, git_reflog_entry_id_new(entry));
    cl_assert_equal_s(new_id, id_str);

    cl_assert_equal_s(message, git_reflog_entry_message(entry));

    git_reflog_free(log);
}
Exemplo n.º 13
0
Arquivo: stash.c Projeto: aep/libgit2
int git_stash_foreach(
	git_repository *repo,
	git_stash_cb callback,
	void *payload)
{
	git_reference *stash;
	git_reflog *reflog = NULL;
	int error;
	size_t i, max;
	const git_reflog_entry *entry;

	error = git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE);
	if (error == GIT_ENOTFOUND) {
		giterr_clear();
		return 0;
	}
	if (error < 0)
		goto cleanup;

	if ((error = git_reflog_read(&reflog, stash)) < 0)
		goto cleanup;

	max = git_reflog_entrycount(reflog);
	for (i = 0; i < max; i++) {
		entry = git_reflog_entry_byindex(reflog, i);

		if (callback(i,
			git_reflog_entry_message(entry),
			git_reflog_entry_id_new(entry),
			payload)) {
				error = GIT_EUSER;
				break;
		}
	}

cleanup:
	git_reference_free(stash);
	git_reflog_free(reflog);
	return error;
}
Exemplo n.º 14
0
int lgit_current::discover( git_repository *repo )
{
    int error, retval = 0;
    const git_oid *oidp;
    git_oid oid;
    const char *sym;
    std::string symbolic_name;

    cur_repo_ = repo;

    clear();

    // Mark one branch as the checked out one
    git_reference *ref;
    if ( ( error = git_repository_head( &ref, repo ) ) < 0 ) {
        state_ = CURRENT_INVALID_MAIN;
        MessagesI.AppendMessageT( "Could not determine which branch is currently checked out" );
    } else {
        switch ( git_reference_type( ref ) ) {

        /* GIT_REF_OID */
        case GIT_REF_OID:
            // Prepare data for .tip_sha
            oidp = git_reference_target( ref );
            if ( !oidp ) {
                state_ = CURRENT_INVALID_OID;
                break;
            }
            state_ = CURRENT_OID;
            oid = *oidp;
            break;

        /* GIT_REF_SYMBOLIC */
        case GIT_REF_SYMBOLIC:
            sym = git_reference_symbolic_target( ref );
            if ( !sym ) {
                state_ = CURRENT_INVALID_SYM;
                break;
            }
            state_ = CURRENT_SYM;
            symbolic_name = std::string( sym );

            // Also establish OID
            if ( ( error = git_reference_name_to_id( &oid, repo, symbolic_name.c_str() ) ) < 0 ) {
                state_ = CURRENT_INVALID_OID2;
                break;
            }

            break;

        /* DEFAULT */
        /* GIT_REF_INVALID */
        /* GIT_REF_LISTALL */
        default:
            state_ = CURRENT_INVALID_OTHER;
            break;

        }

        /*
         * AFTER SWITCH()
         */

        if ( state_ == CURRENT_OID || state_ == CURRENT_SYM ) {
            char sha[ GIT_OID_HEXSZ + 1 ];
            git_oid_fmt( sha, &oid );
            sha[ GIT_OID_HEXSZ ] = '\0';
            current_oid_ = std::string( sha );
            type_ = CURRENT_TYPE_OID;
        }

        if ( state_ == CURRENT_OID ) {
            // Does the reference have any name?
            const char* refname_cstring = git_reference_name( ref );
            if( !refname_cstring ) {
                refname_cstring = "";
            }
            QString refname = QString::fromUtf8( refname_cstring ).trimmed();

            if( refname.isEmpty() || refname == "HEAD" ) {
                git_reflog *reflog;
                const git_reflog_entry *reflog_entry;

                if ( ( error = git_reflog_read( &reflog, repo, "HEAD" ) ) < 0 ) {
                    MessagesI.AppendMessageT( QString( "Could not read reflog, current HEAD will be established as SHA-only" ) +
                                              QString( " (no tag name resolution, error code: %1)" ) . arg( error ) );
                } else {
                    int count = git_reflog_entrycount( reflog );
                    int limit_count = 0;

                    for ( int i = 0; i < count; i ++ ) {
                        reflog_entry = git_reflog_entry_byindex( reflog, i );
                        if( !reflog_entry ) {
                            MessagesI.AppendMessageT( "Problems when reading reflog" );
                            continue;
                        }

                        oidp = git_reflog_entry_id_new( reflog_entry );
                        if( 0 == git_oid_cmp( oidp, &oid ) ) {
                            const char* message_cstring = git_reflog_entry_message( reflog_entry );
                            if( !message_cstring ) {
                                MessagesI.AppendMessageT( "Problems when reading reflog (2)" );
                                continue;
                            }

                            QString message = QString( message_cstring );
                            QRegExp rx("checkout: moving from.*to (.*)$");
                            if( rx.indexIn( message ) != -1 ) {
                                // The target of the catched move message must not be current HEAD's OID prefix
                                if( ! QString::fromStdString( current_oid_ ).startsWith( rx.cap( 1 ) ) ) {
                                    current_tag_ = rx.cap( 1 ).toStdString();
                                    type_ = CURRENT_TYPE_TAG;
                                }
                                break;
                            }

                            // Search only 5 OID-matching entries
                            if( ++ limit_count >= 5 ) {
                                break;
                            }
                        }
                    }

                    git_reflog_free( reflog );
                }
            } else {
                QStringList parts = refname.split( "/", QString::SkipEmptyParts );
                current_branch_ = parts.last().toStdString();
                type_ = CURRENT_TYPE_BRANCH;
            }
        } else if ( state_ == CURRENT_SYM ) {
            current_branch_ = symbolic_name;
        } else {
            MessagesI.AppendMessageT( QString( "Could not determine which branch is currently checked out (error code: %1)" ).arg( state_ ) );
        }

        git_reference_free( ref );
    }

    return retval;
}
Exemplo n.º 15
0
int ParserFromRefLog(CString ref, std::vector<GitRev> &refloglist)
{
	refloglist.clear();
	if (g_Git.m_IsUseLibGit2)
	{
		CAutoRepository repo(g_Git.GetGitRepository());
		if (!repo)
		{
			MessageBox(nullptr, CGit::GetLibGit2LastErr(_T("Could not open repository.")), _T("TortoiseGit"), MB_ICONERROR);
			return -1;
		}

		CAutoReflog reflog;
		if (git_reflog_read(reflog.GetPointer(), repo, CUnicodeUtils::GetUTF8(ref)) < 0)
		{
			MessageBox(nullptr, CGit::GetLibGit2LastErr(_T("Could not read reflog.")), _T("TortoiseGit"), MB_ICONERROR);
			return -1;
		}

		for (size_t i = 0; i < git_reflog_entrycount(reflog); ++i)
		{
			const git_reflog_entry *entry = git_reflog_entry_byindex(reflog, i);
			if (!entry)
				continue;

			GitRev rev;
			rev.m_CommitHash = (char *)git_reflog_entry_id_new(entry)->id;
			rev.m_Ref.Format(_T("%s@{%d}"), ref, i);
			rev.GetCommitterDate() = CTime(git_reflog_entry_committer(entry)->when.time);
			if (git_reflog_entry_message(entry) != nullptr)
			{
				CString one;
				g_Git.StringAppend(&one, (BYTE *)git_reflog_entry_message(entry));
				int message = one.Find(_T(":"), 0);
				if (message > 0)
				{
					rev.m_RefAction = one.Left(message);
					rev.GetSubject() = one.Mid(message + 1);
				}
			}
			refloglist.push_back(rev); 
		}
	}
	else if (g_Git.m_IsUseGitDLL)
	{
		git_for_each_reflog_ent(CUnicodeUtils::GetUTF8(ref), AddToRefLoglist, &refloglist);
		for (size_t i = 0; i < refloglist.size(); ++i)
			refloglist[i].m_Ref.Format(_T("%s@{%d}"), ref, i);
	}
	else
	{
		CString cmd, out;
		GitRev rev;
		cmd.Format(_T("git.exe reflog show --pretty=\"%%H %%gD: %%gs\" --date=raw %s"), ref);
		if (g_Git.Run(cmd, &out, NULL, CP_UTF8))
			return -1;

		int i = 0;
		CString prefix = ref + _T("@{");
		int pos = 0;
		while (pos >= 0)
		{
			CString one = out.Tokenize(_T("\n"), pos);
			int refPos = one.Find(_T(' '), 0);
			if (refPos < 0)
				continue;

			rev.Clear();

			CString hashStr = one.Left(refPos);
			rev.m_CommitHash = hashStr;
			rev.m_Ref.Format(_T("%s@{%d}"), ref, i++);
			int prefixPos = one.Find(prefix, refPos + 1);
			if (prefixPos != refPos + 1)
				continue;

			int spacePos = one.Find(_T(' '), prefixPos + prefix.GetLength() + 1);
			if (spacePos < 0)
				continue;

			CString timeStr = one.Mid(prefixPos + prefix.GetLength(), spacePos - prefixPos - prefix.GetLength());
			rev.GetCommitterDate() = CTime(_ttoi(timeStr));
			int action = one.Find(_T("}: "), spacePos + 1);
			if (action > 0)
			{
				action += 2;
				int message = one.Find(_T(":"), action);
				if (message > 0)
				{
					rev.m_RefAction = one.Mid(action + 1, message - action - 1);
					rev.GetSubject() = one.Right(one.GetLength() - message - 1);
				}
			}

			refloglist.push_back(rev);
		}
	}
	return 0;
}