]> git.ipfire.org Git - thirdparty/git.git/blobdiff - read-cache.c
print an error message for invalid path
[thirdparty/git.git] / read-cache.c
index 5b1b3ad03b6d7294ca06b5b1053799958ad831c7..6f344f345d09b36e379cbc8beb2c3992c6d5809c 100644 (file)
@@ -13,6 +13,7 @@
 #include "diff.h"
 #include "diffcore.h"
 #include "revision.h"
+#include "blob.h"
 
 /* Index extensions.
  *
@@ -511,6 +512,14 @@ static struct cache_entry *create_alias_ce(struct cache_entry *ce, struct cache_
        return new;
 }
 
+static void record_intent_to_add(struct cache_entry *ce)
+{
+       unsigned char sha1[20];
+       if (write_sha1_file("", 0, blob_type, sha1))
+               die("cannot create an empty blob in the object database");
+       hashcpy(ce->sha1, sha1);
+}
+
 int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags)
 {
        int size, namelen, was_same;
@@ -519,6 +528,9 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
        unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY;
        int verbose = flags & (ADD_CACHE_VERBOSE | ADD_CACHE_PRETEND);
        int pretend = flags & ADD_CACHE_PRETEND;
+       int intent_only = flags & ADD_CACHE_INTENT;
+       int add_option = (ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE|
+                         (intent_only ? ADD_CACHE_NEW_ONLY : 0));
 
        if (!S_ISREG(st_mode) && !S_ISLNK(st_mode) && !S_ISDIR(st_mode))
                return error("%s: can only add regular files, symbolic links or git-directories", path);
@@ -532,7 +544,8 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
        ce = xcalloc(1, size);
        memcpy(ce->name, path, namelen);
        ce->ce_flags = namelen;
-       fill_stat_cache_info(ce, st);
+       if (!intent_only)
+               fill_stat_cache_info(ce, st);
 
        if (trust_executable_bit && has_symlinks)
                ce->ce_mode = create_ce_mode(st_mode);
@@ -555,8 +568,12 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
                alias->ce_flags |= CE_ADDED;
                return 0;
        }
-       if (index_path(ce->sha1, path, st, 1))
-               return error("unable to index file %s", path);
+       if (!intent_only) {
+               if (index_path(ce->sha1, path, st, 1))
+                       return error("unable to index file %s", path);
+       } else
+               record_intent_to_add(ce);
+
        if (ignore_case && alias && different_name(ce, alias))
                ce = create_alias_ce(ce, alias);
        ce->ce_flags |= CE_ADDED;
@@ -569,7 +586,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
 
        if (pretend)
                ;
-       else if (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))
+       else if (add_index_entry(istate, ce, add_option))
                return error("unable to add %s to index",path);
        if (verbose && !was_same)
                printf("add '%s'\n", path);
@@ -591,8 +608,10 @@ struct cache_entry *make_cache_entry(unsigned int mode,
        int size, len;
        struct cache_entry *ce;
 
-       if (!verify_path(path))
+       if (!verify_path(path)) {
+               error("Invalid path '%s'", path);
                return NULL;
+       }
 
        len = strlen(path);
        size = cache_entry_size(len);
@@ -848,13 +867,15 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
        int ok_to_add = option & ADD_CACHE_OK_TO_ADD;
        int ok_to_replace = option & ADD_CACHE_OK_TO_REPLACE;
        int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK;
+       int new_only = option & ADD_CACHE_NEW_ONLY;
 
        cache_tree_invalidate_path(istate->cache_tree, ce->name);
        pos = index_name_pos(istate, ce->name, ce->ce_flags);
 
        /* existing match? Just replace it. */
        if (pos >= 0) {
-               replace_index_entry(istate, pos, ce);
+               if (!new_only)
+                       replace_index_entry(istate, pos, ce);
                return 0;
        }
        pos = -pos-1;
@@ -874,7 +895,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
        if (!ok_to_add)
                return -1;
        if (!verify_path(ce->name))
