[PATCH 2/9] Introduce CE_NO_CHECKOUT bit
From: Nguyễn Thái Ngọc Duy <hidden>
Date: 2016-06-15 22:45:25
Subsystem:
documentation, the rest · Maintainers:
Jonathan Corbet, Linus Torvalds
This bit is the basis of sparse checkout. If this bit is on, the entry is outside sparse checkout and therefore should be ignored (similar to CE_VALID) Signed-off-by: Nguyễn Thái Ngọc Duy <redacted> --- Documentation/git-checkout.txt | 33 +++++++++++++++++++++++++++++++++ cache.h | 10 +++++++++- read-cache.c | 6 +++--- 3 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 82e154d..4bd9eba 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt@@ -171,6 +171,39 @@ the reflog for HEAD where you were, e.g. $ git log -g -2 HEAD ------------ +Sparse checkout +--------------- + +Normally when you checkout a branch, your working directory +will be fully populated. In some situations, you just need to +work on certain files, no full checkout is needed. Sparse +checkout is a mode that limits the checkout area according to your +needs. With sparse checkout, you can work on a single file, a +collection of files, a subdirectory or a collection of separated +subdirectories. + +Because sparse checkout uses a new index format, it will be +incompatible with git prior to 1.6.0 regarding worktree operations. +Operations that only need access to the repository itself, such as +clone, push, or pull/fetch from another (normal) repository... should +not be affected by sparse checkout. + +In sparse checkout mode, checkout status of every files in your +working directory will be recorded in index. If a file is marked +"no-checkout", it means that file is not needed to be present in +working directory by user or any git command. When a new file is added +to index, it will be marked "checkout" unless sparse patterns are +applied. Unmerged files are always "checkout". When you checkout new +files using "git checkout <file>" they will be automatically marked +"checkout". Other commands such as "git apply" can also checkout new +files if they are needed. + +"No-checkout" status is very similar to "assume-unchanged bit" +(see linkgit:git-update-index[1]). The main difference between them +is "assume unchanged" bit just ignores corresponding files in working +directory while sparse checkout goes a bit farther, remove those files +when it is safe to do so. + EXAMPLES --------
diff --git a/cache.h b/cache.h
index 5180879..f13ddbc 100644
--- a/cache.h
+++ b/cache.h@@ -170,10 +170,11 @@ struct cache_entry { /* * Extended on-disk flags */ +#define CE_NO_CHECKOUT 0x40000000 /* CE_EXTENDED2 is for future extension */ #define CE_EXTENDED2 0x80000000 -#define CE_EXTENDED_FLAGS (0) +#define CE_EXTENDED_FLAGS (CE_NO_CHECKOUT) /* * Safeguard to avoid saving wrong flags:
@@ -185,6 +186,9 @@ struct cache_entry { #error "CE_EXTENDED_FLAGS out of range" #endif +/* "Assume unchanged" mask */ +#define CE_VALID_MASK (CE_VALID | CE_NO_CHECKOUT) + /* * Copy the sha1 and stat state of a cache entry from one to * another. But we never change the name, or the hash state!
@@ -222,6 +226,10 @@ static inline size_t ce_namelen(const struct cache_entry *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_no_checkout(ce) ((ce)->ce_flags & CE_NO_CHECKOUT) +#define ce_checkout(ce) (!ce_no_checkout(ce)) +#define ce_mark_no_checkout(ce) ((ce)->ce_flags |= CE_NO_CHECKOUT) +#define ce_mark_checkout(ce) ((ce)->ce_flags &= ~CE_NO_CHECKOUT) #define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE) #define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644)
diff --git a/read-cache.c b/read-cache.c
index 667c36b..e965a4c 100644
--- a/read-cache.c
+++ b/read-cache.c@@ -254,7 +254,7 @@ int ie_match_stat(const struct index_state *istate, * 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 & CE_VALID)) + if (!ignore_valid && (ce->ce_flags & CE_VALID_MASK)) return 0; changed = ce_match_stat_basic(ce, st);
@@ -962,10 +962,10 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate, return ce; /* - * CE_VALID means the user promised us that the change to + * CE_VALID_MASK means the user promised us that the change to * the work tree does not matter and told us not to worry. */ - if (!ignore_valid && (ce->ce_flags & CE_VALID)) { + if (!ignore_valid && (ce->ce_flags & CE_VALID_MASK)) { ce_mark_uptodate(ce); return ce; }
--
1.6.0.2.488.gf604a