Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cache.h18
-rw-r--r--unpack-trees.c2
2 files changed, 18 insertions, 2 deletions
diff --git a/cache.h b/cache.h
index 88d3b92d2e..fa5a9e523e 100644
--- a/cache.h
+++ b/cache.h
@@ -110,7 +110,6 @@ struct ondisk_cache_entry {
};
struct cache_entry {
- struct cache_entry *next;
unsigned int ce_ctime;
unsigned int ce_mtime;
unsigned int ce_dev;
@@ -121,6 +120,7 @@ struct cache_entry {
unsigned int ce_size;
unsigned int ce_flags;
unsigned char sha1[20];
+ struct cache_entry *next;
char name[FLEX_ARRAY]; /* more */
};
@@ -138,6 +138,22 @@ struct cache_entry {
#define CE_UNHASHED (0x200000)
/*
+ * Copy the sha1 and stat state of a cache entry from one to
+ * another. But we never change the name, or the hash state!
+ */
+#define CE_STATE_MASK (CE_HASHED | CE_UNHASHED)
+static inline void copy_cache_entry(struct cache_entry *dst, struct cache_entry *src)
+{
+ unsigned int state = dst->ce_flags & CE_STATE_MASK;
+
+ /* Don't copy hash chain and name */
+ memcpy(dst, src, offsetof(struct cache_entry, next));
+
+ /* Restore the hash state */
+ dst->ce_flags = (dst->ce_flags & ~CE_STATE_MASK) | state;
+}
+
+/*
* We don't actually *remove* it, we can just mark it invalid so that
* we won't find it in lookups.
*
diff --git a/unpack-trees.c b/unpack-trees.c
index ec558f9005..07c4c28a5a 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -590,7 +590,7 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
* a match.
*/
if (same(old, merge)) {
- memcpy(merge, old, offsetof(struct cache_entry, name));
+ copy_cache_entry(merge, old);
} else {
verify_uptodate(old, o);
invalidate_ce_path(old);