Merge branch 'jc/add-ita'
authorShawn O. Pearce <spearce@spearce.org>
Thu, 9 Oct 2008 17:21:25 +0000 (10:21 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Thu, 9 Oct 2008 17:21:25 +0000 (10:21 -0700)
* jc/add-ita:
git-add --intent-to-add (-N)

1  2 
cache.h
read-cache.c
diff --combined cache.h
index 9f4e5c0d459dcf73c86ef977469ba4885cc8f4c2,f725783b80f05b7f23495534f86e5f35a40811bd..b5a5e03ac833468e952481858b23b332634f3b94
+++ b/cache.h
@@@ -6,14 -6,8 +6,14 @@@
  #include "hash.h"
  
  #include SHA1_HEADER
 -#include <zlib.h>
 +#ifndef git_SHA_CTX
 +#define git_SHA_CTX   SHA_CTX
 +#define git_SHA1_Init SHA1_Init
 +#define git_SHA1_Update       SHA1_Update
 +#define git_SHA1_Final        SHA1_Final
 +#endif
  
 +#include <zlib.h>
  #if defined(NO_DEFLATE_BOUND) || ZLIB_VERNUM < 0x1200
  #define deflateBound(c,s)  ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11)
  #endif
@@@ -377,6 -371,7 +377,7 @@@ extern int index_name_pos(const struct 
  #define ADD_CACHE_OK_TO_REPLACE 2     /* Ok to replace file/directory */
  #define ADD_CACHE_SKIP_DFCHECK 4      /* Ok to skip DF conflict checks */
  #define ADD_CACHE_JUST_APPEND 8               /* Append only; tree.c::read_tree() */
+ #define ADD_CACHE_NEW_ONLY 16         /* Do not replace existing ones */
  extern int add_index_entry(struct index_state *, struct cache_entry *ce, int option);
  extern struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really);
  extern void rename_index_entry_at(struct index_state *, int pos, const char *new_name);
@@@ -386,6 -381,7 +387,7 @@@ extern int remove_file_from_index(struc
  #define ADD_CACHE_PRETEND 2
  #define ADD_CACHE_IGNORE_ERRORS       4
  #define ADD_CACHE_IGNORE_REMOVAL 8
+ #define ADD_CACHE_INTENT 16
  extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags);
  extern int add_file_to_index(struct index_state *, const char *path, int flags);
  extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh);
@@@ -539,7 -535,6 +541,7 @@@ static inline int is_absolute_path(cons
  {
        return path[0] == '/' || has_dos_drive_prefix(path);
  }
 +int is_directory(const char *);
  const char *make_absolute_path(const char *path);
  const char *make_nonrelative_path(const char *path);
  const char *make_relative_path(const char *abs, const char *base);
@@@ -647,8 -642,6 +649,8 @@@ extern struct alternate_object_databas
  } *alt_odb_list;
  extern void prepare_alt_odb(void);
  extern void add_to_alternates_file(const char *reference);
 +typedef int alt_odb_fn(struct alternate_object_database *, void *);
 +extern void foreach_alt_odb(alt_odb_fn, void*);
  
  struct pack_window {
        struct pack_window *next;
@@@ -717,11 -710,7 +719,11 @@@ extern struct child_process *git_connec
  extern int finish_connect(struct child_process *conn);
  extern int path_match(const char *path, int nr, char **match);
  extern int get_ack(int fd, unsigned char *result_sha1);
 -extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags);
 +struct extra_have_objects {
 +      int nr, alloc;
 +      unsigned char (*array)[20];
 +};
 +extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags, struct extra_have_objects *);
  extern int server_supports(const char *feature);
  
  extern struct packed_git *parse_pack_index(unsigned char *sha1);
@@@ -755,6 -744,7 +757,6 @@@ typedef int (*config_fn_t)(const char *
  extern int git_default_config(const char *, const char *, void *);
  extern int git_config_from_file(config_fn_t fn, const char *, void *);
  extern int git_config(config_fn_t fn, void *);
 -extern int git_parse_long(const char *, long *);
  extern int git_parse_ulong(const char *, unsigned long *);
  extern int git_config_int(const char *, const char *);
  extern unsigned long git_config_ulong(const char *, const char *);
diff --combined read-cache.c
index 901064bf1ae72aacb583ff735058eec953475ae3,276b09e66f603fa3816640a0f692775c5e15ba32..d7900f33ea472e6781ba68b3943cb29ae0a1db34
@@@ -13,6 -13,7 +13,7 @@@
  #include "diff.h"
  #include "diffcore.h"
  #include "revision.h"
+ #include "blob.h"
  
  /* Index extensions.
   *
@@@ -511,6 -512,14 +512,14 @@@ static struct cache_entry *create_alias
        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;
        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);
        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);
                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;
  
        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);
@@@ -848,13 -865,15 +865,15 @@@ static int add_index_entry_with_check(s
        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;
@@@ -1072,16 -1091,16 +1091,16 @@@ struct cache_entry *refresh_cache_entry
  
  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;
@@@ -1253,7 -1272,6 +1272,7 @@@ int discard_index(struct index_state *i
        istate->cache_nr = 0;
        istate->cache_changed = 0;
        istate->timestamp = 0;
 +      istate->name_hash_initialized = 0;
        free_hash(&istate->name_hash);
        cache_tree_free(&(istate->cache_tree));
        free(istate->alloc);
@@@ -1278,11 -1296,11 +1297,11 @@@ int unmerged_index(const struct index_s
  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;
        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;
        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);
                (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 */
        }
  
        /* 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 -1410,7 +1411,7 @@@ static void ce_smudge_racily_clean_entr
        }
  }
  
 -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);
  
  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;
        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;