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

[PATCH] checkout: add --sparse for restoring files in sparse checkout mode

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Mar 24, 2013, 05:06 UTC
Message-ID
<1364101583-6035-1-git-send-email-pclouds@gmail.com>
In-Reply-To
<514C3249.7000100@ivt.baug.ethz.ch>

"git checkout -- <paths>" is usually used to restore all modified files in <paths>. In sparse checkout mode, this command is overloaded with another meaning: to add back all files in <paths> that are excluded by sparse patterns.

Add "--sparse" option to do what normal mode does: restore all modified files and nothing else.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 I'm not sure if rejecting --sparse when it has no effects (e.g.
 switching branches or interactive mode) like this patch does is a
 good idea. I think it's good in general to spot unused options. On
 the other hand, people may want to add an alias
 "co = checkout --sparse" to make this behavior "default". In that
 case silently ignoring --sparse may be a good idea.
 Documentation/git-checkout.txt       |  7 +++++++
 builtin/checkout.c                   | 18 ++++++++++++++++--
 t/t1011-read-tree-sparse-checkout.sh | 12 ++++++++++++
 3 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 8edcdca..45a2b53 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -180,6 +180,13 @@ branch by running "git rm -rf ." from the top level of the working tree.
 Afterwards you will be ready to prepare your new files, repopulating the
 working tree, by copying them from elsewhere, extracting a tarball, etc.
 
+
+--sparse::
+	In sparse checkout mode, `git checkout -- <paths>` would
+	update all entries matched by <paths> regardless sparse
+	patterns. This option only updates entries matched by <paths>
+	and sparse patterns.
+
 -m::
 --merge::
 	When switching branches,
diff --git a/builtin/checkout.c b/builtin/checkout.c
index a9c1b5a..3a32145 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -35,6 +35,7 @@ struct checkout_opts {
 	int force_detach;
 	int writeout_stage;
 	int overwrite_ignore;
+	int sparse;
 
 	const char *new_branch;
 	const char *new_branch_force;
@@ -224,7 +225,7 @@ static int checkout_paths(const struct checkout_opts *opts,
 	struct checkout state;
 	static char *ps_matched;
 	unsigned char rev[20];
-	int flag;
+	int flag, sparse;
 	struct commit *head;
 	int errs = 0;
 	int stage = opts->writeout_stage;
@@ -254,9 +255,13 @@ static int checkout_paths(const struct checkout_opts *opts,
 		die(_("Cannot update paths and switch to branch '%s' at the same time."),
 		    opts->new_branch);
 
-	if (opts->patch_mode)
+	if (opts->patch_mode) {
+		if (opts->sparse != -1)
+			die(_("--[no-]sparse cannot be used in interactive mode"));
 		return run_add_interactive(revision, "--patch=checkout",
 					   opts->pathspec);
+	}
+	sparse = opts->sparse != -1 ? opts->sparse : 0;
 
 	lock_file = xcalloc(1, sizeof(struct lock_file));
 
@@ -275,6 +280,8 @@ static int checkout_paths(const struct checkout_opts *opts,
 		struct cache_entry *ce = active_cache[pos];
 		if (opts->source_tree && !(ce->ce_flags & CE_UPDATE))
 			continue;
+		if (sparse && ce_skip_worktree(ce))
+			continue;
 		match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
 	}
 
@@ -315,6 +322,8 @@ static int checkout_paths(const struct checkout_opts *opts,
 		struct cache_entry *ce = active_cache[pos];
 		if (opts->source_tree && !(ce->ce_flags & CE_UPDATE))
 			continue;
+		if (sparse && ce_skip_worktree(ce))
+			continue;
 		if (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
 			if (!ce_stage(ce)) {
 				errs |= checkout_entry(ce, &state, NULL);
@@ -963,6 +972,9 @@ static int checkout_branch(struct checkout_opts *opts,
 	if (opts->pathspec)
 		die(_("paths cannot be used with switching branches"));
 
+	if (opts->sparse != -1)
+		die(_("--[no-]sparse can only be used with paths"));
+
 	if (opts->patch_mode)
 		die(_("'%s' cannot be used with switching branches"),
 		    "--patch");
@@ -1029,6 +1041,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		OPT_STRING(0, "conflict", &conflict_style, N_("style"),
 			   N_("conflict style (merge or diff3)")),
 		OPT_BOOLEAN('p', "patch", &opts.patch_mode, N_("select hunks interactively")),
+		OPT_BOOL(0, "sparse", &opts.sparse, N_("limit pathspecs to sparse entries only")),
 		{ OPTION_BOOLEAN, 0, "guess", &dwim_new_local_branch, NULL,
 		  N_("second guess 'git checkout no-such-branch'"),
 		  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
@@ -1039,6 +1052,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 	memset(&new, 0, sizeof(new));
 	opts.overwrite_ignore = 1;
 	opts.prefix = prefix;
+	opts.sparse = -1;
 
 	gitmodules_config();
 	git_config(git_checkout_config, &opts);
diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh
index 5c0053a..1441fbe 100755
--- a/t/t1011-read-tree-sparse-checkout.sh
+++ b/t/t1011-read-tree-sparse-checkout.sh
@@ -250,4 +250,16 @@ EOF
 	test_cmp expected actual
 '
 
+test_expect_success 'checkout --sparse' '
+	echo "*" >.git/info/sparse-checkout &&
+	git checkout -f top &&
+	test -f init.t &&
+	echo sub >.git/info/sparse-checkout &&
+	git checkout &&
+	echo modified >> sub/added &&
+	git checkout --sparse . &&
+	! test -f init.t &&
+	git diff --exit-code HEAD
+'
+
 test_done
-- 
1.8.2.83.gc99314b
Previous: Kirill MüllerNext: Eric Sunshine
Message 4 of 17 in “Hard reset of a subdirectory in a sparse checkout setting”
  1. Kirill MüllerMar 22, 2013
  2. Duy NguyenMar 23, 2013
  3. Kirill MüllerMar 23, 2013
  4. checkout: add --sparse for restoring files in sparse checkout modeNguyễn Thái Ngọc Duy, Mar 24, 2013
  5. Eric SunshineMar 24, 2013
  6. Jonathan NiederMar 24, 2013
  7. Kirill MüllerMar 24, 2013
  8. Duy NguyenMar 25, 2013
  9. Jonathan NiederMar 25, 2013
  10. checkout: add --no-widen for restoring files in sparse checkout modeNguyễn Thái Ngọc Duy, Mar 30, 2013
  11. Jonathan NiederApr 1, 2013
  12. Junio C HamanoApr 1, 2013
  13. Duy NguyenApr 1, 2013
  14. Jonathan NiederApr 1, 2013
  15. checkout: add --ignore-skip-worktree-bits in sparse checkout modeNguyễn Thái Ngọc Duy, Apr 12, 2013
  16. Müller KirillMay 14, 2013
  17. Duy NguyenMay 14, 2013

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.