git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Hard reset of a subdirectory in a sparse checkout setting
@ 2013-03-22 10:28 Kirill Müller
  2013-03-23  9:59 ` Duy Nguyen
  2013-03-24  5:06 ` [PATCH] checkout: add --sparse for restoring files in sparse checkout mode Nguyễn Thái Ngọc Duy
  0 siblings, 2 replies; 17+ messages in thread
From: Kirill Müller @ 2013-03-22 10:28 UTC (permalink / raw)
  To: git

Hi

I can't find a neat way to "git reset --hard" a subdirectory of a 
checkout without reading in directories or files which are excluded by a 
sparse checkout. This has been asked on StackOverflow in greater detail, 
but the "right" answer is still missing: 
http://stackoverflow.com/q/15404535/946850

The options I see are:

- git checkout . (will restore excluded directories)

- git reset --hard (won't accept a path argument)

- git diff | patch -R (awkward)

What's the proper way to do this in Git?

The script below illustrates the problem. The proper command should be 
inserted below the "How to make files ..." comment -- the current 
command "git checkout -- a" will restore the file a/c/ac which is 
supposed to be excluded by the sparse checkout. Note that I do not want 
to explicitly restore a/a and a/b, I only "know" a and want to restore 
everything below. And I also don't "know" b, or which other directories 
reside on the same level as a.

Thank you for your help.


Cheers

Kirill


#!/bin/sh

rm -rf repo; git init repo; cd repo
for f in a b; do
   for g in a b c; do
     mkdir -p $f/$g
     touch $f/$g/$f$g
     git add $f/$g
     git commit -m "added $f/$g"
   done
done
git config core.sparsecheckout true
echo a/a > .git/info/sparse-checkout
echo a/b >> .git/info/sparse-checkout
echo b/a >> .git/info/sparse-checkout
git read-tree -m -u HEAD
echo "After read-tree:"
find * -type f

rm a/a/aa
rm a/b/ab
echo >> b/a/ba
echo "After modifying:"
find * -type f
git status

# How to make files a/* reappear without changing b and without 
recreating a/c?
git checkout -- a

echo "After checkout:"
git status
find * -type f

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Hard reset of a subdirectory in a sparse checkout setting
  2013-03-22 10:28 Hard reset of a subdirectory in a sparse checkout setting Kirill Müller
@ 2013-03-23  9:59 ` Duy Nguyen
  2013-03-23 13:02   ` Kirill Müller
  2013-03-24  5:06 ` [PATCH] checkout: add --sparse for restoring files in sparse checkout mode Nguyễn Thái Ngọc Duy
  1 sibling, 1 reply; 17+ messages in thread
From: Duy Nguyen @ 2013-03-23  9:59 UTC (permalink / raw)
  To: Kirill Müller; +Cc: git

On Fri, Mar 22, 2013 at 5:28 PM, Kirill Müller
<kirill.mueller@ivt.baug.ethz.ch> wrote:
> I can't find a neat way to "git reset --hard" a subdirectory of a checkout
> without reading in directories or files which are excluded by a sparse
> checkout. This has been asked on StackOverflow in greater detail, but the
> "right" answer is still missing: http://stackoverflow.com/q/15404535/946850
>
> The options I see are:
>
> - git checkout . (will restore excluded directories)
>
> - git reset --hard (won't accept a path argument)
>
> - git diff | patch -R (awkward)

Another way is

git diff --name-only -z|xargs -0 git checkout

> What's the proper way to do this in Git?

I think adding --sparse to git checkout may be more user-friendly. And
it looks like a simple change. I'll make a patch soon (I need some
time to recall how sparse checkout interacts with git-checkout).
-- 
Duy

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Hard reset of a subdirectory in a sparse checkout setting
  2013-03-23  9:59 ` Duy Nguyen
@ 2013-03-23 13:02   ` Kirill Müller
  0 siblings, 0 replies; 17+ messages in thread
From: Kirill Müller @ 2013-03-23 13:02 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git

On 03/23/2013 10:59 AM, Duy Nguyen wrote:
> On Fri, Mar 22, 2013 at 5:28 PM, Kirill Müller
> <kirill.mueller@ivt.baug.ethz.ch> wrote:
>> What's the proper way to do this in Git?
> I think adding --sparse to git checkout may be more user-friendly. And
> it looks like a simple change. I'll make a patch soon (I need some
> time to recall how sparse checkout interacts with git-checkout).
Thanks for looking into it. Would it mean an extra switch to the 
checkout command, or default behavior?

-Kirill

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH] checkout: add --sparse for restoring files in sparse checkout mode
  2013-03-22 10:28 Hard reset of a subdirectory in a sparse checkout setting Kirill Müller
  2013-03-23  9:59 ` Duy Nguyen
@ 2013-03-24  5:06 ` Nguyễn Thái Ngọc Duy
  2013-03-24  6:12   ` Eric Sunshine
                     ` (2 more replies)
  1 sibling, 3 replies; 17+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-03-24  5:06 UTC (permalink / raw)
  To: git; +Cc: kirill.mueller, Nguyễn Thái Ngọc Duy

"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

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH] checkout: add --sparse for restoring files in sparse checkout mode
  2013-03-24  5:06 ` [PATCH] checkout: add --sparse for restoring files in sparse checkout mode Nguyễn Thái Ngọc Duy
@ 2013-03-24  6:12   ` Eric Sunshine
  2013-03-24 18:17   ` Jonathan Nieder
  2013-03-30 10:02   ` [PATCH v2] checkout: add --no-widen " Nguyễn Thái Ngọc Duy
  2 siblings, 0 replies; 17+ messages in thread
From: Eric Sunshine @ 2013-03-24  6:12 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy; +Cc: Git List, kirill.mueller

On Sun, Mar 24, 2013 at 1:06 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
> 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.
> +--sparse::
> +       In sparse checkout mode, `git checkout -- <paths>` would
> +       update all entries matched by <paths> regardless sparse

s/regardless/regardless of/

> +       patterns. This option only updates entries matched by <paths>
> +       and sparse patterns.
> +

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] checkout: add --sparse for restoring files in sparse checkout mode
  2013-03-24  5:06 ` [PATCH] checkout: add --sparse for restoring files in sparse checkout mode Nguyễn Thái Ngọc Duy
  2013-03-24  6:12   ` Eric Sunshine
@ 2013-03-24 18:17   ` Jonathan Nieder
  2013-03-24 19:50     ` Kirill Müller
  2013-03-25  1:34     ` Duy Nguyen
  2013-03-30 10:02   ` [PATCH v2] checkout: add --no-widen " Nguyễn Thái Ngọc Duy
  2 siblings, 2 replies; 17+ messages in thread
From: Jonathan Nieder @ 2013-03-24 18:17 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy; +Cc: git, kirill.mueller

Hi,

Nguyễn Thái Ngọc Duy wrote:

> --- 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.

Hm, should this be the default?

In principle, I would expect

	git checkout -- .

to make the worktree match the index, respecting the sparse checkout.
And something like

	git checkout --widen -- .

to change the sparse checkout pattern.  But of course it is easily
possible that I am missing some details of how sparse checkout is
used in practice.

What do you think?
Jonathan

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] checkout: add --sparse for restoring files in sparse checkout mode
  2013-03-24 18:17   ` Jonathan Nieder
@ 2013-03-24 19:50     ` Kirill Müller
  2013-03-25  1:34     ` Duy Nguyen
  1 sibling, 0 replies; 17+ messages in thread
From: Kirill Müller @ 2013-03-24 19:50 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Nguyễn Thái Ngọc Duy, git

Hi

On 03/24/2013 07:17 PM, Jonathan Nieder wrote:
> Hi,
>
> Nguyễn Thái Ngọc Duy wrote:
>
>> --- 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.
> Hm, should this be the default?
>
> In principle, I would expect
>
> 	git checkout -- .
>
> to make the worktree match the index, respecting the sparse checkout.
> And something like
>
> 	git checkout --widen -- .
>
> to change the sparse checkout pattern.  But of course it is easily
> possible that I am missing some details of how sparse checkout is
> used in practice.
>
> What do you think?
Thank you for your opinion. I'd second that. When I do a sparse 
checkout, I want to see only the directories I have included and not 
excluded, unless I explicitly change that.


-Kirill

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] checkout: add --sparse for restoring files in sparse checkout mode
  2013-03-24 18:17   ` Jonathan Nieder
  2013-03-24 19:50     ` Kirill Müller
