git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "René Scharfe" <l.s.r@web.de>
To: Varun Naik <vcnaik94@gmail.com>
Cc: git@vger.kernel.org, "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: Re: [RFC PATCH] unpack-trees.c: handle empty deleted ita files
Date: Tue, 13 Aug 2019 20:08:06 +0200	[thread overview]
Message-ID: <b7f4b745-8942-6d90-dbc5-7f79f2cc323e@web.de> (raw)
In-Reply-To: <20190813160353.50018-1-vcnaik94@gmail.com>

Am 13.08.19 um 18:03 schrieb Varun Naik:
> It is possible to delete a committed file from the index and then add it
> as intent-to-add. Several variations of "reset" and "checkout" should
> resurrect the file in the index from HEAD. "merge", "cherry-pick", and
> "revert" should all fail with an error message. This patch provides the
> desired behavior even when the file is empty in HEAD.
>
> The affected commands all compare two cache entries by calling
> unpack-trees.c:same(). A cache entry for an ita file and a cache entry
> for an empty file have the same oid. So, the cache entry for an empty
> deleted ita file was previously considered the "same" as the cache entry
> for an empty file. This fix adds a comparison of the intent-to-add bits
> so that the two cache entries are no longer considered the "same".
>
> Signed-off-by: Varun Naik <vcnaik94@gmail.com>
> ---
> I am marking this patch as RFC because it is changing code deep in
> unpack-trees.c, and I'm sure it will generate some controversy :)

Lacking experience with intent-to-add I don't see why this would be
controversial.  Copying Duy and quoting in full, as he might have more
to say on that topic.

I have just one silly question below.

