Пример #1
0
static int tree_reader_read(
	git_buf *out,
	git_oid *out_id,
	git_filemode_t *out_filemode,
	git_reader *_reader,
	const char *filename)
{
	tree_reader *reader = (tree_reader *)_reader;
	git_tree_entry *tree_entry = NULL;
	git_blob *blob = NULL;
	int error;

	if ((error = git_tree_entry_bypath(&tree_entry, reader->tree, filename)) < 0 ||
	    (error = git_blob_lookup(&blob, git_tree_owner(reader->tree), git_tree_entry_id(tree_entry))) < 0 ||
	    (error = git_buf_set(out, git_blob_rawcontent(blob), git_blob_rawsize(blob))) < 0)
		goto done;

	if (out_id)
		git_oid_cpy(out_id, git_tree_entry_id(tree_entry));

	if (out_filemode)
		*out_filemode = git_tree_entry_filemode(tree_entry);

done:
	git_blob_free(blob);
	git_tree_entry_free(tree_entry);
	return error;
}
Пример #2
0
int git_object_lookup_bypath(
		git_object **out,
		const git_object *treeish,
		const char *path,
		git_otype type)
{
	int error = -1;
	git_tree *tree = NULL;
	git_tree_entry *entry = NULL;

	assert(out && treeish && path);

	if ((error = git_object_peel((git_object**)&tree, treeish, GIT_OBJ_TREE)) < 0 ||
		 (error = git_tree_entry_bypath(&entry, tree, path)) < 0)
	{
		goto cleanup;
	}

	if (type != GIT_OBJ_ANY && git_tree_entry_type(entry) != type)
	{
		giterr_set(GITERR_OBJECT,
				"object at path '%s' is not of the asked-for type %d",
				path, type);
		error = GIT_EINVALIDSPEC;
		goto cleanup;
	}

	error = git_tree_entry_to_object(out, git_object_owner(treeish), entry);

cleanup:
	git_tree_entry_free(entry);
	git_tree_free(tree);
	return error;
}
Пример #3
0
int
Tree_contains(Tree *self, PyObject *py_name)
{
    int err;
    git_tree_entry *entry;
    char *name;

    name = py_path_to_c_str(py_name);
    if (name == NULL)
        return -1;

    err = git_tree_entry_bypath(&entry, self->tree, name);
    free(name);

    if (err == GIT_ENOTFOUND)
        return 0;

    if (err < 0) {
        Error_set(err);
        return -1;
    }

    git_tree_entry_free(entry);

    return 1;
}
Пример #4
0
static int handle_colon_syntax(
	git_object **out,
	git_object *obj,
	const char *path)
{
	git_object *tree;
	int error = -1;
	git_tree_entry *entry = NULL;

	if ((error = git_object_peel(&tree, obj, GIT_OBJ_TREE)) < 0)
		return error == GIT_ENOTFOUND ? GIT_EINVALIDSPEC : error;

	if (*path == '\0') {
		*out = tree;
		return 0;
	}

	/*
	 * TODO: Handle the relative path syntax
	 * (:./relative/path and :../relative/path)
	 */
	if ((error = git_tree_entry_bypath(&entry, (git_tree *)tree, path)) < 0)
		goto cleanup;

	error = git_tree_entry_to_object(out, git_object_owner(tree), entry);

cleanup:
	git_tree_entry_free(entry);
	git_object_free(tree);

	return error;
}
Пример #5
0
void
TreeEntry_dealloc(TreeEntry *self)
{
    Py_CLEAR(self->owner);
    git_tree_entry_free((git_tree_entry*)self->entry);
    PyObject_Del(self);
}
Пример #6
0
static void assert_tree_from_path(
	git_tree *root,
	const char *path,
	const char *expected_entry_name)
{
	git_tree_entry *entry;

	cl_git_pass(git_tree_entry_bypath(&entry, root, path));
	cl_assert_equal_s(git_tree_entry_name(entry), expected_entry_name);
	git_tree_entry_free(entry);
}
Пример #7
0
static VALUE rb_git_tree_path(VALUE self, VALUE rb_path)
{
  int error;
  git_tree *tree;
  git_tree_entry *entry;
  VALUE rb_entry;
  Data_Get_Struct(self, git_tree, tree);
  Check_Type(rb_path, T_STRING);

  error = git_tree_entry_bypath(&entry, tree, StringValueCStr(rb_path));
  rugged_exception_check(error);

  rb_entry = rb_git_treeentry_fromC(entry);
  git_tree_entry_free(entry);

  return rb_entry;
}
Пример #8
0
void test_clone_nonetwork__clone_tag_to_tree(void)
{
	git_repository *stage;
	git_index_entry entry;
	git_index *index;
	git_odb *odb;
	git_oid tree_id;
	git_tree *tree;
	git_reference *tag;
	git_tree_entry *tentry;
	const char *file_path = "some/deep/path.txt";
	const char *file_content = "some content\n";
	const char *tag_name = "refs/tags/tree-tag";

	stage = cl_git_sandbox_init("testrepo.git");
	cl_git_pass(git_repository_odb(&odb, stage));
	cl_git_pass(git_index_new(&index));

	memset(&entry, 0, sizeof(git_index_entry));
	entry.path = file_path;
	entry.mode = GIT_FILEMODE_BLOB;
	cl_git_pass(git_odb_write(&entry.id, odb, file_content, strlen(file_content), GIT_OBJ_BLOB));

	cl_git_pass(git_index_add(index, &entry));
	cl_git_pass(git_index_write_tree_to(&tree_id, index, stage));
	cl_git_pass(git_reference_create(&tag, stage, tag_name, &tree_id, 0, NULL));
	git_reference_free(tag);
	git_odb_free(odb);
	git_index_free(index);

	g_options.local = GIT_CLONE_NO_LOCAL;
	cl_git_pass(git_clone(&g_repo, cl_git_path_url(git_repository_path(stage)), "./foo", &g_options));
	git_repository_free(stage);

	cl_git_pass(git_reference_lookup(&tag, g_repo, tag_name));
	cl_git_pass(git_tree_lookup(&tree, g_repo, git_reference_target(tag)));
	git_reference_free(tag);

	cl_git_pass(git_tree_entry_bypath(&tentry, tree, file_path));
	git_tree_entry_free(tentry);
	git_tree_free(tree);

	cl_fixture_cleanup("testrepo.git");
}
Пример #9
0
void
TreeEntry_dealloc(TreeEntry *self)
{
    git_tree_entry_free((git_tree_entry*)self->entry);
    PyObject_Del(self);
}
Пример #10
0
void test_object_tree_write__cruel_paths(void)
{
	static const char *the_paths[] = {
		"C:\\",
		" : * ? \" \n < > |",
		"a\\b",
		"\\\\b\a",
		":\\",
		"COM1",
		"foo.aux",
		REP1024("1234"), /* 4096 char string */
		REP1024("12345678"), /* 8192 char string */
		"\xC5\xAA\x6E\xC4\xAD\x63\xC5\x8D\x64\x65\xCC\xBD", /* Ūnĭcōde̽ */
		NULL
	};
	git_treebuilder *builder;
	git_tree *tree;
	git_oid id, bid, subid;
	const char **scan;
	int count = 0, i, j;
	git_tree_entry *te;

	git_oid_fromstr(&bid, blob_oid);

	/* create tree */
	cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
	for (scan = the_paths; *scan; ++scan) {
		cl_git_pass(git_treebuilder_insert(
			NULL, builder, *scan, &bid, GIT_FILEMODE_BLOB));
		count++;
	}
	cl_git_pass(git_treebuilder_write(&id, builder));
	git_treebuilder_free(builder);

	/* check data is correct */
	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));

	cl_assert_equal_i(count, git_tree_entrycount(tree));

	for (scan = the_paths; *scan; ++scan) {
		const git_tree_entry *cte = git_tree_entry_byname(tree, *scan);
		cl_assert(cte != NULL);
		cl_assert_equal_s(*scan, git_tree_entry_name(cte));
	}
	for (scan = the_paths; *scan; ++scan) {
		cl_git_pass(git_tree_entry_bypath(&te, tree, *scan));
		cl_assert_equal_s(*scan, git_tree_entry_name(te));
		git_tree_entry_free(te);
	}

	git_tree_free(tree);

	/* let's try longer paths */
	cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
	for (scan = the_paths; *scan; ++scan) {
		cl_git_pass(git_treebuilder_insert(
			NULL, builder, *scan, &id, GIT_FILEMODE_TREE));
	}
	cl_git_pass(git_treebuilder_write(&subid, builder));
	git_treebuilder_free(builder);

	/* check data is correct */
	cl_git_pass(git_tree_lookup(&tree, g_repo, &subid));

	cl_assert_equal_i(count, git_tree_entrycount(tree));

	for (i = 0; i < count; ++i) {
		for (j = 0; j < count; ++j) {
			git_buf b = GIT_BUF_INIT;
			cl_git_pass(git_buf_joinpath(&b, the_paths[i], the_paths[j]));
			cl_git_pass(git_tree_entry_bypath(&te, tree, b.ptr));
			cl_assert_equal_s(the_paths[j], git_tree_entry_name(te));
			git_tree_entry_free(te);
			git_buf_free(&b);
		}
	}

	git_tree_free(tree);
}
Пример #11
0
void PmrWorkspace::stageFile(const QString &pPath, bool pStage)
{
    // Un/stage the file, which path is given, and let people know of the
    // outcome

    if (isOpen()) {
        QByteArray relativePathByteArray = QDir(mPath).relativeFilePath(pPath).toUtf8();
        const char *relativePath = relativePathByteArray.constData();
        bool success = false;
        git_index *index;

       if (git_repository_index(&index, mGitRepository) == GIT_OK) {
            if (pStage) {
                uint statusFlags = 0;

                git_status_file(&statusFlags, mGitRepository, relativePath);

                if ((statusFlags & GIT_STATUS_WT_DELETED) != 0) {
                    success = git_index_remove_bypath(index, relativePath) == GIT_OK;
                } else {
                    success = git_index_add_bypath(index, relativePath) == GIT_OK;
                }
            } else if (git_repository_head_unborn(mGitRepository) == 1) {
                success = git_index_remove_bypath(index, relativePath) == GIT_OK;
            } else {
                // We need to add a "reset stage" to the index, which means
                // getting the tree for HEAD and tree_entry for the file

                git_reference *head;

                if (git_repository_head(&head, mGitRepository) == GIT_OK) {
                    git_tree *headTree;

                    if (git_reference_peel(reinterpret_cast<git_object **>(&headTree),
                                           head, GIT_OBJECT_TREE) == GIT_OK) {
                        git_tree_entry *headEntry;

                        if (git_tree_entry_bypath(&headEntry, headTree,
                                                  relativePath) == GIT_OK) {
                            git_index_entry indexEntry;

                            memset(&indexEntry, '\0', sizeof(git_index_entry));

                            indexEntry.id = *git_tree_entry_id(headEntry);
                            indexEntry.mode = uint32_t(git_tree_entry_filemode(headEntry));
                            indexEntry.path = relativePath;

                            git_index_add(index, &indexEntry);

                            git_tree_entry_free(headEntry);

                            success = true;
                        } else {
                            success = git_index_remove_bypath(index, relativePath) == GIT_OK;
                        }

                        git_tree_free(headTree);
                    }

                    git_reference_free(head);
                }
            }

            if (success) {
                git_index_write(index);
            }

            git_index_free(index);
        }

        if (!success) {
            emitGitError(tr("An error occurred while trying to stage %1.").arg(pPath));
        }
    }
}
Пример #12
0
QByteArray PmrWorkspace::headFileContents(const QString &pFileName)
{
    // Retrieve the contents of the given file name at the HEAD revision
    // Note: the below code is based on Repository::GetHeadBlob() from git-utils
    //       (see https://github.com/atom/git-utils)...

    git_reference *head;

    if (git_repository_head(&head, mGitRepository) != GIT_OK) {
        return {};
    }

    const git_oid *sha = git_reference_target(head);
    git_commit *commit;
    int commitStatus = git_commit_lookup(&commit, mGitRepository, sha);

    git_reference_free(head);

    if (commitStatus != GIT_OK) {
        return {};
    }

    git_tree *tree;
    int treeStatus = git_commit_tree(&tree, commit);

    git_commit_free(commit);

    if (treeStatus != GIT_OK) {
        return {};
    }

    git_tree_entry *treeEntry;

    if (git_tree_entry_bypath(&treeEntry, tree, pFileName.toUtf8().constData()) != GIT_OK) {
        git_tree_free(tree);

        return {};
    }

    git_blob *blob = nullptr;
    const git_oid *blobSha = git_tree_entry_id(treeEntry);

    if (   (blobSha != nullptr)
        && (git_blob_lookup(&blob, mGitRepository, blobSha) != GIT_OK)) {
        blob = nullptr;
    }

    git_tree_entry_free(treeEntry);
    git_tree_free(tree);

    if (blob == nullptr) {
        return {};
    }

    QByteArray res(static_cast<const char *>(git_blob_rawcontent(blob)),
                   int(git_blob_rawsize(blob)));

    git_blob_free(blob);

    return res;
}