@ 2013-03-25  1:34     ` Duy Nguyen
  2013-03-25  1:57       ` Jonathan Nieder
  1 sibling, 1 reply; 17+ messages in thread
From: Duy Nguyen @ 2013-03-25  1:34 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: git, kirill.mueller

On Mon, Mar 25, 2013 at 1:17 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:
>> +--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.
>
> Hm, should this be the default?
>
> In principle, I would expect
>
>         git checkout -- .
>
> to make the worktree match the index, respecting the sparse checkout.
> And something like
>
>         git checkout --widen -- .
>
> to change the sparse checkout pattern.  But of course it is easily
> possible that I am missing some details of how sparse checkout is
> used in practice.
>
> What do you think?

Changing the default may involve a painful transition phase (e.g. "add
-u"). I think making it the default via alias should be good enough in
most cases. We also need to think how it impacts checkout usage in
scripts. I think it might be ok, but I haven't finished my morning
coffee yet, so..
-- 
Duy

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] checkout: add --sparse for restoring files in sparse checkout mode
  2013-03-25  1:34     ` Duy Nguyen
@ 2013-03-25  1:57       ` Jonathan Nieder
  0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2013-03-25  1:57 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git, kirill.mueller

Duy Nguyen wrote:
> On Mon, Mar 25, 2013 at 1:17 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:

>> Hm, should this be the default?
>>
>> In principle, I would expect
>>
>>         git checkout -- .
>>
>> to make the worktree match the index, respecting the sparse checkout.
>> And something like
>>
>>         git checkout --widen -- .
>>
>> to change the sparse checkout pattern.
[...]
> Changing the default may involve a painful transition phase (e.g. "add
> -u").

I don't think it needs to.  There aren't many people using sparse
checkout even these days, and I think they'd generally be happy about
the change.

But if we want to be conservative until some later point (like 2.1),
perhaps --sparse should be named something like --no-widen?  That
way, I can do

	git checkout --no-widen -- .

to make the worktree match the index, respecting the sparse checkout.
And I can do

	git checkout --widen -- .

to change the sparse checkout pattern.  Meanwhile the confusing
command

	git checkout -- .

would be ill-defined for sparse checkouts --- in past git versions,
if I understand you correctly it acted like --widen, while in some
unspecified future version it may change to mean --no-widen.  No
need for warnings because I doubt anyone is relying on either
behavior.

Would that work?
Jonathan

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2] checkout: add --no-widen for restoring files in sparse checkout mode
  2013-03-24  5:06 ` [PATCH] checkout: add --sparse for restoring files in sparse checkout mode Nguyễn Thái Ngọc Duy
  2013-03-24  6:12   ` Eric Sunshine
  2013-03-24 18:17   ` Jonathan Nieder
@ 2013-03-30 10:02   ` Nguyễn Thái Ngọc Duy
  2013-04-01  4:48     ` Jonathan Nieder
  2013-04-12 23:12     ` [PATCH v3] checkout: add --ignore-skip-worktree-bits " Nguyễn Thái Ngọc Duy
  2 siblings, 2 replies; 17+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-03-30 10:02 UTC (permalink / raw)
  To: git
  Cc: kirill.mueller, Junio C Hamano, Jonathan Niedier,
	Nguyễn Thái Ngọc Duy

"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 "--no-widen" option to do what normal mode does: restore all
modified files and nothing else. The user can make it "default" by
putting it to an alias (e.g. "co = checkout --no-widen") and get back
to the original behavior with "git co --widen".

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 --sparse -> --no-widen and git-checkout does not error out when the
 option is specified but has no effects. Let's see how it works out.
 We could change the default from --widen to --no-widen later.

 Documentation/git-checkout.txt       | 11 +++++++++++
 builtin/checkout.c                   |  7 +++++++
 t/t1011-read-tree-sparse-checkout.sh | 12 ++++++++++++
 3 files changed, 30 insertions(+)

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 8edcdca..538b8b8 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -180,6 +180,17 @@ 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.
 
+--no-widen::
+	In sparse checkout mode, `git checkout -- <paths>` would
+	update all entries matched by <paths> regardless of sparse
+	patterns. This option only updates entries matched by <paths>
+	and sparse patterns.
+
+--widen::
+	Revert the effect of `--no-widen` if specified and make
+	`git checkout -- <paths>` update all entries matched by
+	<paths> regardless of sparse patterns.
+
 -m::
 --merge::
 	When switching branches,