-               return -1;
+               return error("Invalid path '%s'", ce->name);
 
        if (!skip_df_check &&
            check_file_directory_conflict(istate, ce, pos, ok_to_replace)) {
@@ -1072,16 +1093,16 @@ struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really)
 
 static int verify_hdr(struct cache_header *hdr, unsigned long size)
 {
-       SHA_CTX c;
+       git_SHA_CTX c;
        unsigned char sha1[20];
 
        if (hdr->hdr_signature != htonl(CACHE_SIGNATURE))
                return error("bad signature");
        if (hdr->hdr_version != htonl(2))
                return error("bad index version");
-       SHA1_Init(&c);
-       SHA1_Update(&c, hdr, size - 20);
-       SHA1_Final(sha1, &c);
+       git_SHA1_Init(&c);
+       git_SHA1_Update(&c, hdr, size - 20);
+       git_SHA1_Final(sha1, &c);
        if (hashcmp(sha1, (unsigned char *)hdr + size - 20))
                return error("bad index file sha1 signature");
        return 0;
@@ -1278,11 +1299,11 @@ int unmerged_index(const struct index_state *istate)
 static unsigned char write_buffer[WRITE_BUFFER_SIZE];
 static unsigned long write_buffer_len;
 
-static int ce_write_flush(SHA_CTX *context, int fd)
+static int ce_write_flush(git_SHA_CTX *context, int fd)
 {
        unsigned int buffered = write_buffer_len;
        if (buffered) {
-               SHA1_Update(context, write_buffer, buffered);
+               git_SHA1_Update(context, write_buffer, buffered);
                if (write_in_full(fd, write_buffer, buffered) != buffered)
                        return -1;
                write_buffer_len = 0;
@@ -1290,7 +1311,7 @@ static int ce_write_flush(SHA_CTX *context, int fd)
        return 0;
 }
 
-static int ce_write(SHA_CTX *context, int fd, void *data, unsigned int len)
+static int ce_write(git_SHA_CTX *context, int fd, void *data, unsigned int len)
 {
        while (len) {
                unsigned int buffered = write_buffer_len;
@@ -1312,7 +1333,7 @@ static int ce_write(SHA_CTX *context, int fd, void *data, unsigned int len)
        return 0;
 }
 
-static int write_index_ext_header(SHA_CTX *context, int fd,
+static int write_index_ext_header(git_SHA_CTX *context, int fd,
                                  unsigned int ext, unsigned int sz)
 {
        ext = htonl(ext);
@@ -1321,13 +1342,13 @@ static int write_index_ext_header(SHA_CTX *context, int fd,
                (ce_write(context, fd, &sz, 4) < 0)) ? -1 : 0;
 }
 
-static int ce_flush(SHA_CTX *context, int fd)
+static int ce_flush(git_SHA_CTX *context, int fd)
 {
        unsigned int left = write_buffer_len;
 
        if (left) {
                write_buffer_len = 0;
-               SHA1_Update(context, write_buffer, left);
+               git_SHA1_Update(context, write_buffer, left);
        }
 
        /* Flush first if not enough space for SHA1 signature */
@@ -1338,7 +1359,7 @@ static int ce_flush(SHA_CTX *context, int fd)
        }
 
        /* Append the SHA1 signature at the end */
-       SHA1_Final(write_buffer + left, context);
+       git_SHA1_Final(write_buffer + left, context);
        left += 20;
        return (write_in_full(fd, write_buffer, left) != left) ? -1 : 0;
 }
@@ -1392,7 +1413,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
        }
 }
 
-static int ce_write_entry(SHA_CTX *c, int fd, struct cache_entry *ce)
+static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce)
 {
        int size = ondisk_ce_size(ce);
        struct ondisk_cache_entry *ondisk = xcalloc(1, size);
@@ -1416,7 +1437,7 @@ static int ce_write_entry(SHA_CTX *c, int fd, struct cache_entry *ce)
 
 int write_index(const struct index_state *istate, int newfd)
 {
-       SHA_CTX c;
+       git_SHA_CTX c;
        struct cache_header hdr;
        int i, err, removed;
        struct cache_entry **cache = istate->cache;
@@ -1430,7 +1451,7 @@ int write_index(const struct index_state *istate, int newfd)
        hdr.hdr_version = htonl(2);
        hdr.hdr_entries = htonl(entries - removed);
 
-       SHA1_Init(&c);
+       git_SHA1_Init(&c);
        if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0)
                return -1;