{"thread":{"id":"27444","subject":"[RFC PATCH] unpack-trees: add the dry_run flag to unpack_trees_options","startedAt":"2011-05-24T21:07:05Z","lastAt":"2011-05-25T22:30:02Z","messageCount":7,"participants":["Jens Lehmann","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"168596","messageId":"4DDC1DF9.9030109@web.de","threadId":"27444","inReplyTo":null,"subject":"[RFC PATCH] unpack-trees: add the dry_run flag to unpack_trees_options","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2011-05-24T21:07:05Z","receivedAt":"2011-05-24T21:07:05Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Until now there was no way to test if unpack_trees() with update=1 would\nsucceed without really updating the work tree. The reason for that is that\nsetting update to 0 does skip the tests for new files and deactivates the\nsparse handling, thereby making that unsuitable as a dry run.\n\nAdd the new dry_run flag to struct unpack_trees_options unpack_trees().\nSetting that together with the update flag will check if the work tree\nupdate would be successful without doing it for real.\n\nThe only class of problems that is not detected at the moment are file\nsystem conditions like ENOSPC or missing permissions. Also the index\nentries of updated files are not as they would be after a real checkout\nbecause lstat() isn't run as the files aren't updated for real.\n\nSigned-off-by: Jens Lehmann <Jens.Lehmann@web.de>\n---\n\nAFAICS this patch enables the user to achieve a dry run by calling\nunpack_trees() with both update and dry_run set.\n\nMy \"Teach read-tree the -n|--dry-run option\" adapted to this new flag\nruns all tests successfully ...\n\n\n unpack-trees.c |    4 ++--\n unpack-trees.h |    3 ++-\n 2 files changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 500ebcf..e26a710 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -203,7 +203,7 @@ static int check_updates(struct unpack_trees_options *o)\n\n \t\tif (ce->ce_flags & CE_WT_REMOVE) {\n \t\t\tdisplay_progress(progress, ++cnt);\n-\t\t\tif (o->update)\n+\t\t\tif (o->update && !o->dry_run)\n \t\t\t\tunlink_entry(ce);\n \t\t\tcontinue;\n \t\t}\n@@ -217,7 +217,7 @@ static int check_updates(struct unpack_trees_options *o)\n \t\tif (ce->ce_flags & CE_UPDATE) {\n \t\t\tdisplay_progress(progress, ++cnt);\n \t\t\tce->ce_flags &= ~CE_UPDATE;\n-\t\t\tif (o->update) {\n+\t\t\tif (o->update && !o->dry_run) {\n \t\t\t\terrs |= checkout_entry(ce, &state, NULL);\n \t\t\t}\n \t\t}\ndiff --git a/unpack-trees.h b/unpack-trees.h\nindex cd11a08..64f02cb 100644\n--- a/unpack-trees.h\n+++ b/unpack-trees.h\n@@ -46,7 +46,8 @@ struct unpack_trees_options {\n \t\t     debug_unpack,\n \t\t     skip_sparse_checkout,\n \t\t     gently,\n-\t\t     show_all_errors;\n+\t\t     show_all_errors,\n+\t\t     dry_run;\n \tconst char *prefix;\n \tint cache_bottom;\n \tstruct dir_struct *dir;\n-- \n1.7.5.1.340.g7f395.dirty\n"},{"id":"168615","messageId":"7v39k37kmo.fsf@alter.siamese.dyndns.org","threadId":"27444","inReplyTo":"4DDC1DF9.9030109@web.de","subject":"Re: [RFC PATCH] unpack-trees: add the dry_run flag to unpack_trees_options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-05-24T23:18:39Z","receivedAt":"2011-05-24T23:18:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jens Lehmann <Jens.Lehmann@web.de> writes:\n\n> Until now there was no way to test if unpack_trees() with update=1 would\n> succeed without really updating the work tree. The reason for that is that\n> setting update to 0 does skip the tests for new files and deactivates the\n> sparse handling, thereby making that unsuitable as a dry run.\n>\n> Add the new dry_run flag to struct unpack_trees_options unpack_trees().\n> Setting that together with the update flag will check if the work tree\n> update would be successful without doing it for real.\n>\n> The only class of problems that is not detected at the moment are file\n> system conditions like ENOSPC or missing permissions. Also the index\n> entries of updated files are not as they would be after a real checkout\n> because lstat() isn't run as the files aren't updated for real.\n>\n> Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>\n> ---\n\nA very sane and clear description. Good.\n\n> AFAICS this patch enables the user to achieve a dry run by calling\n> unpack_trees() with both update and dry_run set.\n>\n> My \"Teach read-tree the -n|--dry-run option\" adapted to this new flag\n> runs all tests successfully ...\n>\n>\n>  unpack-trees.c |    4 ++--\n>  unpack-trees.h |    3 ++-\n>  2 files changed, 4 insertions(+), 3 deletions(-)\n\nBut on which change does this come?\n"},{"id":"168711","messageId":"4DDD615E.7020809@web.de","threadId":"27444","inReplyTo":"7v39k37kmo.fsf@alter.siamese.dyndns.org","subject":"[PATCH v2 0/2] Teach read-tree the -n|--dry-run option","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2011-05-25T20:06:54Z","receivedAt":"2011-05-25T20:06:54Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 25.05.2011 01:18, schrieb Junio C Hamano:\n> Jens Lehmann <Jens.Lehmann@web.de> writes:\n>> My \"Teach read-tree the -n|--dry-run option\" adapted to this new flag\n>> runs all tests successfully ...\n>>\n>>\n>>  unpack-trees.c |    4 ++--\n>>  unpack-trees.h |    3 ++-\n>>  2 files changed, 4 insertions(+), 3 deletions(-)\n> \n> But on which change does this come?\n\nAs a preparing step for \"read-tree the -n|--dry-run\" (and adding\na dry-run option to other users of unpack_trees() should be pretty\nstraightforward now too).\n\nThe first patch in this series enables unpack_trees() to do a dry-run.\nThat enables users of unpack_trees() to see if running this function\nwith the update flag set would succeed.\n\nThe second patch uses this new dry_run flag to teach read-tree the\n-n|--dry-run option.\n\n\nJens Lehmann (2):\n  unpack-trees: add the dry_run flag to unpack_trees_options\n  Teach read-tree the -n|--dry-run option\n\n Documentation/git-read-tree.txt      |    5 ++\n builtin/read-tree.c                  |    3 +-\n t/lib-read-tree.sh                   |   43 ++++++++++++++++++\n t/t1000-read-tree-m-3way.sh          |   81 +++++++++++++++++-----------------\n t/t1001-read-tree-m-2way.sh          |   45 ++++++++++---------\n t/t1002-read-tree-m-u-2way.sh        |   81 +++++++++++++++++-----------------\n t/t1004-read-tree-m-u-wf.sh          |   23 +++++-----\n t/t1005-read-tree-reset.sh           |   13 +++---\n t/t1008-read-tree-overlay.sh         |    3 +-\n t/t1011-read-tree-sparse-checkout.sh |   27 ++++++-----\n t/t1012-read-tree-df.sh              |    9 ++--\n t/t1020-subdirectory.sh              |    5 +-\n unpack-trees.c                       |    4 +-\n unpack-trees.h                       |    3 +-\n 14 files changed, 202 insertions(+), 143 deletions(-)\n create mode 100644 t/lib-read-tree.sh\n\n-- \n1.7.5.2.355.gdceb0\n"},{"id":"168712","messageId":"4DDD6197.7060209@web.de","threadId":"27444","inReplyTo":"4DDD615E.7020809@web.de","subject":"[PATCH v2 1/2] unpack-trees: add the dry_run flag to unpack_trees_options","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2011-05-25T20:07:51Z","receivedAt":"2011-05-25T20:07:51Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Until now there was no way to test if unpack_trees() with update=1 would\nsucceed without really updating the work tree. The reason for that is that\nsetting update to 0 does skip the tests for new files and deactivates the\nsparse handling, thereby making that unsuitable as a dry run.\n\nAdd the new dry_run flag to struct unpack_trees_options unpack_trees().\nSetting that together with the update flag will check if the work tree\nupdate would be successful without doing it for real.\n\nThe only class of problems that is not detected at the moment are file\nsystem conditions like ENOSPC or missing permissions. Also the index\nentries of updated files are not as they would be after a real checkout\nbecause lstat() isn't run as the files aren't updated for real.\n\nSigned-off-by: Jens Lehmann <Jens.Lehmann@web.de>\n---\n unpack-trees.c |    4 ++--\n unpack-trees.h |    3 ++-\n 2 files changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 0bc4b2d..07f8364 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -203,7 +203,7 @@ static int check_updates(struct unpack_trees_options *o)\n\n \t\tif (ce->ce_flags & CE_WT_REMOVE) {\n \t\t\tdisplay_progress(progress, ++cnt);\n-\t\t\tif (o->update)\n+\t\t\tif (o->update && !o->dry_run)\n \t\t\t\tunlink_entry(ce);\n \t\t\tcontinue;\n \t\t}\n@@ -217,7 +217,7 @@ static int check_updates(struct unpack_trees_options *o)\n \t\tif (ce->ce_flags & CE_UPDATE) {\n \t\t\tdisplay_progress(progress, ++cnt);\n \t\t\tce->ce_flags &= ~CE_UPDATE;\n-\t\t\tif (o->update) {\n+\t\t\tif (o->update && !o->dry_run) {\n \t\t\t\terrs |= checkout_entry(ce, &state, NULL);\n \t\t\t}\n \t\t}\ndiff --git a/unpack-trees.h b/unpack-trees.h\nindex cd11a08..64f02cb 100644\n--- a/unpack-trees.h\n+++ b/unpack-trees.h\n@@ -46,7 +46,8 @@ struct unpack_trees_options {\n \t\t     debug_unpack,\n \t\t     skip_sparse_checkout,\n \t\t     gently,\n-\t\t     show_all_errors;\n+\t\t     show_all_errors,\n+\t\t     dry_run;\n \tconst char *prefix;\n \tint cache_bottom;\n \tstruct dir_struct *dir;\n-- \n1.7.5.2.355.gdceb0\n"},{"id":"168713","messageId":"4DDD6241.8070908@web.de","threadId":"27444","inReplyTo":"4DDD615E.7020809@web.de","subject":"[PATCH v2 2/2] Teach read-tree the -n|--dry-run option","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2011-05-25T20:10:41Z","receivedAt":"2011-05-25T20:10:41Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Using this option tells read-tree to not update the index. That makes it\npossible to check if updating the index would be successful without\nchanging anything. Using this option will silently ignore -u but still\ntest if updating the work tree would succeed.\n\nThe relevant tests in the t10?? range were extended to do a read-tree -n\nbefore the real read-tree to make sure neither the index nor any local\nfiles were changed with -n and the same exit code as without -n is\nreturned. The helper functions added for that purpose reside in the new\nt/lib-read-tree.sh file.\n\nThe only exception is #13 in t1004 (\"unlinking an un-unlink-able\nsymlink\"). As this is an issue of wrong directory permissions it is not\ndetected with -n.\n\nSigned-off-by: Jens Lehmann <Jens.Lehmann@web.de>\n---\n Documentation/git-read-tree.txt      |    5 ++\n builtin/read-tree.c                  |    3 +-\n t/lib-read-tree.sh                   |   43 ++++++++++++++++++\n t/t1000-read-tree-m-3way.sh          |   81 +++++++++++++++++-----------------\n t/t1001-read-tree-m-2way.sh          |   45 ++++++++++---------\n t/t1002-read-tree-m-u-2way.sh        |   81 +++++++++++++++++-----------------\n t/t1004-read-tree-m-u-wf.sh          |   23 +++++-----\n t/t1005-read-tree-reset.sh           |   13 +++---\n t/t1008-read-tree-overlay.sh         |    3 +-\n t/t1011-read-tree-sparse-checkout.sh |   27 ++++++-----\n t/t1012-read-tree-df.sh              |    9 ++--\n t/t1020-subdirectory.sh              |    5 +-\n 12 files changed, 198 insertions(+), 140 deletions(-)\n create mode 100644 t/lib-read-tree.sh\n\ndiff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt\nindex 26fdadc..46a96f2 100644\n--- a/Documentation/git-read-tree.txt\n+++ b/Documentation/git-read-tree.txt\n@@ -53,6 +53,11 @@ OPTIONS\n \ttrees that are not directly related to the current\n \tworking tree status into a temporary index file.\n\n+-n::\n+--dry-run::\n+\tCheck if the command would error out, without updating the index\n+\tnor the files in the working tree for real.\n+\n -v::\n \tShow the progress of checking files out.\n\ndiff --git a/builtin/read-tree.c b/builtin/read-tree.c\nindex 93c9281..df6c4c8 100644\n--- a/builtin/read-tree.c\n+++ b/builtin/read-tree.c\n@@ -130,6 +130,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)\n \t\t  PARSE_OPT_NONEG, exclude_per_directory_cb },\n \t\tOPT_SET_INT('i', NULL, &opts.index_only,\n \t\t\t    \"don't check the working tree after merging\", 1),\n+\t\tOPT__DRY_RUN(&opts.dry_run, \"don't update the index or the work tree\"),\n \t\tOPT_SET_INT(0, \"no-sparse-checkout\", &opts.skip_sparse_checkout,\n \t\t\t    \"skip applying sparse checkout filter\", 1),\n \t\tOPT_SET_INT(0, \"debug-unpack\", &opts.debug_unpack,\n@@ -219,7 +220,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)\n \tif (unpack_trees(nr_trees, t, &opts))\n \t\treturn 128;\n\n-\tif (opts.debug_unpack)\n+\tif (opts.debug_unpack || opts.dry_run)\n \t\treturn 0; /* do not write the index out */\n\n \t/*\ndiff --git a/t/lib-read-tree.sh b/t/lib-read-tree.sh\nnew file mode 100644\nindex 0000000..435d19c\n--- /dev/null\n+++ b/t/lib-read-tree.sh\n@@ -0,0 +1,43 @@\n+#!/bin/sh\n+#\n+# Helper functions to check if read-tree would succeed/fail as expected with\n+# and without the dry-run option. They also test that the dry-run does not\n+# write the index and that together with -u it doesn't touch the work tree.\n+#\n+read_tree_must_succeed () {\n+    git ls-files -s >pre-dry-run &&\n+    git read-tree -n \"$@\" &&\n+    git ls-files -s >post-dry-run &&\n+    test_cmp pre-dry-run post-dry-run &&\n+    git read-tree \"$@\"\n+}\n+\n+read_tree_must_fail () {\n+    git ls-files -s >pre-dry-run &&\n+    test_must_fail git read-tree -n \"$@\" &&\n+    git ls-files -s >post-dry-run &&\n+    test_cmp pre-dry-run post-dry-run &&\n+    test_must_fail git read-tree \"$@\"\n+}\n+\n+read_tree_u_must_succeed () {\n+    git ls-files -s >pre-dry-run &&\n+    git diff-files >pre-dry-run-wt &&\n+    git read-tree -n \"$@\" &&\n+    git ls-files -s >post-dry-run &&\n+    git diff-files >post-dry-run-wt &&\n+    test_cmp pre-dry-run post-dry-run &&\n+    test_cmp pre-dry-run-wt post-dry-run-wt &&\n+    git read-tree \"$@\"\n+}\n+\n+read_tree_u_must_fail () {\n+    git ls-files -s >pre-dry-run &&\n+    git diff-files >pre-dry-run-wt &&\n+    test_must_fail git read-tree -n \"$@\" &&\n+    git ls-files -s >post-dry-run &&\n+    git diff-files >post-dry-run-wt &&\n+    test_cmp pre-dry-run post-dry-run &&\n+    test_cmp pre-dry-run-wt post-dry-run-wt &&\n+    test_must_fail git read-tree \"$@\"\n+}\ndiff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh\nindex ca8a409..babcdd2 100755\n--- a/t/t1000-read-tree-m-3way.sh\n+++ b/t/t1000-read-tree-m-3way.sh\n@@ -72,6 +72,7 @@ In addition:\n\n '\n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-read-tree.sh\n . \"$TEST_DIRECTORY\"/lib-read-tree-m-3way.sh\n\n ################################################################\n@@ -137,7 +138,7 @@ test_expect_success \\\n     '3-way merge with git read-tree -m, empty cache' \\\n     \"rm -fr [NDMALTS][NDMALTSF] Z &&\n      rm .git/index &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n # This starts out with the first head, which is the normal\n@@ -146,9 +147,9 @@ test_expect_success \\\n     '3-way merge with git read-tree -m, match H' \\\n     \"rm -fr [NDMALTS][NDMALTSF] Z &&\n      rm .git/index &&\n-     git read-tree $tree_A &&\n+     read_tree_must_succeed $tree_A &&\n      git checkout-index -f -u -a &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n : <<\\END_OF_CASE_TABLE\n@@ -211,7 +212,7 @@ test_expect_success '1 - must not have an entry not in A.' \"\n      rm -f .git/index XX &&\n      echo XX >XX &&\n      git update-index --add XX &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -219,7 +220,7 @@ test_expect_success \\\n     \"rm -f .git/index NA &&\n      cp .orig-B/NA NA &&\n      git update-index --add NA &&\n-     git read-tree -m $tree_O $tree_A $tree_B\"\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B\"\n\n test_expect_success \\\n     '2 - matching B alone is OK in !O && !A && B case.' \\\n@@ -227,14 +228,14 @@ test_expect_success \\\n      cp .orig-B/NA NA &&\n      git update-index --add NA &&\n      echo extra >>NA &&\n-     git read-tree -m $tree_O $tree_A $tree_B\"\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B\"\n\n test_expect_success \\\n     '3 - must match A in !O && A && !B case.' \\\n     \"rm -f .git/index AN &&\n      cp .orig-A/AN AN &&\n      git update-index --add AN &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -243,7 +244,7 @@ test_expect_success \\\n      cp .orig-A/AN AN &&\n      git update-index --add AN &&\n      echo extra >>AN &&\n-     git read-tree -m $tree_O $tree_A $tree_B\"\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B\"\n\n test_expect_success \\\n     '3 (fail) - must match A in !O && A && !B case.' \"\n@@ -251,7 +252,7 @@ test_expect_success \\\n      cp .orig-A/AN AN &&\n      echo extra >>AN &&\n      git update-index --add AN &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -259,7 +260,7 @@ test_expect_success \\\n     \"rm -f .git/index AA &&\n      cp .orig-A/AA AA &&\n      git update-index --add AA &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -268,7 +269,7 @@ test_expect_success \\\n      cp .orig-A/AA AA &&\n      git update-index --add AA &&\n      echo extra >>AA &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -277,7 +278,7 @@ test_expect_success \\\n      cp .orig-A/AA AA &&\n      echo extra >>AA &&\n      git update-index --add AA &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -285,7 +286,7 @@ test_expect_success \\\n     \"rm -f .git/index LL &&\n      cp .orig-A/LL LL &&\n      git update-index --add LL &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -294,7 +295,7 @@ test_expect_success \\\n      cp .orig-A/LL LL &&\n      git update-index --add LL &&\n      echo extra >>LL &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -303,7 +304,7 @@ test_expect_success \\\n      cp .orig-A/LL LL &&\n      echo extra >>LL &&\n      git update-index --add LL &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -311,7 +312,7 @@ test_expect_success \\\n      rm -f .git/index DD &&\n      echo DD >DD &&\n      git update-index --add DD &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -319,7 +320,7 @@ test_expect_success \\\n      rm -f .git/index DM &&\n      cp .orig-B/DM DM &&\n      git update-index --add DM &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -327,7 +328,7 @@ test_expect_success \\\n      rm -f .git/index DN &&\n      cp .orig-B/DN DN &&\n      git update-index --add DN &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -335,7 +336,7 @@ test_expect_success \\\n     \"rm -f .git/index MD &&\n      cp .orig-A/MD MD &&\n      git update-index --add MD &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -344,7 +345,7 @@ test_expect_success \\\n      cp .orig-A/MD MD &&\n      git update-index --add MD &&\n      echo extra >>MD &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -353,7 +354,7 @@ test_expect_success \\\n      cp .orig-A/MD MD &&\n      echo extra >>MD &&\n      git update-index --add MD &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -361,7 +362,7 @@ test_expect_success \\\n     \"rm -f .git/index ND &&\n      cp .orig-A/ND ND &&\n      git update-index --add ND &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -370,7 +371,7 @@ test_expect_success \\\n      cp .orig-A/ND ND &&\n      git update-index --add ND &&\n      echo extra >>ND &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -379,7 +380,7 @@ test_expect_success \\\n      cp .orig-A/ND ND &&\n      echo extra >>ND &&\n      git update-index --add ND &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -387,7 +388,7 @@ test_expect_success \\\n     \"rm -f .git/index MM &&\n      cp .orig-A/MM MM &&\n      git update-index --add MM &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -396,7 +397,7 @@ test_expect_success \\\n      cp .orig-A/MM MM &&\n      git update-index --add MM &&\n      echo extra >>MM &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -405,7 +406,7 @@ test_expect_success \\\n      cp .orig-A/MM MM &&\n      echo extra >>MM &&\n      git update-index --add MM &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -413,7 +414,7 @@ test_expect_success \\\n     \"rm -f .git/index SS &&\n      cp .orig-A/SS SS &&\n      git update-index --add SS &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -422,7 +423,7 @@ test_expect_success \\\n      cp .orig-A/SS SS &&\n      git update-index --add SS &&\n      echo extra >>SS &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -431,7 +432,7 @@ test_expect_success \\\n      cp .orig-A/SS SS &&\n      echo extra >>SS &&\n      git update-index --add SS &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -439,7 +440,7 @@ test_expect_success \\\n     \"rm -f .git/index MN &&\n      cp .orig-A/MN MN &&\n      git update-index --add MN &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -448,7 +449,7 @@ test_expect_success \\\n      cp .orig-A/MN MN &&\n      git update-index --add MN &&\n      echo extra >>MN &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -456,7 +457,7 @@ test_expect_success \\\n     \"rm -f .git/index NM &&\n      cp .orig-A/NM NM &&\n      git update-index --add NM &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -465,7 +466,7 @@ test_expect_success \\\n      cp .orig-B/NM NM &&\n      git update-index --add NM &&\n      echo extra >>NM &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -474,7 +475,7 @@ test_expect_success \\\n      cp .orig-A/NM NM &&\n      git update-index --add NM &&\n      echo extra >>NM &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -483,7 +484,7 @@ test_expect_success \\\n      cp .orig-A/NM NM &&\n      echo extra >>NM &&\n      git update-index --add NM &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n test_expect_success \\\n@@ -491,7 +492,7 @@ test_expect_success \\\n     \"rm -f .git/index NN &&\n      cp .orig-A/NN NN &&\n      git update-index --add NN &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -500,7 +501,7 @@ test_expect_success \\\n      cp .orig-A/NN NN &&\n      git update-index --add NN &&\n      echo extra >>NN &&\n-     git read-tree -m $tree_O $tree_A $tree_B &&\n+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&\n      check_result\"\n\n test_expect_success \\\n@@ -509,7 +510,7 @@ test_expect_success \\\n      cp .orig-A/NN NN &&\n      echo extra >>NN &&\n      git update-index --add NN &&\n-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B\n+     read_tree_must_fail -m $tree_O $tree_A $tree_B\n \"\n\n # #16\n@@ -522,7 +523,7 @@ test_expect_success \\\n     echo E16 >F16 &&\n     git update-index F16 &&\n     tree1=`git write-tree` &&\n-    git read-tree -m $tree0 $tree1 $tree1 $tree0 &&\n+    read_tree_must_succeed -m $tree0 $tree1 $tree1 $tree0 &&\n     git ls-files --stage'\n\n test_done\ndiff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh\nindex 680d992..acaab07 100755\n--- a/t/t1001-read-tree-m-2way.sh\n+++ b/t/t1001-read-tree-m-2way.sh\n@@ -21,6 +21,7 @@ In the test, these paths are used:\n         yomin   - not in H nor M\n '\n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-read-tree.sh\n\n read_tree_twoway () {\n     git read-tree -m \"$1\" \"$2\" && git ls-files --stage\n@@ -94,7 +95,7 @@ echo '+100644 X 0\tyomin' >expected\n test_expect_success \\\n     '4 - carry forward local addition.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      git update-index --add yomin &&\n      read_tree_twoway $treeH $treeM &&\n@@ -106,7 +107,7 @@ test_expect_success \\\n test_expect_success \\\n     '5 - carry forward local addition.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      echo yomin >yomin &&\n      git update-index --add yomin &&\n@@ -120,7 +121,7 @@ test_expect_success \\\n test_expect_success \\\n     '6 - local addition already has the same.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      git update-index --add frotz &&\n      read_tree_twoway $treeH $treeM &&\n@@ -131,7 +132,7 @@ test_expect_success \\\n test_expect_success \\\n     '7 - local addition already has the same.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      echo frotz >frotz &&\n      git update-index --add frotz &&\n@@ -144,7 +145,7 @@ test_expect_success \\\n test_expect_success \\\n     '8 - conflicting addition.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      echo frotz frotz >frotz &&\n      git update-index --add frotz &&\n@@ -153,7 +154,7 @@ test_expect_success \\\n test_expect_success \\\n     '9 - conflicting addition.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      echo frotz frotz >frotz &&\n      git update-index --add frotz &&\n@@ -163,7 +164,7 @@ test_expect_success \\\n test_expect_success \\\n     '10 - path removed.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      echo rezrov >rezrov &&\n      git update-index --add rezrov &&\n@@ -174,7 +175,7 @@ test_expect_success \\\n test_expect_success \\\n     '11 - dirty path removed.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      echo rezrov >rezrov &&\n      git update-index --add rezrov &&\n@@ -184,7 +185,7 @@ test_expect_success \\\n test_expect_success \\\n     '12 - unmatching local changes being removed.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      echo rezrov rezrov >rezrov &&\n      git update-index --add rezrov &&\n@@ -193,7 +194,7 @@ test_expect_success \\\n test_expect_success \\\n     '13 - unmatching local changes being removed.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      echo rezrov rezrov >rezrov &&\n      git update-index --add rezrov &&\n@@ -208,7 +209,7 @@ EOF\n test_expect_success \\\n     '14 - unchanged in two heads.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      echo nitfol nitfol >nitfol &&\n      git update-index --add nitfol &&\n@@ -221,7 +222,7 @@ test_expect_success \\\n test_expect_success \\\n     '15 - unchanged in two heads.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      echo nitfol nitfol >nitfol &&\n      git update-index --add nitfol &&\n@@ -235,7 +236,7 @@ test_expect_success \\\n test_expect_success \\\n     '16 - conflicting local change.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      echo bozbar bozbar >bozbar &&\n      git update-index --add bozbar &&\n@@ -244,7 +245,7 @@ test_expect_success \\\n test_expect_success \\\n     '17 - conflicting local change.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      echo bozbar bozbar >bozbar &&\n      git update-index --add bozbar &&\n@@ -254,7 +255,7 @@ test_expect_success \\\n test_expect_success \\\n     '18 - local change already having a good result.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      cat bozbar-new >bozbar &&\n      git update-index --add bozbar &&\n@@ -266,7 +267,7 @@ test_expect_success \\\n test_expect_success \\\n     '19 - local change already having a good result, further modified.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      cat bozbar-new >bozbar &&\n      git update-index --add bozbar &&\n@@ -279,7 +280,7 @@ test_expect_success \\\n test_expect_success \\\n     '20 - no local change, use new tree.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      cat bozbar-old >bozbar &&\n      git update-index --add bozbar &&\n@@ -291,7 +292,7 @@ test_expect_success \\\n test_expect_success \\\n     '21 - no local change, dirty cache.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      cat bozbar-old >bozbar &&\n      git update-index --add bozbar &&\n@@ -302,7 +303,7 @@ test_expect_success \\\n test_expect_success \\\n     '22 - local change cache updated.' \\\n     'rm -f .git/index &&\n-     git read-tree $treeH &&\n+     read_tree_must_succeed $treeH &&\n      git checkout-index -u -f -q -a &&\n      sed -e \"s/such as/SUCH AS/\" bozbar-old >bozbar &&\n      git update-index --add bozbar &&\n@@ -359,7 +360,7 @@ test_expect_success \\\n\n test_expect_success \\\n     'a/b (untracked) vs a, plus c/d case test.' \\\n-    'test_must_fail git read-tree -u -m \"$treeH\" \"$treeM\" &&\n+    'read_tree_u_must_fail -u -m \"$treeH\" \"$treeM\" &&\n      git ls-files --stage &&\n      test -f a/b'\n\n@@ -386,7 +387,7 @@ test_expect_success \\\n\n test_expect_success \\\n     'a/b vs a, plus c/d case test.' \\\n-    'git read-tree -u -m \"$treeH\" \"$treeM\" &&\n+    'read_tree_u_must_succeed -u -m \"$treeH\" \"$treeM\" &&\n      git ls-files --stage | tee >treeMcheck.out &&\n      test_cmp treeM.out treeMcheck.out'\n\n@@ -401,7 +402,7 @@ test_expect_success '-m references the correct modified tree' '\n \techo a >file-a &&\n \tgit add file-a &&\n \tgit ls-tree $(git write-tree) file-a >expect &&\n-\tgit read-tree -m HEAD initial-mod &&\n+\tread_tree_must_succeed -m HEAD initial-mod &&\n \tgit ls-tree $(git write-tree) file-a >actual &&\n \ttest_cmp expect actual\n '\ndiff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh\nindex a4a17e0..a847709 100755\n--- a/t/t1002-read-tree-m-u-2way.sh\n+++ b/t/t1002-read-tree-m-u-2way.sh\n@@ -9,6 +9,7 @@ This is identical to t1001, but uses -u to update the work tree as well.\n\n '\n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-read-tree.sh\n\n compare_change () {\n \tsed >current \\\n@@ -56,8 +57,8 @@ test_expect_success \\\n test_expect_success \\\n     '1, 2, 3 - no carry forward' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n-     git read-tree -m -u $treeH $treeM &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n+     read_tree_u_must_succeed -m -u $treeH $treeM &&\n      git ls-files --stage >1-3.out &&\n      cmp M.out 1-3.out &&\n      sum bozbar frotz nitfol >actual3.sum &&\n@@ -69,11 +70,11 @@ test_expect_success \\\n test_expect_success \\\n     '4 - carry forward local addition.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo \"+100644 X 0\tyomin\" >expected &&\n      echo yomin >yomin &&\n      git update-index --add yomin &&\n-     git read-tree -m -u $treeH $treeM &&\n+     read_tree_u_must_succeed -m -u $treeH $treeM &&\n      git ls-files --stage >4.out || return 1\n      git diff -U0 --no-index M.out 4.out >4diff.out\n      compare_change 4diff.out expected &&\n@@ -87,12 +88,12 @@ test_expect_success \\\n test_expect_success \\\n     '5 - carry forward local addition.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n-     git read-tree -m -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n+     read_tree_u_must_succeed -m -u $treeH &&\n      echo yomin >yomin &&\n      git update-index --add yomin &&\n      echo yomin yomin >yomin &&\n-     git read-tree -m -u $treeH $treeM &&\n+     read_tree_u_must_succeed -m -u $treeH $treeM &&\n      git ls-files --stage >5.out || return 1\n      git diff -U0 --no-index M.out 5.out >5diff.out\n      compare_change 5diff.out expected &&\n@@ -107,10 +108,10 @@ test_expect_success \\\n test_expect_success \\\n     '6 - local addition already has the same.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo frotz >frotz &&\n      git update-index --add frotz &&\n-     git read-tree -m -u $treeH $treeM &&\n+     read_tree_u_must_succeed -m -u $treeH $treeM &&\n      git ls-files --stage >6.out &&\n      test_cmp M.out 6.out &&\n      check_cache_at frotz clean &&\n@@ -123,11 +124,11 @@ test_expect_success \\\n test_expect_success \\\n     '7 - local addition already has the same.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo frotz >frotz &&\n      git update-index --add frotz &&\n      echo frotz frotz >frotz &&\n-     git read-tree -m -u $treeH $treeM &&\n+     read_tree_u_must_succeed -m -u $treeH $treeM &&\n      git ls-files --stage >7.out &&\n      test_cmp M.out 7.out &&\n      check_cache_at frotz dirty &&\n@@ -141,27 +142,27 @@ test_expect_success \\\n test_expect_success \\\n     '8 - conflicting addition.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo frotz frotz >frotz &&\n      git update-index --add frotz &&\n-     if git read-tree -m -u $treeH $treeM; then false; else :; fi'\n+     if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'\n\n test_expect_success \\\n     '9 - conflicting addition.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo frotz frotz >frotz &&\n      git update-index --add frotz &&\n      echo frotz >frotz &&\n-     if git read-tree -m -u $treeH $treeM; then false; else :; fi'\n+     if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'\n\n test_expect_success \\\n     '10 - path removed.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo rezrov >rezrov &&\n      git update-index --add rezrov &&\n-     git read-tree -m -u $treeH $treeM &&\n+     read_tree_u_must_succeed -m -u $treeH $treeM &&\n      git ls-files --stage >10.out &&\n      cmp M.out 10.out &&\n      sum bozbar frotz nitfol >actual10.sum &&\n@@ -170,28 +171,28 @@ test_expect_success \\\n test_expect_success \\\n     '11 - dirty path removed.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo rezrov >rezrov &&\n      git update-index --add rezrov &&\n      echo rezrov rezrov >rezrov &&\n-     if git read-tree -m -u $treeH $treeM; then false; else :; fi'\n+     if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'\n\n test_expect_success \\\n     '12 - unmatching local changes being removed.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo rezrov rezrov >rezrov &&\n      git update-index --add rezrov &&\n-     if git read-tree -m -u $treeH $treeM; then false; else :; fi'\n+     if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'\n\n test_expect_success \\\n     '13 - unmatching local changes being removed.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo rezrov rezrov >rezrov &&\n      git update-index --add rezrov &&\n      echo rezrov >rezrov &&\n-     if git read-tree -m -u $treeH $treeM; then false; else :; fi'\n+     if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'\n\n cat >expected <<EOF\n -100644 X 0\tnitfol\n@@ -201,10 +202,10 @@ EOF\n test_expect_success \\\n     '14 - unchanged in two heads.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo nitfol nitfol >nitfol &&\n      git update-index --add nitfol &&\n-     git read-tree -m -u $treeH $treeM &&\n+     read_tree_u_must_succeed -m -u $treeH $treeM &&\n      git ls-files --stage >14.out &&\n      test_must_fail git diff -U0 --no-index M.out 14.out >14diff.out &&\n      compare_change 14diff.out expected &&\n@@ -221,11 +222,11 @@ test_expect_success \\\n test_expect_success \\\n     '15 - unchanged in two heads.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo nitfol nitfol >nitfol &&\n      git update-index --add nitfol &&\n      echo nitfol nitfol nitfol >nitfol &&\n-     git read-tree -m -u $treeH $treeM &&\n+     read_tree_u_must_succeed -m -u $treeH $treeM &&\n      git ls-files --stage >15.out &&\n      test_must_fail git diff -U0 --no-index M.out 15.out >15diff.out &&\n      compare_change 15diff.out expected &&\n@@ -242,27 +243,27 @@ test_expect_success \\\n test_expect_success \\\n     '16 - conflicting local change.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo bozbar bozbar >bozbar &&\n      git update-index --add bozbar &&\n-     if git read-tree -m -u $treeH $treeM; then false; else :; fi'\n+     if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'\n\n test_expect_success \\\n     '17 - conflicting local change.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo bozbar bozbar >bozbar &&\n      git update-index --add bozbar &&\n      echo bozbar bozbar bozbar >bozbar &&\n-     if git read-tree -m -u $treeH $treeM; then false; else :; fi'\n+     if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'\n\n test_expect_success \\\n     '18 - local change already having a good result.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo gnusto >bozbar &&\n      git update-index --add bozbar &&\n-     git read-tree -m -u $treeH $treeM &&\n+     read_tree_u_must_succeed -m -u $treeH $treeM &&\n      git ls-files --stage >18.out &&\n      test_cmp M.out 18.out &&\n      check_cache_at bozbar clean &&\n@@ -272,11 +273,11 @@ test_expect_success \\\n test_expect_success \\\n     '19 - local change already having a good result, further modified.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo gnusto >bozbar &&\n      git update-index --add bozbar &&\n      echo gnusto gnusto >bozbar &&\n-     git read-tree -m -u $treeH $treeM &&\n+     read_tree_u_must_succeed -m -u $treeH $treeM &&\n      git ls-files --stage >19.out &&\n      test_cmp M.out 19.out &&\n      check_cache_at bozbar dirty &&\n@@ -292,10 +293,10 @@ test_expect_success \\\n test_expect_success \\\n     '20 - no local change, use new tree.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo bozbar >bozbar &&\n      git update-index --add bozbar &&\n-     git read-tree -m -u $treeH $treeM &&\n+     read_tree_u_must_succeed -m -u $treeH $treeM &&\n      git ls-files --stage >20.out &&\n      test_cmp M.out 20.out &&\n      check_cache_at bozbar clean &&\n@@ -305,11 +306,11 @@ test_expect_success \\\n test_expect_success \\\n     '21 - no local change, dirty cache.' \\\n     'rm -f .git/index nitfol bozbar rezrov frotz &&\n-     git read-tree --reset -u $treeH &&\n+     read_tree_u_must_succeed --reset -u $treeH &&\n      echo bozbar >bozbar &&\n      git update-index --add bozbar &&\n      echo gnusto gnusto >bozbar &&\n-     if git read-tree -m -u $treeH $treeM; then false; else :; fi'\n+     if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'\n\n # Also make sure we did not break DF vs DF/DF case.\n test_expect_success \\\n@@ -336,7 +337,7 @@ test_expect_success \\\n      rm -fr DF &&\n      echo DF >DF &&\n      git update-index --add DF &&\n-     git read-tree -m -u $treeDF $treeDFDF &&\n+     read_tree_u_must_succeed -m -u $treeDF $treeDFDF &&\n      git ls-files --stage >DFDFcheck.out &&\n      test_cmp DFDF.out DFDFcheck.out &&\n      check_cache_at DF/DF clean'\ndiff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh\nindex eb8e3d4..b3ae7d5 100755\n--- a/t/t1004-read-tree-m-u-wf.sh\n+++ b/t/t1004-read-tree-m-u-wf.sh\n@@ -3,6 +3,7 @@\n test_description='read-tree -m -u checks working tree files'\n\n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-read-tree.sh\n\n # two-tree test\n\n@@ -29,7 +30,7 @@ test_expect_success 'two-way not clobbering' '\n\n \techo >file2 master creates untracked file2 &&\n \techo >subdir/file2 master creates untracked subdir/file2 &&\n-\tif err=`git read-tree -m -u master side 2>&1`\n+\tif err=`read_tree_u_must_succeed -m -u master side 2>&1`\n \tthen\n \t\techo should have complained\n \t\tfalse\n@@ -42,7 +43,7 @@ echo file2 >.gitignore\n\n test_expect_success 'two-way with incorrect --exclude-per-directory (1)' '\n\n-\tif err=`git read-tree -m --exclude-per-directory=.gitignore master side 2>&1`\n+\tif err=`read_tree_u_must_succeed -m --exclude-per-directory=.gitignore master side 2>&1`\n \tthen\n \t\techo should have complained\n \t\tfalse\n@@ -53,7 +54,7 @@ test_expect_success 'two-way with incorrect --exclude-per-directory (1)' '\n\n test_expect_success 'two-way with incorrect --exclude-per-directory (2)' '\n\n-\tif err=`git read-tree -m -u --exclude-per-directory=foo --exclude-per-directory=.gitignore master side 2>&1`\n+\tif err=`read_tree_u_must_succeed -m -u --exclude-per-directory=foo --exclude-per-directory=.gitignore master side 2>&1`\n \tthen\n \t\techo should have complained\n \t\tfalse\n@@ -64,7 +65,7 @@ test_expect_success 'two-way with incorrect --exclude-per-directory (2)' '\n\n test_expect_success 'two-way clobbering a ignored file' '\n\n-\tgit read-tree -m -u --exclude-per-directory=.gitignore master side\n+\tread_tree_u_must_succeed -m -u --exclude-per-directory=.gitignore master side\n '\n\n rm -f .gitignore\n@@ -84,7 +85,7 @@ test_expect_success 'three-way not complaining on an untracked path in both' '\n \techo >file2 file two is untracked on the master side &&\n \techo >subdir/file2 file two is untracked on the master side &&\n\n-\tgit read-tree -m -u branch-point master side\n+\tread_tree_u_must_succeed -m -u branch-point master side\n '\n\n test_expect_success 'three-way not clobbering a working tree file' '\n@@ -94,7 +95,7 @@ test_expect_success 'three-way not clobbering a working tree file' '\n \tgit checkout master &&\n \techo >file3 file three created in master, untracked &&\n \techo >subdir/file3 file three created in master, untracked &&\n-\tif err=`git read-tree -m -u branch-point master side 2>&1`\n+\tif err=`read_tree_u_must_succeed -m -u branch-point master side 2>&1`\n \tthen\n \t\techo should have complained\n \t\tfalse\n@@ -113,7 +114,7 @@ test_expect_success 'three-way not complaining on an untracked file' '\n \techo >file3 file three created in master, untracked &&\n \techo >subdir/file3 file three created in master, untracked &&\n\n-\tgit read-tree -m -u --exclude-per-directory=.gitignore branch-point master side\n+\tread_tree_u_must_succeed -m -u --exclude-per-directory=.gitignore branch-point master side\n '\n\n test_expect_success '3-way not overwriting local changes (setup)' '\n@@ -137,7 +138,7 @@ test_expect_success '3-way not overwriting local changes (our side)' '\n \tgit reset --hard &&\n\n \techo >>file1 \"local changes\" &&\n-\tgit read-tree -m -u branch-point side-a side-b &&\n+\tread_tree_u_must_succeed -m -u branch-point side-a side-b &&\n \tgrep \"new line to be kept\" file1 &&\n \tgrep \"local changes\" file1\n\n@@ -151,7 +152,7 @@ test_expect_success '3-way not overwriting local changes (their side)' '\n \tgit reset --hard &&\n\n \techo >>file2 \"local changes\" &&\n-\ttest_must_fail git read-tree -m -u branch-point side-a side-b &&\n+\tread_tree_u_must_fail -m -u branch-point side-a side-b &&\n \t! grep \"new line to be kept\" file2 &&\n \tgrep \"local changes\" file2\n\n@@ -173,7 +174,7 @@ test_expect_success SYMLINKS 'funny symlink in work tree' '\n \tgit add a/b &&\n \tgit commit -m \"we add a/b\" &&\n\n-\tgit read-tree -m -u sym-a sym-a sym-b\n+\tread_tree_u_must_succeed -m -u sym-a sym-a sym-b\n\n '\n\n@@ -209,7 +210,7 @@ test_expect_success 'D/F setup' '\n test_expect_success 'D/F' '\n\n \tgit checkout side-b &&\n-\tgit read-tree -m -u branch-point side-b side-a &&\n+\tread_tree_u_must_succeed -m -u branch-point side-b side-a &&\n \tgit ls-files -u >actual &&\n \t(\n \t\ta=$(git rev-parse branch-point:subdir/file2)\ndiff --git a/t/t1005-read-tree-reset.sh b/t/t1005-read-tree-reset.sh\nindex 8499116..f53de79 100755\n--- a/t/t1005-read-tree-reset.sh\n+++ b/t/t1005-read-tree-reset.sh\n@@ -3,6 +3,7 @@\n test_description='read-tree -u --reset'\n\n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-read-tree.sh\n\n # two-tree test\n\n@@ -22,13 +23,13 @@ test_expect_success 'setup' '\n '\n\n test_expect_success 'reset should work' '\n-  git read-tree -u --reset HEAD^ &&\n+  read_tree_u_must_succeed -u --reset HEAD^ &&\n   git ls-files >actual &&\n   test_cmp expect actual\n '\n\n test_expect_success 'reset should remove remnants from a failed merge' '\n-  git read-tree --reset -u HEAD &&\n+  read_tree_u_must_succeed --reset -u HEAD &&\n   git ls-files -s >expect &&\n   sha1=$(git rev-parse :new) &&\n   (\n@@ -37,13 +38,13 @@ test_expect_success 'reset should remove remnants from a failed merge' '\n   ) | git update-index --index-info &&\n   >old &&\n   git ls-files -s &&\n-  git read-tree --reset -u HEAD &&\n+  read_tree_u_must_succeed --reset -u HEAD &&\n   git ls-files -s >actual &&\n   ! test -f old\n '\n\n test_expect_success 'Porcelain reset should remove remnants too' '\n-  git read-tree --reset -u HEAD &&\n+  read_tree_u_must_succeed --reset -u HEAD &&\n   git ls-files -s >expect &&\n   sha1=$(git rev-parse :new) &&\n   (\n@@ -58,7 +59,7 @@ test_expect_success 'Porcelain reset should remove remnants too' '\n '\n\n test_expect_success 'Porcelain checkout -f should remove remnants too' '\n-  git read-tree --reset -u HEAD &&\n+  read_tree_u_must_succeed --reset -u HEAD &&\n   git ls-files -s >expect &&\n   sha1=$(git rev-parse :new) &&\n   (\n@@ -73,7 +74,7 @@ test_expect_success 'Porcelain checkout -f should remove remnants too' '\n '\n\n test_expect_success 'Porcelain checkout -f HEAD should remove remnants too' '\n-  git read-tree --reset -u HEAD &&\n+  read_tree_u_must_succeed --reset -u HEAD &&\n   git ls-files -s >expect &&\n   sha1=$(git rev-parse :new) &&\n   (\ndiff --git a/t/t1008-read-tree-overlay.sh b/t/t1008-read-tree-overlay.sh\nindex f9e0028..4c50ed9 100755\n--- a/t/t1008-read-tree-overlay.sh\n+++ b/t/t1008-read-tree-overlay.sh\n@@ -3,6 +3,7 @@\n test_description='test multi-tree read-tree without merging'\n\n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-read-tree.sh\n\n test_expect_success setup '\n \techo one >a &&\n@@ -21,7 +22,7 @@ test_expect_success setup '\n '\n\n test_expect_success 'multi-read' '\n-\tgit read-tree initial master side &&\n+\tread_tree_must_succeed initial master side &&\n \t(echo a; echo b/c) >expect &&\n \tgit ls-files >actual &&\n \ttest_cmp expect actual\ndiff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh\nindex 20a50eb..018c354 100755\n--- a/t/t1011-read-tree-sparse-checkout.sh\n+++ b/t/t1011-read-tree-sparse-checkout.sh\n@@ -12,6 +12,7 @@ test_description='sparse checkout tests\n '\n\n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-read-tree.sh\n\n test_expect_success 'setup' '\n \tcat >expected <<-\\EOF &&\n@@ -43,7 +44,7 @@ test_expect_success 'setup' '\n '\n\n test_expect_success 'read-tree without .git/info/sparse-checkout' '\n-\tgit read-tree -m -u HEAD &&\n+\tread_tree_u_must_succeed -m -u HEAD &&\n \tgit ls-files --stage >result &&\n \ttest_cmp expected result &&\n \tgit ls-files -t >result &&\n@@ -52,7 +53,7 @@ test_expect_success 'read-tree without .git/info/sparse-checkout' '\n\n test_expect_success 'read-tree with .git/info/sparse-checkout but disabled' '\n \techo >.git/info/sparse-checkout &&\n-\tgit read-tree -m -u HEAD &&\n+\tread_tree_u_must_succeed -m -u HEAD &&\n \tgit ls-files -t >result &&\n \ttest_cmp expected.swt result &&\n \ttest -f init.t &&\n@@ -62,7 +63,7 @@ test_expect_success 'read-tree with .git/info/sparse-checkout but disabled' '\n test_expect_success 'read-tree --no-sparse-checkout with empty .git/info/sparse-checkout and enabled' '\n \tgit config core.sparsecheckout true &&\n \techo >.git/info/sparse-checkout &&\n-\tgit read-tree --no-sparse-checkout -m -u HEAD &&\n+\tread_tree_u_must_succeed --no-sparse-checkout -m -u HEAD &&\n \tgit ls-files -t >result &&\n \ttest_cmp expected.swt result &&\n \ttest -f init.t &&\n@@ -72,7 +73,7 @@ test_expect_success 'read-tree --no-sparse-checkout with empty .git/info/sparse-\n test_expect_success 'read-tree with empty .git/info/sparse-checkout' '\n \tgit config core.sparsecheckout true &&\n \techo >.git/info/sparse-checkout &&\n-\ttest_must_fail git read-tree -m -u HEAD &&\n+\tread_tree_u_must_fail -m -u HEAD &&\n \tgit ls-files --stage >result &&\n \ttest_cmp expected result &&\n \tgit ls-files -t >result &&\n@@ -90,7 +91,7 @@ test_expect_success 'match directories with trailing slash' '\n \tEOF\n\n \techo sub/ > .git/info/sparse-checkout &&\n-\tgit read-tree -m -u HEAD &&\n+\tread_tree_u_must_succeed -m -u HEAD &&\n \tgit ls-files -t > result &&\n \ttest_cmp expected.swt-noinit result &&\n \ttest ! -f init.t &&\n@@ -99,7 +100,7 @@ test_expect_success 'match directories with trailing slash' '\n\n test_expect_success 'match directories without trailing slash' '\n \techo sub >.git/info/sparse-checkout &&\n-\tgit read-tree -m -u HEAD &&\n+\tread_tree_u_must_succeed -m -u HEAD &&\n \tgit ls-files -t >result &&\n \ttest_cmp expected.swt-noinit result &&\n \ttest ! -f init.t &&\n@@ -149,7 +150,7 @@ EOF\n\n test_expect_success 'match directory pattern' '\n \techo \"s?b\" >.git/info/sparse-checkout &&\n-\tgit read-tree -m -u HEAD &&\n+\tread_tree_u_must_succeed -m -u HEAD &&\n \tgit ls-files -t >result &&\n \ttest_cmp expected.swt-noinit result &&\n \ttest ! -f init.t &&\n@@ -165,7 +166,7 @@ test_expect_success 'checkout area changes' '\n \tEOF\n\n \techo init.t >.git/info/sparse-checkout &&\n-\tgit read-tree -m -u HEAD &&\n+\tread_tree_u_must_succeed -m -u HEAD &&\n \tgit ls-files -t >result &&\n \ttest_cmp expected.swt-nosub result &&\n \ttest -f init.t &&\n@@ -175,7 +176,7 @@ test_expect_success 'checkout area changes' '\n test_expect_success 'read-tree updates worktree, absent case' '\n \techo sub/added >.git/info/sparse-checkout &&\n \tgit checkout -f top &&\n-\tgit read-tree -m -u HEAD^ &&\n+\tread_tree_u_must_succeed -m -u HEAD^ &&\n \ttest ! -f init.t\n '\n\n@@ -183,7 +184,7 @@ test_expect_success 'read-tree updates worktree, dirty case' '\n \techo sub/added >.git/info/sparse-checkout &&\n \tgit checkout -f top &&\n \techo dirty >init.t &&\n-\tgit read-tree -m -u HEAD^ &&\n+\tread_tree_u_must_succeed -m -u HEAD^ &&\n \tgrep -q dirty init.t &&\n \trm init.t\n '\n@@ -192,14 +193,14 @@ test_expect_success 'read-tree removes worktree, dirty case' '\n \techo init.t >.git/info/sparse-checkout &&\n \tgit checkout -f top &&\n \techo dirty >added &&\n-\tgit read-tree -m -u HEAD^ &&\n+\tread_tree_u_must_succeed -m -u HEAD^ &&\n \tgrep -q dirty added\n '\n\n test_expect_success 'read-tree adds to worktree, absent case' '\n \techo init.t >.git/info/sparse-checkout &&\n \tgit checkout -f removed &&\n-\tgit read-tree -u -m HEAD^ &&\n+\tread_tree_u_must_succeed -u -m HEAD^ &&\n \ttest ! -f sub/added\n '\n\n@@ -208,7 +209,7 @@ test_expect_success 'read-tree adds to worktree, dirty case' '\n \tgit checkout -f removed &&\n \tmkdir sub &&\n \techo dirty >sub/added &&\n-\tgit read-tree -u -m HEAD^ &&\n+\tread_tree_u_must_succeed -u -m HEAD^ &&\n \tgrep -q dirty sub/added\n '\n\ndiff --git a/t/t1012-read-tree-df.sh b/t/t1012-read-tree-df.sh\nindex 9811d46..a6a04b6 100755\n--- a/t/t1012-read-tree-df.sh\n+++ b/t/t1012-read-tree-df.sh\n@@ -3,6 +3,7 @@\n test_description='read-tree D/F conflict corner cases'\n\n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-read-tree.sh\n\n maketree () {\n \t(\n@@ -53,7 +54,7 @@ test_expect_success setup '\n\n test_expect_success '3-way (1)' '\n \tsettree A-000 &&\n-\tgit read-tree -m -u O-000 A-000 B-000 &&\n+\tread_tree_u_must_succeed -m -u O-000 A-000 B-000 &&\n \tcheckindex <<-EOF\n \t3 a/b\n \t0 a/b-2/c/d\n@@ -65,7 +66,7 @@ test_expect_success '3-way (1)' '\n\n test_expect_success '3-way (2)' '\n \tsettree A-001 &&\n-\tgit read-tree -m -u O-000 A-001 B-000 &&\n+\tread_tree_u_must_succeed -m -u O-000 A-001 B-000 &&\n \tcheckindex <<-EOF\n \t3 a/b\n \t0 a/b-2/c/d\n@@ -78,7 +79,7 @@ test_expect_success '3-way (2)' '\n\n test_expect_success '3-way (3)' '\n \tsettree A-010 &&\n-\tgit read-tree -m -u O-010 A-010 B-010 &&\n+\tread_tree_u_must_succeed -m -u O-010 A-010 B-010 &&\n \tcheckindex <<-EOF\n \t2 t\n \t1 t-0\n@@ -92,7 +93,7 @@ test_expect_success '3-way (3)' '\n\n test_expect_success '2-way (1)' '\n \tsettree O-020 &&\n-\tgit read-tree -m -u O-020 A-020 &&\n+\tread_tree_u_must_succeed -m -u O-020 A-020 &&\n \tcheckindex <<-EOF\n \t0 ds/dma/ioat/Makefile\n \t0 ds/dma/ioat/registers.h\ndiff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh\nindex ddc3921..f6a44c9 100755\n--- a/t/t1020-subdirectory.sh\n+++ b/t/t1020-subdirectory.sh\n@@ -7,6 +7,7 @@ test_description='Try various core-level commands in subdirectory.\n '\n\n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-read-tree.sh\n\n test_expect_success setup '\n \tlong=\"a b c d e f g h i j k l m n o p q r s t u v w x y z\" &&\n@@ -98,13 +99,13 @@ test_expect_success 'checkout-index' '\n test_expect_success 'read-tree' '\n \trm -f one dir/two &&\n \ttree=`git write-tree` &&\n-\tgit read-tree --reset -u \"$tree\" &&\n+\tread_tree_u_must_succeed --reset -u \"$tree\" &&\n \tcmp one original.one &&\n \tcmp dir/two original.two &&\n \t(\n \t\tcd dir &&\n \t\trm -f two &&\n-\t\tgit read-tree --reset -u \"$tree\" &&\n+\t\tread_tree_u_must_succeed --reset -u \"$tree\" &&\n \t\tcmp two ../original.two &&\n \t\tcmp ../one ../original.one\n \t)\n-- \n1.7.5.2.355.gdceb0\n"},{"id":"168721","messageId":"7vr57m1n0e.fsf@alter.siamese.dyndns.org","threadId":"27444","inReplyTo":"4DDD6197.7060209@web.de","subject":"Re: [PATCH v2 1/2] unpack-trees: add the dry_run flag to unpack_trees_options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-05-25T21:36:01Z","receivedAt":"2011-05-25T21:36:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jens Lehmann <Jens.Lehmann@web.de> writes:\n\n> Until now there was no way to test if unpack_trees() with update=1 would\n> succeed without really updating the work tree. The reason for that is that\n> setting update to 0 does skip the tests for new files and deactivates the\n> sparse handling, thereby making that unsuitable as a dry run.\n>\n> Add the new dry_run flag to struct unpack_trees_options unpack_trees().\n> Setting that together with the update flag will check if the work tree\n> update would be successful without doing it for real.\n>\n> The only class of problems that is not detected at the moment are file\n> system conditions like ENOSPC or missing permissions. Also the index\n> entries of updated files are not as they would be after a real checkout\n> because lstat() isn't run as the files aren't updated for real.\n>\n> Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>\n> ---\n\nLooks good.  remove_marked_cache_entries() does not touch the working\ntree, and because you are not calling unlink_entry(), you won't trigger\nschedule_dir_for_removal() hence remove_scheduled_dirs() won't cause us\nany trouble either.\n\nWill queue.  Thanks.\n"},{"id":"168723","messageId":"7vaaea1kid.fsf@alter.siamese.dyndns.org","threadId":"27444","inReplyTo":"4DDD6241.8070908@web.de","subject":"Re: [PATCH v2 2/2] Teach read-tree the -n|--dry-run option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-05-25T22:30:02Z","receivedAt":"2011-05-25T22:30:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jens Lehmann <Jens.Lehmann@web.de> writes:\n\n> Using this option tells read-tree to not update the index. That makes it\n> possible to check if updating the index would be successful without\n> changing anything. Using this option will silently ignore -u but still\n> test if updating the work tree would succeed.\n\nI'll reword the above to de-stress \"the index\" when I queue this patch, as\nthis is not about the index anymore.  Also I do not think you \"silently\nignore\" the \"-u\" option.  Don't you check what would happen when \"-u\" is\ngiven and checking out the merge result would overwrite the file in the\nworking tree?  In that scenario, \"-u\" actively participates in the dry-run\ncheck you implemented.\n\n> diff --git a/t/lib-read-tree.sh b/t/lib-read-tree.sh\n> new file mode 100644\n> index 0000000..435d19c\n> --- /dev/null\n> +++ b/t/lib-read-tree.sh\n> @@ -0,0 +1,43 @@\n> +#!/bin/sh\n> +#\n> +# Helper functions to check if read-tree would succeed/fail as expected with\n> +# and without the dry-run option. They also test that the dry-run does not\n> +# write the index and that together with -u it doesn't touch the work tree.\n> +#\n> ...\n> +read_tree_u_must_succeed () {\n> +    git ls-files -s >pre-dry-run &&\n> +    git diff-files >pre-dry-run-wt &&\n> +    git read-tree -n \"$@\" &&\n> +    git ls-files -s >post-dry-run &&\n> +    git diff-files >post-dry-run-wt &&\n> +    test_cmp pre-dry-run post-dry-run &&\n> +    test_cmp pre-dry-run-wt post-dry-run-wt &&\n\nAs the RHS of diff-files output that represent the working tree status\nindicates \"contents indeterminate\" with 0{40}, this comparison is the same\nas comparing what is in the index before and after the dry-run.\n\n> ...\n> +read_tree_u_must_fail () {\n> +    git ls-files -s >pre-dry-run &&\n> +    git diff-files >pre-dry-run-wt &&\n> +    test_must_fail git read-tree -n \"$@\" &&\n> +    git ls-files -s >post-dry-run &&\n> +    git diff-files >post-dry-run-wt &&\n> +    test_cmp pre-dry-run post-dry-run &&\n> +    test_cmp pre-dry-run-wt post-dry-run-wt &&\n> +    test_must_fail git read-tree \"$@\"\n> +}\n\nSame here.  A few additions of -p will trivially fix them, though.\n\ndiff --git a/t/lib-read-tree.sh b/t/lib-read-tree.sh\nindex 435d19c..abc2c6f 100644\n--- a/t/lib-read-tree.sh\n+++ b/t/lib-read-tree.sh\n@@ -22,10 +22,10 @@ read_tree_must_fail () {\n \n read_tree_u_must_succeed () {\n     git ls-files -s >pre-dry-run &&\n-    git diff-files >pre-dry-run-wt &&\n+    git diff-files -p >pre-dry-run-wt &&\n     git read-tree -n \"$@\" &&\n     git ls-files -s >post-dry-run &&\n-    git diff-files >post-dry-run-wt &&\n+    git diff-files -p >post-dry-run-wt &&\n     test_cmp pre-dry-run post-dry-run &&\n     test_cmp pre-dry-run-wt post-dry-run-wt &&\n     git read-tree \"$@\"\n@@ -33,10 +33,10 @@ read_tree_u_must_succeed () {\n \n read_tree_u_must_fail () {\n     git ls-files -s >pre-dry-run &&\n-    git diff-files >pre-dry-run-wt &&\n+    git diff-files -p >pre-dry-run-wt &&\n     test_must_fail git read-tree -n \"$@\" &&\n     git ls-files -s >post-dry-run &&\n-    git diff-files >post-dry-run-wt &&\n+    git diff-files -p >post-dry-run-wt &&\n     test_cmp pre-dry-run post-dry-run &&\n     test_cmp pre-dry-run-wt post-dry-run-wt &&\n     test_must_fail git read-tree \"$@\"\n"}]}