diff --git a/builtin/checkout.c b/builtin/checkout.c
index a9c1b5a..246de33 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 widen_sparse;
 
 	const char *new_branch;
 	const char *new_branch_force;
@@ -275,6 +276,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 (!opts->widen_sparse && ce_skip_worktree(ce))
+			continue;
 		match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
 	}
 
@@ -315,6 +318,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 (!opts->widen_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);
@@ -1029,6 +1034,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, "widen", &opts.widen_sparse, N_("do not limit pathspecs to sparse entries only (default)")),
 		{ 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 +1045,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.widen_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..4a45714 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 --no-widen' '
+	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 --no-widen . &&
+	! test -f init.t &&
+	git diff --exit-code HEAD
+'
+
 test_done
-- 
1.8.2.83.gc99314b

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v2] checkout: add --no-widen for restoring files in sparse checkout mode
  2013-03-30 10:02   ` [PATCH v2] checkout: add --no-widen " Nguyễn Thái Ngọc Duy
@ 2013-04-01  4:48     ` Jonathan Nieder
  2013-04-01  5:12       ` Junio C Hamano
  2013-04-01  5:13       ` Duy Nguyen
  2013-04-12 23:12     ` [PATCH v3] checkout: add --ignore-skip-worktree-bits " Nguyễn Thái Ngọc Duy
  1 sibling, 2 replies; 17+ messages in thread
From: Jonathan Nieder @ 2013-04-01  4:48 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy; +Cc: git, kirill.mueller, Junio C Hamano

Hi,

Nguyễn Thái Ngọc Duy wrote:

> "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 "--no-widen" option to do what normal mode does: restore all
> modified files and nothing else.

In an ideal world, I would like "git checkout --widen" to modify the
.git/info/sparse-checkout file, to be able to do:

	git clone --sparse-checkout=Documentation git://repo.or.cz/git.git
	cd git
	git checkout --widen -- README COPYING INSTALL

and hack on a tree with Documentation/, README, COPYING, and INSTALL
present with no actual code to distract.  And "git checkout --no-widen"
could be a way to ask to respect the existing sparse pattern.

This patch isn't about tweaking the sparse-checkout pattern; instead,
it's about how "git checkout" interacts with the skip-worktree bit.
Maybe a good name would be --respect-skip-worktree?

[...]
> --- a/Documentation/git-checkout.txt
> +++ b/Documentation/git-checkout.txt
> @@ -180,6 +180,17 @@ 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.
>  
> +--no-widen::
> +	In sparse checkout mode, `git checkout -- <paths>` would
> +	update all entries matched by <paths> regardless of sparse
> +	patterns. This option only updates entries matched by <paths>
> +	and sparse patterns.
> +
> +--widen::
> +	Revert the effect of `--no-widen` if specified and make
> +	`git checkout -- <paths>` update all entries matched by
> +	<paths> regardless of sparse patterns.

Perhaps, combining the descriptions of the positive and negative forms:

	--respect-skip-worktree::
		By default, `git checkout -- <paths>` creates or updates files
		matching <paths> regardless of the skip-worktree bit.  This
		option makes 'git checkout' skips entries with the
		skip-worktree bit set, which can be useful in sparse checkout
		mode.

I'm afraid I can't imagine when --no-respect-skip-worktree would be
useful.  That can easily be a failure of my imagination, though.

What do you think?

Thanks,
Jonathan

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2] checkout: add --no-widen for restoring files in sparse checkout mode
  2013-04-01  4:48     ` Jonathan Nieder
@ 2013-04-01  5:12       ` Junio C Hamano
  2013-04-01  5:13       ` Duy Nguyen
  1 sibling, 0 replies; 17+ messages in thread
From: Junio C Hamano @ 2013-04-01  5:12 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Nguyễn Thái Ngọc Duy, git, kirill.mueller

Jonathan Nieder <jrnieder@gmail.com> writes:

> Nguyễn Thái Ngọc Duy wrote:
>
>> "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 "--no-widen" option to do what normal mode does: restore all
>> modified files and nothing else.
>
> In an ideal world, I would like "git checkout --widen" to modify the
> .git/info/sparse-checkout file, to be able to do:
>
> 	git clone --sparse-checkout=Documentation git://repo.or.cz/git.git
> 	cd git
> 	git checkout --widen -- README COPYING INSTALL
>
> and hack on a tree with Documentation/, README, COPYING, and INSTALL
> present with no actual code to distract.  And "git checkout --no-widen"
> could be a way to ask to respect the existing sparse pattern.

