aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/config.txt4
-rw-r--r--Documentation/git-read-tree.txt4
-rw-r--r--cache.h1
-rw-r--r--config.c5
-rw-r--r--environment.c1
-rw-r--r--unpack-trees.c36
-rw-r--r--unpack-trees.h4
7 files changed, 48 insertions, 7 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 7791c32bc..5825c914f 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -439,6 +439,10 @@ On some file system/operating system combinations, this is unreliable.
Set this config setting to 'rename' there; However, This will remove the
check that makes sure that existing object files will not get overwritten.
+core.sparseCheckout::
+ Enable "sparse checkout" feature. See section "Sparse checkout" in
+ linkgit:git-read-tree[1] for more information.
+
add.ignore-errors::
Tells 'git-add' to continue adding files when some files cannot be
added due to indexing errors. Equivalent to the '--ignore-errors'
diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt
index 8b3971685..fc3f08b81 100644
--- a/Documentation/git-read-tree.txt
+++ b/Documentation/git-read-tree.txt
@@ -401,7 +401,9 @@ follows:
----------------
Then you can disable sparse checkout. Sparse checkout support in "git
-read-tree" and similar commands is disabled by default.
+read-tree" and similar commands is disabled by default. You need to
+turn `core.sparseCheckout` on in order to have sparse checkout
+support.
SEE ALSO
diff --git a/cache.h b/cache.h
index d3f81a1c7..2de00f812 100644
--- a/cache.h
+++ b/cache.h
@@ -526,6 +526,7 @@ extern size_t delta_base_cache_limit;
extern int auto_crlf;
extern int fsync_object_files;
extern int core_preload_index;
+extern int core_apply_sparse_checkout;
enum safe_crlf {
SAFE_CRLF_FALSE = 0,
diff --git a/config.c b/config.c
index e87edeab0..abd762ebf 100644
--- a/config.c
+++ b/config.c
@@ -503,6 +503,11 @@ static int git_default_core_config(const char *var, const char *value)
return 0;
}
+ if (!strcmp(var, "core.sparsecheckout")) {
+ core_apply_sparse_checkout = git_config_bool(var, value);
+ return 0;
+ }
+
/* Add other config variables here and to Documentation/config.txt. */
return 0;
}
diff --git a/environment.c b/environment.c
index 8f5eaa7dd..020422c03 100644
--- a/environment.c
+++ b/environment.c
@@ -48,6 +48,7 @@ enum push_default_type push_default = PUSH_DEFAULT_MATCHING;
#endif
enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
int grafts_replace_parents = 1;
+int core_apply_sparse_checkout;
/* Parallel index stat data preload? */
int core_preload_index = 0;
diff --git a/unpack-trees.c b/unpack-trees.c
index 8eb4b7095..44f8fdf80 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -378,6 +378,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
{
int ret;
static struct cache_entry *dfc;
+ struct exclude_list el;
if (len > MAX_UNPACK_TREES)
die("unpack_trees takes at most %d trees", MAX_UNPACK_TREES);
@@ -387,6 +388,16 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
state.quiet = 1;
state.refresh_cache = 1;
+ memset(&el, 0, sizeof(el));
+ if (!core_apply_sparse_checkout || !o->update)
+ o->skip_sparse_checkout = 1;
+ if (!o->skip_sparse_checkout) {
+ if (add_excludes_from_file_to_list(git_path("info/sparse-checkout"), "", 0, NULL, &el, 0) < 0)
+ o->skip_sparse_checkout = 1;
+ else
+ o->el = &el;
+ }
+
memset(&o->result, 0, sizeof(o->result));
o->result.initialized = 1;
if (o->src_index) {
@@ -407,26 +418,39 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
info.fn = unpack_callback;
info.data = o;
- if (traverse_trees(len, t, &info) < 0)
- return unpack_failed(o, NULL);
+ if (traverse_trees(len, t, &info) < 0) {
+ ret = unpack_failed(o, NULL);
+ goto done;
+ }
}
/* Any left-over entries in the index? */
if (o->merge) {
while (o->pos < o->src_index->cache_nr) {
struct cache_entry *ce = o->src_index->cache[o->pos];
- if (unpack_index_entry(ce, o) < 0)
- return unpack_failed(o, NULL);
+ if (unpack_index_entry(ce, o) < 0) {
+ ret = unpack_failed(o, NULL);
+ goto done;
+ }
}
}
- if (o->trivial_merges_only && o->nontrivial_merge)
- return unpack_failed(o, "Merge requires file-level merging");
+ if (o->trivial_merges_only && o->nontrivial_merge) {
+ ret = unpack_failed(o, "Merge requires file-level merging");
+ goto done;
+ }
o->src_index = NULL;
ret = check_updates(o) ? (-2) : 0;
if (o->dst_index)
*o->dst_index = o->result;
+
+done:
+ for (i = 0;i < el.nr;i++)
+ free(el.excludes[i]);
+ if (el.excludes)
+ free(el.excludes);
+
return ret;
}
diff --git a/unpack-trees.h b/unpack-trees.h
index d19df44f4..5c9e98a66 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -4,6 +4,7 @@
#define MAX_UNPACK_TREES 8
struct unpack_trees_options;
+struct exclude_list;
typedef int (*merge_fn_t)(struct cache_entry **src,
struct unpack_trees_options *options);
@@ -28,6 +29,7 @@ struct unpack_trees_options {
skip_unmerged,
initial_checkout,
diff_index_cached,
+ skip_sparse_checkout,
gently;
const char *prefix;
int pos;
@@ -44,6 +46,8 @@ struct unpack_trees_options {
struct index_state *dst_index;
struct index_state *src_index;
struct index_state result;
+
+ struct exclude_list *el; /* for internal use */
};
extern int unpack_trees(unsigned n, struct tree_desc *t,