From: "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: newren@gmaill.com, peff@peff.net, me@ttaylorr.com,
jrnieder@gmail.com, Derrick Stolee <dstolee@microsoft.com>,
Derrick Stolee <dstolee@microsoft.com>
Subject: [PATCH 05/10] sparse-checkout: automatically update in-tree definition
Date: Thu, 07 May 2020 13:17:37 +0000 [thread overview]
Message-ID: <9a2cb7bb5ed7a5dc039d4b47bfee83c589252a45.1588857462.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.627.git.1588857462.gitgitgadget@gmail.com>
From: Derrick Stolee <dstolee@microsoft.com>
A benefit of having sparse-checkouts defined in the tree data is that
the sparse-checkout definition can change over time. To take advantage
of that data, a user could run "git sparse-checkout reapply" whenever
they thought the sparse-checkout definition was out of date. That is
likely too manual of a process, since a user would probably only
discover this after a failure to accomplish their goal, such as a build
failure.
Prevent user frustration by automatically updating the sparse-checkout
definition after changing the index when an in-tree definition is
provided by config. This will happen during every index change,
including every step of a rebase, including conflict states.
Special care was needed around the --no-sparse-checkout option in "git
read-tree". This previously relied on changing the skip_sparse_checkout
option in "struct unpack_trees_options" to prevent applying the
skip-worktree bits. However, now that we make a second update to the
index focusing on the skip-worktree bits, this needs to be prevented in
another way. The simplest thing to do was disable the feature through
the core_apply_sparse_checkout global variable.
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
---
Documentation/git-sparse-checkout.txt | 7 ++++---
builtin/commit.c | 4 +++-
builtin/read-tree.c | 4 ++++
read-cache.c | 8 +++++---
sparse-checkout.c | 26 +++++++++++++++++++++++++-
sparse-checkout.h | 1 +
t/t1091-sparse-checkout-builtin.sh | 19 +++++++++++++++----
7 files changed, 57 insertions(+), 12 deletions(-)
diff --git a/Documentation/git-sparse-checkout.txt b/Documentation/git-sparse-checkout.txt
index da9322c5e41..c1713ebb1d2 100644
--- a/Documentation/git-sparse-checkout.txt
+++ b/Documentation/git-sparse-checkout.txt
@@ -233,9 +233,10 @@ Use `git sparse-checkout set --in-tree <path>` to initialize the patterns
to those included in the file at `<path>`. This will override any existing
patterns you have in your sparse-checkout file.
-After switching between commits with different versions of this file, run
-`git sparse-checkout reapply` to adjust the sparse-checkout patterns to
-the new definition.
+As Git switches between commits, it will update the in-tree sparse-checkout
+definition according to the files available at the new commit. If any of
+the specified files do not exist at the new commit, then the sparse-checkout
+definition will not change.
SUBMODULES
diff --git a/builtin/commit.c b/builtin/commit.c
index 7ba33a3bec4..0eab8d74469 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -36,6 +36,7 @@
#include "help.h"
#include "commit-reach.h"
#include "commit-graph.h"
+#include "sparse-checkout.h"
static const char * const builtin_commit_usage[] = {
N_("git commit [<options>] [--] <pathspec>..."),
@@ -222,7 +223,8 @@ static int commit_index_files(void)
case COMMIT_AS_IS:
break; /* nothing to do */
case COMMIT_NORMAL:
- err = commit_lock_file(&index_lock);
+ err = commit_lock_file(&index_lock) ||
+ update_in_tree_sparse_checkout();
break;
case COMMIT_PARTIAL:
err = commit_lock_file(&index_lock);
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index af7424b94c8..9ae81ffffa1 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -247,6 +247,10 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
parse_tree(tree);
init_tree_desc(t+i, tree->buffer, tree->size);
}
+
+ if (opts.skip_sparse_checkout)
+ core_apply_sparse_checkout = 0;
+
if (unpack_trees(nr_trees, t, &opts))
return 128;
diff --git a/read-cache.c b/read-cache.c
index aa427c5c170..150e73feb0d 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -25,6 +25,7 @@
#include "fsmonitor.h"
#include "thread-utils.h"
#include "progress.h"
+#include "sparse-checkout.h"
/* Mask for the name length in ce_flags in the on-disk index */
@@ -3074,9 +3075,10 @@ static int do_write_locked_index(struct index_state *istate, struct lock_file *l
if (ret)
return ret;
- if (flags & COMMIT_LOCK)
- ret = commit_locked_index(lock);
- else
+ if (flags & COMMIT_LOCK) {
+ ret = commit_locked_index(lock) ||
+ update_in_tree_sparse_checkout();
+ } else
ret = close_lock_file_gently(lock);
run_hook_le(NULL, "post-index-change",
diff --git a/sparse-checkout.c b/sparse-checkout.c
index d6c27ca19c4..6c58fda9722 100644
--- a/sparse-checkout.c
+++ b/sparse-checkout.c
@@ -92,9 +92,12 @@ int load_in_tree_pattern_list(struct repository *r,
* Exit silently, as this is likely the case where Git
* changed branches to a location where the inherit file
* does not exist. Do not update the sparse-checkout.
+ *
+ * Use -1 return to ensure populate_from_existing_patterns()
+ * skips the sparse-checkout updates.
*/
if (pos < 0)
- return 1;
+ return -1;
oid = &istate->cache[pos]->oid;
type = oid_object_info(r, oid, NULL);
@@ -145,6 +148,7 @@ int populate_sparse_checkout_patterns(struct pattern_list *pl)
return result;
}
+static int updating_sparse_checkout = 0;
int update_working_directory(struct pattern_list *pl)
{
enum update_sparsity_result result;
@@ -152,6 +156,10 @@ int update_working_directory(struct pattern_list *pl)
struct lock_file lock_file = LOCK_INIT;
struct repository *r = the_repository;
+ if (updating_sparse_checkout)
+ return 0;
+ updating_sparse_checkout = 1;
+
memset(&o, 0, sizeof(o));
o.verbose_update = isatty(2);
o.update = 1;
@@ -180,9 +188,24 @@ int update_working_directory(struct pattern_list *pl)
else
rollback_lock_file(&lock_file);
+ updating_sparse_checkout = 0;
return result;
}
+int update_in_tree_sparse_checkout(void)
+{
+ const char *first_value;
+
+ if (!core_apply_sparse_checkout)
+ return 0;
+
+ /* only update if doing so due to sparse.inTree. */
+ if (!git_config_get_value(SPARSE_CHECKOUT_IN_TREE, &first_value) &&
+ first_value)
+ return update_working_directory(NULL);
+ return 0;
+}
+
static char *escaped_pattern(char *pattern)
{
char *p = pattern;
@@ -273,6 +296,7 @@ int write_patterns_and_update(struct pattern_list *pl)
free(sparse_filename);
clear_pattern_list(pl);
update_working_directory(NULL);
+ updating_sparse_checkout = 0;
return result;
}
diff --git a/sparse-checkout.h b/sparse-checkout.h
index 993a5701a60..fb0ba48524a 100644
--- a/sparse-checkout.h
+++ b/sparse-checkout.h
@@ -13,6 +13,7 @@ char *get_sparse_checkout_filename(void);
int populate_sparse_checkout_patterns(struct pattern_list *pl);
void write_patterns_to_file(FILE *fp, struct pattern_list *pl);
int update_working_directory(struct pattern_list *pl);
+int update_in_tree_sparse_checkout(void);
int write_patterns(struct pattern_list *pl, int and_update);
int write_patterns_and_update(struct pattern_list *pl);
void insert_recursive_pattern(struct pattern_list *pl, struct strbuf *path);
diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh
index 1040bf9c261..fdaafba5377 100755
--- a/t/t1091-sparse-checkout-builtin.sh
+++ b/t/t1091-sparse-checkout-builtin.sh
@@ -605,6 +605,7 @@ test_expect_success MINGW 'cone mode replaces backslashes with slashes' '
'
test_expect_success 'basis of --in-tree' '
+ git -C repo branch no-in-tree &&
git -C repo config auto.crlf false &&
cat >folder1 <<-\EOF &&
[sparse]
@@ -690,18 +691,28 @@ test_expect_success '"add" with --in-tree' '
check_files repo a deep folder1
'
-test_expect_success 'reapply after updating in-tree file' '
+test_expect_success 'automatically change after updating in-tree file' '
git -C repo sparse-checkout set --in-tree .sparse/sparse &&
check_files repo a &&
test_path_is_dir repo/.sparse &&
- echo "\tdir = folder1" >>repo/.sparse/sparse &&
+ printf "\tdir = folder1\n" >>repo/.sparse/sparse &&
git -C repo commit -a -m "Update sparse file" &&
- git -C repo sparse-checkout reapply &&
check_files repo a folder1 &&
test_path_is_dir repo/.sparse &&
git -C repo checkout HEAD~1 &&
- git -C repo sparse-checkout reapply &&
check_files repo a &&
+ test_path_is_dir repo/.sparse &&
+ git -C repo checkout - &&
+ check_files repo a folder1 &&
+ test_path_is_dir repo/.sparse
+'
+
+test_expect_success 'keep definition when in-tree file is missing' '
+ git -C repo checkout no-in-tree &&
+ check_files repo a folder1 &&
+ test_path_is_missing repo/.sparse &&
+ git -C repo checkout - &&
+ check_files repo a folder1 &&
test_path_is_dir repo/.sparse
'
--
gitgitgadget
next prev parent reply other threads:[~2020-05-07 13:18 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-07 13:17 [PATCH 00/10] [RFC] In-tree sparse-checkout definitions Derrick Stolee via GitGitGadget
2020-05-07 13:17 ` [PATCH 01/10] unpack-trees: avoid array out-of-bounds error Derrick Stolee via GitGitGadget
2020-05-07 22:27 ` Junio C Hamano
2020-05-08 12:19 ` Derrick Stolee
2020-05-08 15:09 ` Junio C Hamano
2020-05-20 16:32 ` Elijah Newren
2020-05-07 13:17 ` [PATCH 02/10] sparse-checkout: move code from builtin Derrick Stolee via GitGitGadget
2020-05-07 13:17 ` [PATCH 03/10] sparse-checkout: move code from unpack-trees.c Derrick Stolee via GitGitGadget
2020-05-07 13:17 ` [PATCH 04/10] sparse-checkout: allow in-tree definitions Derrick Stolee via GitGitGadget
2020-05-07 22:58 ` Junio C Hamano
2020-05-08 15:40 ` Derrick Stolee
2020-05-20 17:52 ` Elijah Newren
2020-06-17 23:07 ` Elijah Newren
2020-06-18 8:18 ` Son Luong Ngoc
2020-05-07 13:17 ` Derrick Stolee via GitGitGadget [this message]
2020-05-20 16:28 ` [PATCH 05/10] sparse-checkout: automatically update in-tree definition Elijah Newren
2020-05-07 13:17 ` [PATCH 06/10] sparse-checkout: use oidset to prevent repeat blobs Derrick Stolee via GitGitGadget
2020-05-20 16:40 ` Elijah Newren
2020-05-21 3:49 ` Elijah Newren
2020-05-21 17:54 ` Derrick Stolee
2020-05-07 13:17 ` [PATCH 07/10] sparse-checkout: define in-tree dependencies Derrick Stolee via GitGitGadget
2020-05-20 18:10 ` Elijah Newren
2020-05-30 17:26 ` Elijah Newren
2020-05-07 13:17 ` [PATCH 08/10] Makefile: skip git-gui if dir is missing Derrick Stolee via GitGitGadget
2020-05-07 13:17 ` [PATCH 09/10] Makefile: disable GETTEXT when 'po' " Derrick Stolee via GitGitGadget
2020-05-07 13:17 ` [PATCH 10/10] .sparse: add in-tree sparse-checkout for Git Derrick Stolee via GitGitGadget
2020-05-20 17:38 ` [PATCH 00/10] [RFC] In-tree sparse-checkout definitions Elijah Newren
2020-06-17 23:14 ` Elijah Newren
2020-06-18 1:42 ` Derrick Stolee
2020-06-18 1:59 ` Elijah Newren
2020-06-18 3:01 ` Derrick Stolee
2020-06-18 5:03 ` Elijah Newren
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9a2cb7bb5ed7a5dc039d4b47bfee83c589252a45.1588857462.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=dstolee@microsoft.com \
--cc=git@vger.kernel.org \
--cc=jrnieder@gmail.com \
--cc=me@ttaylorr.com \
--cc=newren@gmaill.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).