{"thread":{"id":"53671","subject":"[PATCH] checkout: teach --worktree","startedAt":"2020-06-13T14:25:30Z","lastAt":"2020-06-24T10:20:20Z","messageCount":9,"participants":["Denton Liu","Eric Sunshine","Junio C Hamano","Phillip Wood"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"399653","messageId":"d10cb03dd8ce00cb6033c61ff9b9b30bbf5f9c89.1592058281.git.liu.denton@gmail.com","threadId":"53671","inReplyTo":null,"subject":"[PATCH] checkout: teach --worktree","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2020-06-13T14:25:12Z","receivedAt":"2020-06-13T14:25:30Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"A complaint that has come up frequently in the past is that it is not\npossible to checkout files directly into a worktree without modifying\nthe index. Even though this could be worked around by redirecting the\noutput of `git show` to overwrite files, this was not feasible if one\nwanted to use patch mode.\n\nSince `git restore` was implemented, this has since been possible using\nthe `--worktree` option. However, some long-time users of Git still\nprefer to use `git checkout` over `git restore` and would like to see\nthe functionality ported over.\n\nTeach `git checkout --worktree`, allowing users to checkout files\ndirectly into the worktree without affecting the index.\n\nSigned-off-by: Denton Liu <liu.denton@gmail.com>\n---\n Documentation/git-checkout.txt | 22 ++++++++++-----\n builtin/checkout.c             | 17 ++++++++++++\n t/t2028-checkout-worktree.sh   | 51 ++++++++++++++++++++++++++++++++++\n t/t9902-completion.sh          |  1 +\n 4 files changed, 84 insertions(+), 7 deletions(-)\n create mode 100755 t/t2028-checkout-worktree.sh\n\ndiff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\nindex 5b697eee1b..ba9c0a900c 100644\n--- a/Documentation/git-checkout.txt\n+++ b/Documentation/git-checkout.txt\n@@ -12,9 +12,9 @@ SYNOPSIS\n 'git checkout' [-q] [-f] [-m] --detach [<branch>]\n 'git checkout' [-q] [-f] [-m] [--detach] <commit>\n 'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]\n-'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>...\n-'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]\n-'git checkout' (-p|--patch) [<tree-ish>] [--] [<pathspec>...]\n+'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [--worktree] [<tree-ish>] [--] <pathspec>...\n+'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [--worktree] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]\n+'git checkout' (-p|--patch) [--worktree] [<tree-ish>] [--] [<pathspec>...]\n \n DESCRIPTION\n -----------\n@@ -79,14 +79,16 @@ be used to detach `HEAD` at the tip of the branch (`git checkout\n +\n Omitting `<branch>` detaches `HEAD` at the tip of the current branch.\n \n-'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>...::\n-'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]::\n+'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [--worktree] [<tree-ish>] [--] <pathspec>...::\n+'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [--worktree] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]::\n \n \tOverwrite the contents of the files that match the pathspec.\n \tWhen the `<tree-ish>` (most often a commit) is not given,\n \toverwrite working tree with the contents in the index.\n \tWhen the `<tree-ish>` is given, overwrite both the index and\n-\tthe working tree with the contents at the `<tree-ish>`.\n+\tthe working tree with the contents at the `<tree-ish>` unless\n+\t`--worktree` is given in which case _only_ the working tree is\n+\toverwritten.\n +\n The index may contain unmerged entries because of a previous failed merge.\n By default, if you try to check out such an entry from the index, the\n@@ -96,7 +98,7 @@ specific side of the merge can be checked out of the index by\n using `--ours` or `--theirs`.  With `-m`, changes made to the working tree\n file can be discarded to re-create the original conflicted merge result.\n \n-'git checkout' (-p|--patch) [<tree-ish>] [--] [<pathspec>...]::\n+'git checkout' (-p|--patch) [--worktree] [<tree-ish>] [--] [<pathspec>...]::\n \tThis is similar to the previous mode, but lets you use the\n \tinteractive interface to show the \"diff\" output and choose which\n \thunks to use in the result.  See below for the description of\n@@ -264,6 +266,12 @@ When switching branches with `--merge`, staged changes may be lost.\n \t\"merge\" (default) and \"diff3\" (in addition to what is shown by\n \t\"merge\" style, shows the original contents).\n \n+-W::\n+--worktree::\n+\tWhen writing contents, only modify files in the worktree. Do not\n+\tmodify the index. This option is essentially a no-op when used\n+\twithout a `<tree-ish>`.\n+\n -p::\n --patch::\n \tInteractively select hunks in the difference between the\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex af849c644f..a2ade85ad5 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -1741,6 +1741,20 @@ static int checkout_main(int argc, const char **argv, const char *prefix,\n \t\treturn checkout_branch(opts, &new_branch_info);\n }\n \n+static int handle_worktree_opt(const struct option *opt, const char *arg, int unset)\n+{\n+\tstruct checkout_opts *opts = opt->value;\n+\n+\tBUG_ON_OPT_NEG(unset);\n+\tBUG_ON_OPT_ARG(arg);\n+\n+\topts->checkout_index = 0;\n+\topts->checkout_worktree = 1;\n+\n+\treturn 0;\n+}\n+\n+\n int cmd_checkout(int argc, const char **argv, const char *prefix)\n {\n \tstruct checkout_opts opts;\n@@ -1750,6 +1764,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t\t\t   N_(\"create and checkout a new branch\")),\n \t\tOPT_STRING('B', NULL, &opts.new_branch_force, N_(\"branch\"),\n \t\t\t   N_(\"create/reset and checkout a branch\")),\n+\t\tOPT_CALLBACK_F('W', \"worktree\", &opts, NULL,\n+\t\t\t   N_(\"restore the working tree (default)\"),\n+\t\t\t   PARSE_OPT_NOARG | PARSE_OPT_NONEG, handle_worktree_opt),\n \t\tOPT_BOOL('l', NULL, &opts.new_branch_log, N_(\"create reflog for new branch\")),\n \t\tOPT_BOOL(0, \"guess\", &opts.dwim_new_local_branch,\n \t\t\t N_(\"second guess 'git checkout <no-such-branch>' (default)\")),\ndiff --git a/t/t2028-checkout-worktree.sh b/t/t2028-checkout-worktree.sh\nnew file mode 100755\nindex 0000000000..7ba36277c9\n--- /dev/null\n+++ b/t/t2028-checkout-worktree.sh\n@@ -0,0 +1,51 @@\n+#!/bin/sh\n+\n+test_description='checkout --worktree'\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\techo first >file1 &&\n+\techo file2 >file2 &&\n+\tgit add file1 file2 &&\n+\tgit commit -m first &&\n+\n+\techo second >file1 &&\n+\tgit commit -am second &&\n+\tgit tag tip\n+'\n+\n+test_expect_success 'checkout --worktree on a commit' '\n+\ttest_when_finished \"git reset --hard tip\" &&\n+\tgit diff HEAD HEAD~ >expect &&\n+\tgit checkout --worktree HEAD~ file1 &&\n+\tgit diff >actual &&\n+\ttest_cmp expect actual &&\n+\tgit diff --cached --exit-code &&\n+\ttest_cmp_rev HEAD tip\n+'\n+\n+test_expect_success 'checkout --worktree with no commit' '\n+\ttest_when_finished \"git reset --hard tip\" &&\n+\techo worktree >file1 &&\n+\tgit checkout --worktree file1 &&\n+\tgit diff --exit-code &&\n+\ttest_cmp_rev HEAD tip\n+'\n+\n+test_expect_success 'checkout --no-worktree fails' '\n+\ttest_must_fail git checkout --no-worktree\n+'\n+\n+test_expect_success PERL 'git checkout -p --worktree' '\n+\ttest_when_finished \"git reset --hard tip\" &&\n+\techo changed >file2 &&\n+\tgit diff -R --src-prefix=b/ --dst-prefix=a/ >expect &&\n+\tgit commit -am file12 &&\n+\ttest_write_lines n y | git checkout --worktree -p HEAD~2 &&\n+\tgit diff >actual &&\n+\ttest_cmp expect actual &&\n+\tgit diff --cached --exit-code\n+'\n+\n+test_done\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 3c44af6940..1db0bb3a31 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1481,6 +1481,7 @@ test_expect_success 'double dash \"git checkout\"' '\n \t--quiet Z\n \t--detach Z\n \t--track Z\n+\t--worktree Z\n \t--orphan=Z\n \t--ours Z\n \t--theirs Z\n-- \n2.27.0.132.g321788e831\n\n"},{"id":"399682","messageId":"CAPig+cQ_G+N=mYqO+=7UaAYft27MhZ2_3v8=QzYpDn5hQySp+A@mail.gmail.com","threadId":"53671","inReplyTo":"d10cb03dd8ce00cb6033c61ff9b9b30bbf5f9c89.1592058281.git.liu.denton@gmail.com","subject":"Re: [PATCH] checkout: teach --worktree","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2020-06-14T02:51:47Z","receivedAt":"2020-06-14T02:52:03Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sat, Jun 13, 2020 at 10:25 AM Denton Liu <liu.denton@gmail.com> wrote:\n> [...]\n> Teach `git checkout --worktree`, allowing users to checkout files\n> directly into the worktree without affecting the index.\n>\n> Signed-off-by: Denton Liu <liu.denton@gmail.com>\n> ---\n> diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\n> @@ -264,6 +266,12 @@ When switching branches with `--merge`, staged changes may be lost.\n> +-W::\n> +--worktree::\n> +       When writing contents, only modify files in the worktree. Do not\n> +       modify the index. This option is essentially a no-op when used\n> +       without a `<tree-ish>`.\n\nWhy a no-op rather than actually diagnosing that --worktree makes no\nsense in that case and erroring out?\n\n> diff --git a/t/t2028-checkout-worktree.sh b/t/t2028-checkout-worktree.sh\n> @@ -0,0 +1,51 @@\n> +test_expect_success 'checkout --worktree on a commit' '\n> +       test_when_finished \"git reset --hard tip\" &&\n> +       git diff HEAD HEAD~ >expect &&\n> +       git checkout --worktree HEAD~ file1 &&\n> +       git diff >actual &&\n> +       test_cmp expect actual &&\n> +       git diff --cached --exit-code &&\n\nWould the intent be clearer if you used 'test_expect_code' here?\n\n    test_expect_code 0 git diff --cached --exit-code &&\n\nSame question for remaining tests.\n"},{"id":"399691","messageId":"20200614074439.GA617439@generichostname","threadId":"53671","inReplyTo":"CAPig+cQ_G+N=mYqO+=7UaAYft27MhZ2_3v8=QzYpDn5hQySp+A@mail.gmail.com","subject":"Re: [PATCH] checkout: teach --worktree","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2020-06-14T07:44:39Z","receivedAt":"2020-06-14T07:44:44Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"Hi Eric,\n\nOn Sat, Jun 13, 2020 at 10:51:47PM -0400, Eric Sunshine wrote:\n> On Sat, Jun 13, 2020 at 10:25 AM Denton Liu <liu.denton@gmail.com> wrote:\n> > [...]\n> > Teach `git checkout --worktree`, allowing users to checkout files\n> > directly into the worktree without affecting the index.\n> >\n> > Signed-off-by: Denton Liu <liu.denton@gmail.com>\n> > ---\n> > diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\n> > @@ -264,6 +266,12 @@ When switching branches with `--merge`, staged changes may be lost.\n> > +-W::\n> > +--worktree::\n> > +       When writing contents, only modify files in the worktree. Do not\n> > +       modify the index. This option is essentially a no-op when used\n> > +       without a `<tree-ish>`.\n> \n> Why a no-op rather than actually diagnosing that --worktree makes no\n> sense in that case and erroring out?\n\nI decided on this behaviour because I assumed that an empty\n`git checkout` has `git restore` behaviour but I guess I was mistaken.\nI'll change it to error out.\n\n> > diff --git a/t/t2028-checkout-worktree.sh b/t/t2028-checkout-worktree.sh\n> > @@ -0,0 +1,51 @@\n> > +test_expect_success 'checkout --worktree on a commit' '\n> > +       test_when_finished \"git reset --hard tip\" &&\n> > +       git diff HEAD HEAD~ >expect &&\n> > +       git checkout --worktree HEAD~ file1 &&\n> > +       git diff >actual &&\n> > +       test_cmp expect actual &&\n> > +       git diff --cached --exit-code &&\n> \n> Would the intent be clearer if you used 'test_expect_code' here?\n> \n>     test_expect_code 0 git diff --cached --exit-code &&\n> \n> Same question for remaining tests.\n\nI'm not really sure that this adds anything. When I read through the\ntests, I already expect each command to be successful, i.e. return 0.\nI don't see how explicitly documenting for this one command would make\nthat more clear.\n\nLooking through the test suite, I only see 15 results of\n`test_expect_code 0 git diff --exit-code` and all of those are in t4035.\nMeanwhile, I see at least 234 instances without the `test_expect_code`.\nI believe that we should leave this as-is.\n\nThanks,\n\nDenton\n"},{"id":"399692","messageId":"20200614080254.GA1202945@generichostname","threadId":"53671","inReplyTo":"20200614074439.GA617439@generichostname","subject":"Re: [PATCH] checkout: teach --worktree","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2020-06-14T08:02:54Z","receivedAt":"2020-06-14T08:03:03Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"On Sun, Jun 14, 2020 at 03:44:39AM -0400, Denton Liu wrote:\n> Hi Eric,\n> \n> On Sat, Jun 13, 2020 at 10:51:47PM -0400, Eric Sunshine wrote:\n> > On Sat, Jun 13, 2020 at 10:25 AM Denton Liu <liu.denton@gmail.com> wrote:\n> > > [...]\n> > > Teach `git checkout --worktree`, allowing users to checkout files\n> > > directly into the worktree without affecting the index.\n> > >\n> > > Signed-off-by: Denton Liu <liu.denton@gmail.com>\n> > > ---\n> > > diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\n> > > @@ -264,6 +266,12 @@ When switching branches with `--merge`, staged changes may be lost.\n> > > +-W::\n> > > +--worktree::\n> > > +       When writing contents, only modify files in the worktree. Do not\n> > > +       modify the index. This option is essentially a no-op when used\n> > > +       without a `<tree-ish>`.\n> > \n> > Why a no-op rather than actually diagnosing that --worktree makes no\n> > sense in that case and erroring out?\n> \n> I decided on this behaviour because I assumed that an empty\n> `git checkout` has `git restore` behaviour but I guess I was mistaken.\n> I'll change it to error out.\n\n...Disregard the above. I misread your comments.\n\nI thought about it some more and I think that the real bug is in how I\nphrased it in the documentation. I meant that --worktree itself was\nessentially no-op, not the whole checkout operation.\n\nI think that it makes sense to allow this behaviour. The documentation\nstates that we only modify files in the worktree. So if we do\n`git checkout --worktree <path>`, we should overwrite the worktree with the\nindex. This should be exactly the same as running `git checkout <path>`.\n\nHowever, one additonal behaviour I should implement is running\n`git checkout --worktree` should behave like running `git checkout .`.\nSo this would make --worktree not a no-op without a tree-ish.\n"},{"id":"399696","messageId":"2a434d328429907a304ad6aaad4c1d9261d27831.1592124367.git.liu.denton@gmail.com","threadId":"53671","inReplyTo":"d10cb03dd8ce00cb6033c61ff9b9b30bbf5f9c89.1592058281.git.liu.denton@gmail.com","subject":"[PATCH v2] checkout: teach --worktree","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2020-06-14T08:49:22Z","receivedAt":"2020-06-14T08:49:33Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"A complaint that has come up frequently in the past is that it is not\npossible to checkout files directly into a worktree without modifying\nthe index. Even though this could be worked around by redirecting the\noutput of `git show` to overwrite files, this was not feasible if one\nwanted to use patch mode.\n\nSince `git restore` was implemented, this has since been possible using\nthe `--worktree` option. However, some long-time users of Git still\nprefer to use `git checkout` over `git restore` and would like to see\nthe functionality ported over.\n\nTeach `git checkout --worktree`, allowing users to checkout files\ndirectly into the worktree without affecting the index.\n\nSigned-off-by: Denton Liu <liu.denton@gmail.com>\n---\nI realised that making `git checkout --worktree` without a pathspec to\ncheck out the current directory doesn't really make sense so I didn't\nmake that change.\n\nRange-diff against v1:\n1:  d10cb03dd8 ! 1:  2a434d3284 checkout: teach --worktree\n    @@ Documentation/git-checkout.txt: When switching branches with `--merge`, staged c\n     +-W::\n     +--worktree::\n     +\tWhen writing contents, only modify files in the worktree. Do not\n    -+\tmodify the index. This option is essentially a no-op when used\n    -+\twithout a `<tree-ish>`.\n    ++\tmodify the index.  This option does not make sense without a\n    ++\t`<pathspec>`.\n     +\n      -p::\n      --patch::\n    @@ builtin/checkout.c: static int checkout_main(int argc, const char **argv, const\n     +\n     +\topts->checkout_index = 0;\n     +\topts->checkout_worktree = 1;\n    ++\topts->empty_pathspec_ok = 0;\n     +\n     +\treturn 0;\n     +}\n    @@ builtin/checkout.c: int cmd_checkout(int argc, const char **argv, const char *pr\n      \t\tOPT_STRING('B', NULL, &opts.new_branch_force, N_(\"branch\"),\n      \t\t\t   N_(\"create/reset and checkout a branch\")),\n     +\t\tOPT_CALLBACK_F('W', \"worktree\", &opts, NULL,\n    -+\t\t\t   N_(\"restore the working tree (default)\"),\n    ++\t\t\t   N_(\"restore the working tree\"),\n     +\t\t\t   PARSE_OPT_NOARG | PARSE_OPT_NONEG, handle_worktree_opt),\n      \t\tOPT_BOOL('l', NULL, &opts.new_branch_log, N_(\"create reflog for new branch\")),\n      \t\tOPT_BOOL(0, \"guess\", &opts.dwim_new_local_branch,\n    @@ t/t2028-checkout-worktree.sh (new)\n     +\ttest_cmp_rev HEAD tip\n     +'\n     +\n    ++test_expect_success 'checkout --worktree without pathspec fails' '\n    ++\ttest_must_fail git checkout --worktree\n    ++'\n    ++\n     +test_expect_success 'checkout --no-worktree fails' '\n     +\ttest_must_fail git checkout --no-worktree\n     +'\n\n Documentation/git-checkout.txt | 22 +++++++++-----\n builtin/checkout.c             | 18 +++++++++++\n t/t2028-checkout-worktree.sh   | 55 ++++++++++++++++++++++++++++++++++\n t/t9902-completion.sh          |  1 +\n 4 files changed, 89 insertions(+), 7 deletions(-)\n create mode 100755 t/t2028-checkout-worktree.sh\n\ndiff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\nindex 5b697eee1b..c303839920 100644\n--- a/Documentation/git-checkout.txt\n+++ b/Documentation/git-checkout.txt\n@@ -12,9 +12,9 @@ SYNOPSIS\n 'git checkout' [-q] [-f] [-m] --detach [<branch>]\n 'git checkout' [-q] [-f] [-m] [--detach] <commit>\n 'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]\n-'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>...\n-'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]\n-'git checkout' (-p|--patch) [<tree-ish>] [--] [<pathspec>...]\n+'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [--worktree] [<tree-ish>] [--] <pathspec>...\n+'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [--worktree] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]\n+'git checkout' (-p|--patch) [--worktree] [<tree-ish>] [--] [<pathspec>...]\n \n DESCRIPTION\n -----------\n@@ -79,14 +79,16 @@ be used to detach `HEAD` at the tip of the branch (`git checkout\n +\n Omitting `<branch>` detaches `HEAD` at the tip of the current branch.\n \n-'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>...::\n-'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]::\n+'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [--worktree] [<tree-ish>] [--] <pathspec>...::\n+'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [--worktree] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]::\n \n \tOverwrite the contents of the files that match the pathspec.\n \tWhen the `<tree-ish>` (most often a commit) is not given,\n \toverwrite working tree with the contents in the index.\n \tWhen the `<tree-ish>` is given, overwrite both the index and\n-\tthe working tree with the contents at the `<tree-ish>`.\n+\tthe working tree with the contents at the `<tree-ish>` unless\n+\t`--worktree` is given in which case _only_ the working tree is\n+\toverwritten.\n +\n The index may contain unmerged entries because of a previous failed merge.\n By default, if you try to check out such an entry from the index, the\n@@ -96,7 +98,7 @@ specific side of the merge can be checked out of the index by\n using `--ours` or `--theirs`.  With `-m`, changes made to the working tree\n file can be discarded to re-create the original conflicted merge result.\n \n-'git checkout' (-p|--patch) [<tree-ish>] [--] [<pathspec>...]::\n+'git checkout' (-p|--patch) [--worktree] [<tree-ish>] [--] [<pathspec>...]::\n \tThis is similar to the previous mode, but lets you use the\n \tinteractive interface to show the \"diff\" output and choose which\n \thunks to use in the result.  See below for the description of\n@@ -264,6 +266,12 @@ When switching branches with `--merge`, staged changes may be lost.\n \t\"merge\" (default) and \"diff3\" (in addition to what is shown by\n \t\"merge\" style, shows the original contents).\n \n+-W::\n+--worktree::\n+\tWhen writing contents, only modify files in the worktree. Do not\n+\tmodify the index.  This option does not make sense without a\n+\t`<pathspec>`.\n+\n -p::\n --patch::\n \tInteractively select hunks in the difference between the\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex af849c644f..8c533a305b 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -1741,6 +1741,21 @@ static int checkout_main(int argc, const char **argv, const char *prefix,\n \t\treturn checkout_branch(opts, &new_branch_info);\n }\n \n+static int handle_worktree_opt(const struct option *opt, const char *arg, int unset)\n+{\n+\tstruct checkout_opts *opts = opt->value;\n+\n+\tBUG_ON_OPT_NEG(unset);\n+\tBUG_ON_OPT_ARG(arg);\n+\n+\topts->checkout_index = 0;\n+\topts->checkout_worktree = 1;\n+\topts->empty_pathspec_ok = 0;\n+\n+\treturn 0;\n+}\n+\n+\n int cmd_checkout(int argc, const char **argv, const char *prefix)\n {\n \tstruct checkout_opts opts;\n@@ -1750,6 +1765,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t\t\t   N_(\"create and checkout a new branch\")),\n \t\tOPT_STRING('B', NULL, &opts.new_branch_force, N_(\"branch\"),\n \t\t\t   N_(\"create/reset and checkout a branch\")),\n+\t\tOPT_CALLBACK_F('W', \"worktree\", &opts, NULL,\n+\t\t\t   N_(\"restore the working tree\"),\n+\t\t\t   PARSE_OPT_NOARG | PARSE_OPT_NONEG, handle_worktree_opt),\n \t\tOPT_BOOL('l', NULL, &opts.new_branch_log, N_(\"create reflog for new branch\")),\n \t\tOPT_BOOL(0, \"guess\", &opts.dwim_new_local_branch,\n \t\t\t N_(\"second guess 'git checkout <no-such-branch>' (default)\")),\ndiff --git a/t/t2028-checkout-worktree.sh b/t/t2028-checkout-worktree.sh\nnew file mode 100755\nindex 0000000000..b5b5e287c1\n--- /dev/null\n+++ b/t/t2028-checkout-worktree.sh\n@@ -0,0 +1,55 @@\n+#!/bin/sh\n+\n+test_description='checkout --worktree'\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\techo first >file1 &&\n+\techo file2 >file2 &&\n+\tgit add file1 file2 &&\n+\tgit commit -m first &&\n+\n+\techo second >file1 &&\n+\tgit commit -am second &&\n+\tgit tag tip\n+'\n+\n+test_expect_success 'checkout --worktree on a commit' '\n+\ttest_when_finished \"git reset --hard tip\" &&\n+\tgit diff HEAD HEAD~ >expect &&\n+\tgit checkout --worktree HEAD~ file1 &&\n+\tgit diff >actual &&\n+\ttest_cmp expect actual &&\n+\tgit diff --cached --exit-code &&\n+\ttest_cmp_rev HEAD tip\n+'\n+\n+test_expect_success 'checkout --worktree with no commit' '\n+\ttest_when_finished \"git reset --hard tip\" &&\n+\techo worktree >file1 &&\n+\tgit checkout --worktree file1 &&\n+\tgit diff --exit-code &&\n+\ttest_cmp_rev HEAD tip\n+'\n+\n+test_expect_success 'checkout --worktree without pathspec fails' '\n+\ttest_must_fail git checkout --worktree\n+'\n+\n+test_expect_success 'checkout --no-worktree fails' '\n+\ttest_must_fail git checkout --no-worktree\n+'\n+\n+test_expect_success PERL 'git checkout -p --worktree' '\n+\ttest_when_finished \"git reset --hard tip\" &&\n+\techo changed >file2 &&\n+\tgit diff -R --src-prefix=b/ --dst-prefix=a/ >expect &&\n+\tgit commit -am file12 &&\n+\ttest_write_lines n y | git checkout --worktree -p HEAD~2 &&\n+\tgit diff >actual &&\n+\ttest_cmp expect actual &&\n+\tgit diff --cached --exit-code\n+'\n+\n+test_done\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 3c44af6940..1db0bb3a31 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1481,6 +1481,7 @@ test_expect_success 'double dash \"git checkout\"' '\n \t--quiet Z\n \t--detach Z\n \t--track Z\n+\t--worktree Z\n \t--orphan=Z\n \t--ours Z\n \t--theirs Z\n-- \n2.27.0.132.g321788e831\n\n"},{"id":"399732","messageId":"xmqqa715xrb0.fsf@gitster.c.googlers.com","threadId":"53671","inReplyTo":"CAPig+cQ_G+N=mYqO+=7UaAYft27MhZ2_3v8=QzYpDn5hQySp+A@mail.gmail.com","subject":"Re: [PATCH] checkout: teach --worktree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-06-14T21:37:07Z","receivedAt":"2020-06-14T21:37:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n>> +       When writing contents, only modify files in the worktree. Do not\n>> +       modify the index. This option is essentially a no-op when used\n>> +       without a `<tree-ish>`.\n>\n> Why a no-op rather than actually diagnosing that --worktree makes no\n> sense in that case and erroring out?\n\nShould it be a no-op?  If checking paths out of the index, with or\nwithout the new --worktree option, the files in the working tree\nwill be affected and the contents in the index won't change.\n\n"},{"id":"399894","messageId":"3c223d33-7f3f-7f4c-df91-3b72271308cd@gmail.com","threadId":"53671","inReplyTo":"2a434d328429907a304ad6aaad4c1d9261d27831.1592124367.git.liu.denton@gmail.com","subject":"Re: [PATCH v2] checkout: teach --worktree","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2020-06-16T16:01:53Z","receivedAt":"2020-06-16T16:02:01Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Denton\n\nOn 14/06/2020 09:49, Denton Liu wrote:\n> A complaint that has come up frequently in the past is that it is not\n> possible to checkout files directly into a worktree without modifying\n> the index. Even though this could be worked around by redirecting the\n> output of `git show` to overwrite files, this was not feasible if one\n> wanted to use patch mode.\n> \n> Since `git restore` was implemented, this has since been possible using\n> the `--worktree` option. However, some long-time users of Git still\n> prefer to use `git checkout` over `git restore` and would like to see\n> the functionality ported over.\n> \n> Teach `git checkout --worktree`, allowing users to checkout files\n> directly into the worktree without affecting the index.\n\nI'm afraid I'm not sure that adding another option to `git checkout` is \na good idea. The behavior of `git checkout` is already complicated \nenough which is why we ended up with switch and restore separating out \nbranch switching from file updating.\n\nGiven `git restore` provides a way to update the worktree without \ntouching the index I'm not convinced we should be further complicating \n`git checkout` especially as it defaults to --overlay unless -p is given \nwhich is confusing in itself.\n\nBest Wishes\n\nPhillip\n\n> Signed-off-by: Denton Liu <liu.denton@gmail.com>\n> ---\n> I realised that making `git checkout --worktree` without a pathspec to\n> check out the current directory doesn't really make sense so I didn't\n> make that change.\n> \n> Range-diff against v1:\n> 1:  d10cb03dd8 ! 1:  2a434d3284 checkout: teach --worktree\n>      @@ Documentation/git-checkout.txt: When switching branches with `--merge`, staged c\n>       +-W::\n>       +--worktree::\n>       +\tWhen writing contents, only modify files in the worktree. Do not\n>      -+\tmodify the index. This option is essentially a no-op when used\n>      -+\twithout a `<tree-ish>`.\n>      ++\tmodify the index.  This option does not make sense without a\n>      ++\t`<pathspec>`.\n>       +\n>        -p::\n>        --patch::\n>      @@ builtin/checkout.c: static int checkout_main(int argc, const char **argv, const\n>       +\n>       +\topts->checkout_index = 0;\n>       +\topts->checkout_worktree = 1;\n>      ++\topts->empty_pathspec_ok = 0;\n>       +\n>       +\treturn 0;\n>       +}\n>      @@ builtin/checkout.c: int cmd_checkout(int argc, const char **argv, const char *pr\n>        \t\tOPT_STRING('B', NULL, &opts.new_branch_force, N_(\"branch\"),\n>        \t\t\t   N_(\"create/reset and checkout a branch\")),\n>       +\t\tOPT_CALLBACK_F('W', \"worktree\", &opts, NULL,\n>      -+\t\t\t   N_(\"restore the working tree (default)\"),\n>      ++\t\t\t   N_(\"restore the working tree\"),\n>       +\t\t\t   PARSE_OPT_NOARG | PARSE_OPT_NONEG, handle_worktree_opt),\n>        \t\tOPT_BOOL('l', NULL, &opts.new_branch_log, N_(\"create reflog for new branch\")),\n>        \t\tOPT_BOOL(0, \"guess\", &opts.dwim_new_local_branch,\n>      @@ t/t2028-checkout-worktree.sh (new)\n>       +\ttest_cmp_rev HEAD tip\n>       +'\n>       +\n>      ++test_expect_success 'checkout --worktree without pathspec fails' '\n>      ++\ttest_must_fail git checkout --worktree\n>      ++'\n>      ++\n>       +test_expect_success 'checkout --no-worktree fails' '\n>       +\ttest_must_fail git checkout --no-worktree\n>       +'\n> \n>   Documentation/git-checkout.txt | 22 +++++++++-----\n>   builtin/checkout.c             | 18 +++++++++++\n>   t/t2028-checkout-worktree.sh   | 55 ++++++++++++++++++++++++++++++++++\n>   t/t9902-completion.sh          |  1 +\n>   4 files changed, 89 insertions(+), 7 deletions(-)\n>   create mode 100755 t/t2028-checkout-worktree.sh\n> \n> diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\n> index 5b697eee1b..c303839920 100644\n> --- a/Documentation/git-checkout.txt\n> +++ b/Documentation/git-checkout.txt\n> @@ -12,9 +12,9 @@ SYNOPSIS\n>   'git checkout' [-q] [-f] [-m] --detach [<branch>]\n>   'git checkout' [-q] [-f] [-m] [--detach] <commit>\n>   'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]\n> -'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>...\n> -'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]\n> -'git checkout' (-p|--patch) [<tree-ish>] [--] [<pathspec>...]\n> +'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [--worktree] [<tree-ish>] [--] <pathspec>...\n> +'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [--worktree] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]\n> +'git checkout' (-p|--patch) [--worktree] [<tree-ish>] [--] [<pathspec>...]\n>   \n>   DESCRIPTION\n>   -----------\n> @@ -79,14 +79,16 @@ be used to detach `HEAD` at the tip of the branch (`git checkout\n>   +\n>   Omitting `<branch>` detaches `HEAD` at the tip of the current branch.\n>   \n> -'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>...::\n> -'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]::\n> +'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [--worktree] [<tree-ish>] [--] <pathspec>...::\n> +'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [--worktree] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]::\n>   \n>   \tOverwrite the contents of the files that match the pathspec.\n>   \tWhen the `<tree-ish>` (most often a commit) is not given,\n>   \toverwrite working tree with the contents in the index.\n>   \tWhen the `<tree-ish>` is given, overwrite both the index and\n> -\tthe working tree with the contents at the `<tree-ish>`.\n> +\tthe working tree with the contents at the `<tree-ish>` unless\n> +\t`--worktree` is given in which case _only_ the working tree is\n> +\toverwritten.\n>   +\n>   The index may contain unmerged entries because of a previous failed merge.\n>   By default, if you try to check out such an entry from the index, the\n> @@ -96,7 +98,7 @@ specific side of the merge can be checked out of the index by\n>   using `--ours` or `--theirs`.  With `-m`, changes made to the working tree\n>   file can be discarded to re-create the original conflicted merge result.\n>   \n> -'git checkout' (-p|--patch) [<tree-ish>] [--] [<pathspec>...]::\n> +'git checkout' (-p|--patch) [--worktree] [<tree-ish>] [--] [<pathspec>...]::\n>   \tThis is similar to the previous mode, but lets you use the\n>   \tinteractive interface to show the \"diff\" output and choose which\n>   \thunks to use in the result.  See below for the description of\n> @@ -264,6 +266,12 @@ When switching branches with `--merge`, staged changes may be lost.\n>   \t\"merge\" (default) and \"diff3\" (in addition to what is shown by\n>   \t\"merge\" style, shows the original contents).\n>   \n> +-W::\n> +--worktree::\n> +\tWhen writing contents, only modify files in the worktree. Do not\n> +\tmodify the index.  This option does not make sense without a\n> +\t`<pathspec>`.\n> +\n>   -p::\n>   --patch::\n>   \tInteractively select hunks in the difference between the\n> diff --git a/builtin/checkout.c b/builtin/checkout.c\n> index af849c644f..8c533a305b 100644\n> --- a/builtin/checkout.c\n> +++ b/builtin/checkout.c\n> @@ -1741,6 +1741,21 @@ static int checkout_main(int argc, const char **argv, const char *prefix,\n>   \t\treturn checkout_branch(opts, &new_branch_info);\n>   }\n>   \n> +static int handle_worktree_opt(const struct option *opt, const char *arg, int unset)\n> +{\n> +\tstruct checkout_opts *opts = opt->value;\n> +\n> +\tBUG_ON_OPT_NEG(unset);\n> +\tBUG_ON_OPT_ARG(arg);\n> +\n> +\topts->checkout_index = 0;\n> +\topts->checkout_worktree = 1;\n> +\topts->empty_pathspec_ok = 0;\n> +\n> +\treturn 0;\n> +}\n> +\n> +\n>   int cmd_checkout(int argc, const char **argv, const char *prefix)\n>   {\n>   \tstruct checkout_opts opts;\n> @@ -1750,6 +1765,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n>   \t\t\t   N_(\"create and checkout a new branch\")),\n>   \t\tOPT_STRING('B', NULL, &opts.new_branch_force, N_(\"branch\"),\n>   \t\t\t   N_(\"create/reset and checkout a branch\")),\n> +\t\tOPT_CALLBACK_F('W', \"worktree\", &opts, NULL,\n> +\t\t\t   N_(\"restore the working tree\"),\n> +\t\t\t   PARSE_OPT_NOARG | PARSE_OPT_NONEG, handle_worktree_opt),\n>   \t\tOPT_BOOL('l', NULL, &opts.new_branch_log, N_(\"create reflog for new branch\")),\n>   \t\tOPT_BOOL(0, \"guess\", &opts.dwim_new_local_branch,\n>   \t\t\t N_(\"second guess 'git checkout <no-such-branch>' (default)\")),\n> diff --git a/t/t2028-checkout-worktree.sh b/t/t2028-checkout-worktree.sh\n> new file mode 100755\n> index 0000000000..b5b5e287c1\n> --- /dev/null\n> +++ b/t/t2028-checkout-worktree.sh\n> @@ -0,0 +1,55 @@\n> +#!/bin/sh\n> +\n> +test_description='checkout --worktree'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success setup '\n> +\techo first >file1 &&\n> +\techo file2 >file2 &&\n> +\tgit add file1 file2 &&\n> +\tgit commit -m first &&\n> +\n> +\techo second >file1 &&\n> +\tgit commit -am second &&\n> +\tgit tag tip\n> +'\n> +\n> +test_expect_success 'checkout --worktree on a commit' '\n> +\ttest_when_finished \"git reset --hard tip\" &&\n> +\tgit diff HEAD HEAD~ >expect &&\n> +\tgit checkout --worktree HEAD~ file1 &&\n> +\tgit diff >actual &&\n> +\ttest_cmp expect actual &&\n> +\tgit diff --cached --exit-code &&\n> +\ttest_cmp_rev HEAD tip\n> +'\n> +\n> +test_expect_success 'checkout --worktree with no commit' '\n> +\ttest_when_finished \"git reset --hard tip\" &&\n> +\techo worktree >file1 &&\n> +\tgit checkout --worktree file1 &&\n> +\tgit diff --exit-code &&\n> +\ttest_cmp_rev HEAD tip\n> +'\n> +\n> +test_expect_success 'checkout --worktree without pathspec fails' '\n> +\ttest_must_fail git checkout --worktree\n> +'\n> +\n> +test_expect_success 'checkout --no-worktree fails' '\n> +\ttest_must_fail git checkout --no-worktree\n> +'\n> +\n> +test_expect_success PERL 'git checkout -p --worktree' '\n> +\ttest_when_finished \"git reset --hard tip\" &&\n> +\techo changed >file2 &&\n> +\tgit diff -R --src-prefix=b/ --dst-prefix=a/ >expect &&\n> +\tgit commit -am file12 &&\n> +\ttest_write_lines n y | git checkout --worktree -p HEAD~2 &&\n> +\tgit diff >actual &&\n> +\ttest_cmp expect actual &&\n> +\tgit diff --cached --exit-code\n> +'\n> +\n> +test_done\n> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n> index 3c44af6940..1db0bb3a31 100755\n> --- a/t/t9902-completion.sh\n> +++ b/t/t9902-completion.sh\n> @@ -1481,6 +1481,7 @@ test_expect_success 'double dash \"git checkout\"' '\n>   \t--quiet Z\n>   \t--detach Z\n>   \t--track Z\n> +\t--worktree Z\n>   \t--orphan=Z\n>   \t--ours Z\n>   \t--theirs Z\n> \n"},{"id":"400390","messageId":"20200623155538.GA2014954@generichostname","threadId":"53671","inReplyTo":"3c223d33-7f3f-7f4c-df91-3b72271308cd@gmail.com","subject":"Re: [PATCH v2] checkout: teach --worktree","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2020-06-23T15:55:38Z","receivedAt":"2020-06-23T15:55:44Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"Hi Phillip,\n\nSorry for the late reply.\n\nOn Tue, Jun 16, 2020 at 05:01:53PM +0100, Phillip Wood wrote:\n> I'm afraid I'm not sure that adding another option to `git checkout` is a\n> good idea. The behavior of `git checkout` is already complicated enough\n> which is why we ended up with switch and restore separating out branch\n> switching from file updating.\n\nI think that since this option clearly applies only for a\nrestore-type action and there are checks in place to ensure that\nthe user is not attempting to use it for a switch-type action, it\ndoesn't introduce much more complexity than the `git restore --worktree`\noption does.\n\n> Given `git restore` provides a way to update the worktree without touching\n> the index I'm not convinced we should be further complicating `git checkout`\n> especially as it defaults to --overlay unless -p is given which is confusing\n> in itself.\n\nI don't think it'll hurt to provide more than one way of doing it. As a\npretty long-time user of git, I've been having trouble picking up the\nswitch/restore commands in favour of good ol' checkout due to muscle\nmemory. I agree that I should try and switch over to these new commands\nbut old habits die hard and I think it would be much easier to just\nprovide this option to checkout.\n\nThanks,\n\nDenton\n"},{"id":"400492","messageId":"dd17f82a-f5b3-d57e-d296-c1b5ecc8c1f5@gmail.com","threadId":"53671","inReplyTo":"20200623155538.GA2014954@generichostname","subject":"Re: [PATCH v2] checkout: teach --worktree","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2020-06-24T10:20:06Z","receivedAt":"2020-06-24T10:20:20Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Denton\n\nOn 23/06/2020 16:55, Denton Liu wrote:\n> Hi Phillip,\n> \n> Sorry for the late reply.\n> \n> On Tue, Jun 16, 2020 at 05:01:53PM +0100, Phillip Wood wrote:\n>> I'm afraid I'm not sure that adding another option to `git checkout` is a\n>> good idea. The behavior of `git checkout` is already complicated enough\n>> which is why we ended up with switch and restore separating out branch\n>> switching from file updating.\n> \n> I think that since this option clearly applies only for a\n> restore-type action and there are checks in place to ensure that\n> the user is not attempting to use it for a switch-type action, it\n> doesn't introduce much more complexity than the `git restore --worktree`\n> option does.\n\nIt introduces more complexity to checkout by existing. The point I was\ntrying to make was that checkout is complicated to use and adding more\nfeatures makes that problem worse. As to being obvious that it applies\nto a restore-type action, when I first saw the patch subject line my\nimmediate thought was that it was going to be doing something with\nworktrees.\n\nI am worried that people will think 'checkout --worktree' is the same as\n'restore --worktree' but it isn't it's the same as 'restore --overlay\n--worktree'. Having subtle differences like this between commands is\nconfusing for users and wastes our time answering queries about the\ndifference on the mailing list. It is not possible to make 'checkout\n--worktree' imply --no-overlay as that would be inconsistent with\n'checkout <pathspec>'\n\n> \n>> Given `git restore` provides a way to update the worktree without touching\n>> the index I'm not convinced we should be further complicating `git checkout`\n>> especially as it defaults to --overlay unless -p is given which is confusing\n>> in itself.\n> \n> I don't think it'll hurt to provide more than one way of doing it.\n\nI disagree, it is confusing to users if they see one person saying \"use\ncheckout\" and another \"use restore\". They will wonder if there is a\ndifference between them and which one is better. It's to be expected\nthat there will be some overlap in functionality between commands as git\ngrows and adds new commands but in this case we're adding functionality\nthat already exists. There was a lot of thought and discussion put into\ndesigning and implementing 'switch' and 'restore' to make more\npredictable and easier for users to understand, adding more options to\n'checkout' under cuts that by muddying the waters on which command\nshould be used.\n\n> As a\n> pretty long-time user of git, I've been having trouble picking up the\n> switch/restore commands in favour of good ol' checkout due to muscle\n> memory. I agree that I should try and switch over to these new commands\n> but old habits die hard and I think it would be much easier to just\n> provide this option to checkout.\n\nWhile I have sympathy with that (I still use checkout myself a lot of\nthe time) it's hard to argue you have a muscle memory for an option that\ndoes not exist!\n\nBest Wishes\n\nPhillip\n\n> Thanks,\n> \n> Denton\n> \n\n"}]}