Yeah, I think the above makes tons of sense, and --widen would be an
ideal name for that optional behaviour.  When you are limited by
your original sparse pathspecs, that would be a way to explicitly
widen the paths you interact with.  In that sense, making it off by
default would be a sensible thing to do.  When you limited yourself
to a subset of dir/, you do not want "git checkout dir/" to
automatically widen it by accident.

> This patch isn't about tweaking the sparse-checkout pattern; instead,
> it's about how "git checkout" interacts with the skip-worktree bit.
> Maybe a good name would be --respect-skip-worktree?

Yeah, but when would one want to say --no-respect without widening
the sparce pathspecs?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2] checkout: add --no-widen for restoring files in sparse checkout mode
  2013-04-01  4:48     ` Jonathan Nieder
  2013-04-01  5:12       ` Junio C Hamano
@ 2013-04-01  5:13       ` Duy Nguyen
  2013-04-01  6:18         ` Jonathan Nieder
  1 sibling, 1 reply; 17+ messages in thread
From: Duy Nguyen @ 2013-04-01  5:13 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Git Mailing List, Kirill Müller, Junio C Hamano

On Mon, Apr 1, 2013 at 11:48 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:
> Hi,
>
> Nguyễn Thái Ngọc Duy wrote:
>
>> "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 "--no-widen" option to do what normal mode does: restore all
>> modified files and nothing else.
>
> In an ideal world, I would like "git checkout --widen" to modify the
> .git/info/sparse-checkout file, to be able to do:
>
>         git clone --sparse-checkout=Documentation git://repo.or.cz/git.git
>         cd git
>         git checkout --widen -- README COPYING INSTALL
>
> and hack on a tree with Documentation/, README, COPYING, and INSTALL
> present with no actual code to distract.  And "git checkout --no-widen"
> could be a way to ask to respect the existing sparse pattern.

In an ideal world, I would spend more time on this and add
--edit-sparse, which opens up $EDITOR, lets you edit the patterns and
reapplies the patterns after $EDITOR exits (catching faults if
possible). Unfortunately I don't use sparse checkout as much as before
and therefore have little motivation to do it. I would really like
narrow clone to replace sparse checkout, but I haven't made much
progress on that front either. I'll try to get back on that once
pathspec-magics topic is settled.

> This patch isn't about tweaking the sparse-checkout pattern; instead,
> it's about how "git checkout" interacts with the skip-worktree bit.
> Maybe a good name would be --respect-skip-worktree?

I'm bad at naming. If nobody objects, I'll take this as the new option name.

>> --- a/Documentation/git-checkout.txt
>> +++ b/Documentation/git-checkout.txt
>> @@ -180,6 +180,17 @@ 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.
>>
>> +--no-widen::
>> +     In sparse checkout mode, `git checkout -- <paths>` would
>> +     update all entries matched by <paths> regardless of sparse
>> +     patterns. This option only updates entries matched by <paths>
>> +     and sparse patterns.
>> +
>> +--widen::
>> +     Revert the effect of `--no-widen` if specified and make
>> +     `git checkout -- <paths>` update all entries matched by
>> +     <paths> regardless of sparse patterns.
>
> Perhaps, combining the descriptions of the positive and negative forms:
>
>         --respect-skip-worktree::
>                 By default, `git checkout -- <paths>` creates or updates files
>                 matching <paths> regardless of the skip-worktree bit.  This
>                 option makes 'git checkout' skips entries with the
>                 skip-worktree bit set, which can be useful in sparse checkout
>                 mode.

OK

> I'm afraid I can't imagine when --no-respect-skip-worktree would be
> useful.  That can easily be a failure of my imagination, though.

There may be scripts that expect "git checkout -- foo" to reset
everything in "foo". Or maybe you just want to check out a single file
and do not bother to edit sparse patterns as you won't need it for
long.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2] checkout: add --no-widen for restoring files in sparse checkout mode
  2013-04-01  5:13       ` Duy Nguyen
@ 2013-04-01  6:18         ` Jonathan Nieder
  0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2013-04-01  6:18 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Git Mailing List, Kirill Müller, Junio C Hamano

