2008-08-21 08:44:53 +00:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='Intent to add'
|
|
|
|
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
test_expect_success 'intent to add' '
|
2016-10-24 10:42:19 +00:00
|
|
|
test_commit 1 &&
|
|
|
|
git rm 1.t &&
|
|
|
|
echo hello >1.t &&
|
2008-08-21 08:44:53 +00:00
|
|
|
echo hello >file &&
|
|
|
|
echo hello >elif &&
|
|
|
|
git add -N file &&
|
2016-10-24 10:42:19 +00:00
|
|
|
git add elif &&
|
|
|
|
git add -N 1.t
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'git status' '
|
|
|
|
git status --porcelain | grep -v actual >actual &&
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
DA 1.t
|
|
|
|
A elif
|
|
|
|
A file
|
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
2008-08-21 08:44:53 +00:00
|
|
|
'
|
|
|
|
|
2017-12-27 10:18:34 +00:00
|
|
|
test_expect_success 'git status with porcelain v2' '
|
|
|
|
git status --porcelain=v2 | grep -v "^?" >actual &&
|
2018-05-13 02:24:21 +00:00
|
|
|
nam1=$(echo 1 | git hash-object --stdin) &&
|
|
|
|
nam2=$(git hash-object elif) &&
|
2017-12-27 10:18:34 +00:00
|
|
|
cat >expect <<-EOF &&
|
2018-05-13 02:24:13 +00:00
|
|
|
1 DA N... 100644 000000 100644 $nam1 $ZERO_OID 1.t
|
|
|
|
1 A. N... 000000 100644 100644 $ZERO_OID $nam2 elif
|
|
|
|
1 .A N... 000000 000000 100644 $ZERO_OID $ZERO_OID file
|
2017-12-27 10:18:34 +00:00
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2008-08-21 08:44:53 +00:00
|
|
|
test_expect_success 'check result of "add -N"' '
|
|
|
|
git ls-files -s file >actual &&
|
|
|
|
empty=$(git hash-object --stdin </dev/null) &&
|
|
|
|
echo "100644 $empty 0 file" >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'intent to add is just an ordinary empty blob' '
|
|
|
|
git add -u &&
|
|
|
|
git ls-files -s file >actual &&
|
|
|
|
git ls-files -s elif | sed -e "s/elif/file/" >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'intent to add does not clobber existing paths' '
|
|
|
|
git add -N file elif &&
|
|
|
|
empty=$(git hash-object --stdin </dev/null) &&
|
|
|
|
git ls-files -s >actual &&
|
|
|
|
! grep "$empty" actual
|
|
|
|
'
|
|
|
|
|
commit: ignore intent-to-add entries instead of refusing
Originally, "git add -N" was introduced to help users from forgetting to
add new files to the index before they ran "git commit -a". As an attempt
to help them further so that they do not forget to say "-a", "git commit"
to commit the index as-is was taught to error out, reminding the user that
they may have forgotten to add the final contents of the paths before
running the command.
This turned out to be a false "safety" that is useless. If the user made
changes to already tracked paths and paths added with "git add -N", and
then ran "git add" to register the final contents of the paths added with
"git add -N", "git commit" will happily create a commit out of the index,
without including the local changes made to the already tracked paths. It
was not a useful "safety" measure to prevent "forgetful" mistakes from
happening.
It turns out that this behaviour is not just a useless false "safety", but
actively hurts use cases of "git add -N" that were discovered later and
have become popular, namely, to tell Git to be aware of these paths added
by "git add -N", so that commands like "git status" and "git diff" would
include them in their output, even though the user is not interested in
including them in the next commit they are going to make.
Fix this ancient UI mistake, and instead make a commit from the index
ignoring the paths added by "git add -N" without adding real contents.
Based on the work by Nguyễn Thái Ngọc Duy, and helped by injection of
sanity from Jonathan Nieder and others on the Git mailing list.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-07 19:55:48 +00:00
|
|
|
test_expect_success 'i-t-a entry is simply ignored' '
|
2008-11-29 03:56:34 +00:00
|
|
|
test_tick &&
|
|
|
|
git commit -a -m initial &&
|
|
|
|
git reset --hard &&
|
|
|
|
|
|
|
|
echo xyzzy >rezrov &&
|
|
|
|
echo frotz >nitfol &&
|
|
|
|
git add rezrov &&
|
|
|
|
git add -N nitfol &&
|
commit: ignore intent-to-add entries instead of refusing
Originally, "git add -N" was introduced to help users from forgetting to
add new files to the index before they ran "git commit -a". As an attempt
to help them further so that they do not forget to say "-a", "git commit"
to commit the index as-is was taught to error out, reminding the user that
they may have forgotten to add the final contents of the paths before
running the command.
This turned out to be a false "safety" that is useless. If the user made
changes to already tracked paths and paths added with "git add -N", and
then ran "git add" to register the final contents of the paths added with
"git add -N", "git commit" will happily create a commit out of the index,
without including the local changes made to the already tracked paths. It
was not a useful "safety" measure to prevent "forgetful" mistakes from
happening.
It turns out that this behaviour is not just a useless false "safety", but
actively hurts use cases of "git add -N" that were discovered later and
have become popular, namely, to tell Git to be aware of these paths added
by "git add -N", so that commands like "git status" and "git diff" would
include them in their output, even though the user is not interested in
including them in the next commit they are going to make.
Fix this ancient UI mistake, and instead make a commit from the index
ignoring the paths added by "git add -N" without adding real contents.
Based on the work by Nguyễn Thái Ngọc Duy, and helped by injection of
sanity from Jonathan Nieder and others on the Git mailing list.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-07 19:55:48 +00:00
|
|
|
git commit -m second &&
|
|
|
|
test $(git ls-tree HEAD -- nitfol | wc -l) = 0 &&
|
2016-10-24 10:42:20 +00:00
|
|
|
test $(git diff --name-only HEAD -- nitfol | wc -l) = 1 &&
|
2018-05-26 12:08:44 +00:00
|
|
|
test $(git diff --name-only -- nitfol | wc -l) = 1
|
2008-11-29 03:56:34 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'can commit with an unrelated i-t-a entry in index' '
|
|
|
|
git reset --hard &&
|
commit: ignore intent-to-add entries instead of refusing
Originally, "git add -N" was introduced to help users from forgetting to
add new files to the index before they ran "git commit -a". As an attempt
to help them further so that they do not forget to say "-a", "git commit"
to commit the index as-is was taught to error out, reminding the user that
they may have forgotten to add the final contents of the paths before
running the command.
This turned out to be a false "safety" that is useless. If the user made
changes to already tracked paths and paths added with "git add -N", and
then ran "git add" to register the final contents of the paths added with
"git add -N", "git commit" will happily create a commit out of the index,
without including the local changes made to the already tracked paths. It
was not a useful "safety" measure to prevent "forgetful" mistakes from
happening.
It turns out that this behaviour is not just a useless false "safety", but
actively hurts use cases of "git add -N" that were discovered later and
have become popular, namely, to tell Git to be aware of these paths added
by "git add -N", so that commands like "git status" and "git diff" would
include them in their output, even though the user is not interested in
including them in the next commit they are going to make.
Fix this ancient UI mistake, and instead make a commit from the index
ignoring the paths added by "git add -N" without adding real contents.
Based on the work by Nguyễn Thái Ngọc Duy, and helped by injection of
sanity from Jonathan Nieder and others on the Git mailing list.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-07 19:55:48 +00:00
|
|
|
echo bozbar >rezrov &&
|
2008-11-29 03:56:34 +00:00
|
|
|
echo frotz >nitfol &&
|
|
|
|
git add rezrov &&
|
|
|
|
git add -N nitfol &&
|
|
|
|
git commit -m partial rezrov
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'can "commit -a" with an i-t-a entry' '
|
|
|
|
git reset --hard &&
|
|
|
|
: >nitfol &&
|
|
|
|
git add -N nitfol &&
|
|
|
|
git commit -a -m all
|
|
|
|
'
|
|
|
|
|
2012-12-16 04:15:28 +00:00
|
|
|
test_expect_success 'cache-tree invalidates i-t-a paths' '
|
|
|
|
git reset --hard &&
|
|
|
|
mkdir dir &&
|
|
|
|
: >dir/foo &&
|
|
|
|
git add dir/foo &&
|
|
|
|
git commit -m foo &&
|
|
|
|
|
|
|
|
: >dir/bar &&
|
|
|
|
git add -N dir/bar &&
|
2018-05-26 12:08:44 +00:00
|
|
|
git diff --name-only >actual &&
|
Revert "diff-lib.c: adjust position of i-t-a entries in diff"
This reverts commit d95d728aba06a34394d15466045cbdabdada58a2.
It turns out that many other commands that need to interact with the
result of running diff-files and diff-index, e.g. "git apply", "git
rm", etc., need to be adjusted to the new world order it brings in.
For example, it would break this sequence to correct a whitespace
breakage in the parts you changed:
git add -N file
git diff --cached file | git apply --cached --whitespace=fix
git checkout file
In the old world order, "diff" showed a patch to modify an existing
empty file by adding its full contents, and "apply" updated the
index by modifying the existing empty blob (which is what an
Intent-to-Add entry records in the index) with that patch.
In the new world order, "diff" shows a patch to create a new file
with its full contents, but because "apply" thinks that the i-t-a
entry already exists in the index, it refused to accept a creation.
Adjusting "apply" to this new world order is easy, but we need to
assess the extent of the damage to the rest of the system the new
world order brought in before going forward and adjust them all,
after which we can resurrect the commit being reverted here.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-23 17:27:47 +00:00
|
|
|
echo dir/bar >expect &&
|
2012-12-16 04:15:28 +00:00
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
git write-tree >/dev/null &&
|
|
|
|
|
2018-05-26 12:08:44 +00:00
|
|
|
git diff --name-only >actual &&
|
Revert "diff-lib.c: adjust position of i-t-a entries in diff"
This reverts commit d95d728aba06a34394d15466045cbdabdada58a2.
It turns out that many other commands that need to interact with the
result of running diff-files and diff-index, e.g. "git apply", "git
rm", etc., need to be adjusted to the new world order it brings in.
For example, it would break this sequence to correct a whitespace
breakage in the parts you changed:
git add -N file
git diff --cached file | git apply --cached --whitespace=fix
git checkout file
In the old world order, "diff" showed a patch to modify an existing
empty file by adding its full contents, and "apply" updated the
index by modifying the existing empty blob (which is what an
Intent-to-Add entry records in the index) with that patch.
In the new world order, "diff" shows a patch to create a new file
with its full contents, but because "apply" thinks that the i-t-a
entry already exists in the index, it refused to accept a creation.
Adjusting "apply" to this new world order is easy, but we need to
assess the extent of the damage to the rest of the system the new
world order brought in before going forward and adjust them all,
after which we can resurrect the commit being reverted here.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-23 17:27:47 +00:00
|
|
|
echo dir/bar >expect &&
|
2012-12-16 04:15:28 +00:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2016-07-16 05:06:26 +00:00
|
|
|
test_expect_success 'cache-tree does not ignore dir that has i-t-a entries' '
|
|
|
|
git init ita-in-dir &&
|
|
|
|
(
|
|
|
|
cd ita-in-dir &&
|
|
|
|
mkdir 2 &&
|
|
|
|
for f in 1 2/1 2/2 3
|
|
|
|
do
|
|
|
|
echo "$f" >"$f"
|
|
|
|
done &&
|
|
|
|
git add 1 2/2 3 &&
|
|
|
|
git add -N 2/1 &&
|
|
|
|
git commit -m committed &&
|
|
|
|
git ls-tree -r HEAD >actual &&
|
|
|
|
grep 2/2 actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2016-07-16 05:06:27 +00:00
|
|
|
test_expect_success 'cache-tree does skip dir that becomes empty' '
|
|
|
|
rm -fr ita-in-dir &&
|
|
|
|
git init ita-in-dir &&
|
|
|
|
(
|
|
|
|
cd ita-in-dir &&
|
|
|
|
mkdir -p 1/2/3 &&
|
|
|
|
echo 4 >1/2/3/4 &&
|
|
|
|
git add -N 1/2/3/4 &&
|
|
|
|
git write-tree >actual &&
|
|
|
|
echo $EMPTY_TREE >expected &&
|
|
|
|
test_cmp expected actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2017-06-25 10:20:41 +00:00
|
|
|
test_expect_success 'commit: ita entries ignored in empty initial commit check' '
|
|
|
|
git init empty-initial-commit &&
|
2016-10-24 10:42:22 +00:00
|
|
|
(
|
2017-06-25 10:20:41 +00:00
|
|
|
cd empty-initial-commit &&
|
2016-10-24 10:42:22 +00:00
|
|
|
: >one &&
|
|
|
|
git add -N one &&
|
|
|
|
test_must_fail git commit -m nothing-new-here
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2016-10-24 10:42:21 +00:00
|
|
|
test_expect_success 'commit: ita entries ignored in empty commit check' '
|
|
|
|
git init empty-subsequent-commit &&
|
|
|
|
(
|
|
|
|
cd empty-subsequent-commit &&
|
|
|
|
test_commit one &&
|
|
|
|
: >two &&
|
|
|
|
git add -N two &&
|
|
|
|
test_must_fail git commit -m nothing-new-here
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2017-12-27 10:18:39 +00:00
|
|
|
test_expect_success 'rename detection finds the right names' '
|
|
|
|
git init rename-detection &&
|
|
|
|
(
|
|
|
|
cd rename-detection &&
|
|
|
|
echo contents >first &&
|
|
|
|
git add first &&
|
|
|
|
git commit -m first &&
|
|
|
|
mv first third &&
|
|
|
|
git add -N third &&
|
|
|
|
|
|
|
|
git status | grep -v "^?" >actual.1 &&
|
|
|
|
test_i18ngrep "renamed: *first -> third" actual.1 &&
|
|
|
|
|
|
|
|
git status --porcelain | grep -v "^?" >actual.2 &&
|
|
|
|
cat >expected.2 <<-\EOF &&
|
|
|
|
R first -> third
|
|
|
|
EOF
|
|
|
|
test_cmp expected.2 actual.2 &&
|
|
|
|
|
2018-05-13 02:24:21 +00:00
|
|
|
hash=$(git hash-object third) &&
|
2017-12-27 10:18:39 +00:00
|
|
|
git status --porcelain=v2 | grep -v "^?" >actual.3 &&
|
|
|
|
cat >expected.3 <<-EOF &&
|
|
|
|
2 .R N... 100644 100644 100644 $hash $hash R100 third first
|
|
|
|
EOF
|
2018-05-26 12:08:44 +00:00
|
|
|
test_cmp expected.3 actual.3 &&
|
|
|
|
|
|
|
|
git diff --stat >actual.4 &&
|
|
|
|
cat >expected.4 <<-EOF &&
|
|
|
|
first => third | 0
|
|
|
|
1 file changed, 0 insertions(+), 0 deletions(-)
|
|
|
|
EOF
|
|
|
|
test_cmp expected.4 actual.4 &&
|
|
|
|
|
|
|
|
git diff --cached --stat >actual.5 &&
|
tests: use 'test_must_be_empty' instead of 'test_cmp <empty> <out>'
Using 'test_must_be_empty' is shorter and more idiomatic than
>empty &&
test_cmp empty out
as it saves the creation of an empty file. Furthermore, sometimes the
expected empty file doesn't have such a descriptive name like 'empty',
and its creation is far away from the place where it's finally used
for comparison (e.g. in 't7600-merge.sh', where two expected empty
files are created in the 'setup' test, but are used only about 500
lines later).
These cases were found by instrumenting 'test_cmp' to error out the
test script when it's used to compare empty files, and then converted
manually.
Note that even after this patch there still remain a lot of cases
where we use 'test_cmp' to check empty files:
- Sometimes the expected output is not hard-coded in the test, but
'test_cmp' is used to ensure that two similar git commands produce
the same output, and that output happens to be empty, e.g. the
test 'submodule update --merge - ignores --merge for new
submodules' in 't7406-submodule-update.sh'.
- Repetitive common tasks, including preparing the expected results
and running 'test_cmp', are often extracted into a helper
function, and some of this helper's callsites expect no output.
- For the same reason as above, the whole 'test_expect_success'
block is within a helper function, e.g. in 't3070-wildmatch.sh'.
- Or 'test_cmp' is invoked in a loop, e.g. the test 'cvs update
(-p)' in 't9400-git-cvsserver-server.sh'.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-19 21:57:25 +00:00
|
|
|
test_must_be_empty actual.5
|
2018-05-26 12:08:44 +00:00
|
|
|
|
2017-12-27 10:18:39 +00:00
|
|
|
)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'double rename detection in status' '
|
|
|
|
git init rename-detection-2 &&
|
|
|
|
(
|
|
|
|
cd rename-detection-2 &&
|
|
|
|
echo contents >first &&
|
|
|
|
git add first &&
|
|
|
|
git commit -m first &&
|
|
|
|
git mv first second &&
|
|
|
|
mv second third &&
|
|
|
|
git add -N third &&
|
|
|
|
|
|
|
|
git status | grep -v "^?" >actual.1 &&
|
|
|
|
test_i18ngrep "renamed: *first -> second" actual.1 &&
|
|
|
|
test_i18ngrep "renamed: *second -> third" actual.1 &&
|
|
|
|
|
|
|
|
git status --porcelain | grep -v "^?" >actual.2 &&
|
|
|
|
cat >expected.2 <<-\EOF &&
|
|
|
|
R first -> second
|
|
|
|
R second -> third
|
|
|
|
EOF
|
|
|
|
test_cmp expected.2 actual.2 &&
|
|
|
|
|
2018-05-13 02:24:21 +00:00
|
|
|
hash=$(git hash-object third) &&
|
2017-12-27 10:18:39 +00:00
|
|
|
git status --porcelain=v2 | grep -v "^?" >actual.3 &&
|
|
|
|
cat >expected.3 <<-EOF &&
|
|
|
|
2 R. N... 100644 100644 100644 $hash $hash R100 second first
|
|
|
|
2 .R N... 100644 100644 100644 $hash $hash R100 third second
|
|
|
|
EOF
|
|
|
|
test_cmp expected.3 actual.3
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2020-06-20 16:38:45 +00:00
|
|
|
test_expect_success 'i-t-a files shown as new for "diff", "diff-files"; not-new for "diff --cached"' '
|
2018-05-26 12:08:44 +00:00
|
|
|
git reset --hard &&
|
2020-06-20 16:38:45 +00:00
|
|
|
: >empty &&
|
|
|
|
content="foo" &&
|
|
|
|
echo "$content" >not-empty &&
|
|
|
|
|
|
|
|
hash_e=$(git hash-object empty) &&
|
|
|
|
hash_n=$(git hash-object not-empty) &&
|
|
|
|
|
|
|
|
cat >expect.diff_p <<-EOF &&
|
|
|
|
diff --git a/empty b/empty
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000..$(git rev-parse --short $hash_e)
|
|
|
|
diff --git a/not-empty b/not-empty
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000..$(git rev-parse --short $hash_n)
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/not-empty
|
|
|
|
@@ -0,0 +1 @@
|
|
|
|
+$content
|
|
|
|
EOF
|
|
|
|
cat >expect.diff_s <<-EOF &&
|
|
|
|
create mode 100644 empty
|
|
|
|
create mode 100644 not-empty
|
|
|
|
EOF
|
|
|
|
cat >expect.diff_a <<-EOF &&
|
2020-07-01 21:19:06 +00:00
|
|
|
:000000 100644 0000000 0000000 A$(printf "\t")empty
|
|
|
|
:000000 100644 0000000 0000000 A$(printf "\t")not-empty
|
2020-06-20 16:38:45 +00:00
|
|
|
EOF
|
|
|
|
|
|
|
|
git add -N empty not-empty &&
|
|
|
|
|
|
|
|
git diff >actual &&
|
|
|
|
test_cmp expect.diff_p actual &&
|
|
|
|
|
2018-05-26 12:08:44 +00:00
|
|
|
git diff --summary >actual &&
|
2020-06-20 16:38:45 +00:00
|
|
|
test_cmp expect.diff_s actual &&
|
|
|
|
|
|
|
|
git diff-files -p >actual &&
|
|
|
|
test_cmp expect.diff_p actual &&
|
2008-08-21 08:44:53 +00:00
|
|
|
|
2020-06-20 16:38:45 +00:00
|
|
|
git diff-files --abbrev >actual &&
|
|
|
|
test_cmp expect.diff_a actual &&
|
|
|
|
|
|
|
|
git diff --cached >actual &&
|
|
|
|
test_must_be_empty actual
|
|
|
|
'
|
2008-08-21 08:44:53 +00:00
|
|
|
|
2018-05-26 12:08:45 +00:00
|
|
|
test_expect_success '"diff HEAD" includes ita as new files' '
|
|
|
|
git reset --hard &&
|
|
|
|
echo new >new-ita &&
|
2019-06-28 22:59:28 +00:00
|
|
|
oid=$(git hash-object new-ita) &&
|
|
|
|
oid=$(git rev-parse --short $oid) &&
|
2018-05-26 12:08:45 +00:00
|
|
|
git add -N new-ita &&
|
|
|
|
git diff HEAD >actual &&
|
2019-06-28 22:59:28 +00:00
|
|
|
cat >expected <<-EOF &&
|
2018-05-26 12:08:45 +00:00
|
|
|
diff --git a/new-ita b/new-ita
|
|
|
|
new file mode 100644
|
2019-06-28 22:59:28 +00:00
|
|
|
index 0000000..$oid
|
2018-05-26 12:08:45 +00:00
|
|
|
--- /dev/null
|
|
|
|
+++ b/new-ita
|
|
|
|
@@ -0,0 +1 @@
|
|
|
|
+new
|
|
|
|
EOF
|
|
|
|
test_cmp expected actual
|
|
|
|
'
|
|
|
|
|
2018-05-26 12:08:46 +00:00
|
|
|
test_expect_success 'apply --intent-to-add' '
|
|
|
|
git reset --hard &&
|
|
|
|
echo new >new-ita &&
|
|
|
|
git add -N new-ita &&
|
|
|
|
git diff >expected &&
|
|
|
|
grep "new file" expected &&
|
|
|
|
git reset --hard &&
|
|
|
|
git apply --intent-to-add expected &&
|
|
|
|
git diff >actual &&
|
|
|
|
test_cmp expected actual
|
|
|
|
'
|
|
|
|
|
2018-05-26 12:08:44 +00:00
|
|
|
test_done
|