git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 11/16] unpack_trees(): add support for narrow checkout

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Sep 14, 2008, 13:08 UTC
Message-ID
<1221397685-27715-12-git-send-email-pclouds@gmail.com>
In-Reply-To
<1221397685-27715-11-git-send-email-pclouds@gmail.com>

This patch teaches unpack_trees() to checkout/remove entries on working directories appropriately when narrow area is changed. There are three kind of changes:

 - new_narrow_path: reset workdir to a new narrow checkout
 - add_narrow_path: keep current narrow areas and add more entries
 - remove_narrow_path: remove some entries from current narrow areas

A simple "narrow spec" is introduced to specify what entries is in narrow area. For now it is just a list of prefix separated by colon.

CE_WD_REMOVE is introduced to remove entries from working directories, but still keep them in index

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 cache.h        |    3 ++
 unpack-trees.c |  100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 unpack-trees.h |    6 +++
 3 files changed, 109 insertions(+), 0 deletions(-)
diff --git a/cache.h b/cache.h
index 2b2c90f..1fc0f83 100644
--- a/cache.h
+++ b/cache.h
@@ -167,6 +167,9 @@ struct cache_entry {
 #define CE_HASHED    (0x100000)
 #define CE_UNHASHED  (0x200000)
 
+/* Only remove in work directory, not index */
+#define CE_WD_REMOVE (0x400000)
+
 /*
  * Extended on-disk flags
  */
diff --git a/unpack-trees.c b/unpack-trees.c
index e59d144..968cc98 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -96,6 +96,15 @@ static int check_updates(struct unpack_trees_options *o)
 	if (o->update && o->verbose_update) {
 		for (total = cnt = 0; cnt < index->cache_nr; cnt++) {
 			struct cache_entry *ce = index->cache[cnt];
+
+			if (ce->ce_flags & CE_WD_REMOVE) {
+				total++;
+				continue;
+			}
+
+			if (ce_no_checkout(ce))
+				continue;
+
 			if (ce->ce_flags & (CE_UPDATE | CE_REMOVE))
 				total++;
 		}
@@ -108,6 +117,16 @@ static int check_updates(struct unpack_trees_options *o)
 	for (i = 0; i < index->cache_nr; i++) {
 		struct cache_entry *ce = index->cache[i];
 
+		if (ce->ce_flags & CE_WD_REMOVE) {
+			display_progress(progress, ++cnt);
+			if (o->update)
+				unlink_entry(ce);
+			continue;
+		}
+
+		if (ce_no_checkout(ce))
+			continue;
+
 		if (ce->ce_flags & CE_REMOVE) {
 			display_progress(progress, ++cnt);
 			if (o->update)
@@ -121,6 +140,9 @@ static int check_updates(struct unpack_trees_options *o)
 	for (i = 0; i < index->cache_nr; i++) {
 		struct cache_entry *ce = index->cache[i];
 
+		if (ce_no_checkout(ce))
+			continue;
+
 		if (ce->ce_flags & CE_UPDATE) {
 			display_progress(progress, ++cnt);
 			ce->ce_flags &= ~CE_UPDATE;
@@ -133,6 +155,47 @@ static int check_updates(struct unpack_trees_options *o)
 	return errs != 0;
 }
 
+static int verify_uptodate(struct cache_entry *ce, struct unpack_trees_options *o);
+static int apply_narrow_checkout(struct unpack_trees_options *o)
+{
+	struct index_state *index = &o->result;
+	int i;
+
+	if (!(o->new_narrow_path | o->add_narrow_path | o->remove_narrow_path))
+		return 0;
+
+	for (i = 0; i < index->cache_nr; i++) {
+		struct cache_entry *ce = index->cache[i];
+		int was_checkout = ce_checkout(ce);
+		int match = match_narrow_spec(o->narrow_spec, ce->name, o->narrow_prefix);
+
+		if (ce_stage(ce))
+			continue;
+
+		if (o->new_narrow_path) {
+			if (match)
+				ce_mark_checkout(ce);
+			else
+				ce_mark_no_checkout(ce);
+		}
+
+		if (o->add_narrow_path && match)
+			ce_mark_checkout(ce);
+
+		if (o->remove_narrow_path && match)
+			ce_mark_no_checkout(ce);
+
+		if (was_checkout && ce_no_checkout(ce)) {
+			if (verify_uptodate(ce, o))
+				return -1;
+			ce->ce_flags |= CE_WD_REMOVE;
+		}
+		if (!was_checkout && ce_checkout(ce))
+			ce->ce_flags |= CE_UPDATE;
+	}
+	return 0;
+}
+
 static inline int call_unpack_fn(struct cache_entry **src, struct unpack_trees_options *o)
 {
 	int ret = o->fn(src, o);
@@ -409,6 +472,9 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
 	if (o->trivial_merges_only && o->nontrivial_merge)
 		return unpack_failed(o, "Merge requires file-level merging");
 
+	if (apply_narrow_checkout(o))
+		return unpack_failed(o, NULL);
+
 	o->src_index = NULL;
 	ret = check_updates(o) ? (-2) : 0;
 	if (o->dst_index)
@@ -677,6 +743,8 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
 				return -1;
 			invalidate_ce_path(old, o);
 		}
+		if (ce_no_checkout(old))
+			update |= CE_NO_CHECKOUT;
 	}
 	else {
 		if (verify_absent(merge, "overwritten", o))
@@ -726,6 +794,38 @@ static void show_stage_entry(FILE *o,
 }
 #endif
 
+int match_narrow_spec(const char *spec_, const char *path, const char *prefix)
+{
+	int match = 0;
+	char *spec, *cur_spec;
+	int prefix_len = 0;
+
+	if (!spec_)
+		return 1; /* always match if spec_ is NULL */
+	if (prefix) {
+		if (prefixcmp(path, prefix))
+			return 0;
+		prefix_len = strlen(prefix);
+	}
+
+	spec = cur_spec = xstrdup(spec_);
+
+	while (!match) {
+		char *next_spec = strchr(cur_spec, ':');
+		if (next_spec)
+			*next_spec = '\0';
+
+		if (!fnmatch(cur_spec, path+prefix_len, 0))
+			match = 1;
+
+		if (!next_spec)
+			break;
+		cur_spec = next_spec+1;
+	}
+	free(spec);
+	return match;
+}
+
 int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o)
 {
 	struct cache_entry *index;
diff --git a/unpack-trees.h b/unpack-trees.h
index 0d26f3d..942a007 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -27,6 +27,9 @@ struct unpack_trees_options {
 		     aggressive:1,
 		     skip_unmerged:1,
 		     initial_checkout:1,
+		     new_narrow_path:1,
+		     add_narrow_path:2,
+		     remove_narrow_path:2,
 		     gently:1;
 	const char *prefix;
 	int pos;
@@ -38,6 +41,8 @@ struct unpack_trees_options {
 	int merge_size;
 
 	struct cache_entry *df_conflict_entry;
+	const char *narrow_spec;
+	const char *narrow_prefix;
 	void *unpack_data;
 
 	struct index_state *dst_index;
@@ -48,6 +53,7 @@ struct unpack_trees_options {
 extern int unpack_trees(unsigned n, struct tree_desc *t,
 		struct unpack_trees_options *options);
 
+int match_narrow_spec(const char *spec_, const char *path, const char *prefix);
 int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o);
 int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o);
 int bind_merge(struct cache_entry **src, struct unpack_trees_options *o);
-- 
1.6.0.96.g2fad1.dirty
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 12 of 35 in “Narrow/Partial/Sparse checkout”
  1. 00/16 Narrow/Partial/Sparse checkoutNguyễn Thái Ngọc Duy, Sep 14, 2008
  2. 01/16 Extend index to save more flagsNguyễn Thái Ngọc Duy, Sep 14, 2008
  3. 02/16 Introduce CE_NO_CHECKOUT bitNguyễn Thái Ngọc Duy, Sep 14, 2008
  4. 03/16 update-index: refactor mark_valid() in preparation for new optionsNguyễn Thái Ngọc Duy, Sep 14, 2008
  5. 04/16 update-index: add --checkout/--no-checkout to update CE_NO_CHECKOUT bitNguyễn Thái Ngọc Duy, Sep 14, 2008
  6. 05/16 ls-files: add --narrow-checkout option to "will checkout" entriesNguyễn Thái Ngọc Duy, Sep 14, 2008
  7. 06/16 Add tests for updating no-checkout entries in indexNguyễn Thái Ngọc Duy, Sep 14, 2008
  8. 07/16 Prevent diff machinery from examining worktree outside narrow checkoutNguyễn Thái Ngọc Duy, Sep 14, 2008
  9. 08/16 checkout_entry(): CE_NO_CHECKOUT on checked out entries.Nguyễn Thái Ngọc Duy, Sep 14, 2008
  10. 09/16 ls-files: apply --deleted on narrow area onlyNguyễn Thái Ngọc Duy, Sep 14, 2008
  11. 10/16 grep: skip files that have not been checked outNguyễn Thái Ngọc Duy, Sep 14, 2008
  12. 11/16 unpack_trees(): add support for narrow checkoutNguyễn Thái Ngọc Duy, Sep 14, 2008
  13. 12/16 narrow spec: put '+' before a spec will change semantic of '*'Nguyễn Thái Ngọc Duy, Sep 14, 2008
  14. 13/16 ls-files: add --narrow-match=spec option for testing narrow matchingNguyễn Thái Ngọc Duy, Sep 14, 2008
  15. 14/16 clone: support narrow checkout with --path optionNguyễn Thái Ngọc Duy, Sep 14, 2008
  16. 15/16 checkout: add new options to support narrow checkoutNguyễn Thái Ngọc Duy, Sep 14, 2008
  17. 16/16 ls-files: add --overlay optionNguyễn Thái Ngọc Duy, Sep 14, 2008
  18. Jakub NarebskiSep 14, 2008
  19. Junio C HamanoSep 15, 2008
  20. Nguyen Thai Ngoc DuySep 16, 2008
  21. Junio C HamanoSep 16, 2008
  22. Jakub NarebskiSep 14, 2008
  23. BazSep 16, 2008
  24. Johannes SixtSep 16, 2008
  25. Nguyen Thai Ngoc DuySep 16, 2008
  26. Jakub NarebskiSep 14, 2008
  27. Junio C HamanoSep 15, 2008
  28. Jakub NarebskiSep 14, 2008
  29. Junio C HamanoSep 15, 2008
  30. Nguyen Thai Ngoc DuySep 16, 2008
  31. Jakub NarebskiSep 14, 2008
  32. Junio C HamanoSep 15, 2008
  33. Jakub NarebskiSep 14, 2008
  34. Junio C HamanoSep 15, 2008
  35. Jakub NarebskiSep 14, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.