Code

mktree: fix a memory leak in write_tree()
[git.git] / read-cache.c
index a363f312c7f70d2a087dc16ebfe0969a03c1be42..8b1c94e0e3f539cd0b507fd130b60aa443b9680b 100644 (file)
@@ -7,6 +7,7 @@
 #include "cache.h"
 #include "cache-tree.h"
 #include "refs.h"
+#include "dir.h"
 
 /* Index extensions.
  *
@@ -380,7 +381,7 @@ static int index_name_pos_also_unmerged(struct index_state *istate,
 
 int add_file_to_index(struct index_state *istate, const char *path, int verbose)
 {
-       int size, namelen;
+       int size, namelen, pos;
        struct stat st;
        struct cache_entry *ce;
 
@@ -414,6 +415,15 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
                ce->ce_mode = ce_mode_from_stat(ent, st.st_mode);
        }
 
+       pos = index_name_pos(istate, ce->name, namelen);
+       if (0 <= pos &&
+           !ce_stage(istate->cache[pos]) &&
+           !ie_modified(istate, istate->cache[pos], &st, 1)) {
+               /* Nothing changed, really */
+               free(ce);
+               return 0;
+       }
+
        if (index_path(ce->sha1, path, &st, 1))
                die("unable to index file %s", path);
        if (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))
@@ -656,7 +666,7 @@ static int check_file_directory_conflict(struct index_state *istate,
        return retval + has_dir_name(istate, ce, pos, ok_to_replace);
 }
 
-int add_index_entry(struct index_state *istate, struct cache_entry *ce, int option)
+static int add_index_entry_with_check(struct index_state *istate, struct cache_entry *ce, int option)
 {
        int pos;
        int ok_to_add = option & ADD_CACHE_OK_TO_ADD;
@@ -698,6 +708,22 @@ int add_index_entry(struct index_state *istate, struct cache_entry *ce, int opti
                pos = index_name_pos(istate, ce->name, ntohs(ce->ce_flags));
                pos = -pos-1;
        }
+       return pos + 1;
+}
+
+int add_index_entry(struct index_state *istate, struct cache_entry *ce, int option)
+{
+       int pos;
+
+       if (option & ADD_CACHE_JUST_APPEND)
+               pos = istate->cache_nr;
+       else {
+               int ret;
+               ret = add_index_entry_with_check(istate, ce, option);
+               if (ret <= 0)
+                       return ret;
+               pos = ret - 1;
+       }
 
        /* Make sure the array is big enough .. */
        if (istate->cache_nr == istate->cache_alloc) {
@@ -708,7 +734,7 @@ int add_index_entry(struct index_state *istate, struct cache_entry *ce, int opti
 
        /* Add it in.. */
        istate->cache_nr++;
-       if (istate->cache_nr > pos)
+       if (istate->cache_nr > pos + 1)
                memmove(istate->cache + pos + 1,
                        istate->cache + pos,
                        (istate->cache_nr - pos - 1) * sizeof(ce));
@@ -773,7 +799,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
        return updated;
 }
 
-int refresh_index(struct index_state *istate, unsigned int flags)
+int refresh_index(struct index_state *istate, unsigned int flags, const char **pathspec, char *seen)
 {
        int i;
        int has_errors = 0;
@@ -799,6 +825,9 @@ int refresh_index(struct index_state *istate, unsigned int flags)
                        continue;
                }
 
+               if (pathspec && !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen))
+                       continue;
+
                new = refresh_cache_ent(istate, ce, really, &cache_errno);
                if (new == ce)
                        continue;