Duy Nguyen wrote:
> On Mon, Apr 1, 2013 at 11:48 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:

>> I'm afraid I can't imagine when --no-respect-skip-worktree would be
>> useful.  That can easily be a failure of my imagination, though.
>
> There may be scripts that expect "git checkout -- foo" to reset
> everything in "foo". Or maybe you just want to check out a single file
> and do not bother to edit sparse patterns as you won't need it for
> long.

Those scripts are bringing suffering on themselves by using porcelain
instead of "git checkout-index".  The usual way to look at a single
file from the index is "git show :git.c >git.c".

So you've convinced me.  I think --respect-skip-worktree can be just
the normal behavior (and that there's no need for a --no-respect
option).  That would let me do:

	git clone --no-checkout git://repo.or.cz/git.git
	cd git
	echo '/Documentation/' >.git/info/sparse-checkout
	git config core.sparsecheckout true
	git checkout

	printf '%s\n' /README /INSTALL /COPYING >>.git/info/sparse-checkout
	git checkout

	... hack hack hack ...

	# return to what the index has
	git checkout .

without having to see any pesky actual source (*.c) files.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v3] checkout: add --ignore-skip-worktree-bits in sparse checkout mode
  2013-03-30 10:02   ` [PATCH v2] checkout: add --no-widen " Nguyễn Thái Ngọc Duy
  2013-04-01  4:48     ` Jonathan Nieder
@ 2013-04-12 23:12     ` Nguyễn Thái Ngọc Duy
  2013-05-14  9:27       ` Müller  Kirill
  1 sibling, 1 reply; 17+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-04-12 23:12 UTC (permalink / raw)
  To: git
  Cc: Jonathan Nieder, Junio C Hamano, kirill.mueller,
	Nguyễn Thái Ngọc Duy

"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.

As the former makes more sense for day-to-day use. Switch it to the
default and the latter enabled with --ignore-skip-worktree-bits.

While at there, add info/sparse-checkout to gitrepository-layout.txt

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/git-checkout.txt         |  6 ++++++
 Documentation/gitrepository-layout.txt |  4 ++++
 builtin/checkout.c                     |  5 +++++
 t/t1011-read-tree-sparse-checkout.sh   | 24 ++++++++++++++++++++++++
 t/t3001-ls-files-others-exclude.sh     |  2 +-
 5 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 8edcdca..23a9413 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -180,6 +180,12 @@ 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.
 
+--ignore-skip-worktree-bits::
+	In sparse checkout mode, `git checkout -- <paths>` would
+	update only entries matched by <paths> and sparse patterns
+	in $GIT_DIR/info/sparse-checkout. This option ignores
+	the sparse patterns and adds back any files in <paths>.
+
 -m::
 --merge::
 	When switching branches,
diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt
index f0eef76..817337f 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -184,6 +184,10 @@ info/exclude::
 	'git clean' look at it but the core Git commands do not look
 	at it.  See also: linkgit:gitignore[5].
 
+info/sparse-checkout::
+	This file stores sparse checkout patterns.
+	See also: linkgit:git-read-tree[1].
+
 remotes::
 	Stores shorthands for URL and default refnames for use
 	when interacting with remote repositories via 'git fetch',
diff --git a/builtin/checkout.c b/builtin/checkout.c
index f8033f4..4ed1ee7 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 ignore_skipworktree;
 
 	const char *new_branch;
 	const char *new_branch_force;
