summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVicent Martí <tanoku@gmail.com>2012-01-02 09:58:39 +0100
committerVicent Martí <tanoku@gmail.com>2012-01-02 09:58:39 +0100
commit7a704309ae012b8e92eb6103b0d14dd3c22a1cb5 (patch)
treea0e917d553db5fc4475be2fff7004268dc36d13d /src
parent9191a6d2466d0f3c187a66f65757c95c1c3f772d (diff)
parent0fb3fba123d8fbd99a9e1f9f47c192c704daee24 (diff)
downloadlibgit2-7a704309ae012b8e92eb6103b0d14dd3c22a1cb5.tar.gz
Merge remote-tracking branch 'drizzd/diff-index-tests' into development
Conflicts: tests-clay/clay.h tests-clay/clay_main.c
Diffstat (limited to 'src')
-rw-r--r--src/index.c42
-rw-r--r--src/repository.c3
-rw-r--r--src/tree.c35
-rw-r--r--src/tree.h5
4 files changed, 66 insertions, 19 deletions
diff --git a/src/index.c b/src/index.c
index 43e8efa57..9f9a08f0d 100644
--- a/src/index.c
+++ b/src/index.c
@@ -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);
+}
diff --git a/src/repository.c b/src/repository.c
index a94ecce55..a408599f7 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -349,9 +349,6 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo)
{
assert(out && repo);
- if (repo->is_bare)
- return git__throw(GIT_EBAREINDEX, "Cannot open index in bare repository");
-
if (repo->_index == NULL) {
int error;
git_buf index_path = GIT_BUF_INIT;
diff --git a/src/tree.c b/src/tree.c
index b698a8a24..8bc17d975 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -15,8 +15,6 @@
#define MAX_FILEMODE 0777777
#define MAX_FILEMODE_BYTES 6
-#define ENTRY_IS_TREE(e) ((e)->attr & 040000)
-
static int valid_attributes(const int attributes)
{
return attributes >= 0 && attributes <= MAX_FILEMODE;
@@ -33,8 +31,8 @@ static int entry_sort_cmp(const void *a, const void *b)
const git_tree_entry *entry_b = (const git_tree_entry *)(b);
return git_futils_cmp_path(
- entry_a->filename, entry_a->filename_len, ENTRY_IS_TREE(entry_a),
- entry_b->filename, entry_b->filename_len, ENTRY_IS_TREE(entry_b));
+ entry_a->filename, entry_a->filename_len, entry_is_tree(entry_a),
+ entry_b->filename, entry_b->filename_len, entry_is_tree(entry_b));
}
@@ -717,7 +715,7 @@ static int tree_walk_post(
if (callback(path->ptr, entry, payload) < 0)
continue;
- if (ENTRY_IS_TREE(entry)) {
+ if (entry_is_tree(entry)) {
git_tree *subtree;
size_t path_len = path->size;
@@ -961,15 +959,22 @@ static int cmp_tentry_ientry(git_tree_entry *tentry, git_index_entry *ientry)
return git_oid_cmp(&tentry->oid, &ientry->oid);
}
-static void make_tentry(git_tree_entry *tentry, git_index_entry *ientry, git_buf *buf)
+static void make_tentry(git_tree_entry *tentry, git_index_entry *ientry)
{
+ char *last_slash;
+
memset(tentry, 0x0, sizeof(git_tree_entry));
tentry->attr = ientry->mode;
+
+ last_slash = strrchr(ientry->path, '/');
+ if (last_slash)
+ last_slash++;
+ else
+ last_slash = ientry->path;
+ tentry->filename = last_slash;
+
git_oid_cpy(&tentry->oid, &ientry->oid);
- if (buf != NULL) {
- tentry->filename = buf->ptr;
- tentry->filename_len = buf->size;
- }
+ tentry->filename_len = strlen(tentry->filename);
}
static int diff_index_cb(const char *root, git_tree_entry *tentry, void *data)
@@ -980,7 +985,7 @@ static int diff_index_cb(const char *root, git_tree_entry *tentry, void *data)
git_buf fn_buf = GIT_BUF_INIT;
int cmp, error = GIT_SUCCESS;
- if (ENTRY_IS_TREE(tentry))
+ if (entry_is_tree(tentry))
return GIT_SUCCESS;
git_buf_puts(&fn_buf, root);
@@ -993,25 +998,24 @@ static int diff_index_cb(const char *root, git_tree_entry *tentry, void *data)
/* Like with 'git diff-index', the index is the right side*/
cmp = strcmp(git_buf_cstr(&fn_buf), ientry->path);
+ git_buf_free(&fn_buf);
if (cmp == 0) {
cbdata->i++;
if (!cmp_tentry_ientry(tentry, ientry))
goto exit;
/* modification */
- make_tentry(&fake_entry, ientry, &fn_buf);
+ make_tentry(&fake_entry, ientry);
if ((error = signal_modification(tentry, &fake_entry, cbdata->cb, cbdata->data)) < 0)
goto exit;
} else if (cmp < 0) {
/* deletion */
memcpy(&fake_entry, tentry, sizeof(git_tree_entry));
- fake_entry.filename = fn_buf.ptr;
- fake_entry.filename_len = fn_buf.size;
if ((error = signal_deletion(tentry, cbdata->cb, cbdata->data)) < 0)
goto exit;
} else {
/* addition */
cbdata->i++;
- make_tentry(&fake_entry, ientry, &fn_buf);
+ make_tentry(&fake_entry, ientry);
if ((error = signal_addition(&fake_entry, cbdata->cb, cbdata->data)) < 0)
goto exit;
/*
@@ -1024,7 +1028,6 @@ static int diff_index_cb(const char *root, git_tree_entry *tentry, void *data)
}
exit:
- git_buf_free(&fn_buf);
return error;
}
diff --git a/src/tree.h b/src/tree.h
index 4f8c07f08..6b2a7d36d 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -31,6 +31,11 @@ struct git_treebuilder {
};
+GIT_INLINE(unsigned int) entry_is_tree(const struct git_tree_entry *e)
+{
+ return e->attr & 040000;
+}
+
void git_tree__free(git_tree *tree);
int git_tree__parse(git_tree *tree, git_odb_object *obj);