Exemplo n.º 1
0
static int check_pack_sha1(git_pack *p)
{
	unsigned char *data = p->idx_map.data;
	off_t pack_sha1_off = p->pack_size - GIT_OID_RAWSZ;
	size_t idx_pack_sha1_off = p->idx_map.len - 2 * GIT_OID_RAWSZ;
	git_oid pack_id, idx_pack_id;

	if (gitfo_lseek(p->pack_fd, pack_sha1_off, SEEK_SET) == -1)
		return GIT_ERROR;

	if (gitfo_read(p->pack_fd, pack_id.id, sizeof(pack_id.id)))
		return GIT_ERROR;

	git_oid_mkraw(&idx_pack_id, data + idx_pack_sha1_off);

	if (git_oid_cmp(&pack_id, &idx_pack_id))
		return GIT_ERROR;

	return GIT_SUCCESS;
}
Exemplo n.º 2
0
void test_revwalk_mergebase__single1(void)
{
	git_oid result, one, two, expected;
	size_t ahead, behind;

	cl_git_pass(git_oid_fromstr(&one, "c47800c7266a2be04c571c04d5a6614691ea99bd "));
	cl_git_pass(git_oid_fromstr(&two, "9fd738e8f7967c078dceed8190330fc8648ee56a"));
	cl_git_pass(git_oid_fromstr(&expected, "5b5b025afb0b4c913b4c338a42934a3863bf3644"));

	cl_git_pass(git_merge_base(&result, _repo, &one, &two));
	cl_assert(git_oid_cmp(&result, &expected) == 0);

	cl_git_pass(git_graph_ahead_behind(&ahead, &behind, _repo, &one, &two));
	cl_assert_equal_sz(ahead, 2);
	cl_assert_equal_sz(behind, 1);

	cl_git_pass(git_graph_ahead_behind(&ahead, &behind, _repo, &two, &one));
	cl_assert_equal_sz(ahead,  1);
	cl_assert_equal_sz(behind,  2);
}
Exemplo n.º 3
0
void test_revwalk_mergebase__single2(void)
{
	git_oid result, one, two, expected;
	size_t ahead, behind;

	cl_git_pass(git_oid_fromstr(&one, "763d71aadf09a7951596c9746c024e7eece7c7af"));
	cl_git_pass(git_oid_fromstr(&two, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"));
	cl_git_pass(git_oid_fromstr(&expected, "c47800c7266a2be04c571c04d5a6614691ea99bd"));

	cl_git_pass(git_merge_base(&result, _repo, &one, &two));
	cl_assert(git_oid_cmp(&result, &expected) == 0);

	cl_git_pass(git_graph_ahead_behind( &ahead, &behind, _repo, &one, &two));
	cl_assert_equal_sz(ahead,  4);
	cl_assert_equal_sz(behind,  1);

	cl_git_pass(git_graph_ahead_behind( &ahead, &behind, _repo, &two, &one));
	cl_assert_equal_sz(ahead,  1);
	cl_assert_equal_sz(behind,  4);
}
Exemplo n.º 4
0
PyObject *
Oid_richcompare(PyObject *o1, PyObject *o2, int op)
{
    PyObject *res;
    int cmp;

    /* Comparing to something else than an Oid is not supported. */
    if (!PyObject_TypeCheck(o2, &OidType)) {
        Py_INCREF(Py_NotImplemented);
        return Py_NotImplemented;
    }

    /* Ok go. */
    cmp = git_oid_cmp(&((Oid*)o1)->oid, &((Oid*)o2)->oid);
    switch (op) {
        case Py_LT:
            res = (cmp <= 0) ? Py_True: Py_False;
            break;
        case Py_LE:
            res = (cmp < 0) ? Py_True: Py_False;
            break;
        case Py_EQ:
            res = (cmp == 0) ? Py_True: Py_False;
            break;
        case Py_NE:
            res = (cmp != 0) ? Py_True: Py_False;
            break;
        case Py_GT:
            res = (cmp > 0) ? Py_True: Py_False;
            break;
        case Py_GE:
            res = (cmp >= 0) ? Py_True: Py_False;
            break;
        default:
            PyErr_Format(PyExc_RuntimeError, "Unexpected '%d' op", op);
            return NULL;
    }

    Py_INCREF(res);
    return res;
}
Exemplo n.º 5
0
static int reference__update_terminal(
	git_repository *repo,
	const char *ref_name,
	const git_oid *oid,
	int nesting,
	const git_signature *signature,
	const char *log_message)
{
	git_reference *ref;
	int error = 0;

	if (nesting > MAX_NESTING_LEVEL) {
		giterr_set(GITERR_REFERENCE, "Reference chain too deep (%d)", nesting);
		return GIT_ENOTFOUND;
	}

	error = git_reference_lookup(&ref, repo, ref_name);

	/* If we haven't found the reference at all, create a new reference. */
	if (error == GIT_ENOTFOUND) {
		giterr_clear();
		return git_reference_create(NULL, repo, ref_name, oid, 0, signature, log_message);
	}

	if (error < 0)
		return error;

	/* If the ref is a symbolic reference, follow its target. */
	if (git_reference_type(ref) == GIT_REF_SYMBOLIC) {
		error = reference__update_terminal(repo, git_reference_symbolic_target(ref), oid,
			nesting+1, signature, log_message);
		git_reference_free(ref);
	} else {
		/* If we're not moving the target, don't recreate the ref */
		if (0 != git_oid_cmp(git_reference_target(ref), oid))
			error = git_reference_create(NULL, repo, ref_name, oid, 1, signature, log_message);
		git_reference_free(ref);
	}

	return error;
}
Exemplo n.º 6
0
void test_object_tag_write__lightweight_over_existing(void)
{
   // Attempt to write a lightweight tag bearing the same name than an already existing tag
	git_oid target_id, object_id, existing_object_id;
	git_object *target;

	git_oid_fromstr(&target_id, tagged_commit);
	cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT));

	cl_assert_equal_i(GIT_EEXISTS, git_tag_create_lightweight(
                                          &object_id,
                                          g_repo,
                                          "e90810b",
                                          target,
                                          0));

	git_oid_fromstr(&existing_object_id, tag2_id);
	cl_assert(git_oid_cmp(&object_id, &existing_object_id) == 0);

	git_object_free(target);
}
Exemplo n.º 7
0
void test_index_tests__add(void)
{
   git_index *index;
   git_filebuf file = GIT_FILEBUF_INIT;
   git_repository *repo;
   git_index_entry *entry;
   git_oid id1;

   /* Intialize a new repository */
   cl_git_pass(git_repository_init(&repo, "./myrepo", 0));

   /* Ensure we're the only guy in the room */
   cl_git_pass(git_repository_index(&index, repo));
   cl_assert(git_index_entrycount(index) == 0);

   /* Create a new file in the working directory */
   cl_git_pass(git_futils_mkpath2file("myrepo/test.txt", 0777));
   cl_git_pass(git_filebuf_open(&file, "myrepo/test.txt", 0));
   cl_git_pass(git_filebuf_write(&file, "hey there\n", 10));
   cl_git_pass(git_filebuf_commit(&file, 0666));

   /* Store the expected hash of the file/blob
   * This has been generated by executing the following
   * $ echo "hey there" | git hash-object --stdin
   */
   cl_git_pass(git_oid_fromstr(&id1, "a8233120f6ad708f843d861ce2b7228ec4e3dec6"));

   /* Add the new file to the index */
   cl_git_pass(git_index_add(index, "test.txt", 0));

   /* Wow... it worked! */
   cl_assert(git_index_entrycount(index) == 1);
   entry = git_index_get(index, 0);

   /* And the built-in hashing mechanism worked as expected */
   cl_assert(git_oid_cmp(&id1, &entry->oid) == 0);

   git_index_free(index);
   git_repository_free(repo);
}
Exemplo n.º 8
0
void test_object_tree_write__from_memory(void)
{
	/* write a tree from a memory */
	git_treebuilder *builder;
	git_tree *tree;
	git_oid id, bid, rid, id2;

	git_oid_fromstr(&id, first_tree);
	git_oid_fromstr(&id2, second_tree);
	git_oid_fromstr(&bid, blob_oid);

	/* create a second tree from first tree using `git_treebuilder_insert`
	 * on REPOSITORY_FOLDER.
	 */
	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
	cl_git_pass(git_treebuilder_new(&builder, g_repo, tree));

	cl_git_fail(git_treebuilder_insert(NULL, builder, "",
		&bid, GIT_FILEMODE_BLOB));
	cl_git_fail(git_treebuilder_insert(NULL, builder, "/",
		&bid, GIT_FILEMODE_BLOB));
	cl_git_fail(git_treebuilder_insert(NULL, builder, ".git",
		&bid, GIT_FILEMODE_BLOB));
	cl_git_fail(git_treebuilder_insert(NULL, builder, "..",
		&bid, GIT_FILEMODE_BLOB));
	cl_git_fail(git_treebuilder_insert(NULL, builder, ".",
		&bid, GIT_FILEMODE_BLOB));
	cl_git_fail(git_treebuilder_insert(NULL, builder, "folder/new.txt",
		&bid, GIT_FILEMODE_BLOB));

	cl_git_pass(git_treebuilder_insert(
		NULL, builder, "new.txt", &bid, GIT_FILEMODE_BLOB));

	cl_git_pass(git_treebuilder_write(&rid, builder));

	cl_assert(git_oid_cmp(&rid, &id2) == 0);

	git_treebuilder_free(builder);
	git_tree_free(tree);
}
Exemplo n.º 9
0
static int reference_matches_remote_head(
	const char *reference_name,
	void *payload)
{
	struct head_info *head_info = (struct head_info *)payload;
	git_oid oid;

	/* TODO: Should we guard against references
	 * which name doesn't start with refs/heads/ ?
	 */

	/* Stop looking if we've already found a match */
	if (git_buf_len(&head_info->branchname) > 0)
		return 0;

	if (git_reference_name_to_oid(
		&oid,
		head_info->repo,
		reference_name) < 0) {
			/* TODO: How to handle not found references?
			 */
			return -1;
	}

	if (git_oid_cmp(&head_info->remote_head_oid, &oid) == 0) {
		/* Determine the local reference name from the remote tracking one */
		if (git_refspec_transform_l(
			&head_info->branchname, 
			head_info->refspec,
			reference_name) < 0)
				return -1;
		
		if (git_buf_sets(
			&head_info->branchname,
			git_buf_cstr(&head_info->branchname) + strlen(GIT_REFS_HEADS_DIR)) < 0)
				return -1;
	}

	return 0;
}
Exemplo n.º 10
0
static void assert_peel(
	const char *ref_name,
	git_otype requested_type,
	const char* expected_sha,
	git_otype expected_type)
{
	git_oid expected_oid;
	git_reference *ref;
	git_object *peeled;

	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
	
	cl_git_pass(git_reference_peel(&peeled, ref, requested_type));

	cl_git_pass(git_oid_fromstr(&expected_oid, expected_sha));
	cl_assert_equal_i(0, git_oid_cmp(&expected_oid, git_object_id(peeled)));

	cl_assert_equal_i(expected_type, git_object_type(peeled));

	git_object_free(peeled);
	git_reference_free(ref);
}
Exemplo n.º 11
0
static int validate_tree_and_parents(git_array_oid_t *parents, git_repository *repo, const git_oid *tree,
				     git_commit_parent_callback parent_cb, void *parent_payload,
				     const git_oid *current_id, bool validate)
{
	size_t i;
	int error;
	git_oid *parent_cpy;
	const git_oid *parent;

	if (validate && !git_object__is_valid(repo, tree, GIT_OBJECT_TREE))
		return -1;

	i = 0;
	while ((parent = parent_cb(i, parent_payload)) != NULL) {
		if (validate && !git_object__is_valid(repo, parent, GIT_OBJECT_COMMIT)) {
			error = -1;
			goto on_error;
		}

		parent_cpy = git_array_alloc(*parents);
		GITERR_CHECK_ALLOC(parent_cpy);

		git_oid_cpy(parent_cpy, parent);
		i++;
	}

	if (current_id && (parents->size == 0 || git_oid_cmp(current_id, git_array_get(*parents, 0)))) {
		giterr_set(GITERR_OBJECT, "failed to create commit: current tip is not the first parent");
		error = GIT_EMODIFIED;
		goto on_error;
	}

	return 0;

on_error:
	git_array_clear(*parents);
	return error;
}
Exemplo n.º 12
0
static void assert_mergebase_many(const char *expected_sha, int count, ...)
{
	va_list ap;
	int i; 
	git_oid *oids;
	git_oid oid, expected;
	char *partial_oid;
	git_object *object;

	oids = git__malloc(count * sizeof(git_oid));
	cl_assert(oids != NULL);

	memset(oids, 0x0, count * sizeof(git_oid));

	va_start(ap, count);
	
	for (i = 0; i < count; ++i) {
		partial_oid = va_arg(ap, char *);
		cl_git_pass(git_oid_fromstrn(&oid, partial_oid, strlen(partial_oid)));

		cl_git_pass(git_object_lookup_prefix(&object, _repo, &oid, strlen(partial_oid), GIT_OBJ_COMMIT));
		git_oid_cpy(&oids[i], git_object_id(object));
		git_object_free(object);
	}

	va_end(ap);

	if (expected_sha == NULL)
		cl_assert_equal_i(GIT_ENOTFOUND, git_merge_base_many(&oid, _repo, count, oids));
	else {
		cl_git_pass(git_merge_base_many(&oid, _repo, count, oids));
		cl_git_pass(git_oid_fromstr(&expected, expected_sha));

		cl_assert(git_oid_cmp(&expected, &oid) == 0);
	}

	git__free(oids);
}
Exemplo n.º 13
0
void test_refs_branches_create__can_create_branch_with_unicode(void)
{
	const char *nfc = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D";
	const char *nfd = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D";
	const char *emoji = "\xF0\x9F\x8D\xB7";
	const char *names[] = { nfc, nfd, emoji };
	const char *alt[] = { nfd, nfc, NULL };
	const char *expected[] = { nfc, nfd, emoji };
	unsigned int i;
	bool fs_decompose_unicode =
		git_path_does_fs_decompose_unicode(git_repository_path(repo));

	retrieve_known_commit(&target, repo);

	if (cl_repo_get_bool(repo, "core.precomposeunicode"))
		expected[1] = nfc;
	/* test decomp. because not all Mac filesystems decompose unicode */
	else if (fs_decompose_unicode)
		expected[0] = nfd;

	for (i = 0; i < ARRAY_SIZE(names); ++i) {
		const char *name;
		cl_git_pass(git_branch_create(
			&branch, repo, names[i], target, 0, NULL, NULL));
		cl_git_pass(git_oid_cmp(
			git_reference_target(branch), git_commit_id(target)));

		cl_git_pass(git_branch_name(&name, branch));
		cl_assert_equal_s(expected[i], name);
		assert_branch_matches_name(expected[i], names[i]);
		if (fs_decompose_unicode && alt[i])
			assert_branch_matches_name(expected[i], alt[i]);

		cl_git_pass(git_branch_delete(branch));
		git_reference_free(branch);
		branch = NULL;
	}
}
Exemplo n.º 14
0
static void assert_peel(
	const char *sha,
	git_otype requested_type,
	const char* expected_sha,
	git_otype expected_type)
{
	git_oid oid, expected_oid;
	git_object *obj;
	git_object *peeled;

	cl_git_pass(git_oid_fromstr(&oid, sha));
	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
	
	cl_git_pass(git_object_peel(&peeled, obj, requested_type));

	cl_git_pass(git_oid_fromstr(&expected_oid, expected_sha));
	cl_assert_equal_i(0, git_oid_cmp(&expected_oid, git_object_id(peeled)));

	cl_assert_equal_i(expected_type, git_object_type(peeled));

	git_object_free(peeled);
	git_object_free(obj);
}
Exemplo n.º 15
0
static int index_entry_eq_merge_index_entry(const struct merge_index_entry *expected, const git_index_entry *actual)
{
	git_oid expected_oid;
	bool test_oid;

	if (strlen(expected->oid_str) != 0) {
		cl_git_pass(git_oid_fromstr(&expected_oid, expected->oid_str));
		test_oid = 1;
	} else
		test_oid = 0;

	if (actual->mode != expected->mode ||
		(test_oid && git_oid_cmp(&actual->oid, &expected_oid) != 0) ||
		git_index_entry_stage(actual) != expected->stage)
		return 0;

	if (actual->mode == 0 && (actual->path != NULL || strlen(expected->path) > 0))
		return 0;

	if (actual->mode != 0 && (strcmp(actual->path, expected->path) != 0))
		return 0;

	return 1;
}
Exemplo n.º 16
0
void test_object_tree_write__subtree(void)
{
	/* write a hierarchical tree from a memory */
	git_treebuilder *builder;
	git_tree *tree;
	git_oid id, bid, subtree_id, id2, id3;
	git_oid id_hiearar;

	git_oid_fromstr(&id, first_tree);
	git_oid_fromstr(&id2, second_tree);
	git_oid_fromstr(&id3, third_tree);
	git_oid_fromstr(&bid, blob_oid);

	/* create subtree */
	cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
	cl_git_pass(git_treebuilder_insert(
		NULL, builder, "new.txt", &bid, GIT_FILEMODE_BLOB)); /* -V536 */
	cl_git_pass(git_treebuilder_write(&subtree_id, builder));
	git_treebuilder_free(builder);

	/* create parent tree */
	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
	cl_git_pass(git_treebuilder_new(&builder, g_repo, tree));
	cl_git_pass(git_treebuilder_insert(
		NULL, builder, "new", &subtree_id, GIT_FILEMODE_TREE)); /* -V536 */
	cl_git_pass(git_treebuilder_write(&id_hiearar, builder));
	git_treebuilder_free(builder);
	git_tree_free(tree);

	cl_assert(git_oid_cmp(&id_hiearar, &id3) == 0);

	/* check data is correct */
	cl_git_pass(git_tree_lookup(&tree, g_repo, &id_hiearar));
	cl_assert(2 == git_tree_entrycount(tree));
	git_tree_free(tree);
}
Exemplo n.º 17
0
static void do_walk(struct gbr_dump_context *dump_ctx,
		    const char *remote, const git_oid *o1, const git_oid *o2)
{
	struct gbr_sha sha;
	struct gbr_walk_context *ctx;

	if (git_oid_cmp(o1, o2) == 0) {
		/* Skip the costly walking */
		dump_info(remote, gbr_sha(&sha, o2, dump_ctx->abbrev), 0, 0);
		dump_ctx->uptodate_remotes++;
		return;
	}

	ctx = gbr_walk_init(dump_ctx->repo, o1, o2);
	if (ctx == NULL) {
		return;
	}


	/* Walk from the base down towards the head of each commit and
	 * note when they start diverging.
	 */
	while (gbr_walk_next(ctx) != 0) {
		;
	}

	dump_info(remote, gbr_sha(&sha, o2, dump_ctx->abbrev),
		  ctx->count[0], ctx->count[1]);

	gbr_walk_free(ctx);

	if (ctx->count[0] == 0) {
		/* 0 Diverging commits here. */
		dump_ctx->uptodate_remotes++;
	}
}
Exemplo n.º 18
0
void test_clone_nonetwork__can_detached_head(void)
{
	git_object *obj;
	git_repository *cloned;
	git_reference *cloned_head;

	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));

	cl_git_pass(git_revparse_single(&obj, g_repo, "master~1"));
	cl_git_pass(git_repository_set_head_detached(g_repo, git_object_id(obj)));

	cl_git_pass(git_clone(&cloned, "./foo", "./foo1", &g_options));

	cl_assert(git_repository_head_detached(cloned));

	cl_git_pass(git_repository_head(&cloned_head, cloned));
	cl_assert(!git_oid_cmp(git_object_id(obj), git_reference_target(cloned_head)));

	git_object_free(obj);
	git_reference_free(cloned_head);
	git_repository_free(cloned);

	cl_fixture_cleanup("./foo1");
}
Exemplo n.º 19
0
int merge_test_workdir(git_repository *repo, const struct merge_index_entry expected[], size_t expected_len)
{
	size_t actual_len = 0, i;
	git_oid actual_oid, expected_oid;
	git_buf wd = GIT_BUF_INIT;

	git_buf_puts(&wd, repo->workdir);
	git_path_direach(&wd, 0, dircount, &actual_len);

	if (actual_len != expected_len)
		return 0;

	for (i = 0; i < expected_len; i++) {
		git_blob_create_fromworkdir(&actual_oid, repo, expected[i].path);
		git_oid_fromstr(&expected_oid, expected[i].oid_str);

		if (git_oid_cmp(&actual_oid, &expected_oid) != 0)
			return 0;
	}

	git_buf_free(&wd);

	return 1;
}
Exemplo n.º 20
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.º 21
0
int git_commit_amend(
	git_oid *id,
	const git_commit *commit_to_amend,
	const char *update_ref,
	const git_signature *author,
	const git_signature *committer,
	const char *message_encoding,
	const char *message,
	const git_tree *tree)
{
	git_repository *repo;
	git_oid tree_id;
	git_reference *ref;
	int error;

	assert(id && commit_to_amend);

	repo = git_commit_owner(commit_to_amend);

	if (!author)
		author = git_commit_author(commit_to_amend);
	if (!committer)
		committer = git_commit_committer(commit_to_amend);
	if (!message_encoding)
		message_encoding = git_commit_message_encoding(commit_to_amend);
	if (!message)
		message = git_commit_message(commit_to_amend);

	if (!tree) {
		git_tree *old_tree;
		GITERR_CHECK_ERROR( git_commit_tree(&old_tree, commit_to_amend) );
		git_oid_cpy(&tree_id, git_tree_id(old_tree));
		git_tree_free(old_tree);
	} else {
		assert(git_tree_owner(tree) == repo);
		git_oid_cpy(&tree_id, git_tree_id(tree));
	}

	if (update_ref) {
		if ((error = git_reference_lookup_resolved(&ref, repo, update_ref, 5)) < 0)
			return error;

		if (git_oid_cmp(git_commit_id(commit_to_amend), git_reference_target(ref))) {
			git_reference_free(ref);
			giterr_set(GITERR_REFERENCE, "commit to amend is not the tip of the given branch");
			return -1;
		}
	}

	error = git_commit__create_internal(
		id, repo, NULL, author, committer, message_encoding, message,
		&tree_id, commit_parent_for_amend, (void *)commit_to_amend, false);

	if (!error && update_ref) {
		error = git_reference__update_for_commit(
			repo, ref, NULL, id, "commit");
		git_reference_free(ref);
	}

	return error;
}
Exemplo n.º 22
0
int CGitIndexList::GetFileStatus(const CString &gitdir, const CString &pathorg, git_wc_status_kind *status, __int64 time, __int64 filesize, FILL_STATUS_CALLBACK callback, void *pData, CGitHash *pHash, bool * assumeValid, bool * skipWorktree)
{
	if (!status)
		return 0;

	CString path = pathorg;
	path.MakeLower();

	int index = SearchInSortVector(*this, path, -1);

	if (index < 0)
	{
		*status = git_wc_status_unversioned;
		if (pHash)
			pHash->Empty();

		if (callback && assumeValid && skipWorktree)
			callback(CombinePath(gitdir, pathorg), *status, false, pData, *assumeValid, *skipWorktree);

		return 0;
	}

	// skip-worktree has higher priority than assume-valid
	if (at(index).m_FlagsExtended & GIT_IDXENTRY_SKIP_WORKTREE)
	{
		*status = git_wc_status_normal;
		if (skipWorktree)
			*skipWorktree = true;
	}
	else if (at(index).m_Flags & GIT_IDXENTRY_VALID)
	{
		*status = git_wc_status_normal;
		if (assumeValid)
			*assumeValid = true;
	}
	else if (filesize != at(index).m_Size)
		*status = git_wc_status_modified;
	else if (time == at(index).m_ModifyTime)
		*status = git_wc_status_normal;
	else if (repository && filesize < m_iMaxCheckSize)
	{
		git_oid actual;
		CStringA fileA = CUnicodeUtils::GetMulti(pathorg, CP_UTF8);
		m_critRepoSec.Lock(); // prevent concurrent access to repository instance and especially filter-lists
		if (!git_repository_hashfile(&actual, repository, fileA, GIT_OBJ_BLOB, nullptr) && !git_oid_cmp(&actual, (const git_oid*)at(index).m_IndexHash.m_hash))
		{
			at(index).m_ModifyTime = time;
			*status = git_wc_status_normal;
		}
		else
			*status = git_wc_status_modified;
		m_critRepoSec.Unlock();
	}
	else
		*status = git_wc_status_modified;

	if (at(index).m_Flags & GIT_IDXENTRY_STAGEMASK)
		*status = git_wc_status_conflicted;
	else if (at(index).m_FlagsExtended & GIT_IDXENTRY_INTENT_TO_ADD)
		*status = git_wc_status_added;

	if (pHash)
		*pHash = at(index).m_IndexHash;

	if (callback && assumeValid && skipWorktree)
		callback(CombinePath(gitdir, pathorg), *status, false, pData, *assumeValid, *skipWorktree);

	return 0;
}
Exemplo n.º 23
0
/* Compare two oid structures. */
static int kGitOid_compareTo(kRawPtr *p1, kRawPtr *p2)
{
    const git_oid *a = (const git_oid *)p1->rawptr;
    const git_oid *b = (const git_oid *)p2->rawptr;
    return git_oid_cmp(a, b);
}
Exemplo n.º 24
0
#define STATUS_REPOSITORY_TEMP_FOLDER TEMP_REPO_FOLDER ".gitted/"

BEGIN_TEST(file0, "test retrieving OID from a file apart from the ODB")
	git_oid expected_id, actual_id;
	char filename[] = "new_file";
	int fd;

	fd = p_creat(filename, 0644);
	must_pass(fd);
	must_pass(p_write(fd, "new_file\n", 9));
	must_pass(p_close(fd));

	must_pass(git_odb_hashfile(&actual_id, filename, GIT_OBJ_BLOB));

	must_pass(git_oid_fromstr(&expected_id, test_blob_oid));
	must_be_true(git_oid_cmp(&expected_id, &actual_id) == 0);

	must_pass(p_unlink(filename));
END_TEST

static const char *entry_paths[] = {
	"current_file",
	"file_deleted",
	"modified_file",
	"new_file",
	"staged_changes",
	"staged_changes_file_deleted",
	"staged_changes_modified_file",
	"staged_delete_file_deleted",
	"staged_delete_modified_file",
	"staged_new_file",
Exemplo n.º 25
0
int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
{
	git_mwindow *w = NULL;
	unsigned int i, long_offsets = 0, left;
	int error;
	struct git_pack_idx_header hdr;
	git_buf filename = GIT_BUF_INIT;
	struct entry *entry;
	git_oid trailer_hash, file_hash;
	git_hash_ctx ctx;
	git_filebuf index_file = {0};
	void *packfile_trailer;

	if (git_hash_ctx_init(&ctx) < 0)
		return -1;

	/* Test for this before resolve_deltas(), as it plays with idx->off */
	if (idx->off < idx->pack->mwf.size - 20) {
		giterr_set(GITERR_INDEXER, "Unexpected data at the end of the pack");
		return -1;
	}

	packfile_trailer = git_mwindow_open(&idx->pack->mwf, &w, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ, &left);
	if (packfile_trailer == NULL) {
		git_mwindow_close(&w);
		goto on_error;
	}

	/* Compare the packfile trailer as it was sent to us and what we calculated */
	git_oid_fromraw(&file_hash, (unsigned char*) packfile_trailer);
	git_mwindow_close(&w);

	git_hash_final(&trailer_hash, &idx->trailer);
	if (git_oid_cmp(&file_hash, &trailer_hash)) {
		giterr_set(GITERR_INDEXER, "packfile trailer mismatch");
		return -1;
	}

	/* Freeze the number of deltas */
	stats->total_deltas = stats->total_objects - stats->indexed_objects;

	if ((error = resolve_deltas(idx, stats)) < 0)
		return error;

	if (stats->indexed_objects != stats->total_objects) {
		giterr_set(GITERR_INDEXER, "early EOF");
		return -1;
	}

	if (stats->local_objects > 0) {
		if (update_header_and_rehash(idx, stats) < 0)
			return -1;

		git_hash_final(&trailer_hash, &idx->trailer);
		write_at(idx, &trailer_hash, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ);
	}

	git_vector_sort(&idx->objects);

	git_buf_sets(&filename, idx->pack->pack_name);
	git_buf_shorten(&filename, strlen("pack"));
	git_buf_puts(&filename, "idx");
	if (git_buf_oom(&filename))
		return -1;

	if (git_filebuf_open(&index_file, filename.ptr,
		GIT_FILEBUF_HASH_CONTENTS, idx->mode) < 0)
		goto on_error;

	/* Write out the header */
	hdr.idx_signature = htonl(PACK_IDX_SIGNATURE);
	hdr.idx_version = htonl(2);
	git_filebuf_write(&index_file, &hdr, sizeof(hdr));

	/* Write out the fanout table */
	for (i = 0; i < 256; ++i) {
		uint32_t n = htonl(idx->fanout[i]);
		git_filebuf_write(&index_file, &n, sizeof(n));
	}

	/* Write out the object names (SHA-1 hashes) */
	git_vector_foreach(&idx->objects, i, entry, struct entry*) {
		git_filebuf_write(&index_file, &entry->oid, sizeof(git_oid));
		git_hash_update(&ctx, &entry->oid, GIT_OID_RAWSZ);
	}
	git_hash_final(&idx->hash, &ctx);

	/* Write out the CRC32 values */
	git_vector_foreach(&idx->objects, i, entry, struct entry*) {
		git_filebuf_write(&index_file, &entry->crc, sizeof(uint32_t));
	}

	/* Write out the offsets */
	git_vector_foreach(&idx->objects, i, entry, struct entry*) {
		uint32_t n;

		if (entry->offset == UINT32_MAX)
			n = htonl(0x80000000 | long_offsets++);
		else
			n = htonl(entry->offset);

		git_filebuf_write(&index_file, &n, sizeof(uint32_t));
	}

	/* Write out the long offsets */
	git_vector_foreach(&idx->objects, i, entry, struct entry*) {
		uint32_t split[2];

		if (entry->offset != UINT32_MAX)
			continue;

		split[0] = htonl(entry->offset_long >> 32);
		split[1] = htonl(entry->offset_long & 0xffffffff);

		git_filebuf_write(&index_file, &split, sizeof(uint32_t) * 2);
	}

	/* Write out the packfile trailer to the index */
	if (git_filebuf_write(&index_file, &trailer_hash, GIT_OID_RAWSZ) < 0)
		goto on_error;

	/* Write out the hash of the idx */
	if (git_filebuf_hash(&trailer_hash, &index_file) < 0)
		goto on_error;

	git_filebuf_write(&index_file, &trailer_hash, sizeof(git_oid));

	/* Figure out what the final name should be */
	if (index_path(&filename, idx, ".idx") < 0)
		goto on_error;

	/* Commit file */
	if (git_filebuf_commit_at(&index_file, filename.ptr) < 0)
		goto on_error;

	git_mwindow_free_all(&idx->pack->mwf);
	/* We need to close the descriptor here so Windows doesn't choke on commit_at */
	if (p_close(idx->pack->mwf.fd) < 0) {
		giterr_set(GITERR_OS, "failed to close packfile");
		goto on_error;
	}

	idx->pack->mwf.fd = -1;

	if (index_path(&filename, idx, ".pack") < 0)
		goto on_error;

	/* And don't forget to rename the packfile to its new place. */
	p_rename(idx->pack->pack_name, git_buf_cstr(&filename));

	git_buf_free(&filename);
	git_hash_ctx_cleanup(&ctx);
	return 0;

on_error:
	git_mwindow_free_all(&idx->pack->mwf);
	git_filebuf_cleanup(&index_file);
	git_buf_free(&filename);
	git_hash_ctx_cleanup(&ctx);
	return -1;
}
Exemplo n.º 26
0
	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));

	git_oid_mkstr(&id1, tag1_id);
	git_oid_mkstr(&id2, tag2_id);
	git_oid_mkstr(&id_commit, tagged_commit);

	must_pass(git_tag_lookup(&tag1, repo, &id1));

	must_be_true(strcmp(git_tag_name(tag1), "test") == 0);
	must_be_true(git_tag_type(tag1) == GIT_OBJ_TAG);

	must_pass(git_tag_target((git_object **)&tag2, tag1));
	must_be_true(tag2 != NULL);

	must_be_true(git_oid_cmp(&id2, git_tag_id(tag2)) == 0);

	must_pass(git_tag_target((git_object **)&commit, tag2));
	must_be_true(commit != NULL);

	must_be_true(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0);

	git_tag_close(tag1);
	git_tag_close(tag2);
	git_commit_close(commit);
	git_repository_free(repo);
