@matheusbsbs / matheus-bagliano / commits / e800ec9d72
Fork 0

unpack_trees(): apply $GIT_DIR/info/sparse-checkout to the final index

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Aug 20, 2009 at 20:47 UTC e800ec9d72a0fafbc323c41e90f7757062c2680e
2 files changed +83 -1
unpack-trees.c
+81 -1
@@ -32,6 +32,12 @@ static struct unpack_trees_error_msgs unpack_plumbing_errors = {
32
33 /* bind_overlap */
34 "Entry '%s' overlaps with '%s'. Cannot bind.",
35 +
36 + /* sparse_not_uptodate_file */
37 + "Entry '%s' not uptodate. Cannot update sparse checkout.",
38 +
39 + /* would_lose_orphaned */
40 + "Working tree file '%s' would be %s by sparse checkout update.",
41 };
42
43 #define ERRORMSG(o,fld) \
@@ -125,6 +131,57 @@ static int check_updates(struct unpack_trees_options *o)
131 return errs != 0;
132 }
133
134 +static int verify_uptodate_sparse(struct cache_entry *ce, struct unpack_trees_options *o);
135 +static int verify_absent_sparse(struct cache_entry *ce, const char *action, struct unpack_trees_options *o);
136 +
137 +static int will_have_skip_worktree(const struct cache_entry *ce, struct unpack_trees_options *o)
138 +{
139 + const char *basename;
140 +
141 + if (ce_stage(ce))
142 + return 0;
143 +
144 + basename = strrchr(ce->name, '/');
145 + basename = basename ? basename+1 : ce->name;
146 + return excluded_from_list(ce->name, ce_namelen(ce), basename, NULL, o->el) <= 0;
147 +}
148 +
149 +static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_options *o)
150 +{
151 + int was_skip_worktree = ce_skip_worktree(ce);
152 +
153 + if (will_have_skip_worktree(ce, o))
154 + ce->ce_flags |= CE_SKIP_WORKTREE;
155 + else
156 + ce->ce_flags &= ~CE_SKIP_WORKTREE;
157 +
158 + /*
159 + * We only care about files getting into the checkout area
160 + * If merge strategies want to remove some, go ahead, this
161 + * flag will be removed eventually in unpack_trees() if it's
162 + * outside checkout area.
163 + */
164 + if (ce->ce_flags & CE_REMOVE)
165 + return 0;
166 +
167 + if (!was_skip_worktree && ce_skip_worktree(ce)) {
168 + /*
169 + * If CE_UPDATE is set, verify_uptodate() must be called already
170 + * also stat info may have lost after merged_entry() so calling
171 + * verify_uptodate() again may fail
172 + */
173 + if (!(ce->ce_flags & CE_UPDATE) && verify_uptodate_sparse(ce, o))
174 + return -1;
175 + ce->ce_flags |= CE_WT_REMOVE;
176 + }
177 + if (was_skip_worktree && !ce_skip_worktree(ce)) {
178 + if (verify_absent_sparse(ce, "overwritten", o))
179 + return -1;
180 + ce->ce_flags |= CE_UPDATE;
181 + }
182 + return 0;
183 +}
184 +
185 static inline int call_unpack_fn(struct cache_entry **src, struct unpack_trees_options *o)
186 {
187 int ret = o->fn(src, o);
@@ -376,7 +433,7 @@ static int unpack_failed(struct unpack_trees_options *o, const char *message)
433 */
434 int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options *o)
435 {
379 - int ret;
436 + int i, ret;
437 static struct cache_entry *dfc;
438 struct exclude_list el;
439
@@ -440,6 +497,17 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
497 goto done;
498 }
499
500 + if (!o->skip_sparse_checkout) {
501 + for (i = 0;i < o->result.cache_nr;i++) {
502 + struct cache_entry *ce = o->result.cache[i];
503 +
504 + if (apply_sparse_checkout(ce, o)) {
505 + ret = -1;
506 + goto done;
507 + }
508 + }
509 + }
510 +
511 o->src_index = NULL;
512 ret = check_updates(o) ? (-2) : 0;
513 if (o->dst_index)
@@ -512,6 +580,12 @@ static int verify_uptodate(struct cache_entry *ce,
580 return verify_uptodate_1(ce, o, ERRORMSG(o, not_uptodate_file));
581 }
582
583 +static int verify_uptodate_sparse(struct cache_entry *ce,
584 + struct unpack_trees_options *o)
585 +{
586 + return verify_uptodate_1(ce, o, ERRORMSG(o, sparse_not_uptodate_file));
587 +}
588 +
589 static void invalidate_ce_path(struct cache_entry *ce, struct unpack_trees_options *o)
590 {
591 if (ce)
@@ -705,6 +779,12 @@ static int verify_absent(struct cache_entry *ce, const char *action,
779 return verify_absent_1(ce, action, o, ERRORMSG(o, would_lose_untracked));
780 }
781
782 +static int verify_absent_sparse(struct cache_entry *ce, const char *action,
783 + struct unpack_trees_options *o)
784 +{
785 + return verify_absent_1(ce, action, o, ERRORMSG(o, would_lose_orphaned));
786 +}
787 +
788 static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
789 struct unpack_trees_options *o)
790 {
unpack-trees.h
+2
@@ -15,6 +15,8 @@ struct unpack_trees_error_msgs {
15 const char *not_uptodate_dir;
16 const char *would_lose_untracked;
17 const char *bind_overlap;
18 + const char *sparse_not_uptodate_file;
19 + const char *would_lose_orphaned;
20 };
21
22 struct unpack_trees_options {