From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [RFC PATCH] ce_uptodate(): discriminate lstat()-based and assume-unchanged uptodate
Date: Sat, 22 Aug 2009 19:43:53 +0700 [thread overview]
Message-ID: <1250945033-14059-1-git-send-email-pclouds@gmail.com> (raw)
Commit 1dcafcc (verify_uptodate(): add ce_uptodate(ce) test) makes me
realize that people might not be well aware of assume-unchanged bit (CE_VALID).
Back when there was no assume-unchanged bit, ce_uptodate() means that
entry is really uptodate and has been checked by lstat(). When
assume-unchanged comes into play, it will blindly mark an entry
uptodate if that entry is assume-unchanged.
Even if it is assume-unchanged, it may have local changes that users
may want to keep. Thus when it comes to updating worktree, we may need to
know if it is _really_ uptodate regardless assume-unchanged. For that
matter, ce_uptodate() does not help much as it could be a result of
lstat() or assume-unchanged bit.
This patch attempts to make Git developers think twice about that
by.. getting rid of ce_uptodate() in favor of two new macros
ce_maybe_uptodate() and ce_really_uptodate()
- ce_maybe_uptodate() works as ce_uptodate() does now.
- ce_really_uptodate() is true only if it is lstat()-based uptodate.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
OK I could not stop looking at CE_VALID :-) I think this is a good
change. However I may have made mistakes in translating from
ce_uptodate() to ce_{maybe,really}_uptodate().
cache.h | 14 ++++++++++++--
diff-lib.c | 6 +++---
diff.c | 2 +-
dir.c | 4 ++--
preload-index.c | 4 ++--
read-cache.c | 12 ++++++------
unpack-trees.c | 4 ++--
7 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/cache.h b/cache.h
index f793789..24f66ab 100644
--- a/cache.h
+++ b/cache.h
@@ -176,6 +176,7 @@ struct cache_entry {
#define CE_HASHED (0x100000)
#define CE_UNHASHED (0x200000)
+#define CE_ASSUME_UPTODATE (0x800000)
/*
* Extended on-disk flags
@@ -232,8 +233,9 @@ static inline size_t ce_namelen(const struct cache_entry *ce)
ondisk_cache_entry_extended_size(ce_namelen(ce)) : \
ondisk_cache_entry_size(ce_namelen(ce)))
#define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT)
-#define ce_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE)
-#define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE)
+#define ce_maybe_uptodate(ce) ((ce)->ce_flags & (CE_UPTODATE | CE_ASSUME_UPTODATE))
+#define ce_really_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE)
+/* #define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE) */
#define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644)
static inline unsigned int create_ce_mode(unsigned int mode)
@@ -463,6 +465,14 @@ extern int index_name_is_other(const struct index_state *, const char *, int);
extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
+static inline void ce_mark_uptodate(struct cache_entry *ce, int options)
+{
+ if ((ce->ce_flags & CE_VALID) && !(options & CE_MATCH_IGNORE_VALID))
+ ce->ce_flags |= CE_ASSUME_UPTODATE;
+ else
+ ce->ce_flags |= CE_UPTODATE;
+}
+
extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);
extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
diff --git a/diff-lib.c b/diff-lib.c
index e7e8e88..9cbfec0 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -159,7 +159,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
continue;
}
- if (ce_uptodate(ce))
+ if (ce_maybe_uptodate(ce))
continue;
changed = check_removed(ce, &st);
@@ -176,7 +176,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
}
changed = ce_match_stat(ce, &st, ce_option);
if (!changed) {
- ce_mark_uptodate(ce);
+ ce_mark_uptodate(ce, ce_option);
if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
continue;
}
@@ -214,7 +214,7 @@ static int get_stat_data(struct cache_entry *ce,
const unsigned char *sha1 = ce->sha1;
unsigned int mode = ce->ce_mode;
- if (!cached && !ce_uptodate(ce)) {
+ if (!cached && !ce_really_uptodate(ce)) {
int changed;
struct stat st;
changed = check_removed(ce, &st);
diff --git a/diff.c b/diff.c
index 91d6ea2..7b94fb9 100644
--- a/diff.c
+++ b/diff.c
@@ -1811,7 +1811,7 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
/*
* If ce matches the file in the work tree, we can reuse it.
*/
- if (ce_uptodate(ce) ||
+ if (ce_really_uptodate(ce) ||
(!lstat(name, &st) && !ce_match_stat(ce, &st, 0)))
return 1;
diff --git a/dir.c b/dir.c
index d0999ba..64f0fc6 100644
--- a/dir.c
+++ b/dir.c
@@ -573,7 +573,7 @@ static int get_index_dtype(const char *path, int len)
ce = cache_name_exists(path, len, 0);
if (ce) {
- if (!ce_uptodate(ce))
+ if (!ce_maybe_uptodate(ce))
return DT_UNKNOWN;
if (S_ISGITLINK(ce->ce_mode))
return DT_DIR;
@@ -597,7 +597,7 @@ static int get_index_dtype(const char *path, int len)
break;
if (ce->name[len] < '/')
continue;
- if (!ce_uptodate(ce))
+ if (!ce_maybe_uptodate(ce))
break; /* continue? */
return DT_DIR;
}
diff --git a/preload-index.c b/preload-index.c
index 9289933..85c31c5 100644
--- a/preload-index.c
+++ b/preload-index.c
@@ -47,7 +47,7 @@ static void *preload_thread(void *_data)
if (ce_stage(ce))
continue;
- if (ce_uptodate(ce))
+ if (ce_maybe_uptodate(ce))
continue;
if (!ce_path_match(ce, p->pathspec))
continue;
@@ -57,7 +57,7 @@ static void *preload_thread(void *_data)
continue;
if (ie_match_stat(index, ce, &st, CE_MATCH_RACY_IS_DIRTY))
continue;
- ce_mark_uptodate(ce);
+ ce_mark_uptodate(ce, 0);
} while (--nr > 0);
return NULL;
}
diff --git a/read-cache.c b/read-cache.c
index 4e3e272..ac7cdd3 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -81,7 +81,7 @@ void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
ce->ce_flags |= CE_VALID;
if (S_ISREG(st->st_mode))
- ce_mark_uptodate(ce);
+ ce_mark_uptodate(ce, CE_MATCH_IGNORE_VALID);
}
static int ce_compare_data(struct cache_entry *ce, struct stat *st)
@@ -605,7 +605,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, st, ce_option)) {
/* Nothing changed, really */
free(ce);
- ce_mark_uptodate(alias);
+ ce_mark_uptodate(alias, ce_option);
alias->ce_flags |= CE_ADDED;
return 0;
}
@@ -1001,7 +1001,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
int changed, size;
int ignore_valid = options & CE_MATCH_IGNORE_VALID;
- if (ce_uptodate(ce))
+ if (ce_maybe_uptodate(ce))
return ce;
/*
@@ -1009,7 +1009,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
* the work tree does not matter and told us not to worry.
*/
if (!ignore_valid && (ce->ce_flags & CE_VALID)) {
- ce_mark_uptodate(ce);
+ ce_mark_uptodate(ce, options);
return ce;
}
@@ -1037,7 +1037,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
* because CE_UPTODATE flag is in-core only;
* we are not going to write this change out.
*/
- ce_mark_uptodate(ce);
+ ce_mark_uptodate(ce, options);
return ce;
}
}
@@ -1543,7 +1543,7 @@ int write_index(struct index_state *istate, int newfd)
struct cache_entry *ce = cache[i];
if (ce->ce_flags & CE_REMOVE)
continue;
- if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce))
+ if (!ce_maybe_uptodate(ce) && is_racy_timestamp(istate, ce))
ce_smudge_racily_clean_entry(ce);
if (ce_write_entry(&c, newfd, ce) < 0)
return -1;
diff --git a/unpack-trees.c b/unpack-trees.c
index 720f7a1..c0774d7 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -450,7 +450,7 @@ static int verify_uptodate(struct cache_entry *ce,
{
struct stat st;
- if (o->index_only || o->reset || ce_uptodate(ce))
+ if (o->index_only || o->reset || ce_really_uptodate(ce))
return 0;
if (!lstat(ce->name, &st)) {
@@ -1004,7 +1004,7 @@ int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o)
if (old && same(old, a)) {
int update = 0;
- if (o->reset && !ce_uptodate(old)) {
+ if (o->reset && !ce_really_uptodate(old)) {
struct stat st;
if (lstat(old->name, &st) ||
ie_match_stat(o->src_index, old, &st, CE_MATCH_IGNORE_VALID))
--
1.6.3.GIT
reply other threads:[~2009-08-22 12:47 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1250945033-14059-1-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).