END_TEST

BEGIN_TEST(read1, "list all tag names from the repository")
	git_repository *repo;
	git_strarray tag_list;
Exemplo n.º 27
0
void test_pack_indexer__fix_thin(void)
{
	git_indexer *idx = NULL;
	git_transfer_progress stats = { 0 };
	git_repository *repo;
	git_odb *odb;
	git_oid id, should_id;

	cl_git_pass(git_repository_init(&repo, "thin.git", true));
	cl_git_pass(git_repository_odb(&odb, repo));

	/* Store the missing base into your ODB so the indexer can fix the pack */
	cl_git_pass(git_odb_write(&id, odb, base_obj, base_obj_len, GIT_OBJ_BLOB));
	git_oid_fromstr(&should_id, "e68fe8129b546b101aee9510c5328e7f21ca1d18");
	cl_assert(!git_oid_cmp(&id, &should_id));

	cl_git_pass(git_indexer_new(&idx, ".", 0, odb, NULL, NULL));
	cl_git_pass(git_indexer_append(idx, thin_pack, thin_pack_len, &stats));
	cl_git_pass(git_indexer_commit(idx, &stats));

	cl_assert_equal_i(stats.total_objects, 2);
	cl_assert_equal_i(stats.received_objects, 2);
	cl_assert_equal_i(stats.indexed_objects, 2);
	cl_assert_equal_i(stats.local_objects, 1);

	git_oid_fromstr(&should_id, "11f0f69b334728fdd8bc86b80499f22f29d85b15");
	cl_assert(!git_oid_cmp(git_indexer_hash(idx), &should_id));

	git_indexer_free(idx);
	git_odb_free(odb);
	git_repository_free(repo);

	/*
	 * The pack's name/hash only tells us what objects there are,
	 * so we need to go through the packfile again in order to
	 * figure out whether we calculated the trailer correctly.
	 */
	{
		unsigned char buffer[128];
		int fd;
		ssize_t read;
		struct stat st;
		const char *name = "pack-11f0f69b334728fdd8bc86b80499f22f29d85b15.pack";

		fd = p_open(name, O_RDONLY);
		cl_assert(fd != -1);

		cl_git_pass(p_stat(name, &st));

		cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL));
		read = p_read(fd, buffer, sizeof(buffer));
		cl_assert(read != -1);
		p_close(fd);

		cl_git_pass(git_indexer_append(idx, buffer, read, &stats));
		cl_git_pass(git_indexer_commit(idx, &stats));

		cl_assert_equal_i(stats.total_objects, 3);
		cl_assert_equal_i(stats.received_objects, 3);
		cl_assert_equal_i(stats.indexed_objects, 3);
		cl_assert_equal_i(stats.local_objects, 0);

		git_indexer_free(idx);
	}
}
Exemplo n.º 28
0
Arquivo: index.c Projeto: hef/libgit2
int git_index__parse(git_index *index, const char *buffer, size_t buffer_size)
{
	unsigned int i;
	struct index_header header;
	git_oid checksum_calculated, checksum_expected;

#define seek_forward(_increase) { \
	if (_increase >= buffer_size) \
		return GIT_EOBJCORRUPTED; \
	buffer += _increase; \
	buffer_size -= _increase;\
}

	if (buffer_size < INDEX_HEADER_SIZE + INDEX_FOOTER_SIZE)
		return GIT_EOBJCORRUPTED;

	/* Precalculate the SHA1 of the files's contents -- we'll match it to
	 * the provided SHA1 in the footer */
	git_hash_buf(&checksum_calculated, (const void *)buffer, buffer_size - INDEX_FOOTER_SIZE);

	/* Parse header */
	if (read_header(&header, buffer) < 0)
		return GIT_EOBJCORRUPTED;

	seek_forward(INDEX_HEADER_SIZE);

	index->entry_count = header.entry_count;

	/* If there is already a entires array, reuse it if it can hold all the
	 * entries. If not, free and reallocate */
	if (index->entry_count > index->entries_size) {
		free(index->entries);
		index->entries_size = (uint32_t)(index->entry_count * 1.3f);
		index->entries = git__malloc(index->entries_size * sizeof(git_index_entry));
	}

	/* Parse all the entries */
	for (i = 0; i < index->entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) {
		size_t entry_size;
		entry_size = read_entry(&index->entries[i], buffer, buffer_size);

		/* 0 bytes read means an object corruption */
		if (entry_size == 0)
			return GIT_EOBJCORRUPTED;

		seek_forward(entry_size);
	}

	if (i != index->entry_count)
		return GIT_EOBJCORRUPTED;

	/* There's still space for some extensions! */
	while (buffer_size > INDEX_FOOTER_SIZE) {
		size_t extension_size;

		extension_size = read_extension(index, buffer, buffer_size);

		/* see if we have read any bytes from the extension */
		if (extension_size == 0)
			return GIT_EOBJCORRUPTED;

		seek_forward(extension_size);
	}

	if (buffer_size != INDEX_FOOTER_SIZE)
		return GIT_EOBJCORRUPTED;

	/* 160-bit SHA-1 over the content of the index file before this checksum. */
	git_oid_mkraw(&checksum_expected, (const unsigned char *)buffer);

	if (git_oid_cmp(&checksum_calculated, &checksum_expected) != 0)
		return GIT_EOBJCORRUPTED;