@@ -278,6 +279,8 @@ static int checkout_paths(const struct checkout_opts *opts,
 	for (pos = 0; pos < active_nr; pos++) {
 		struct cache_entry *ce = active_cache[pos];
 		ce->ce_flags &= ~CE_MATCHED;
+		if (!opts->ignore_skipworktree && ce_skip_worktree(ce))
+			continue;
 		if (opts->source_tree && !(ce->ce_flags & CE_UPDATE))
 			/*
 			 * "git checkout tree-ish -- path", but this entry
@@ -1058,6 +1061,8 @@ 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, "ignore-skip-worktree-bits", &opts.ignore_skipworktree,
+			 N_("do not 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 },
diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh
index 5c0053a..0c74bee 100755
--- a/t/t1011-read-tree-sparse-checkout.sh
+++ b/t/t1011-read-tree-sparse-checkout.sh
@@ -250,4 +250,28 @@ EOF
 	test_cmp expected actual
 '
 
+test_expect_success 'checkout without --ignore-skip-worktree-bits' '
+	echo "*" >.git/info/sparse-checkout &&
+	git checkout -f top &&
+	test_path_is_file init.t &&
+	echo sub >.git/info/sparse-checkout &&
+	git checkout &&
+	echo modified >> sub/added &&
+	git checkout . &&
+	test_path_is_missing init.t &&
+	git diff --exit-code HEAD
+'
+
+test_expect_success 'checkout with --ignore-skip-worktree-bits' '
+	echo "*" >.git/info/sparse-checkout &&
+	git checkout -f top &&
+	test_path_is_file init.t &&
+	echo sub >.git/info/sparse-checkout &&
+	git checkout &&
+	echo modified >> sub/added &&
+	git checkout --ignore-skip-worktree-bits . &&
+	test_path_is_file init.t &&
+	git diff --exit-code HEAD
+'
+
 test_done
diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh
index efb7ebc..2d274bf 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-exclude.sh
@@ -103,7 +103,7 @@ test_expect_success \
      test_cmp expect output'
 
 test_expect_success 'restore gitignore' '
-	git checkout $allignores &&
+	git checkout --ignore-skip-worktree-bits $allignores &&
 	rm .git/index
 '
 
-- 
1.8.2.82.gc24b958

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v3] checkout: add --ignore-skip-worktree-bits in sparse checkout mode
  2013-04-12 23:12     ` [PATCH v3] checkout: add --ignore-skip-worktree-bits " Nguyễn Thái Ngọc Duy
@ 2013-05-14  9:27       ` Müller  Kirill
  2013-05-14 10:21         ` Duy Nguyen
  0 siblings, 1 reply; 17+ messages in thread
From: Müller  Kirill @ 2013-05-14  9:27 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy
  Cc: git, Jonathan Nieder, Junio C Hamano

Thank you, this looks nice. What needs to be done that this will
eventually reach the git in my favorite distribution? Which version of
Git will this be?


Cheers

Kirill


On Sat, 2013-04-13 at 09:12 +1000, Nguyễn Thái Ngọc Duy wrote:
> "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.
> 
> As the former makes more sense for day-to-day use. Switch it to the
> default and the latter enabled with --ignore-skip-worktree-bits.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3] checkout: add --ignore-skip-worktree-bits in sparse checkout mode
  2013-05-14  9:27       ` Müller  Kirill
@ 2013-05-14 10:21         ` Duy Nguyen
  0 siblings, 0 replies; 17+ messages in thread
From: Duy Nguyen @ 2013-05-14 10:21 UTC (permalink / raw)
  To: Müller Kirill; +Cc: git, Jonathan Nieder, Junio C Hamano

On Tue, May 14, 2013 at 4:27 PM, Müller  Kirill
<kirill.mueller@ivt.baug.ethz.ch> wrote:
> Thank you, this looks nice. What needs to be done that this will
> eventually reach the git in my favorite distribution? Which version of
> Git will this be?

It'll be in the upcoming 1.8.3.
--
Duy

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2013-05-14 10:22 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-22 10:28 Hard reset of a subdirectory in a sparse checkout setting Kirill Müller
2013-03-23  9:59 ` Duy Nguyen
2013-03-23 13:02   ` Kirill Müller
2013-03-24  5:06 ` [PATCH] checkout: add --sparse for restoring files in sparse checkout mode Nguyễn Thái Ngọc Duy
2013-03-24  6:12   ` Eric Sunshine
2013-03-24 18:17   ` Jonathan Nieder
2013-03-24 19:50     ` Kirill Müller
2013-03-25  1:34     ` Duy Nguyen
2013-03-25  1:57       ` Jonathan Nieder
2013-03-30 10:02   ` [PATCH v2] checkout: add --no-widen " Nguyễn Thái Ngọc Duy
2013-04-01  4:48     ` Jonathan Nieder
2013-04-01  5:12       ` Junio C Hamano
2013-04-01  5:13       ` Duy Nguyen
2013-04-01  6:18         ` Jonathan Nieder
2013-04-12 23:12     ` [PATCH v3] checkout: add --ignore-skip-worktree-bits " Nguyễn Thái Ngọc Duy
2013-05-14  9:27       ` Müller  Kirill
2013-05-14 10:21         ` Duy Nguyen

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 NNTP newsgroup(s).