>
> The affected "reset" and "checkout" commands call
> unpack-trees.c:oneway_merge(), which calls same(). The affected "merge",
> "cherry-pick", and "revert" commands call
> unpack-trees.c:threeway_merge(), which calls same(). "stash" also calls
> oneway_merge(), and "rebase" also calls threeway_merge(), but they are
> not included in the test cases because their behaviors have not changed.
>
> The new tests are not comprehensive. In particular, they don't call
> plumbing commands, such as "read-tree". But hopefully they provide
> enough coverage to prevent most regressions.
>
> The new test cases for "cherry-pick" and "revert" grep for the single
> word "overwritten" rather than a more precise error message because the
> error message for an empty deleted ita file changes slightly if the
> patch in [0] is also applied. In retrospect, the commands affected by
> [0], [1], and this patch were all intertwined, and it would have been
> better to create a single large patch instead of three smaller patches.
>
> [0]: https://public-inbox.org/git/20190801161558.12838-1-vcnaik94@gmail.com/
> [1]: https://public-inbox.org/git/20190802162852.14498-1-vcnaik94@gmail.com/
>
>  t/t3030-merge-recursive.sh    | 25 +++++++++++++++---
>  t/t3501-revert-cherry-pick.sh | 49 ++++++++++++++++++++++++++++++++++-
>  t/t7104-reset-hard.sh         | 11 ++++++++
>  t/t7110-reset-merge.sh        | 31 ++++++++++++++++++++++
>  t/t7201-co.sh                 | 12 +++++++++
>  unpack-trees.c                |  1 +
>  6 files changed, 125 insertions(+), 4 deletions(-)
>
> diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh
> index ff641b348a..8aebb829a6 100755
> --- a/t/t3030-merge-recursive.sh
> +++ b/t/t3030-merge-recursive.sh
> @@ -303,13 +303,32 @@ test_expect_success 'fail if the index has unresolved entries' '
>  	git checkout -f "$c1" &&
>
>  	test_must_fail git merge "$c5" &&
> -	test_must_fail git merge "$c5" 2> out &&
> +	test_must_fail git merge "$c5" 2>out &&
>  	test_i18ngrep "not possible because you have unmerged files" out &&
>  	git add -u &&
> -	test_must_fail git merge "$c5" 2> out &&
> +	test_must_fail git merge "$c5" 2>out &&
>  	test_i18ngrep "You have not concluded your merge" out &&
>  	rm -f .git/MERGE_HEAD &&
> -	test_must_fail git merge "$c5" 2> out &&
> +	test_must_fail git merge "$c5" 2>out &&
> +	test_i18ngrep "Your local changes to the following files would be overwritten by merge:" out
> +'
> +
> +test_expect_success 'fail if a deleted intent-to-add file exists in the index' '
> +	git checkout -f "$c1" &&
> +	echo "nonempty" >nonempty &&
> +	git add nonempty &&
> +	git commit -m "create file to be deleted" &&
> +	git rm --cached nonempty &&
> +	git add -N nonempty &&
> +	test_must_fail git merge "$c5" 2>out &&
> +	test_i18ngrep "Your local changes to the following files would be overwritten by merge:" out &&
> +	git checkout -f "$c1" &&
> +	>empty &&
> +	git add empty &&
> +	git commit -m "create file to be deleted" &&
> +	git rm --cached empty &&
> +	git add -N empty &&
> +	test_must_fail git merge "$c5" 2>out &&
>  	test_i18ngrep "Your local changes to the following files would be overwritten by merge:" out
>  '
>
> diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
> index d1c68af8c5..45d816fc0c 100755
> --- a/t/t3501-revert-cherry-pick.sh
> +++ b/t/t3501-revert-cherry-pick.sh
> @@ -91,16 +91,63 @@ test_expect_success 'cherry-pick on stat-dirty working tree' '
>  	)
>  '
>
> -test_expect_success 'revert forbidden on dirty working tree' '
> +test_expect_success 'cherry-pick forbidden on dirty working tree' '
>
> +	git checkout -b temp &&
>  	echo content >extra_file &&
>  	git add extra_file &&
> +	test_must_fail git cherry-pick rename2 2>errors &&
> +	test_i18ngrep "your local changes would be overwritten by " errors
> +
> +'
> +
> +test_expect_success 'revert forbidden on dirty working tree' '
> +
>  	test_must_fail git revert HEAD 2>errors &&
>  	test_i18ngrep "your local changes would be overwritten by " errors
>
>  '
>
> +test_expect_success 'cherry-pick fails if a deleted intent-to-add file exists in the index' '
> +	git reset --hard rename1 &&
> +	echo "nonempty" >nonempty &&
> +	git add nonempty &&
> +	git commit -m "create file to be deleted" &&
> +	git rm --cached nonempty &&
> +	git add -N nonempty &&
> +	test_must_fail git cherry-pick rename2 2>errors &&
> +	test_i18ngrep "overwritten" errors &&
> +	git reset --hard rename1 &&
> +	>empty &&
> +	git add empty &&
> +	git commit -m "create file to be deleted" &&
> +	git rm --cached empty &&
> +	git add -N empty &&
> +	test_must_fail git cherry-pick rename2 2>errors &&
> +	test_i18ngrep "overwritten" errors
> +'
> +
> +test_expect_success 'revert fails if a deleted intent-to-add file exists in the index' '
> +	git reset --hard rename1 &&
> +	echo "nonempty" >nonempty &&
> +	git add nonempty &&
> +	git commit -m "create file to be deleted" &&
> +	git rm --cached nonempty &&
> +	git add -N nonempty &&
> +	test_must_fail git revert rename2 2>errors &&
> +	test_i18ngrep "overwritten" errors &&
> +	git reset --hard rename1 &&
> +	>empty &&
> +	git add empty &&
> +	git commit -m "create file to be deleted" &&
> +	git rm --cached empty &&
> +	git add -N empty &&
> +	test_must_fail git revert rename2 2>errors &&
> +	test_i18ngrep "overwritten" errors
> +'
> +
>  test_expect_success 'cherry-pick on unborn branch' '
> +	git checkout -f rename1 &&
>  	git checkout --orphan unborn &&
>  	git rm --cached -r . &&
>  	rm -rf * &&
> diff --git a/t/t7104-reset-hard.sh b/t/t7104-reset-hard.sh
> index 16faa07813..96a0b779e7 100755
> --- a/t/t7104-reset-hard.sh
> +++ b/t/t7104-reset-hard.sh
> @@ -43,4 +43,15 @@ test_expect_success 'reset --hard did not corrupt index or cached-tree' '
>
>  '
>
> +test_expect_success 'reset --hard adds deleted intent-to-add file back to index' '
> +	echo "nonempty" >nonempty &&
> +	>empty &&
> +	git add nonempty empty &&
> +	git commit -m "create files to be deleted" &&
> +	git rm --cached nonempty empty &&
> +	git add -N nonempty empty &&
> +	git reset --hard &&
> +	git diff --cached --exit-code nonempty empty
> +'
> +
>  test_done
> diff --git a/t/t7110-reset-merge.sh b/t/t7110-reset-merge.sh
> index a82a07a04a..3346759375 100755
> --- a/t/t7110-reset-merge.sh
> +++ b/t/t7110-reset-merge.sh
> @@ -292,4 +292,35 @@ test_expect_success '--keep fails with added/deleted merge' '
>      test_i18ngrep "middle of a merge" err.log
>  '
>
> +test_expect_success 'reset --merge adds deleted intent-to-add file back to index' '
> +    git reset --hard initial &&
> +    echo "nonempty" >nonempty &&
> +    git add nonempty &&
> +    git commit -m "create file to be deleted" &&
> +    git rm --cached nonempty &&
> +    git add -N nonempty &&
> +    test_must_fail git reset --merge HEAD 2>err.log &&
> +    grep nonempty err.log | grep "not uptodate" &&
> +    git reset --hard initial &&
> +    >empty &&
> +    git add empty &&
> +    git commit -m "create file to be deleted" &&
> +    git rm --cached empty &&
> +    git add -N empty &&
> +    test_must_fail git reset --merge HEAD 2>err.log &&
> +    grep empty err.log | grep "not uptodate"
> +'
> +
> +test_expect_success 'reset --keep adds deleted intent-to-add file back to index' '
> +    git reset --hard initial &&
> +    echo "nonempty" >nonempty &&
> +    >empty &&
> +    git add nonempty empty &&
> +    git commit -m "create files to be deleted" &&
> +    git rm --cached nonempty empty &&
> +    git add -N nonempty empty &&
> +    git reset --keep HEAD &&
> +    git diff --cached --exit-code nonempty empty
> +'
> +
>  test_done
> diff --git a/t/t7201-co.sh b/t/t7201-co.sh
> index 5990299fc9..4c0c33ce33 100755
> --- a/t/t7201-co.sh
> +++ b/t/t7201-co.sh
> @@ -674,4 +674,16 @@ test_expect_success 'custom merge driver with checkout -m' '
>  	test_cmp expect arm
>  '
>
> +test_expect_success 'checkout -f HEAD adds deleted intent-to-add file back to index' '
> +	git reset --hard master &&
> +	echo "nonempty" >nonempty &&
> +	>empty &&
> +	git add nonempty empty &&
> +	git commit -m "create files to be deleted" &&
> +	git rm --cached nonempty empty &&
> +	git add -N nonempty empty &&
> +	git checkout -f HEAD &&
> +	git diff --cached --exit-code nonempty empty
> +'
> +
>  test_done
> diff --git a/unpack-trees.c b/unpack-trees.c
> index 50189909b8..9b7e6b01c4 100644
> --- a/unpack-trees.c
> +++ b/unpack-trees.c
> @@ -1661,6 +1661,7 @@ static int same(const struct cache_entry *a, const struct cache_entry *b)
>  	if ((a->ce_flags | b->ce_flags) & CE_CONFLICTED)
>  		return 0;
>  	return a->ce_mode == b->ce_mode &&
> +	       !ce_intent_to_add(a) == !ce_intent_to_add(b) &&