#undef seek_forward

	return 0;
}
Exemplo n.º 29
0
	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));

	must_pass(git_reference_lookup(&reference, repo, GIT_HEAD_FILE));
	must_be_true(reference->type & GIT_REF_SYMBOLIC);
	must_be_true((reference->type & GIT_REF_PACKED) == 0);
	must_be_true(strcmp(reference->name, GIT_HEAD_FILE) == 0);

	must_pass(git_reference_resolve(&resolved_ref, reference));
	must_be_true(resolved_ref->type == GIT_REF_OID);

	must_pass(git_object_lookup(&object, repo, git_reference_oid(resolved_ref), GIT_OBJ_ANY));
	must_be_true(object != NULL);
	must_be_true(git_object_type(object) == GIT_OBJ_COMMIT);

	git_oid_fromstr(&id, current_master_tip);
	must_be_true(git_oid_cmp(&id, git_object_id(object)) == 0);

	git_object_close(object);
	git_repository_free(repo);
END_TEST

BEGIN_TEST(readsym1, "lookup a nested symbolic reference")
	git_repository *repo;
	git_reference *reference, *resolved_ref;
	git_object *object;
	git_oid id;

	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));

	must_pass(git_reference_lookup(&reference, repo, head_tracker_sym_ref_name));
	must_be_true(reference->type & GIT_REF_SYMBOLIC);
Exemplo n.º 30
0
int git_revwalk__commit_keycmp(const void *key_a, const void *key_b)
{
	git_commit *a = (git_commit *)key_a;
	git_commit *b = (git_commit *)key_b;
	return git_oid_cmp(&a->object.id, &b->object.id);
}