245
static int verify_uptodate_sparse(struct cache_entry *ce, struct unpack_trees_options *o);
246
static int verify_absent_sparse(struct cache_entry *ce, enum unpack_trees_error_types, struct unpack_trees_options *o);
247
248
-static int will_have_skip_worktree(const struct cache_entry *ce, struct unpack_trees_options *o)
249
-{
250
- const char *basename;
251
-
252
- basename = strrchr(ce->name, '/');
253
- basename = basename ? basename+1 : ce->name;
254
- return excluded_from_list(ce->name, ce_namelen(ce), basename, NULL, o->el) <= 0;
255
-}
256
-
248
static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_options *o)
249
{
250
int was_skip_worktree = ce_skip_worktree(ce);
825
return mask;
826
}
827
828
+/* Whole directory matching */
829
+static int clear_ce_flags_dir(struct cache_entry **cache, int nr,
830
+ char *prefix, int prefix_len,
831
+ char *basename,
832
+ int select_mask, int clear_mask,
833
+ struct exclude_list *el)
834
+{
835
+ struct cache_entry **cache_end = cache + nr;
836
+ int dtype = DT_DIR;
837
+ int ret = excluded_from_list(prefix, prefix_len, basename, &dtype, el);
838
+
839
+ prefix[prefix_len++] = '/';
840
+
841
+ /* included, no clearing for any entries under this directory */
842
+ if (!ret) {
843
+ for (; cache != cache_end; cache++) {
844
+ struct cache_entry *ce = *cache;
845
+ if (strncmp(ce->name, prefix, prefix_len))
846
+ break;
847
+ }
848
+ return nr - (cache_end - cache);
849
+ }
850
+
851
+ /* excluded, clear all selected entries under this directory. */
852
+ if (ret == 1) {
853
+ for (; cache != cache_end; cache++) {
854
+ struct cache_entry *ce = *cache;
855
+ if (select_mask && !(ce->ce_flags & select_mask))
856
+ continue;
857
+ if (strncmp(ce->name, prefix, prefix_len))
858
+ break;
859
+ ce->ce_flags &= ~clear_mask;
860
+ }
861
+ return nr - (cache_end - cache);
862
+ }
863
+
864
+ return 0;
865
+}
866
+
867
+/*
868
+ * Traverse the index, find every entry that matches according to
869
+ * o->el. Do "ce_flags &= ~clear_mask" on those entries. Return the
870
+ * number of traversed entries.
871
+ *
872
+ * If select_mask is non-zero, only entries whose ce_flags has on of
873
+ * those bits enabled are traversed.
874
+ *
875
+ * cache : pointer to an index entry
876
+ * prefix_len : an offset to its path
877
+ *
878
+ * The current path ("prefix") including the trailing '/' is
879
+ * cache[0]->name[0..(prefix_len-1)]
880
+ * Top level path has prefix_len zero.
881
+ */
882
+static int clear_ce_flags_1(struct cache_entry **cache, int nr,
883
+ char *prefix, int prefix_len,
884
+ int select_mask, int clear_mask,
885
+ struct exclude_list *el)
886
+{
887
+ struct cache_entry **cache_end = cache + nr;
888
+
889
+ /*
890
+ * Process all entries that have the given prefix and meet
891
+ * select_mask condition
892
+ */
893
+ while(cache != cache_end) {
894
+ struct cache_entry *ce = *cache;
895
+ const char *name, *slash;
896
+ int len, dtype;
897
+
898
+ if (select_mask && !(ce->ce_flags & select_mask)) {
899
+ cache++;
900
+ continue;
901
+ }
902
+
903
+ if (prefix_len && strncmp(ce->name, prefix, prefix_len))
904
+ break;
905
+
906
+ name = ce->name + prefix_len;
907
+ slash = strchr(name, '/');
908
+
909
+ /* If it's a directory, try whole directory match first */
910
+ if (slash) {
911
+ int processed;
912
+
913
+ len = slash - name;
914
+ memcpy(prefix + prefix_len, name, len);
915
+
916
+ /*
917
+ * terminate the string (no trailing slash),
918
+ * clear_c_f_dir needs it
919
+ */
920
+ prefix[prefix_len + len] = '\0';
921
+ processed = clear_ce_flags_dir(cache, cache_end - cache,
922
+ prefix, prefix_len + len,
923
+ prefix + prefix_len,
924
+ select_mask, clear_mask,
925
+ el);
926
+
927
+ /* clear_c_f_dir eats a whole dir already? */
928
+ if (processed) {
929
+ cache += processed;
930
+ continue;
931
+ }
932
+
933
+ prefix[prefix_len + len++] = '/';
934
+ cache += clear_ce_flags_1(cache, cache_end - cache,
935
+ prefix, prefix_len + len,
936
+ select_mask, clear_mask, el);
937
+ continue;
938
+ }
939
+
940
+ /* Non-directory */
941
+ dtype = ce_to_dtype(ce);
942
+ if (excluded_from_list(ce->name, ce_namelen(ce), name, &dtype, el) > 0)
943
+ ce->ce_flags &= ~clear_mask;
944
+ cache++;
945
+ }
946
+ return nr - (cache_end - cache);
947
+}
948
+
949
+static int clear_ce_flags(struct cache_entry **cache, int nr,
950
+ int select_mask, int clear_mask,
951
+ struct exclude_list *el)
952
+{
953
+ char prefix[PATH_MAX];
954
+ return clear_ce_flags_1(cache, nr,
955
+ prefix, 0,
956
+ select_mask, clear_mask,
957
+ el);
958
+}
959
+
960
/*
961
* Set/Clear CE_NEW_SKIP_WORKTREE according to $GIT_DIR/info/sparse-checkout
962
*/
966
{
967
int i;
968
969
+ /*
970
+ * 1. Pretend the narrowest worktree: only unmerged entries
971
+ * are checked out
972
+ */
973
for (i = 0; i < the_index->cache_nr; i++) {
974
struct cache_entry *ce = the_index->cache[i];
975
976
if (select_flag && !(ce->ce_flags & select_flag))
977
continue;
978
852
- if (!ce_stage(ce) && will_have_skip_worktree(ce, o))
979
+ if (!ce_stage(ce))
980
ce->ce_flags |= skip_wt_flag;
981
else
982
ce->ce_flags &= ~skip_wt_flag;
983
}
984
+
985
+ /*
986
+ * 2. Widen worktree according to sparse-checkout file.
987
+ * Matched entries will have skip_wt_flag cleared (i.e. "in")
988
+ */
989
+ clear_ce_flags(the_index->cache, the_index->cache_nr,
990
+ select_flag, skip_wt_flag, el);
991
}
992
993
static int verify_absent(struct cache_entry *, enum unpack_trees_error_types, struct unpack_trees_options *);