Exemple #1
0
void test_object_tree_frompath__fail_when_processing_an_invalid_path(void)
{
	git_tree_entry *e;

	cl_must_fail(git_tree_entry_bypath(&e, tree, "/"));
	cl_must_fail(git_tree_entry_bypath(&e, tree, "/ab"));
	cl_must_fail(git_tree_entry_bypath(&e, tree, "/ab/de"));
	cl_must_fail(git_tree_entry_bypath(&e, tree, "ab//de"));
}
Exemple #2
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;
}
Exemple #3
0
TreeEntry *
Tree_getitem(Tree *self, PyObject *value)
{
    char *path;
    git_tree_entry *entry;
    int err;

    /* Case 1: integer */
    if (PyLong_Check(value))
        return Tree_getitem_by_index(self, value);

    /* Case 2: byte or text string */
    path = py_path_to_c_str(value);
    if (path == NULL)
        return NULL;

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

    if (err == GIT_ENOTFOUND) {
        PyErr_SetObject(PyExc_KeyError, value);
        return NULL;
    }

    if (err < 0)
        return (TreeEntry*)Error_set(err);

    /* git_tree_entry_dup is already done in git_tree_entry_bypath */
    return wrap_tree_entry(entry);
}
Exemple #4
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;
}
Exemple #5
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;
}
Exemple #6
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;
}
Exemple #7
0
/**
 * ggit_tree_get_by_path:
 * @tree: a #GgitTree.
 * @path: a path.
 * @error: a #GError for error reporting, or %NULL.
 *
 * Retrieves a tree entry contained in a tree or in any of its subtrees,
 * given its relative path.
 *
 * Returns: (transfer full): a #GgitTreeEntry.
 *
 **/
GgitTreeEntry *
ggit_tree_get_by_path (GgitTree     *tree,
                       const gchar  *path,
                       GError      **error)
{
	git_tree *t;
	GgitTreeEntry *entry = NULL;
	git_tree_entry *tree_entry;
	gint ret;

	g_return_val_if_fail (GGIT_IS_TREE (tree), NULL);
	g_return_val_if_fail (path != NULL, NULL);

	t = _ggit_native_get (tree);

	ret = git_tree_entry_bypath (&tree_entry, t, path);

	if (ret == GIT_OK)
	{
		entry = _ggit_tree_entry_wrap (tree_entry, TRUE);
	}
	else
	{
		_ggit_error_set (error, ret);
	}

	return entry;
}
Exemple #8
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);
}
Exemple #9
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;
}
Exemple #10
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");
}
Exemple #11
0
void test_object_tree_frompath__retrieve_tree_from_path_to_treeentry(void)
{
	git_tree_entry *e;

	assert_tree_from_path(tree, "README", "README");
	assert_tree_from_path(tree, "ab/de/fgh/1.txt", "1.txt");
	assert_tree_from_path(tree, "ab/de/fgh", "fgh");
	assert_tree_from_path(tree, "ab/de/fgh/", "fgh");
	assert_tree_from_path(tree, "ab/de", "de");
	assert_tree_from_path(tree, "ab/", "ab");
	assert_tree_from_path(tree, "ab/de/", "de");

	cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "i-do-not-exist.txt"));
	cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "README/"));
	cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "ab/de/fgh/i-do-not-exist.txt"));
	cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "nope/de/fgh/1.txt"));
	cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "ab/me-neither/fgh/2.txt"));
	cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "ab/me-neither/fgh/2.txt/"));
}
int CRepositoryBrowser::ReadTree(CShadowFilesTree * treeroot, const CString& root)
{
	CWaitCursor wait;
	CAutoRepository repository(g_Git.GetGitRepository());
	if (!repository)
	{
		MessageBox(CGit::GetLibGit2LastErr(_T("Could not open repository.")), _T("TortoiseGit"), MB_ICONERROR);
		return -1;
	}

	if (m_sRevision == _T("HEAD"))
	{
		int ret = git_repository_head_unborn(repository);
		if (ret == 1)	// is orphan
			return ret;
		else if (ret != 0)
		{
			MessageBox(g_Git.GetLibGit2LastErr(_T("Could not check HEAD.")), _T("TortoiseGit"), MB_ICONERROR);
			return ret;
		}
	}

	CGitHash hash;
	if (CGit::GetHash(repository, hash, m_sRevision))
	{
		MessageBox(CGit::GetLibGit2LastErr(_T("Could not get hash of ") + m_sRevision + _T(".")), _T("TortoiseGit"), MB_ICONERROR);
		return -1;
	}

	CAutoCommit commit;
	if (git_commit_lookup(commit.GetPointer(), repository, (git_oid *)hash.m_hash))
	{
		MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup commit.")), _T("TortoiseGit"), MB_ICONERROR);
		return -1;
	}

	CAutoTree tree;
	if (git_commit_tree(tree.GetPointer(), commit))
	{
		MessageBox(CGit::GetLibGit2LastErr(_T("Could not get tree of commit.")), _T("TortoiseGit"), MB_ICONERROR);
		return -1;
	}

	if (!root.IsEmpty())
	{
		CAutoTreeEntry treeEntry;
		if (git_tree_entry_bypath(treeEntry.GetPointer(), tree, CUnicodeUtils::GetUTF8(root)))
		{
			MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup path.")), _T("TortoiseGit"), MB_ICONERROR);
			return -1;
		}
		if (git_tree_entry_type(treeEntry) != GIT_OBJ_TREE)
		{
			MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup path.")), _T("TortoiseGit"), MB_ICONERROR);
			return -1;
		}

		CAutoObject object;
		if (git_tree_entry_to_object(object.GetPointer(), repository, treeEntry))
		{
			MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup path.")), _T("TortoiseGit"), MB_ICONERROR);
			return -1;
		}

		tree = (git_tree*)object.Detach();
	}

	treeroot->m_hash = CGitHash((char *)git_tree_id(tree)->id);
	ReadTreeRecursive(*repository, tree, treeroot);

	// try to resolve hash to a branch name
	if (m_sRevision == hash.ToString())
	{
		MAP_HASH_NAME map;
		if (CGit::GetMapHashToFriendName(repository, map))
			MessageBox(g_Git.GetLibGit2LastErr(_T("Could not get all refs.")), _T("TortoiseGit"), MB_ICONERROR);
		if (!map[hash].empty())
			m_sRevision = map[hash].at(0);
	}
	this->GetDlgItem(IDC_BUTTON_REVISION)->SetWindowText(m_sRevision);

	return 0;
}
Exemple #13
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);
}
Exemple #14
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));
        }
    }
}
Exemple #15
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;
}