Commit 599f2849 by Clemens Buchacher

add git_index_read_tree

parent a26a1563
......@@ -301,6 +301,17 @@ GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged_byindex(git_
*/
GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry);
/**
* Read a tree into the index file
*
* The current index contents will be replaced by the specified tree.
*
* @param index an existing index object
* @param tree tree to read
* @return GIT_SUCCESS or an error code
*/
GIT_EXTERN(int) git_index_read_tree(git_index *index, git_tree *tree);
/** @} */
GIT_END_DECL
#endif
......@@ -10,6 +10,7 @@
#include "common.h"
#include "repository.h"
#include "index.h"
#include "tree.h"
#include "tree-cache.h"
#include "hash.h"
#include "git2/odb.h"
......@@ -936,3 +937,44 @@ int git_index_entry_stage(const git_index_entry *entry)
{
return (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT;
}
static int read_tree_cb(const char *root, git_tree_entry *tentry, void *data)
{
int ret = GIT_SUCCESS;
git_index *index = data;
git_index_entry *entry = NULL;
git_buf path = GIT_BUF_INIT;
if (entry_is_tree(tentry))
goto exit;
ret = git_buf_joinpath(&path, root, tentry->filename);
if (ret < GIT_SUCCESS)
goto exit;
entry = git__calloc(1, sizeof(git_index_entry));
if (!entry) {
ret = GIT_ENOMEM;
goto exit;
}
entry->mode = tentry->attr;
entry->oid = tentry->oid;
entry->path = git_buf_detach(&path);
ret = index_insert(index, entry, 0);
exit:
git_buf_free(&path);
if (ret < GIT_SUCCESS)
index_entry_free(entry);
return ret;
}
int git_index_read_tree(git_index *index, git_tree *tree)
{
git_index_clear(index);
return git_tree_walk(tree, read_tree_cb, GIT_TREEWALK_POST, index);
}
#include "clay_libgit2.h"
#include "testlib.h"
#include "posix.h"
/* Test that reading and writing a tree is a no-op */
void test_index_read_tree__read_write_involution(void)
{
git_repository *repo;
git_index *index;
git_oid tree_oid;
git_tree *tree;
git_oid expected;
p_mkdir("read_tree", 0700);
cl_git_pass(git_repository_init(&repo, "./read_tree", 0));
cl_git_pass(git_repository_index(&index, repo));
cl_assert(git_index_entrycount(index) == 0);
p_mkdir("./read_tree/abc", 0700);
/* Sort order: '-' < '/' < '_' */
file_create("./read_tree/abc-d", NULL);
file_create("./read_tree/abc/d", NULL);
file_create("./read_tree/abc_d", NULL);
cl_git_pass(git_index_add(index, "abc-d", 0));
cl_git_pass(git_index_add(index, "abc_d", 0));
cl_git_pass(git_index_add(index, "abc/d", 0));
/* write-tree */
cl_git_pass(git_tree_create_fromindex(&expected, index));
/* read-tree */
git_tree_lookup(&tree, repo, &expected);
cl_git_pass(git_index_read_tree(index, tree));
cl_git_pass(git_tree_create_fromindex(&tree_oid, index));
cl_assert(git_oid_cmp(&expected, &tree_oid) == 0);
git_index_free(index);
git_repository_free(repo);
cl_fixture_cleanup("read_tree");
}
#include "clay_libgit2.h"
#include "testlib.h"
#include "posix.h"
static void file_create(const char *filename, const char *content)
{
int fd;
fd = p_creat(filename, 0666);
cl_assert(fd != 0);
cl_git_pass(p_write(fd, content, strlen(content)));
cl_git_pass(p_close(fd));
}
void test_index_rename__single_file(void)
{
git_repository *repo;
......
#include "clay.h"
#include "testlib.h"
#include "posix.h"
void file_create(const char *filename, const char *content)
{
int fd;
fd = p_creat(filename, 0666);
cl_assert(fd != 0);
if (content) {
cl_must_pass(p_write(fd, content, strlen(content)));
} else {
cl_must_pass(p_write(fd, filename, strlen(filename)));
cl_must_pass(p_write(fd, "\n", 1));
}
cl_must_pass(p_close(fd));
}
#ifndef INCLUDE_testlib_h__
#define INCLUDE_testlib_h__
void file_create(const char *filename, const char *content);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment