summaryrefslogtreecommitdiff
path: root/fast-import.c
diff options
context:
space:
mode:
Diffstat (limited to 'fast-import.c')
-rw-r--r--fast-import.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/fast-import.c b/fast-import.c
index eab68d5..534c68d 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -156,6 +156,7 @@ Format of STDIN stream:
#include "csum-file.h"
#include "quote.h"
#include "exec_cmd.h"
+#include "dir.h"
#define PACK_ID_BITS 16
#define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
@@ -1437,6 +1438,20 @@ static void store_tree(struct tree_entry *root)
t->entry_count -= del;
}
+static void tree_content_replace(
+ struct tree_entry *root,
+ const unsigned char *sha1,
+ const uint16_t mode,
+ struct tree_content *newtree)
+{
+ if (!S_ISDIR(mode))
+ die("Root cannot be a non-directory");
+ hashcpy(root->versions[1].sha1, sha1);
+ if (root->tree)
+ release_tree_content_recursive(root->tree);
+ root->tree = newtree;
+}
+
static int tree_content_set(
struct tree_entry *root,
const char *p,
@@ -1444,7 +1459,7 @@ static int tree_content_set(
const uint16_t mode,
struct tree_content *subtree)
{
- struct tree_content *t = root->tree;
+ struct tree_content *t;
const char *slash1;
unsigned int i, n;
struct tree_entry *e;
@@ -1459,9 +1474,12 @@ static int tree_content_set(
if (!slash1 && !S_ISDIR(mode) && subtree)
die("Non-directories cannot have subtrees");
+ if (!root->tree)
+ load_tree(root);
+ t = root->tree;
for (i = 0; i < t->entry_count; i++) {
e = t->entries[i];
- if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
+ if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
if (!slash1) {
if (!S_ISDIR(mode)
&& e->versions[1].mode == mode
@@ -1514,7 +1532,7 @@ static int tree_content_remove(
const char *p,
struct tree_entry *backup_leaf)
{
- struct tree_content *t = root->tree;
+ struct tree_content *t;
const char *slash1;
unsigned int i, n;
struct tree_entry *e;
@@ -1525,9 +1543,12 @@ static int tree_content_remove(
else
n = strlen(p);
+ if (!root->tree)
+ load_tree(root);
+ t = root->tree;
for (i = 0; i < t->entry_count; i++) {
e = t->entries[i];
- if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
+ if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
if (slash1 && !S_ISDIR(e->versions[1].mode))
/*
* If p names a file in some subdirectory, and a
@@ -1572,7 +1593,7 @@ static int tree_content_get(
const char *p,
struct tree_entry *leaf)
{
- struct tree_content *t = root->tree;
+ struct tree_content *t;
const char *slash1;
unsigned int i, n;
struct tree_entry *e;
@@ -1583,9 +1604,12 @@ static int tree_content_get(
else
n = strlen(p);
+ if (!root->tree)
+ load_tree(root);
+ t = root->tree;
for (i = 0; i < t->entry_count; i++) {
e = t->entries[i];
- if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
+ if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
if (!slash1) {
memcpy(leaf, e, sizeof(*leaf));
if (e->tree && is_null_sha1(e->versions[1].sha1))
@@ -2209,6 +2233,10 @@ static void file_change_m(struct branch *b)
command_buf.buf);
}
+ if (!*p) {
+ tree_content_replace(&b->branch_tree, sha1, mode, NULL);
+ return;
+ }
tree_content_set(&b->branch_tree, p, sha1, mode, NULL);
}
@@ -2267,6 +2295,13 @@ static void file_change_cr(struct branch *b, int rename)
tree_content_get(&b->branch_tree, s, &leaf);
if (!leaf.versions[1].mode)
die("Path %s not in branch", s);
+ if (!*d) { /* C "path/to/subdir" "" */
+ tree_content_replace(&b->branch_tree,
+ leaf.versions[1].sha1,
+ leaf.versions[1].mode,
+ leaf.tree);
+ return;
+ }
tree_content_set(&b->branch_tree, d,
leaf.versions[1].sha1,
leaf.versions[1].mode,