git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH] stash: avoid recursive hard reset on submodules
@ 2019-10-10 23:34 Jakob Jarmar
  2019-10-11  0:11 ` [PATCH v2] " Jakob Jarmar
  0 siblings, 1 reply; 8+ messages in thread
From: Jakob Jarmar @ 2019-10-10 23:34 UTC (permalink / raw)
  To: git

git stash push does not recursively stash submodules, but if
submodule.recurse is set, it may recursively reset --hard them. Having
only the destructive action recurse is likely to be surprising
behaviour, and unlikely to be desirable, so the easiest fix should be to
ensure that the call to git reset --hard never recurses into submodules.

This matches the behavior of check_changes_tracked_files, which ignores
submodules.

Signed-off-by: Jakob Jarmar <jakob@jarmar.se>
---
 builtin/stash.c     | 2 +-
 git-legacy-stash.sh | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/builtin/stash.c b/builtin/stash.c
index b5a301f24d..c986c258f2 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -1383,7 +1383,7 @@ static int do_push_stash(const struct pathspec
*ps, const char *stash_msg, int q
             struct child_process cp = CHILD_PROCESS_INIT;
             cp.git_cmd = 1;
             argv_array_pushl(&cp.args, "reset", "--hard", "-q",
-                     NULL);
+                     "--no-recurse-submodules", NULL);
             if (run_command(&cp)) {
                 ret = -1;
                 goto done;
diff --git a/git-legacy-stash.sh b/git-legacy-stash.sh
index f60e9b3e87..07ad4a5459 100755
--- a/git-legacy-stash.sh
+++ b/git-legacy-stash.sh
@@ -370,7 +370,7 @@ push_stash () {
             git diff-index -p --cached --binary HEAD -- "$@" |
             git apply --index -R
         else
-            git reset --hard -q
+            git reset --hard -q --no-recurse-submodules
         fi

         if test "$keep_index" = "t" && test -n "$i_tree"
-- 
2.23.0

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

* [PATCH v2] stash: avoid recursive hard reset on submodules
  2019-10-10 23:34 [PATCH] stash: avoid recursive hard reset on submodules Jakob Jarmar
@ 2019-10-11  0:11 ` Jakob Jarmar
  2019-10-11  6:02   ` Junio C Hamano
  0 siblings, 1 reply; 8+ messages in thread
From: Jakob Jarmar @ 2019-10-11  0:11 UTC (permalink / raw)
  To: git

git stash push does not recursively stash submodules, but if
submodule.recurse is set, it may recursively reset --hard them. Having
only the destructive action recurse is likely to be surprising
behaviour, and unlikely to be desirable, so the easiest fix should be to
ensure that the call to git reset --hard never recurses into submodules.

This matches the behavior of check_changes_tracked_files, which ignores
submodules.

Signed-off-by: Jakob Jarmar <jakob@jarmar.se>
---

Sorry for sending a patch with messed up whitespace. This one should be
correct.

 builtin/stash.c     | 2 +-
 git-legacy-stash.sh | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/builtin/stash.c b/builtin/stash.c
index b5a301f24d..c986c258f2 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -1383,7 +1383,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
 			struct child_process cp = CHILD_PROCESS_INIT;
 			cp.git_cmd = 1;
 			argv_array_pushl(&cp.args, "reset", "--hard", "-q",
-					 NULL);
+					 "--no-recurse-submodules", NULL);
 			if (run_command(&cp)) {
 				ret = -1;
 				goto done;
diff --git a/git-legacy-stash.sh b/git-legacy-stash.sh
index f60e9b3e87..07ad4a5459 100755
--- a/git-legacy-stash.sh
+++ b/git-legacy-stash.sh
@@ -370,7 +370,7 @@ push_stash () {
 			git diff-index -p --cached --binary HEAD -- "$@" |
 			git apply --index -R
 		else
-			git reset --hard -q
+			git reset --hard -q --no-recurse-submodules
 		fi
 
 		if test "$keep_index" = "t" && test -n "$i_tree"
-- 
2.23.0


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

* Re: [PATCH v2] stash: avoid recursive hard reset on submodules
  2019-10-11  0:11 ` [PATCH v2] " Jakob Jarmar
