summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ce33288)
raw | patch | inline | side by side (parent: ce33288)
author | Linus Torvalds <torvalds@linux-foundation.org> | |
Tue, 15 Jan 2008 00:03:17 +0000 (16:03 -0800) | ||
committer | Linus Torvalds <torvalds@linux-foundation.org> | |
Mon, 21 Jan 2008 20:44:31 +0000 (12:44 -0800) |
This converts the index explicitly on read and write to its on-disk
format, allowing the in-core format to contain more flags, and be
simpler.
In particular, the in-core format is now host-endian (as opposed to the
on-disk one that is network endian in order to be able to be shared
across machines) and as a result we can dispense with all the
htonl/ntohl on accesses to the cache_entry fields.
This will make it easier to make use of various temporary flags that do
not exist in the on-disk format.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
format, allowing the in-core format to contain more flags, and be
simpler.
In particular, the in-core format is now host-endian (as opposed to the
on-disk one that is network endian in order to be able to be shared
across machines) and as a result we can dispense with all the
htonl/ntohl on accesses to the cache_entry fields.
This will make it easier to make use of various temporary flags that do
not exist in the on-disk format.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
21 files changed:
builtin-apply.c | patch | blob | history | |
builtin-blame.c | patch | blob | history | |
builtin-commit.c | patch | blob | history | |
builtin-fsck.c | patch | blob | history | |
builtin-grep.c | patch | blob | history | |
builtin-ls-files.c | patch | blob | history | |
builtin-read-tree.c | patch | blob | history | |
builtin-rerere.c | patch | blob | history | |
builtin-update-index.c | patch | blob | history | |
cache-tree.c | patch | blob | history | |
cache.h | patch | blob | history | |
diff-lib.c | patch | blob | history | |
dir.c | patch | blob | history | |
entry.c | patch | blob | history | |
merge-index.c | patch | blob | history | |
merge-recursive.c | patch | blob | history | |
reachable.c | patch | blob | history | |
read-cache.c | patch | blob | history | |
sha1_name.c | patch | blob | history | |
tree.c | patch | blob | history | |
unpack-trees.c | patch | blob | history |
diff --git a/builtin-apply.c b/builtin-apply.c
index 15432b6782400b556333ee4117c7daaff20412ab..30d86f21972d1f7e0bee45d6bf582859b9819921 100644 (file)
--- a/builtin-apply.c
+++ b/builtin-apply.c
if (!ce)
return 0;
- if (S_ISGITLINK(ntohl(ce->ce_mode))) {
+ if (S_ISGITLINK(ce->ce_mode)) {
strbuf_grow(buf, 100);
strbuf_addf(buf, "Subproject commit %s\n", sha1_to_hex(ce->sha1));
} else {
static int verify_index_match(struct cache_entry *ce, struct stat *st)
{
- if (S_ISGITLINK(ntohl(ce->ce_mode))) {
+ if (S_ISGITLINK(ce->ce_mode)) {
if (!S_ISDIR(st->st_mode))
return -1;
return 0;
return error("%s: does not match index",
old_name);
if (cached)
- st_mode = ntohl(ce->ce_mode);
+ st_mode = ce->ce_mode;
} else if (stat_ret < 0)
return error("%s: %s", old_name, strerror(errno));
if (!cached)
- st_mode = ntohl(ce_mode_from_stat(ce, st.st_mode));
+ st_mode = ce_mode_from_stat(ce, st.st_mode);
if (patch->is_new < 0)
patch->is_new = 0;
@@ -2388,7 +2388,7 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
ce = xcalloc(1, ce_size);
memcpy(ce->name, path, namelen);
ce->ce_mode = create_ce_mode(mode);
- ce->ce_flags = htons(namelen);
+ ce->ce_flags = namelen;
if (S_ISGITLINK(mode)) {
const char *s = buf;
diff --git a/builtin-blame.c b/builtin-blame.c
index 9b4c02e87f7ef4a20d269ab9315b6977cf7fb3fb..c7e68874e7f02ac150343ab6d7a0aa95601f2ba3 100644 (file)
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -2092,7 +2092,7 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con
if (!mode) {
int pos = cache_name_pos(path, len);
if (0 <= pos)
- mode = ntohl(active_cache[pos]->ce_mode);
+ mode = active_cache[pos]->ce_mode;
else
/* Let's not bother reading from HEAD tree */
mode = S_IFREG | 0644;
diff --git a/builtin-commit.c b/builtin-commit.c
index 02279360f78f3533bcc3b9ab7caae866cb7ee97b..c63ff826fc1c87c232b61c0059f12bb26f3098b2 100644 (file)
--- a/builtin-commit.c
+++ b/builtin-commit.c
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
- if (ce->ce_flags & htons(CE_UPDATE))
+ if (ce->ce_flags & CE_UPDATE)
continue;
if (!pathspec_match(pattern, m, ce->name, 0))
continue;
diff --git a/builtin-fsck.c b/builtin-fsck.c
index 2a6e94deaf6b27f27ad7655ebf6072a05b25017c..6fc9525e0485f3dba00fa6bea8df1479221f0ce0 100644 (file)
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
struct blob *blob;
struct object *obj;
- mode = ntohl(active_cache[i]->ce_mode);
+ mode = active_cache[i]->ce_mode;
if (S_ISGITLINK(mode))
continue;
blob = lookup_blob(active_cache[i]->sha1);
diff --git a/builtin-grep.c b/builtin-grep.c
index 0d6cc7361f6e1a70e4d3d9e24913d60e8ceb9e58..9180b39e3f22e5d3805649c655c61aafc7861968 100644 (file)
--- a/builtin-grep.c
+++ b/builtin-grep.c
struct cache_entry *ce = active_cache[i];
char *name;
int kept;
- if (!S_ISREG(ntohl(ce->ce_mode)))
+ if (!S_ISREG(ce->ce_mode))
continue;
if (!pathspec_matches(paths, ce->name))
continue;
for (nr = 0; nr < active_nr; nr++) {
struct cache_entry *ce = active_cache[nr];
- if (!S_ISREG(ntohl(ce->ce_mode)))
+ if (!S_ISREG(ce->ce_mode))
continue;
if (!pathspec_matches(paths, ce->name))
continue;
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 0f0ab2da167c57402efad9dc09e58964759c23cd..d56e33e251036274dbe48e300fcebd8289624cbe 100644 (file)
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
return;
if (tag && *tag && show_valid_bit &&
- (ce->ce_flags & htons(CE_VALID))) {
+ (ce->ce_flags & CE_VALID)) {
static char alttag[4];
memcpy(alttag, tag, 3);
if (isalpha(tag[0]))
} else {
printf("%s%06o %s %d\t",
tag,
- ntohl(ce->ce_mode),
+ ce->ce_mode,
abbrev ? find_unique_abbrev(ce->sha1,abbrev)
: sha1_to_hex(ce->sha1),
ce_stage(ce));
continue;
if (show_unmerged && !ce_stage(ce))
continue;
- if (ce->ce_flags & htons(CE_UPDATE))
+ if (ce->ce_flags & CE_UPDATE)
continue;
show_ce_entry(ce_stage(ce) ? tag_unmerged : tag_cached, ce);
}
struct cache_entry *ce = active_cache[i];
if (!ce_stage(ce))
continue;
- ce->ce_flags |= htons(CE_STAGEMASK);
+ ce->ce_flags |= CE_STAGEMASK;
}
if (prefix) {
*/
if (last_stage0 &&
!strcmp(last_stage0->name, ce->name))
- ce->ce_flags |= htons(CE_UPDATE);
+ ce->ce_flags |= CE_UPDATE;
}
}
}
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index c0ea0342b755c6749391803d19f852182c0c512e..57854017535a36fc1fcd7bb997f198956391199d 100644 (file)
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
continue;
cache_tree_invalidate_path(active_cache_tree, ce->name);
last = ce;
- ce->ce_mode = 0;
- ce->ce_flags &= ~htons(CE_STAGEMASK);
+ ce->ce_flags |= CE_REMOVE;
}
*dst++ = ce;
}
diff --git a/builtin-rerere.c b/builtin-rerere.c
index a9e3ebc13725cbe8658478797d6e1d8e097e5292..b0c17bde879d42c16fe5c7f0756763cd638f8bac 100644 (file)
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
if (ce_stage(e2) == 2 &&
ce_stage(e3) == 3 &&
ce_same_name(e2, e3) &&
- S_ISREG(ntohl(e2->ce_mode)) &&
- S_ISREG(ntohl(e3->ce_mode))) {
+ S_ISREG(e2->ce_mode) &&
+ S_ISREG(e3->ce_mode)) {
path_list_insert((const char *)e2->name, conflict);
i++; /* skip over both #2 and #3 */
}
diff --git a/builtin-update-index.c b/builtin-update-index.c
index c3a14c74ed00db592db55a018db37657148a9900..a8795d3d5fea9f340dfe21a71190f120c63856cd 100644 (file)
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
if (0 <= pos) {
switch (mark_valid_only) {
case MARK_VALID:
- active_cache[pos]->ce_flags |= htons(CE_VALID);
+ active_cache[pos]->ce_flags |= CE_VALID;
break;
case UNMARK_VALID:
- active_cache[pos]->ce_flags &= ~htons(CE_VALID);
+ active_cache[pos]->ce_flags &= ~CE_VALID;
break;
}
cache_tree_invalidate_path(active_cache_tree, path);
size = cache_entry_size(len);
ce = xcalloc(1, size);
memcpy(ce->name, path, len);
- ce->ce_flags = htons(len);
+ ce->ce_flags = len;
fill_stat_cache_info(ce, st);
ce->ce_mode = ce_mode_from_stat(old, st->st_mode);
/* Exact match: file or existing gitlink */
if (pos >= 0) {
struct cache_entry *ce = active_cache[pos];
- if (S_ISGITLINK(ntohl(ce->ce_mode))) {
+ if (S_ISGITLINK(ce->ce_mode)) {
/* Do nothing to the index if there is no HEAD! */
if (resolve_gitlink_ref(path, "HEAD", sha1) < 0)
int pos = cache_name_pos(path, len);
struct cache_entry *ce = pos < 0 ? NULL : active_cache[pos];
- if (ce && S_ISGITLINK(ntohl(ce->ce_mode)))
+ if (ce && S_ISGITLINK(ce->ce_mode))
return error("%s is already a gitlink, not replacing", path);
return add_one_path(ce, path, len, st);
ce->ce_flags = create_ce_flags(len, stage);
ce->ce_mode = create_ce_mode(mode);
if (assume_unchanged)
- ce->ce_flags |= htons(CE_VALID);
+ ce->ce_flags |= CE_VALID;
option = allow_add ? ADD_CACHE_OK_TO_ADD : 0;
option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;
if (add_cache_entry(ce, option))
if (pos < 0)
goto fail;
ce = active_cache[pos];
- mode = ntohl(ce->ce_mode);
+ mode = ce->ce_mode;
if (!S_ISREG(mode))
goto fail;
switch (flip) {
case '+':
- ce->ce_mode |= htonl(0111); break;
+ ce->ce_mode |= 0111; break;
case '-':
- ce->ce_mode &= htonl(~0111); break;
+ ce->ce_mode &= ~0111; break;
default:
goto fail;
}
diff --git a/cache-tree.c b/cache-tree.c
index 50b35264fd0405a299700ef8bf4a61f416f30e46..bfc95d2dc9600083b73b61c06d2b32c983db8511 100644 (file)
--- a/cache-tree.c
+++ b/cache-tree.c
}
else {
sha1 = ce->sha1;
- mode = ntohl(ce->ce_mode);
+ mode = ce->ce_mode;
entlen = pathlen - baselen;
}
if (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1))
return error("invalid object %s", sha1_to_hex(sha1));
- if (!ce->ce_mode)
+ if (ce->ce_flags & CE_REMOVE)
continue; /* entry being removed */
strbuf_grow(&buffer, entlen + 100);
index 549f4bbac7242714283e58dd576460ca86015d52..4a054c5402c0e25770282bfae25b2a63cf3ca4b6 100644 (file)
--- a/cache.h
+++ b/cache.h
* We save the fields in big-endian order to allow using the
* index file over NFS transparently.
*/
+struct ondisk_cache_entry {
+ struct cache_time ctime;
+ struct cache_time mtime;
+ unsigned int dev;
+ unsigned int ino;
+ unsigned int mode;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int size;
+ unsigned char sha1[20];
+ unsigned short flags;
+ char name[FLEX_ARRAY]; /* more */
+};
+
struct cache_entry {
- struct cache_time ce_ctime;
- struct cache_time ce_mtime;
+ unsigned int ce_ctime;
+ unsigned int ce_mtime;
unsigned int ce_dev;
unsigned int ce_ino;
unsigned int ce_mode;
unsigned int ce_uid;
unsigned int ce_gid;
unsigned int ce_size;
+ unsigned int ce_flags;
unsigned char sha1[20];
- unsigned short ce_flags;
char name[FLEX_ARRAY]; /* more */
};
#define CE_NAMEMASK (0x0fff)
#define CE_STAGEMASK (0x3000)
-#define CE_UPDATE (0x4000)
#define CE_VALID (0x8000)
#define CE_STAGESHIFT 12
-#define create_ce_flags(len, stage) htons((len) | ((stage) << CE_STAGESHIFT))
-#define ce_namelen(ce) (CE_NAMEMASK & ntohs((ce)->ce_flags))
+/* In-memory only */
+#define CE_UPDATE (0x10000)
+#define CE_REMOVE (0x20000)
+
+#define create_ce_flags(len, stage) ((len) | ((stage) << CE_STAGESHIFT))
+#define ce_namelen(ce) (CE_NAMEMASK & (ce)->ce_flags)
#define ce_size(ce) cache_entry_size(ce_namelen(ce))
-#define ce_stage(ce) ((CE_STAGEMASK & ntohs((ce)->ce_flags)) >> CE_STAGESHIFT)
+#define ondisk_ce_size(ce) ondisk_cache_entry_size(ce_namelen(ce))
+#define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT)
#define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644)
static inline unsigned int create_ce_mode(unsigned int mode)
{
if (S_ISLNK(mode))
- return htonl(S_IFLNK);
+ return S_IFLNK;
if (S_ISDIR(mode) || S_ISGITLINK(mode))
- return htonl(S_IFGITLINK);
- return htonl(S_IFREG | ce_permissions(mode));
+ return S_IFGITLINK;
+ return S_IFREG | ce_permissions(mode);
}
static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned int mode)
{
extern int trust_executable_bit, has_symlinks;
if (!has_symlinks && S_ISREG(mode) &&
- ce && S_ISLNK(ntohl(ce->ce_mode)))
+ ce && S_ISLNK(ce->ce_mode))
return ce->ce_mode;
if (!trust_executable_bit && S_ISREG(mode)) {
- if (ce && S_ISREG(ntohl(ce->ce_mode)))
+ if (ce && S_ISREG(ce->ce_mode))
return ce->ce_mode;
return create_ce_mode(0666);
}
@@ -146,14 +164,14 @@ static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned in
S_ISLNK(mode) ? S_IFLNK : S_ISDIR(mode) ? S_IFDIR : S_IFGITLINK)
#define cache_entry_size(len) ((offsetof(struct cache_entry,name) + (len) + 8) & ~7)
+#define ondisk_cache_entry_size(len) ((offsetof(struct ondisk_cache_entry,name) + (len) + 8) & ~7)
struct index_state {
struct cache_entry **cache;
unsigned int cache_nr, cache_alloc, cache_changed;
struct cache_tree *cache_tree;
time_t timestamp;
- void *mmap;
- size_t mmap_size;
+ void *alloc;
};
extern struct index_state the_index;
diff --git a/diff-lib.c b/diff-lib.c
index d85d8f34ba055ad7e02bf5d61ae4a675ce0be1d3..4a05b02cd0f53f61efa1d3acd43ca66870b0b33d 100644 (file)
--- a/diff-lib.c
+++ b/diff-lib.c
if (!path || !strcmp(path, "/dev/null"))
*mode = 0;
else if (!strcmp(path, "-"))
- *mode = ntohl(create_ce_mode(0666));
+ *mode = create_ce_mode(0666);
else if (stat(path, &st))
return error("Could not access '%s'", path);
else
continue;
}
else
- dpath->mode = ntohl(ce_mode_from_stat(ce, st.st_mode));
+ dpath->mode = ce_mode_from_stat(ce, st.st_mode);
while (i < entries) {
struct cache_entry *nce = active_cache[i];
*/
stage = ce_stage(nce);
if (2 <= stage) {
- int mode = ntohl(nce->ce_mode);
+ int mode = nce->ce_mode;
num_compare_stages++;
hashcpy(dpath->parent[stage-2].sha1, nce->sha1);
- dpath->parent[stage-2].mode = ntohl(ce_mode_from_stat(nce, mode));
+ dpath->parent[stage-2].mode = ce_mode_from_stat(nce, mode);
dpath->parent[stage-2].status =
DIFF_STATUS_MODIFIED;
}
}
if (silent_on_removed)
continue;
- diff_addremove(&revs->diffopt, '-', ntohl(ce->ce_mode),
+ diff_addremove(&revs->diffopt, '-', ce->ce_mode,
ce->sha1, ce->name, NULL);
continue;
}
changed = ce_match_stat(ce, &st, ce_option);
if (!changed && !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
continue;
- oldmode = ntohl(ce->ce_mode);
- newmode = ntohl(ce_mode_from_stat(ce, st.st_mode));
+ oldmode = ce->ce_mode;
+ newmode = ce_mode_from_stat(ce, st.st_mode);
diff_change(&revs->diffopt, oldmode, newmode,
ce->sha1, (changed ? null_sha1 : ce->sha1),
ce->name, NULL);
struct cache_entry *ce,
unsigned char *sha1, unsigned int mode)
{
- diff_addremove(&revs->diffopt, prefix[0], ntohl(mode),
+ diff_addremove(&revs->diffopt, prefix[0], mode,
sha1, ce->name, NULL);
}
p->len = pathlen;
memcpy(p->path, new->name, pathlen);
p->path[pathlen] = 0;
- p->mode = ntohl(mode);
+ p->mode = mode;
hashclr(p->sha1);
memset(p->parent, 0, 2 * sizeof(struct combine_diff_parent));
p->parent[0].status = DIFF_STATUS_MODIFIED;
- p->parent[0].mode = ntohl(new->ce_mode);
+ p->parent[0].mode = new->ce_mode;
hashcpy(p->parent[0].sha1, new->sha1);
p->parent[1].status = DIFF_STATUS_MODIFIED;
- p->parent[1].mode = ntohl(old->ce_mode);
+ p->parent[1].mode = old->ce_mode;
hashcpy(p->parent[1].sha1, old->sha1);
show_combined_diff(p, 2, revs->dense_combined_merges, revs);
free(p);
!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
return 0;
- mode = ntohl(mode);
- oldmode = ntohl(oldmode);
-
diff_change(&revs->diffopt, oldmode, mode,
old->sha1, sha1, old->name, NULL);
return 0;
cached, match_missing))
break;
diff_unmerge(&revs->diffopt, ce->name,
- ntohl(ce->ce_mode), ce->sha1);
+ ce->ce_mode, ce->sha1);
break;
case 3:
diff_unmerge(&revs->diffopt, ce->name,
struct cache_entry *ce = active_cache[i];
if (!ce_stage(ce))
continue;
- ce->ce_flags |= htons(CE_STAGEMASK);
+ ce->ce_flags |= CE_STAGEMASK;
}
}
cache_tree_invalidate_path(active_cache_tree,
ce->name);
last = ce;
- ce->ce_mode = 0;
- ce->ce_flags &= ~htons(CE_STAGEMASK);
+ ce->ce_flags |= CE_REMOVE;
}
*dst++ = ce;
}
index 3e345c2fc508eb82e66f4ffe2c825670f0bddd99..1b9cc7a8a81002fa2971d71c41a256444e6112fe 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -391,7 +391,7 @@ static enum exist_status directory_exists_in_index(const char *dirname, int len)
break;
if (endchar == '/')
return index_directory;
- if (!endchar && S_ISGITLINK(ntohl(ce->ce_mode)))
+ if (!endchar && S_ISGITLINK(ce->ce_mode))
return index_gitdir;
}
return index_nonexistent;
index 257ab46e943f1f8b7445f01c10d949224c17112f..44f4b897d4ff7afff7dbab92ce8754645ad8da6a 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -103,7 +103,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
int fd;
long wrote;
- switch (ntohl(ce->ce_mode) & S_IFMT) {
+ switch (ce->ce_mode & S_IFMT) {
char *new;
struct strbuf buf;
unsigned long size;
@@ -129,7 +129,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
strcpy(path, ".merge_file_XXXXXX");
fd = mkstemp(path);
} else
- fd = create_file(path, ntohl(ce->ce_mode));
+ fd = create_file(path, ce->ce_mode);
if (fd < 0) {
free(new);
return error("git-checkout-index: unable to create file %s (%s)",
@@ -221,7 +221,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
unlink(path);
if (S_ISDIR(st.st_mode)) {
/* If it is a gitlink, leave it alone! */
- if (S_ISGITLINK(ntohl(ce->ce_mode)))
+ if (S_ISGITLINK(ce->ce_mode))
return 0;
if (!state->force)
return error("%s is a directory", path);
diff --git a/merge-index.c b/merge-index.c
index fa719cb0b1bd227423587c9e41eed77c755465a4..bbb700b54eab2a14f60e090231a196874ff3a9e0 100644 (file)
--- a/merge-index.c
+++ b/merge-index.c
break;
found++;
strcpy(hexbuf[stage], sha1_to_hex(ce->sha1));
- sprintf(ownbuf[stage], "%o", ntohl(ce->ce_mode));
+ sprintf(ownbuf[stage], "%o", ce->ce_mode);
arguments[stage] = hexbuf[stage];
arguments[stage + 4] = ownbuf[stage];
} while (++pos < active_nr);
diff --git a/merge-recursive.c b/merge-recursive.c
index c292a77a81d137a3ee73111162c9aa515c975d70..bdf03b1f1f7acacafebc0541309be097cc80336c 100644 (file)
--- a/merge-recursive.c
+++ b/merge-recursive.c
item->util = xcalloc(1, sizeof(struct stage_data));
}
e = item->util;
- e->stages[ce_stage(ce)].mode = ntohl(ce->ce_mode);
+ e->stages[ce_stage(ce)].mode = ce->ce_mode;
hashcpy(e->stages[ce_stage(ce)].sha, ce->sha1);
}
diff --git a/reachable.c b/reachable.c
index 6383401e2dd6bef3251a105ac136312dfdcdeb3c..00f289f2f470c0f4b95e0fcac043aa2e054d1ce6 100644 (file)
--- a/reachable.c
+++ b/reachable.c
* lookup_blob() on them, to avoid populating the hash table
* with invalid information
*/
- if (S_ISGITLINK(ntohl(active_cache[i]->ce_mode)))
+ if (S_ISGITLINK(active_cache[i]->ce_mode))
continue;
lookup_blob(active_cache[i]->sha1);
diff --git a/read-cache.c b/read-cache.c
index 7db55883d65fd28c2eaa291b5688273532988d88..82a6238b7783ef41896834dae11a528e77f4e447 100644 (file)
--- a/read-cache.c
+++ b/read-cache.c
*/
void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
{
- ce->ce_ctime.sec = htonl(st->st_ctime);
- ce->ce_mtime.sec = htonl(st->st_mtime);
-#ifdef USE_NSEC
- ce->ce_ctime.nsec = htonl(st->st_ctim.tv_nsec);
- ce->ce_mtime.nsec = htonl(st->st_mtim.tv_nsec);
-#endif
- ce->ce_dev = htonl(st->st_dev);
- ce->ce_ino = htonl(st->st_ino);
- ce->ce_uid = htonl(st->st_uid);
- ce->ce_gid = htonl(st->st_gid);
- ce->ce_size = htonl(st->st_size);
+ ce->ce_ctime = st->st_ctime;
+ ce->ce_mtime = st->st_mtime;
+ ce->ce_dev = st->st_dev;
+ ce->ce_ino = st->st_ino;
+ ce->ce_uid = st->st_uid;
+ ce->ce_gid = st->st_gid;
+ ce->ce_size = st->st_size;
if (assume_unchanged)
- ce->ce_flags |= htons(CE_VALID);
+ ce->ce_flags |= CE_VALID;
}
static int ce_compare_data(struct cache_entry *ce, struct stat *st)
return DATA_CHANGED;
break;
case S_IFDIR:
- if (S_ISGITLINK(ntohl(ce->ce_mode)))
+ if (S_ISGITLINK(ce->ce_mode))
return 0;
default:
return TYPE_CHANGED;
{
unsigned int changed = 0;
- switch (ntohl(ce->ce_mode) & S_IFMT) {
+ if (ce->ce_flags & CE_REMOVE)
+ return MODE_CHANGED | DATA_CHANGED | TYPE_CHANGED;
+
+ switch (ce->ce_mode & S_IFMT) {
case S_IFREG:
changed |= !S_ISREG(st->st_mode) ? TYPE_CHANGED : 0;
/* We consider only the owner x bit to be relevant for
* "mode changes"
*/
if (trust_executable_bit &&
- (0100 & (ntohl(ce->ce_mode) ^ st->st_mode)))
+ (0100 & (ce->ce_mode ^ st->st_mode)))
changed |= MODE_CHANGED;
break;
case S_IFLNK:
else if (ce_compare_gitlink(ce))
changed |= DATA_CHANGED;
return changed;
- case 0: /* Special case: unmerged file in index */
- return MODE_CHANGED | DATA_CHANGED | TYPE_CHANGED;
default:
- die("internal error: ce_mode is %o", ntohl(ce->ce_mode));
+ die("internal error: ce_mode is %o", ce->ce_mode);
}
- if (ce->ce_mtime.sec != htonl(st->st_mtime))
- changed |= MTIME_CHANGED;
- if (ce->ce_ctime.sec != htonl(st->st_ctime))
- changed |= CTIME_CHANGED;
-
-#ifdef USE_NSEC
- /*
- * nsec seems unreliable - not all filesystems support it, so
- * as long as it is in the inode cache you get right nsec
- * but after it gets flushed, you get zero nsec.
- */
- if (ce->ce_mtime.nsec != htonl(st->st_mtim.tv_nsec))
+ if (ce->ce_mtime != (unsigned int) st->st_mtime)
changed |= MTIME_CHANGED;
- if (ce->ce_ctime.nsec != htonl(st->st_ctim.tv_nsec))
+ if (ce->ce_ctime != (unsigned int) st->st_ctime)
changed |= CTIME_CHANGED;
-#endif
- if (ce->ce_uid != htonl(st->st_uid) ||
- ce->ce_gid != htonl(st->st_gid))
+ if (ce->ce_uid != (unsigned int) st->st_uid ||
+ ce->ce_gid != (unsigned int) st->st_gid)
changed |= OWNER_CHANGED;
- if (ce->ce_ino != htonl(st->st_ino))
+ if (ce->ce_ino != (unsigned int) st->st_ino)
changed |= INODE_CHANGED;
#ifdef USE_STDEV
* clients will have different views of what "device"
* the filesystem is on
*/
- if (ce->ce_dev != htonl(st->st_dev))
+ if (ce->ce_dev != (unsigned int) st->st_dev)
changed |= INODE_CHANGED;
#endif
- if (ce->ce_size != htonl(st->st_size))
+ if (ce->ce_size != (unsigned int) st->st_size)
changed |= DATA_CHANGED;
return changed;
* If it's marked as always valid in the index, it's
* valid whatever the checked-out copy says.
*/
- if (!ignore_valid && (ce->ce_flags & htons(CE_VALID)))
+ if (!ignore_valid && (ce->ce_flags & CE_VALID))
return 0;
changed = ce_match_stat_basic(ce, st);
*/
if (!changed &&
istate->timestamp &&
- istate->timestamp <= ntohl(ce->ce_mtime.sec)) {
+ istate->timestamp <= ce->ce_mtime) {
if (assume_racy_is_modified)
changed |= DATA_CHANGED;
else
* the length field is zero. For other cases the ce_size
* should match the SHA1 recorded in the index entry.
*/
- if ((changed & DATA_CHANGED) && ce->ce_size != htonl(0))
+ if ((changed & DATA_CHANGED) && ce->ce_size != 0)
return changed;
changed_fs = ce_modified_check_fs(ce, st);
while (last > first) {
int next = (last + first) >> 1;
struct cache_entry *ce = istate->cache[next];
- int cmp = cache_name_compare(name, namelen, ce->name, ntohs(ce->ce_flags));
+ int cmp = cache_name_compare(name, namelen, ce->name, ce->ce_flags);
if (!cmp)
return next;
if (cmp < 0) {
@@ -405,7 +390,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
size = cache_entry_size(namelen);
ce = xcalloc(1, size);
memcpy(ce->name, path, namelen);
- ce->ce_flags = htons(namelen);
+ ce->ce_flags = namelen;
fill_stat_cache_info(ce, &st);
if (trust_executable_bit && has_symlinks)
continue;
if (p->name[len] != '/')
continue;
- if (!ce_stage(p) && !p->ce_mode)
+ if (p->ce_flags & CE_REMOVE)
continue;
retval = -1;
if (!ok_to_replace)
}
len = slash - name;
- pos = index_name_pos(istate, name, ntohs(create_ce_flags(len, stage)));
+ pos = index_name_pos(istate, name, create_ce_flags(len, stage));
if (pos >= 0) {
/*
* Found one, but not so fast. This could
/*
* When ce is an "I am going away" entry, we allow it to be added
*/
- if (!ce_stage(ce) && !ce->ce_mode)
+ if (ce->ce_flags & CE_REMOVE)
return 0;
/*
@@ -704,7 +689,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK;
cache_tree_invalidate_path(istate->cache_tree, ce->name);
- pos = index_name_pos(istate, ce->name, ntohs(ce->ce_flags));
+ pos = index_name_pos(istate, ce->name, ce->ce_flags);
/* existing match? Just replace it. */
if (pos >= 0) {
@@ -736,7 +721,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
if (!ok_to_replace)
return error("'%s' appears as both a file and as a directory",
ce->name);
- pos = index_name_pos(istate, ce->name, ntohs(ce->ce_flags));
+ pos = index_name_pos(istate, ce->name, ce->ce_flags);
pos = -pos-1;
}
return pos + 1;
* valid again, under "assume unchanged" mode.
*/
if (ignore_valid && assume_unchanged &&
- !(ce->ce_flags & htons(CE_VALID)))
+ !(ce->ce_flags & CE_VALID))
; /* mark this one VALID again */
else
return ce;
updated = xmalloc(size);
memcpy(updated, ce, size);
fill_stat_cache_info(updated, &st);
-
/*
* If ignore_valid is not set, we should leave CE_VALID bit
* alone. Otherwise, paths marked with --no-assume-unchanged
* automatically, which is not really what we want.
*/
if (!ignore_valid && assume_unchanged &&
- !(ce->ce_flags & htons(CE_VALID)))
- updated->ce_flags &= ~htons(CE_VALID);
+ !(ce->ce_flags & CE_VALID))
+ updated->ce_flags &= ~CE_VALID;
return updated;
}
@@ -880,7 +864,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
/* If we are doing --really-refresh that
* means the index is not valid anymore.
*/
- ce->ce_flags &= ~htons(CE_VALID);
+ ce->ce_flags &= ~CE_VALID;
istate->cache_changed = 1;
}
if (quiet)
return read_index_from(istate, get_index_file());
}
+static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_entry *ce)
+{
+ ce->ce_ctime = ntohl(ondisk->ctime.sec);
+ ce->ce_mtime = ntohl(ondisk->mtime.sec);
+ ce->ce_dev = ntohl(ondisk->dev);
+ ce->ce_ino = ntohl(ondisk->ino);
+ ce->ce_mode = ntohl(ondisk->mode);
+ ce->ce_uid = ntohl(ondisk->uid);
+ ce->ce_gid = ntohl(ondisk->gid);
+ ce->ce_size = ntohl(ondisk->size);
+ /* On-disk flags are just 16 bits */
+ ce->ce_flags = ntohs(ondisk->flags);
+ hashcpy(ce->sha1, ondisk->sha1);
+ memcpy(ce->name, ondisk->name, ce_namelen(ce)+1);
+}
+
/* remember to discard_cache() before reading a different cache! */
int read_index_from(struct index_state *istate, const char *path)
{
int fd, i;
struct stat st;
- unsigned long offset;
+ unsigned long src_offset, dst_offset;
struct cache_header *hdr;
+ void *mmap;
+ size_t mmap_size;
errno = EBUSY;
- if (istate->mmap)
+ if (istate->alloc)
return istate->cache_nr;
errno = ENOENT;
die("cannot stat the open index (%s)", strerror(errno));
errno = EINVAL;
- istate->mmap_size = xsize_t(st.st_size);
- if (istate->mmap_size < sizeof(struct cache_header) + 20)
+ mmap_size = xsize_t(st.st_size);
+ if (mmap_size < sizeof(struct cache_header) + 20)
die("index file smaller than expected");
- istate->mmap = xmmap(NULL, istate->mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
close(fd);
+ if (mmap == MAP_FAILED)
+ die("unable to map index file");
- hdr = istate->mmap;
- if (verify_hdr(hdr, istate->mmap_size) < 0)
+ hdr = mmap;
+ if (verify_hdr(hdr, mmap_size) < 0)
goto unmap;
istate->cache_nr = ntohl(hdr->hdr_entries);
istate->cache_alloc = alloc_nr(istate->cache_nr);
istate->cache = xcalloc(istate->cache_alloc, sizeof(struct cache_entry *));
- offset = sizeof(*hdr);
+ /*
+ * The disk format is actually larger than the in-memory format,
+ * due to space for nsec etc, so even though the in-memory one
+ * has room for a few more flags, we can allocate using the same
+ * index size
+ */
+ istate->alloc = xmalloc(mmap_size);
+
+ src_offset = sizeof(*hdr);
+ dst_offset = 0;
for (i = 0; i < istate->cache_nr; i++) {
+ struct ondisk_cache_entry *disk_ce;
struct cache_entry *ce;
- ce = (struct cache_entry *)((char *)(istate->mmap) + offset);
- offset = offset + ce_size(ce);
+ disk_ce = (struct ondisk_cache_entry *)((char *)mmap + src_offset);
+ ce = (struct cache_entry *)((char *)istate->alloc + dst_offset);
+ convert_from_disk(disk_ce, ce);
istate->cache[i] = ce;
+
+ src_offset += ondisk_ce_size(ce);
+ dst_offset += ce_size(ce);
}
istate->timestamp = st.st_mtime;
- while (offset <= istate->mmap_size - 20 - 8) {
+ while (src_offset <= mmap_size - 20 - 8) {
/* After an array of active_nr index entries,
* there can be arbitrary number of extended
* sections, each of which is prefixed with
* in 4-byte network byte order.
*/
unsigned long extsize;
- memcpy(&extsize, (char *)(istate->mmap) + offset + 4, 4);
+ memcpy(&extsize, (char *)mmap + src_offset + 4, 4);
extsize = ntohl(extsize);
if (read_index_extension(istate,
- ((const char *) (istate->mmap)) + offset,
- (char *) (istate->mmap) + offset + 8,
+ (const char *) mmap + src_offset,
+ (char *) mmap + src_offset + 8,
extsize) < 0)
goto unmap;
- offset += 8;
- offset += extsize;
+ src_offset += 8;
+ src_offset += extsize;
}
+ munmap(mmap, mmap_size);
return istate->cache_nr;
unmap:
- munmap(istate->mmap, istate->mmap_size);
+ munmap(mmap, mmap_size);
errno = EINVAL;
die("index file corrupt");
}
int discard_index(struct index_state *istate)
{
- int ret;
-
istate->cache_nr = 0;
istate->cache_changed = 0;
istate->timestamp = 0;
cache_tree_free(&(istate->cache_tree));
- if (istate->mmap == NULL)
- return 0;
- ret = munmap(istate->mmap, istate->mmap_size);
- istate->mmap = NULL;
- istate->mmap_size = 0;
+ free(istate->alloc);
+ istate->alloc = NULL;
/* no need to throw away allocated active_cache */
- return ret;
+ return 0;
}
#define WRITE_BUFFER_SIZE 8192
* file, and never calls us, so the cached size information
* for "frotz" stays 6 which does not match the filesystem.
*/
- ce->ce_size = htonl(0);
+ ce->ce_size = 0;
}
}
+static int ce_write_entry(SHA_CTX *c, int fd, struct cache_entry *ce)
+{
+ int size = ondisk_ce_size(ce);
+ struct ondisk_cache_entry *ondisk = xcalloc(1, size);
+
+ ondisk->ctime.sec = htonl(ce->ce_ctime);
+ ondisk->ctime.nsec = 0;
+ ondisk->mtime.sec = htonl(ce->ce_mtime);
+ ondisk->mtime.nsec = 0;
+ ondisk->dev = htonl(ce->ce_dev);
+ ondisk->ino = htonl(ce->ce_ino);
+ ondisk->mode = htonl(ce->ce_mode);
+ ondisk->uid = htonl(ce->ce_uid);
+ ondisk->gid = htonl(ce->ce_gid);
+ ondisk->size = htonl(ce->ce_size);
+ hashcpy(ondisk->sha1, ce->sha1);
+ ondisk->flags = htons(ce->ce_flags);
+ memcpy(ondisk->name, ce->name, ce_namelen(ce));
+
+ return ce_write(c, fd, ondisk, size);
+}
+
int write_index(struct index_state *istate, int newfd)
{
SHA_CTX c;
int entries = istate->cache_nr;
for (i = removed = 0; i < entries; i++)
- if (!cache[i]->ce_mode)
+ if (cache[i]->ce_flags & CE_REMOVE)
removed++;
hdr.hdr_signature = htonl(CACHE_SIGNATURE);
for (i = 0; i < entries; i++) {
struct cache_entry *ce = cache[i];
- if (!ce->ce_mode)
+ if (ce->ce_flags & CE_REMOVE)
continue;
if (istate->timestamp &&
- istate->timestamp <= ntohl(ce->ce_mtime.sec))
+ istate->timestamp <= ce->ce_mtime)
ce_smudge_racily_clean_entry(ce);
- if (ce_write(&c, newfd, ce, ce_size(ce)) < 0)
+ if (ce_write_entry(&c, newfd, ce) < 0)
return -1;
}
diff --git a/sha1_name.c b/sha1_name.c
index 13e11645e1fd6b61812cc3e88d2ad6cd42cad9ce..be8489e4e5fc98c6e38036a40fb5ca8c0db77ebc 100644 (file)
--- a/sha1_name.c
+++ b/sha1_name.c
break;
if (ce_stage(ce) == stage) {
hashcpy(sha1, ce->sha1);
- *mode = ntohl(ce->ce_mode);
+ *mode = ce->ce_mode;
return 0;
}
pos++;
index 8c0819fa721771f6dc2e727860345376edb3ea60..87708ef420aaa328c9a8dfcefbcf4aa7ba6d4b72 100644 (file)
--- a/tree.c
+++ b/tree.c
ce1 = *((const struct cache_entry **)a_);
ce2 = *((const struct cache_entry **)b_);
- return cache_name_compare(ce1->name, ntohs(ce1->ce_flags),
- ce2->name, ntohs(ce2->ce_flags));
+ return cache_name_compare(ce1->name, ce1->ce_flags,
+ ce2->name, ce2->ce_flags);
}
int read_tree(struct tree *tree, int stage, const char **match)
diff --git a/unpack-trees.c b/unpack-trees.c
index aa2513ed798969c02fc5e14097666eb4c4c02bae..ff46fd62fdceeefc2ebd98ae1c9483964cb37bd5 100644 (file)
--- a/unpack-trees.c
+++ b/unpack-trees.c
static void check_updates(struct cache_entry **src, int nr,
struct unpack_trees_options *o)
{
- unsigned short mask = htons(CE_UPDATE);
unsigned cnt = 0, total = 0;
struct progress *progress = NULL;
char last_symlink[PATH_MAX];
if (o->update && o->verbose_update) {
for (total = cnt = 0; cnt < nr; cnt++) {
struct cache_entry *ce = src[cnt];
- if (!ce->ce_mode || ce->ce_flags & mask)
+ if (ce->ce_flags & (CE_UPDATE | CE_REMOVE))
total++;
}
while (nr--) {
struct cache_entry *ce = *src++;
- if (!ce->ce_mode || ce->ce_flags & mask)
+ if (ce->ce_flags & (CE_UPDATE | CE_REMOVE))
display_progress(progress, ++cnt);
- if (!ce->ce_mode) {
+ if (ce->ce_flags & CE_REMOVE) {
if (o->update)
unlink_entry(ce->name, last_symlink);
continue;
}
- if (ce->ce_flags & mask) {
- ce->ce_flags &= ~mask;
+ if (ce->ce_flags & CE_UPDATE) {
+ ce->ce_flags &= ~CE_UPDATE;
if (o->update) {
checkout_entry(ce, &state, NULL);
*last_symlink = '\0';
* submodules that are marked to be automatically
* checked out.
*/
- if (S_ISGITLINK(ntohl(ce->ce_mode)))
+ if (S_ISGITLINK(ce->ce_mode))
return;
errno = 0;
}
@@ -450,7 +449,7 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
int cnt = 0;
unsigned char sha1[20];
- if (S_ISGITLINK(ntohl(ce->ce_mode)) &&
+ if (S_ISGITLINK(ce->ce_mode) &&
resolve_gitlink_ref(ce->name, "HEAD", sha1) == 0) {
/* If we are not going to update the submodule, then
* we don't care.
@@ -481,7 +480,7 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
*/
if (!ce_stage(ce)) {
verify_uptodate(ce, o);
- ce->ce_mode = 0;
+ ce->ce_flags |= CE_REMOVE;
}
cnt++;
}
cnt = cache_name_pos(ce->name, strlen(ce->name));
if (0 <= cnt) {
struct cache_entry *ce = active_cache[cnt];
- if (!ce_stage(ce) && !ce->ce_mode)
+ if (ce->ce_flags & CE_REMOVE)
return;
}
static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
struct unpack_trees_options *o)
{
- merge->ce_flags |= htons(CE_UPDATE);
+ merge->ce_flags |= CE_UPDATE;
if (old) {
/*
* See if we can re-use the old CE directly?
invalidate_ce_path(merge);
}
- merge->ce_flags &= ~htons(CE_STAGEMASK);
+ merge->ce_flags &= ~CE_STAGEMASK;
add_cache_entry(merge, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
return 1;
}
verify_uptodate(old, o);
else
verify_absent(ce, "removed", o);
- ce->ce_mode = 0;
+ ce->ce_flags |= CE_REMOVE;
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
invalidate_ce_path(ce);
return 1;
else
fprintf(o, "%s%06o %s %d\t%s\n",
label,
- ntohl(ce->ce_mode),
+ ce->ce_mode,
sha1_to_hex(ce->sha1),
ce_stage(ce),
ce->name);
struct stat st;
if (lstat(old->name, &st) ||
ce_match_stat(old, &st, CE_MATCH_IGNORE_VALID))
- old->ce_flags |= htons(CE_UPDATE);
+ old->ce_flags |= CE_UPDATE;
}
return keep_entry(old, o);
}