Why the bangs?  This would work just as well and be slightly easier to
read without negating both sides, wouldn't it?

>  	       oideq(&a->oid, &b->oid);
>  }
>
>


  reply	other threads:[~2019-08-13 18:08 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-13 16:03 [RFC PATCH] unpack-trees.c: handle empty deleted ita files Varun Naik
2019-08-13 18:08 ` René Scharfe [this message]
2019-08-13 20:32   ` Junio C Hamano
2019-08-14  4:30     ` René Scharfe
2019-08-15 16:17     ` Varun Naik
2019-08-15 16:34       ` Junio C Hamano
2019-08-19 15:35         ` Varun Naik
2019-08-19 19:54           ` Junio C Hamano
2019-08-15 16:21 ` [PATCH v2] unpack-trees.c: distinguish ita files from empty files Varun Naik
2019-08-15 16:46   ` René Scharfe
2019-08-21  3:21 ` [PATCH v3] " Varun Naik
2020-02-14 17:14   ` [PATCH v4] " Varun Naik

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

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b7f4b745-8942-6d90-dbc5-7f79f2cc323e@web.de \
    --to=l.s.r@web.de \
    --cc=git@vger.kernel.org \
    --cc=pclouds@gmail.com \
    --cc=vcnaik94@gmail.com \
    /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.
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).