@ 2019-10-11  6:02   ` Junio C Hamano
  2019-10-11 22:24     ` [PATCH v3] " Jakob Jarmar
  0 siblings, 1 reply; 8+ messages in thread
From: Junio C Hamano @ 2019-10-11  6:02 UTC (permalink / raw)
  To: Jakob Jarmar; +Cc: git

Jakob Jarmar <jakob.j@gmail.com> writes:

> git stash push does not recursively stash submodules, but if
> submodule.recurse is set, it may recursively reset --hard them. Having
> only the destructive action recurse is likely to be surprising
> behaviour, and unlikely to be desirable, so the easiest fix should be to
> ensure that the call to git reset --hard never recurses into submodules.
>
> This matches the behavior of check_changes_tracked_files, which ignores
> submodules.

Makes sense.  Can we demonstrate an existing breakage and the fix in
a new test or two in perhaps t3906-stash-submodule.sh?

Thanks.

>
> Signed-off-by: Jakob Jarmar <jakob@jarmar.se>
> ---
>
> Sorry for sending a patch with messed up whitespace. This one should be
> correct.
>
>  builtin/stash.c     | 2 +-
>  git-legacy-stash.sh | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/builtin/stash.c b/builtin/stash.c
> index b5a301f24d..c986c258f2 100644
> --- a/builtin/stash.c
> +++ b/builtin/stash.c
> @@ -1383,7 +1383,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
>  			struct child_process cp = CHILD_PROCESS_INIT;
>  			cp.git_cmd = 1;
>  			argv_array_pushl(&cp.args, "reset", "--hard", "-q",
> -					 NULL);
> +					 "--no-recurse-submodules", NULL);
>  			if (run_command(&cp)) {
>  				ret = -1;
>  				goto done;
> diff --git a/git-legacy-stash.sh b/git-legacy-stash.sh
> index f60e9b3e87..07ad4a5459 100755
> --- a/git-legacy-stash.sh
> +++ b/git-legacy-stash.sh
> @@ -370,7 +370,7 @@ push_stash () {
>  			git diff-index -p --cached --binary HEAD -- "$@" |
>  			git apply --index -R
>  		else
> -			git reset --hard -q
> +			git reset --hard -q --no-recurse-submodules
>  		fi
>  
>  		if test "$keep_index" = "t" && test -n "$i_tree"

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

* [PATCH v3] stash: avoid recursive hard reset on submodules
  2019-10-11  6:02   ` Junio C Hamano
@ 2019-10-11 22:24     ` Jakob Jarmar
  2019-10-12  1:46       ` Junio C Hamano
  0 siblings, 1 reply; 8+ messages in thread
From: Jakob Jarmar @ 2019-10-11 22:24 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

git stash push does not recursively stash submodules, but if
submodule.recurse is set, it may recursively reset --hard them. Having
only the destructive action recurse is likely to be surprising
behaviour, and unlikely to be desirable, so the easiest fix should be to
ensure that the call to git reset --hard never recurses into submodules.

This matches the behavior of check_changes_tracked_files, which ignores
submodules.

Signed-off-by: Jakob Jarmar <jakob@jarmar.se>
---

Notes:
    I went for two separate tests with the same basic setup, one that does
    push + pop (which should be valid regardless of future changes), and one
    that just does push before checking that the submodule still is dirty
    (which would become invalid if git stash were to learn --recurse-submodules
    in the future, but matches this approach).

 builtin/stash.c            |  2 +-
 git-legacy-stash.sh        |  2 +-
 t/t3906-stash-submodule.sh | 42 +++++++++++++++++++++++++++++++++++++-
 3 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/builtin/stash.c b/builtin/stash.c
index b5a301f24d..c986c258f2 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -1383,7 +1383,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
 			struct child_process cp = CHILD_PROCESS_INIT;
 			cp.git_cmd = 1;
 			argv_array_pushl(&cp.args, "reset", "--hard", "-q",
-					 NULL);
+					 "--no-recurse-submodules", NULL);
 			if (run_command(&cp)) {
 				ret = -1;
 				goto done;
diff --git a/git-legacy-stash.sh b/git-legacy-stash.sh
index f60e9b3e87..07ad4a5459 100755
--- a/git-legacy-stash.sh
+++ b/git-legacy-stash.sh
@@ -370,7 +370,7 @@ push_stash () {
 			git diff-index -p --cached --binary HEAD -- "$@" |
 			git apply --index -R
 		else
-			git reset --hard -q
+			git reset --hard -q --no-recurse-submodules
 		fi
 
 		if test "$keep_index" = "t" && test -n "$i_tree"
diff --git a/t/t3906-stash-submodule.sh b/t/t3906-stash-submodule.sh
index d7219d6f8f..83106fa958 100755
--- a/t/t3906-stash-submodule.sh
+++ b/t/t3906-stash-submodule.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-test_description='stash apply can handle submodules'
+test_description='stash can handle submodules'
 
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-submodule-update.sh
@@ -21,4 +21,44 @@ KNOWN_FAILURE_CHERRY_PICK_SEES_EMPTY_COMMIT=1
 KNOWN_FAILURE_NOFF_MERGE_DOESNT_CREATE_EMPTY_SUBMODULE_DIR=1
 test_submodule_switch "git_stash"
 
+setup_basic() {
+	git init sub &&
+	(
+		cd sub &&
+		test_commit sub_file
+	) &&
+	git init main &&
+	(
+		cd main &&
+		git submodule add ../sub &&
+		test_commit main_file
+	) &&
+	test_when_finished "rm -rf main sub"
+}
+
+test_expect_success 'stash push with submodule.recurse=true preserves dirty submodule worktree' '
+	setup_basic &&
+	(
+		cd main &&
+		git config submodule.recurse true &&
+		echo "x" >main_file.t &&
+		echo "y" >sub/sub_file.t &&
+		git stash push &&
+		test_must_fail git -C sub diff --quiet
+	)
+'
+
+test_expect_success 'stash push and pop with submodule.recurse=true preserves dirty submodule worktree' '
+	setup_basic &&
+	(
+		cd main &&
+		git config submodule.recurse true &&
+		echo "x" >main_file.t &&
+		echo "y" >sub/sub_file.t &&
+		git stash push &&
+		git stash pop &&
+		test_must_fail git -C sub diff --quiet
+	)
+'
+
 test_done
-- 
2.23.0


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

* Re: [PATCH v3] stash: avoid recursive hard reset on submodules
  2019-10-11 22:24     ` [PATCH v3] " Jakob Jarmar
@ 2019-10-12  1:46       ` Junio C Hamano
  2019-10-12 15:24         ` Jakob Jarmar
  2019-10-12 15:38         ` [PATCH v4] " Jakob Jarmar
  0 siblings, 2 replies; 8+ messages in thread
From: Junio C Hamano @ 2019-10-12  1:46 UTC (permalink / raw)
  To: Jakob Jarmar; +Cc: git

Jakob Jarmar <jakob.j@gmail.com> writes:

> diff --git a/t/t3906-stash-submodule.sh b/t/t3906-stash-submodule.sh
> index d7219d6f8f..83106fa958 100755
> --- a/t/t3906-stash-submodule.sh
> +++ b/t/t3906-stash-submodule.sh
> @@ -1,6 +1,6 @@
>  #!/bin/sh
>  
> -test_description='stash apply can handle submodules'
> +test_description='stash can handle submodules'

Good attention to the detail ;-)

> +setup_basic() {

Style.  SP on both sides of () in our shell scripts (as seen in the
existing shell function in the same file).

> +	git init sub &&
> +	(
> +		cd sub &&
> +		test_commit sub_file
> +	) &&
> +	git init main &&
> +	(
> +		cd main &&
> +		git submodule add ../sub &&
> +		test_commit main_file
> +	) &&
> +	test_when_finished "rm -rf main sub"

Have test_when_finished that removes main and sub _before_ you start
creating sub and main.  

When the &&-cascade breaks anywhere, the control may not even reach
your test_when_finished that registers the clean-up procedure.
Imagine "git init sub" succeeds but "git init main" somehow
fails---you still want to clean up "sub".

Other than that, looks reasonably well done.  

Thanks for working on this.


> +}
> +
> +test_expect_success 'stash push with submodule.recurse=true preserves dirty submodule worktree' '
> +	setup_basic &&
> +	(
> +		cd main &&
> +		git config submodule.recurse true &&
> +		echo "x" >main_file.t &&
> +		echo "y" >sub/sub_file.t &&
> +		git stash push &&
> +		test_must_fail git -C sub diff --quiet
> +	)
> +'
> +
> +test_expect_success 'stash push and pop with submodule.recurse=true preserves dirty submodule worktree' '
> +	setup_basic &&
> +	(
> +		cd main &&
> +		git config submodule.recurse true &&
> +		echo "x" >main_file.t &&
> +		echo "y" >sub/sub_file.t &&
> +		git stash push &&
> +		git stash pop &&
> +		test_must_fail git -C sub diff --quiet
> +	)
> +'
> +
>  test_done

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

* Re: [PATCH v3] stash: avoid recursive hard reset on submodules
  2019-10-12  1:46       ` Junio C Hamano
@ 2019-10-12 15:24         ` Jakob Jarmar
  2019-10-12 15:38         ` [PATCH v4] " Jakob Jarmar
  1 sibling, 0 replies; 8+ messages in thread
From: Jakob Jarmar @ 2019-10-12 15:24 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Sat, Oct 12, 2019 at 10:46:36AM +0900, Junio C Hamano wrote:
> > +	git init sub &&
> > +	(
> > +		cd sub &&
> > +		test_commit sub_file
> > +	) &&
> > +	git init main &&
> > +	(
> > +		cd main &&
> > +		git submodule add ../sub &&
> > +		test_commit main_file
> > +	) &&
> > +	test_when_finished "rm -rf main sub"
> 
> Have test_when_finished that removes main and sub _before_ you start
> creating sub and main.  
> 
> When the &&-cascade breaks anywhere, the control may not even reach
> your test_when_finished that registers the clean-up procedure.
> Imagine "git init sub" succeeds but "git init main" somehow
> fails---you still want to clean up "sub".

Ah, of course, will fix this (and the other point as well).

> Other than that, looks reasonably well done.  

Thanks. This was fun to figure out and fix.

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

* [PATCH v4] stash: avoid recursive hard reset on submodules
  2019-10-12  1:46       ` Junio C Hamano
  2019-10-12 15:24         ` Jakob Jarmar
@ 2019-10-12 15:38         ` Jakob Jarmar
  2019-10-15  1:35           ` Junio C Hamano
  1 sibling, 1 reply; 8+ messages in thread
From: Jakob Jarmar @ 2019-10-12 15:38 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

git stash push does not recursively stash submodules, but if
submodule.recurse is set, it may recursively reset --hard them. Having
only the destructive action recurse is likely to be surprising
behaviour, and unlikely to be desirable, so the easiest fix should be to
ensure that the call to git reset --hard never recurses into submodules.

This matches the behavior of check_changes_tracked_files, which ignores
submodules.

Signed-off-by: Jakob Jarmar <jakob@jarmar.se>
---

Notes:
    1. Added space between function name and parentheses
    2. Moved test_when_finished cleanup to top of setup_basic

 builtin/stash.c            |  2 +-
 git-legacy-stash.sh        |  2 +-
 t/t3906-stash-submodule.sh | 42 +++++++++++++++++++++++++++++++++++++-
 3 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/builtin/stash.c b/builtin/stash.c
index b5a301f24d..c986c258f2 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -1383,7 +1383,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
 			struct child_process cp = CHILD_PROCESS_INIT;
 			cp.git_cmd = 1;
 			argv_array_pushl(&cp.args, "reset", "--hard", "-q",
-					 NULL);
+					 "--no-recurse-submodules", NULL);
 			if (run_command(&cp)) {
 				ret = -1;
 				goto done;
diff --git a/git-legacy-stash.sh b/git-legacy-stash.sh
index f60e9b3e87..07ad4a5459 100755
--- a/git-legacy-stash.sh
+++ b/git-legacy-stash.sh
@@ -370,7 +370,7 @@ push_stash () {
 			git diff-index -p --cached --binary HEAD -- "$@" |
 			git apply --index -R
 		else
-			git reset --hard -q
+			git reset --hard -q --no-recurse-submodules
 		fi
 
 		if test "$keep_index" = "t" && test -n "$i_tree"
diff --git a/t/t3906-stash-submodule.sh b/t/t3906-stash-submodule.sh
index d7219d6f8f..b93d1d74da 100755
--- a/t/t3906-stash-submodule.sh
+++ b/t/t3906-stash-submodule.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-test_description='stash apply can handle submodules'
+test_description='stash can handle submodules'
 
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-submodule-update.sh
@@ -21,4 +21,44 @@ KNOWN_FAILURE_CHERRY_PICK_SEES_EMPTY_COMMIT=1
 KNOWN_FAILURE_NOFF_MERGE_DOESNT_CREATE_EMPTY_SUBMODULE_DIR=1
 test_submodule_switch "git_stash"
 
+setup_basic () {
+	test_when_finished "rm -rf main sub" &&
+	git init sub &&
+	(
+		cd sub &&
+		test_commit sub_file
+	) &&
+	git init main &&
+	(
+		cd main &&
+		git submodule add ../sub &&
+		test_commit main_file
+	)
+}
+
+test_expect_success 'stash push with submodule.recurse=true preserves dirty submodule worktree' '
+	setup_basic &&
+	(
+		cd main &&
+		git config submodule.recurse true &&
+		echo "x" >main_file.t &&
+		echo "y" >sub/sub_file.t &&
+		git stash push &&
+		test_must_fail git -C sub diff --quiet
+	)
+'
+
+test_expect_success 'stash push and pop with submodule.recurse=true preserves dirty submodule worktree' '
+	setup_basic &&
+	(
+		cd main &&
+		git config submodule.recurse true &&
+		echo "x" >main_file.t &&
+		echo "y" >sub/sub_file.t &&
+		git stash push &&
+		git stash pop &&
+		test_must_fail git -C sub diff --quiet
+	)
+'
+
 test_done
-- 
2.23.0


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

* Re: [PATCH v4] stash: avoid recursive hard reset on submodules
  2019-10-12 15:38         ` [PATCH v4] " Jakob Jarmar
@ 2019-10-15  1:35           ` Junio C Hamano
  0 siblings, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2019-10-15  1:35 UTC (permalink / raw)
  To: Jakob Jarmar; +Cc: git

Jakob Jarmar <jakob.j@gmail.com> writes:

> git stash push does not recursively stash submodules, but if
> submodule.recurse is set, it may recursively reset --hard them. Having
> only the destructive action recurse is likely to be surprising
> behaviour, and unlikely to be desirable, so the easiest fix should be to
> ensure that the call to git reset --hard never recurses into submodules.
>
> This matches the behavior of check_changes_tracked_files, which ignores
> submodules.
>
> Signed-off-by: Jakob Jarmar <jakob@jarmar.se>
> ---
>
> Notes:
>     1. Added space between function name and parentheses
>     2. Moved test_when_finished cleanup to top of setup_basic

Looks good; will queue.

Thanks.

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

end of thread, other threads:[~2019-10-15  1:35 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-10 23:34 [PATCH] stash: avoid recursive hard reset on submodules Jakob Jarmar
2019-10-11  0:11 ` [PATCH v2] " Jakob Jarmar
2019-10-11  6:02   ` Junio C Hamano
2019-10-11 22:24     ` [PATCH v3] " Jakob Jarmar
2019-10-12  1:46       ` Junio C Hamano
2019-10-12 15:24         ` Jakob Jarmar
2019-10-12 15:38         ` [PATCH v4] " Jakob Jarmar
2019-10-15  1:35           ` Junio C Hamano

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