{"thread":{"id":"39777","subject":"[PATCH v2 01/23] Documentation/git-checkout: fix incorrect worktree prune command","startedAt":"2015-07-04T00:17:09Z","lastAt":"2015-07-06T19:14:54Z","messageCount":38,"participants":["Eric Sunshine","Duy Nguyen","Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":23},"messages":[{"id":"265483","messageId":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":null,"subject":"[PATCH v2 00/23] replace \"checkout --to\" with \"worktree add\"","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:09Z","receivedAt":"2015-07-04T00:17:09Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"This is v2 of the series to replace \"git checkout --to\" with \"git\nworktree add\". It's built atop Duy's df0b6cf (worktree: new place for\n\"git prune --worktrees\", 2015-06-29) which introduces the git-worktree\ncommand and replaces \"git prune --worktrees\" with \"git worktree prune\".\n\nAlthough v1[*1*] consisted of only 1 patch, v2 is just a wee bit\nlonger at 23 patches. Sorry for the length. Fortunately, most patches\nare quite small, thus (hopefully) easy to review.\n\nv2 goes a bit beyond v1 by implementing Duy's suggestion[*2*] of\nallowing <branch> in \"git worktree add <path> <branch>\" to be omitted,\nin which case, as a convenience, it auto-vivifies a new branch named\nafter <path>, as if it had been invoked as \"git worktree add -b\n$(basename <path>) <path> HEAD\". Moreover, unlike \"git checkout -b\n<newbranch> --to <path> <branch>\", the <branch> in \"git worktree add -b\n<newbranch> <path> <branch>\" is also optional, and defaults to HEAD.\n\nv2 does not attempt either of the suggestions by Junio[*3*] or Duy[*4*]\nfor eliminating git-checkout from the equation, which would allow us to\nremove the final couple bits of code in git-checkout which require\nintimate knowledge that the checkout is occurring in a newly created\nlinked worktree. This series is already too long, and I didn't want it\nto grow further by implementing either of those ideas. Instead, this\nseries leaves git-worktree at a state where one or the other of those\nsuggestions can be done as follow-on patches touching only the\nunderlying machinery, without affecting the user-facing interface.\n\n[*1*]: http://thread.gmane.org/gmane.comp.version-control.git/273032\n[*2*]: http://thread.gmane.org/gmane.comp.version-control.git/273032/focus=273035\n[*3*]: via private email which suggested using \"git-reset --hard\" rather\n       than \"git checkout\" to populate the new linked worktree.\n[*4*]: http://thread.gmane.org/gmane.comp.version-control.git/273032/focus=273226\n\nEric Sunshine (23):\n  Documentation/git-checkout: fix incorrect worktree prune command\n  Documentation/git-worktree: associate options with commands\n  Documentation: move linked worktree description from checkout to\n    worktree\n  Documentation/git-worktree: add BUGS section\n  Documentation/git-worktree: split technical info from general\n    description\n  Documentation/git-worktree: add high-level 'lock' overview\n  Documentation/git-worktree: add EXAMPLES section\n  checkout: fix bug with --to and relative HEAD\n  checkout: relocate --to's \"no branch specified\" check\n  checkout: prepare_linked_checkout: drop now-unused 'new' argument\n  checkout: make --to unconditionally verbose\n  checkout: drop 'checkout_opts' dependency from prepare_linked_checkout\n  worktree: introduce \"add\" command\n  worktree: add --force option\n  worktree: add --detach option\n  worktree: add -b/-B options\n  tests: worktree: retrofit \"checkout --to\" tests for \"worktree add\"\n  checkout: retire --to option\n  checkout: require worktree unconditionally\n  worktree: extract basename computation to new function\n  worktree: add: make -b/-B default to HEAD when <branch> is omitted\n  worktree: add: auto-vivify new branch when <branch> is omitted\n  checkout: retire --ignore-other-worktrees in favor of --force\n\n Documentation/git-checkout.txt                    |  78 +--------\n Documentation/git-worktree.txt                    | 141 +++++++++++++++-\n builtin/checkout.c                                | 161 +-----------------\n builtin/worktree.c                                | 193 ++++++++++++++++++++++\n git.c                                             |   2 +-\n t/{t2025-checkout-to.sh => t2025-worktree-add.sh} |  68 +++++---\n t/t2026-prune-linked-checkouts.sh                 |   2 +-\n t/t7410-submodule-checkout-to.sh                  |   4 +-\n 8 files changed, 383 insertions(+), 266 deletions(-)\n rename t/{t2025-checkout-to.sh => t2025-worktree-add.sh} (51%)\n\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265481","messageId":"1435969052-540-2-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 01/23] Documentation/git-checkout: fix incorrect worktree prune command","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:10Z","receivedAt":"2015-07-04T00:17:10Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"This was missed when \"git prune --worktrees\" became \"git worktree prune\".\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n Documentation/git-checkout.txt | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\nindex 72def5b..ce223e6 100644\n--- a/Documentation/git-checkout.txt\n+++ b/Documentation/git-checkout.txt\n@@ -444,7 +444,7 @@ When you are done with a linked working tree you can simply delete it.\n The working tree's entry in the repository's $GIT_DIR/worktrees\n directory will eventually be removed automatically (see\n `gc.pruneworktreesexpire` in linkgit::git-config[1]), or you can run\n-`git prune --worktrees` in the main or any linked working tree to\n+`git worktree prune` in the main or any linked working tree to\n clean up any stale entries in $GIT_DIR/worktrees.\n \n If you move a linked working directory to another file system, or\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265484","messageId":"1435969052-540-3-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 02/23] Documentation/git-worktree: associate options with commands","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:11Z","receivedAt":"2015-07-04T00:17:11Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"git-worktree options affect some worktree commands but not others, but\nthis is not necessarily obvious from the option descriptions. Make this\nclear by indicating explicitly which commands are affected by which\noptions.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n Documentation/git-worktree.txt | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 41103e5..1ac1217 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -28,15 +28,15 @@ OPTIONS\n \n -n::\n --dry-run::\n-\tDo not remove anything; just report what it would\n+\tWith `prune`, do not remove anything; just report what it would\n \tremove.\n \n -v::\n --verbose::\n-\tReport all removals.\n+\tWith `prune`, report all removals.\n \n --expire <time>::\n-\tOnly expire unused worktrees older than <time>.\n+\tWith `prune`, only expire unused worktrees older than <time>.\n \n SEE ALSO\n --------\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265485","messageId":"1435969052-540-4-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 03/23] Documentation: move linked worktree description from checkout to worktree","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:12Z","receivedAt":"2015-07-04T00:17:12Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"Now that the git-worktree command exists, its documentation page is the\nnatural place for the linked worktree description to reside. Relocate\nthe \"MULTIPLE WORKING TREES\" description verbatim from git-checkout.txt\nto git-worktree.txt.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n\nWhen Junio queued v1[1] on 'pu', he changed the second sentence of the\nfirst paragraph of the description to say \"...a new working tree is\ncreated and associated...\" in place of the original \"...a new working\ntree is associated...\". I wanted this to be a pure documentation-\nmovement patch, so I did not carry over his modification. Moreover, his\ntext is not quite accurate since, although <path> will be created if\nmissing, <path> can also be pre-existing, provided that it is an empty\ndirectory. Patch 13/23 adds documentation which states this explicitly.\n\n[1]: http://thread.gmane.org/gmane.comp.version-control.git/273032\n\n Documentation/git-checkout.txt | 69 ++----------------------------------------\n Documentation/git-worktree.txt | 62 +++++++++++++++++++++++++++++++++++++\n 2 files changed, 64 insertions(+), 67 deletions(-)\n\ndiff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\nindex ce223e6..77b7141 100644\n--- a/Documentation/git-checkout.txt\n+++ b/Documentation/git-checkout.txt\n@@ -229,8 +229,8 @@ section of linkgit:git-add[1] to learn how to operate the `--patch` mode.\n \tCheck out a branch in a separate working directory at\n \t`<path>`. A new working directory is linked to the current\n \trepository, sharing everything except working directory\n-\tspecific files such as HEAD, index... See \"MULTIPLE WORKING\n-\tTREES\" section for more information.\n+\tspecific files such as HEAD, index, etc. See\n+\tlinkgit:git-worktree[1] for a description of linked worktrees.\n \n --ignore-other-worktrees::\n \t`git checkout` refuses when the wanted ref is already checked\n@@ -401,71 +401,6 @@ $ git reflog -2 HEAD # or\n $ git log -g -2 HEAD\n ------------\n \n-MULTIPLE WORKING TREES\n-----------------------\n-\n-A git repository can support multiple working trees, allowing you to check\n-out more than one branch at a time.  With `git checkout --to` a new working\n-tree is associated with the repository.  This new working tree is called a\n-\"linked working tree\" as opposed to the \"main working tree\" prepared by \"git\n-init\" or \"git clone\".  A repository has one main working tree (if it's not a\n-bare repository) and zero or more linked working trees.\n-\n-Each linked working tree has a private sub-directory in the repository's\n-$GIT_DIR/worktrees directory.  The private sub-directory's name is usually\n-the base name of the linked working tree's path, possibly appended with a\n-number to make it unique.  For example, when `$GIT_DIR=/path/main/.git` the\n-command `git checkout --to /path/other/test-next next` creates the linked\n-working tree in `/path/other/test-next` and also creates a\n-`$GIT_DIR/worktrees/test-next` directory (or `$GIT_DIR/worktrees/test-next1`\n-if `test-next` is already taken).\n-\n-Within a linked working tree, $GIT_DIR is set to point to this private\n-directory (e.g. `/path/main/.git/worktrees/test-next` in the example) and\n-$GIT_COMMON_DIR is set to point back to the main working tree's $GIT_DIR\n-(e.g. `/path/main/.git`). These settings are made in a `.git` file located at\n-the top directory of the linked working tree.\n-\n-Path resolution via `git rev-parse --git-path` uses either\n-$GIT_DIR or $GIT_COMMON_DIR depending on the path. For example, in the\n-linked working tree `git rev-parse --git-path HEAD` returns\n-`/path/main/.git/worktrees/test-next/HEAD` (not\n-`/path/other/test-next/.git/HEAD` or `/path/main/.git/HEAD`) while `git\n-rev-parse --git-path refs/heads/master` uses\n-$GIT_COMMON_DIR and returns `/path/main/.git/refs/heads/master`,\n-since refs are shared across all working trees.\n-\n-See linkgit:gitrepository-layout[5] for more information. The rule of\n-thumb is do not make any assumption about whether a path belongs to\n-$GIT_DIR or $GIT_COMMON_DIR when you need to directly access something\n-inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path.\n-\n-When you are done with a linked working tree you can simply delete it.\n-The working tree's entry in the repository's $GIT_DIR/worktrees\n-directory will eventually be removed automatically (see\n-`gc.pruneworktreesexpire` in linkgit::git-config[1]), or you can run\n-`git worktree prune` in the main or any linked working tree to\n-clean up any stale entries in $GIT_DIR/worktrees.\n-\n-If you move a linked working directory to another file system, or\n-within a file system that does not support hard links, you need to run\n-at least one git command inside the linked working directory\n-(e.g. `git status`) in order to update its entry in $GIT_DIR/worktrees\n-so that it does not get automatically removed.\n-\n-To prevent a $GIT_DIR/worktrees entry from from being pruned (which\n-can be useful in some situations, such as when the\n-entry's working tree is stored on a portable device), add a file named\n-'locked' to the entry's directory. The file contains the reason in\n-plain text. For example, if a linked working tree's `.git` file points\n-to `/path/main/.git/worktrees/test-next` then a file named\n-`/path/main/.git/worktrees/test-next/locked` will prevent the\n-`test-next` entry from being pruned.  See\n-linkgit:gitrepository-layout[5] for details.\n-\n-Multiple checkout support for submodules is incomplete. It is NOT\n-recommended to make multiple checkouts of a superproject.\n-\n EXAMPLES\n --------\n \ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 1ac1217..3d28896 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -17,6 +17,68 @@ DESCRIPTION\n Manage multiple worktrees attached to the same repository. These are\n created by the command `git checkout --to`.\n \n+A git repository can support multiple working trees, allowing you to check\n+out more than one branch at a time.  With `git checkout --to` a new working\n+tree is associated with the repository.  This new working tree is called a\n+\"linked working tree\" as opposed to the \"main working tree\" prepared by \"git\n+init\" or \"git clone\".  A repository has one main working tree (if it's not a\n+bare repository) and zero or more linked working trees.\n+\n+Each linked working tree has a private sub-directory in the repository's\n+$GIT_DIR/worktrees directory.  The private sub-directory's name is usually\n+the base name of the linked working tree's path, possibly appended with a\n+number to make it unique.  For example, when `$GIT_DIR=/path/main/.git` the\n+command `git checkout --to /path/other/test-next next` creates the linked\n+working tree in `/path/other/test-next` and also creates a\n+`$GIT_DIR/worktrees/test-next` directory (or `$GIT_DIR/worktrees/test-next1`\n+if `test-next` is already taken).\n+\n+Within a linked working tree, $GIT_DIR is set to point to this private\n+directory (e.g. `/path/main/.git/worktrees/test-next` in the example) and\n+$GIT_COMMON_DIR is set to point back to the main working tree's $GIT_DIR\n+(e.g. `/path/main/.git`). These settings are made in a `.git` file located at\n+the top directory of the linked working tree.\n+\n+Path resolution via `git rev-parse --git-path` uses either\n+$GIT_DIR or $GIT_COMMON_DIR depending on the path. For example, in the\n+linked working tree `git rev-parse --git-path HEAD` returns\n+`/path/main/.git/worktrees/test-next/HEAD` (not\n+`/path/other/test-next/.git/HEAD` or `/path/main/.git/HEAD`) while `git\n+rev-parse --git-path refs/heads/master` uses\n+$GIT_COMMON_DIR and returns `/path/main/.git/refs/heads/master`,\n+since refs are shared across all working trees.\n+\n+See linkgit:gitrepository-layout[5] for more information. The rule of\n+thumb is do not make any assumption about whether a path belongs to\n+$GIT_DIR or $GIT_COMMON_DIR when you need to directly access something\n+inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path.\n+\n+When you are done with a linked working tree you can simply delete it.\n+The working tree's entry in the repository's $GIT_DIR/worktrees\n+directory will eventually be removed automatically (see\n+`gc.pruneworktreesexpire` in linkgit::git-config[1]), or you can run\n+`git worktree prune` in the main or any linked working tree to\n+clean up any stale entries in $GIT_DIR/worktrees.\n+\n+If you move a linked working directory to another file system, or\n+within a file system that does not support hard links, you need to run\n+at least one git command inside the linked working directory\n+(e.g. `git status`) in order to update its entry in $GIT_DIR/worktrees\n+so that it does not get automatically removed.\n+\n+To prevent a $GIT_DIR/worktrees entry from from being pruned (which\n+can be useful in some situations, such as when the\n+entry's working tree is stored on a portable device), add a file named\n+'locked' to the entry's directory. The file contains the reason in\n+plain text. For example, if a linked working tree's `.git` file points\n+to `/path/main/.git/worktrees/test-next` then a file named\n+`/path/main/.git/worktrees/test-next/locked` will prevent the\n+`test-next` entry from being pruned.  See\n+linkgit:gitrepository-layout[5] for details.\n+\n+Multiple checkout support for submodules is incomplete. It is NOT\n+recommended to make multiple checkouts of a superproject.\n+\n COMMANDS\n --------\n prune::\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265482","messageId":"1435969052-540-5-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 04/23] Documentation/git-worktree: add BUGS section","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:13Z","receivedAt":"2015-07-04T00:17:13Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"Relocate submodule warning to BUGS and enumerate missing commands.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n Documentation/git-worktree.txt | 18 +++++++++++++++---\n 1 file changed, 15 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 3d28896..4fbcdd2 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -76,9 +76,6 @@ to `/path/main/.git/worktrees/test-next` then a file named\n `test-next` entry from being pruned.  See\n linkgit:gitrepository-layout[5] for details.\n \n-Multiple checkout support for submodules is incomplete. It is NOT\n-recommended to make multiple checkouts of a superproject.\n-\n COMMANDS\n --------\n prune::\n@@ -100,6 +97,21 @@ OPTIONS\n --expire <time>::\n \tWith `prune`, only expire unused worktrees older than <time>.\n \n+BUGS\n+----\n+Multiple checkout support for submodules is incomplete. It is NOT\n+recommended to make multiple checkouts of a superproject.\n+\n+git-worktree could provide more automation for tasks currently\n+performed manually or via other commands, such as:\n+\n+- `add` to create a new linked worktree\n+- `remove` to remove a linked worktree and its administrative files (and\n+  warn if the worktree is dirty)\n+- `mv` to move or rename a worktree and update its administrative files\n+- `lock` to prevent automatic pruning of administrative files (for instance,\n+  for a worktree on a portable device)\n+\n SEE ALSO\n --------\n \n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265488","messageId":"1435969052-540-6-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 05/23] Documentation/git-worktree: split technical info from general description","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:14Z","receivedAt":"2015-07-04T00:17:14Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"The DESCRIPTION section should provide a high-level overview of linked\nworktree functionality to bring users up to speed quickly, without\noverloading them with low-level details, so relocate the technical\ninformation to a new DETAILS section.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n Documentation/git-worktree.txt | 70 ++++++++++++++++++++++--------------------\n 1 file changed, 36 insertions(+), 34 deletions(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 4fbcdd2..2fdfb3e 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -24,47 +24,18 @@ tree is associated with the repository.  This new working tree is called a\n init\" or \"git clone\".  A repository has one main working tree (if it's not a\n bare repository) and zero or more linked working trees.\n \n-Each linked working tree has a private sub-directory in the repository's\n-$GIT_DIR/worktrees directory.  The private sub-directory's name is usually\n-the base name of the linked working tree's path, possibly appended with a\n-number to make it unique.  For example, when `$GIT_DIR=/path/main/.git` the\n-command `git checkout --to /path/other/test-next next` creates the linked\n-working tree in `/path/other/test-next` and also creates a\n-`$GIT_DIR/worktrees/test-next` directory (or `$GIT_DIR/worktrees/test-next1`\n-if `test-next` is already taken).\n-\n-Within a linked working tree, $GIT_DIR is set to point to this private\n-directory (e.g. `/path/main/.git/worktrees/test-next` in the example) and\n-$GIT_COMMON_DIR is set to point back to the main working tree's $GIT_DIR\n-(e.g. `/path/main/.git`). These settings are made in a `.git` file located at\n-the top directory of the linked working tree.\n-\n-Path resolution via `git rev-parse --git-path` uses either\n-$GIT_DIR or $GIT_COMMON_DIR depending on the path. For example, in the\n-linked working tree `git rev-parse --git-path HEAD` returns\n-`/path/main/.git/worktrees/test-next/HEAD` (not\n-`/path/other/test-next/.git/HEAD` or `/path/main/.git/HEAD`) while `git\n-rev-parse --git-path refs/heads/master` uses\n-$GIT_COMMON_DIR and returns `/path/main/.git/refs/heads/master`,\n-since refs are shared across all working trees.\n-\n-See linkgit:gitrepository-layout[5] for more information. The rule of\n-thumb is do not make any assumption about whether a path belongs to\n-$GIT_DIR or $GIT_COMMON_DIR when you need to directly access something\n-inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path.\n-\n When you are done with a linked working tree you can simply delete it.\n-The working tree's entry in the repository's $GIT_DIR/worktrees\n-directory will eventually be removed automatically (see\n+The working tree's administrative files in the repository (see\n+\"DETAILS\" below) will eventually be removed automatically (see\n `gc.pruneworktreesexpire` in linkgit::git-config[1]), or you can run\n `git worktree prune` in the main or any linked working tree to\n-clean up any stale entries in $GIT_DIR/worktrees.\n+clean up any stale administrative files.\n \n If you move a linked working directory to another file system, or\n within a file system that does not support hard links, you need to run\n at least one git command inside the linked working directory\n-(e.g. `git status`) in order to update its entry in $GIT_DIR/worktrees\n-so that it does not get automatically removed.\n+(e.g. `git status`) in order to update its administrative files in the\n+repository so that they do not get automatically pruned.\n \n To prevent a $GIT_DIR/worktrees entry from from being pruned (which\n can be useful in some situations, such as when the\n@@ -97,6 +68,37 @@ OPTIONS\n --expire <time>::\n \tWith `prune`, only expire unused worktrees older than <time>.\n \n+DETAILS\n+-------\n+Each linked working tree has a private sub-directory in the repository's\n+$GIT_DIR/worktrees directory.  The private sub-directory's name is usually\n+the base name of the linked working tree's path, possibly appended with a\n+number to make it unique.  For example, when `$GIT_DIR=/path/main/.git` the\n+command `git checkout --to /path/other/test-next next` creates the linked\n+working tree in `/path/other/test-next` and also creates a\n+`$GIT_DIR/worktrees/test-next` directory (or `$GIT_DIR/worktrees/test-next1`\n+if `test-next` is already taken).\n+\n+Within a linked working tree, $GIT_DIR is set to point to this private\n+directory (e.g. `/path/main/.git/worktrees/test-next` in the example) and\n+$GIT_COMMON_DIR is set to point back to the main working tree's $GIT_DIR\n+(e.g. `/path/main/.git`). These settings are made in a `.git` file located at\n+the top directory of the linked working tree.\n+\n+Path resolution via `git rev-parse --git-path` uses either\n+$GIT_DIR or $GIT_COMMON_DIR depending on the path. For example, in the\n+linked working tree `git rev-parse --git-path HEAD` returns\n+`/path/main/.git/worktrees/test-next/HEAD` (not\n+`/path/other/test-next/.git/HEAD` or `/path/main/.git/HEAD`) while `git\n+rev-parse --git-path refs/heads/master` uses\n+$GIT_COMMON_DIR and returns `/path/main/.git/refs/heads/master`,\n+since refs are shared across all working trees.\n+\n+See linkgit:gitrepository-layout[5] for more information. The rule of\n+thumb is do not make any assumption about whether a path belongs to\n+$GIT_DIR or $GIT_COMMON_DIR when you need to directly access something\n+inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path.\n+\n BUGS\n ----\n Multiple checkout support for submodules is incomplete. It is NOT\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265487","messageId":"1435969052-540-7-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 06/23] Documentation/git-worktree: add high-level 'lock' overview","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:15Z","receivedAt":"2015-07-04T00:17:15Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"Due to the (current) absence of a \"git worktree lock\" command, locking\na worktree's administrative files to prevent automatic pruning is a\nmanual task, necessarily requiring low-level understanding of linked\nworktree functionality. However, this level of detail does not belong\nin the high-level DESCRIPTION section, so add a generalized discussion\nof locking to DESCRIPTION and move the technical information to DETAILS.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n Documentation/git-worktree.txt | 24 +++++++++++++++---------\n 1 file changed, 15 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 2fdfb3e..410f0b4 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -37,15 +37,11 @@ at least one git command inside the linked working directory\n (e.g. `git status`) in order to update its administrative files in the\n repository so that they do not get automatically pruned.\n \n-To prevent a $GIT_DIR/worktrees entry from from being pruned (which\n-can be useful in some situations, such as when the\n-entry's working tree is stored on a portable device), add a file named\n-'locked' to the entry's directory. The file contains the reason in\n-plain text. For example, if a linked working tree's `.git` file points\n-to `/path/main/.git/worktrees/test-next` then a file named\n-`/path/main/.git/worktrees/test-next/locked` will prevent the\n-`test-next` entry from being pruned.  See\n-linkgit:gitrepository-layout[5] for details.\n+If a linked working tree is stored on a portable device or network share\n+which is not always mounted, you can prevent its administrative files from\n+being pruned by creating a file named 'lock' alongside the other\n+administrative files, optionally containing a plain text reason that\n+pruning should be suppressed. See section \"DETAILS\" for more information.\n \n COMMANDS\n --------\n@@ -99,6 +95,16 @@ thumb is do not make any assumption about whether a path belongs to\n $GIT_DIR or $GIT_COMMON_DIR when you need to directly access something\n inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path.\n \n+To prevent a $GIT_DIR/worktrees entry from from being pruned (which\n+can be useful in some situations, such as when the\n+entry's working tree is stored on a portable device), add a file named\n+'locked' to the entry's directory. The file contains the reason in\n+plain text. For example, if a linked working tree's `.git` file points\n+to `/path/main/.git/worktrees/test-next` then a file named\n+`/path/main/.git/worktrees/test-next/locked` will prevent the\n+`test-next` entry from being pruned.  See\n+linkgit:gitrepository-layout[5] for details.\n+\n BUGS\n ----\n Multiple checkout support for submodules is incomplete. It is NOT\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265486","messageId":"1435969052-540-8-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 07/23] Documentation/git-worktree: add EXAMPLES section","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:16Z","receivedAt":"2015-07-04T00:17:16Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n Documentation/git-worktree.txt | 22 ++++++++++++++++++++++\n 1 file changed, 22 insertions(+)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 410f0b4..028bbd9 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -105,6 +105,28 @@ to `/path/main/.git/worktrees/test-next` then a file named\n `test-next` entry from being pruned.  See\n linkgit:gitrepository-layout[5] for details.\n \n+EXAMPLES\n+--------\n+You are middle of a refactoring session and your boss comes in and demands\n+that you fix something immediately. You might typically use\n+linkgit:git-stash[1] to store your changes away temporarily, however, your\n+worktree is in such a state of disarray (with new, removed, moved files,\n+and other bits and pieces strewn around) that you don't want to risk\n+disturbing any of it. Instead, you create a temporary linked worktree to\n+make the emergency fix, remove it when done, and then resume your earlier\n+refactoring session.\n+\n+------------\n+$ git branch emergency-fix master\n+$ git checkout --to ../temp emergency-fix\n+$ pushd ../temp\n+# ... hack hack hack ...\n+$ git commit -a -m 'emergency fix for boss'\n+$ popd\n+$ rm -rf ../temp\n+$ git worktree prune\n+------------\n+\n BUGS\n ----\n Multiple checkout support for submodules is incomplete. It is NOT\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265491","messageId":"1435969052-540-9-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 08/23] checkout: fix bug with --to and relative HEAD","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:17Z","receivedAt":"2015-07-04T00:17:17Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"Given \"git checkout --to <path> HEAD~1\", the new worktree's HEAD should\nbegin life at the current branch's HEAD~1, however, it actually ends up\nat HEAD~2. The happens because:\n\n    1. git-checkout resolves HEAD~1\n\n    2. to satisfy is_git_directory, prepare_linked_worktree() creates a\n       HEAD in the new worktree with the value of the resolved HEAD~1\n\n    3. git-checkout re-invokes itself with the same arguments within the\n       new worktree to populate the worktree\n\n    4. the sub git-checkout resolves HEAD~1 relative to its own HEAD,\n       which is the resolved HEAD~1 from the original invocation,\n       resulting unexpectedly and incorrectly in HEAD~2 (relative to the\n       original)\n\nFix this by unconditionally assigning the current worktree's HEAD as the\nvalue of the new worktree's HEAD.\n\nAs a side-effect, this change also eliminates a dependence within\nprepare_linked_checkout() upon 'struct branch_info'. The eventual plan\nis to relocate \"git checkout --to\" functionality to \"git worktree add\",\nand worktree.c won't have knowledge of 'struct branch_info', so removal\nof this dependency is a step toward that goal.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n builtin/checkout.c     |  5 ++++-\n t/t2025-checkout-to.sh | 10 ++++++++++\n 2 files changed, 14 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 2079aa4..f5f953d 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -863,6 +863,7 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,\n \tstruct stat st;\n \tstruct child_process cp;\n \tint counter = 0, len, ret;\n+\tunsigned char rev[20];\n \n \tif (!new->commit)\n \t\tdie(_(\"no branch specified\"));\n@@ -924,9 +925,11 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,\n \t * value would do because this value will be ignored and\n \t * replaced at the next (real) checkout.\n \t */\n+\tif (!resolve_ref_unsafe(\"HEAD\", 0, rev, NULL))\n+\t\tdie(_(\"unable to resolve HEAD\"));\n \tstrbuf_reset(&sb);\n \tstrbuf_addf(&sb, \"%s/HEAD\", sb_repo.buf);\n-\twrite_file(sb.buf, 1, \"%s\\n\", sha1_to_hex(new->commit->object.sha1));\n+\twrite_file(sb.buf, 1, \"%s\\n\", sha1_to_hex(rev));\n \tstrbuf_reset(&sb);\n \tstrbuf_addf(&sb, \"%s/commondir\", sb_repo.buf);\n \twrite_file(sb.buf, 1, \"../..\\n\");\ndiff --git a/t/t2025-checkout-to.sh b/t/t2025-checkout-to.sh\nindex a8d9336..0fd731b 100755\n--- a/t/t2025-checkout-to.sh\n+++ b/t/t2025-checkout-to.sh\n@@ -134,4 +134,14 @@ test_expect_success 'checkout with grafts' '\n \ttest_cmp expected actual\n '\n \n+test_expect_success 'checkout --to from relative HEAD' '\n+\ttest_commit a &&\n+\ttest_commit b &&\n+\ttest_commit c &&\n+\tgit rev-parse HEAD~1 >expected &&\n+\tgit checkout --to relhead HEAD~1 &&\n+\tgit -C relhead rev-parse HEAD >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265489","messageId":"1435969052-540-10-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 09/23] checkout: relocate --to's \"no branch specified\" check","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:18Z","receivedAt":"2015-07-04T00:17:18Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"The plan is to relocate \"git checkout --to\" functionality to \"git\nworktree add\", however, this check expects a 'struct branch_info' which\ngit-worktree won't have at hand. It will, however, have access to its\nown command-line from which it can pick up the branch name. Therefore,\nas a preparatory step, rather than having prepare_linked_checkout()\nperform this check, make it the caller's responsibility.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n builtin/checkout.c | 7 ++++---\n 1 file changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex f5f953d..0cb81ee 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -865,8 +865,6 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,\n \tint counter = 0, len, ret;\n \tunsigned char rev[20];\n \n-\tif (!new->commit)\n-\t\tdie(_(\"no branch specified\"));\n \tif (file_exists(path) && !is_empty_dir(path))\n \t\tdie(_(\"'%s' already exists\"), path);\n \n@@ -1298,8 +1296,11 @@ static int checkout_branch(struct checkout_opts *opts,\n \t\tfree(head_ref);\n \t}\n \n-\tif (opts->new_worktree)\n+\tif (opts->new_worktree) {\n+\t\tif (!new->commit)\n+\t\t\tdie(_(\"no branch specified\"));\n \t\treturn prepare_linked_checkout(opts, new);\n+\t}\n \n \tif (!new->commit && opts->new_branch) {\n \t\tunsigned char rev[20];\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265490","messageId":"1435969052-540-11-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 10/23] checkout: prepare_linked_checkout: drop now-unused 'new' argument","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:19Z","receivedAt":"2015-07-04T00:17:19Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"The only references to 'new' were folded out by the last two patches.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n builtin/checkout.c | 5 ++---\n 1 file changed, 2 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 0cb81ee..0dcdde2 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -854,8 +854,7 @@ static void remove_junk_on_signal(int signo)\n \traise(signo);\n }\n \n-static int prepare_linked_checkout(const struct checkout_opts *opts,\n-\t\t\t\t   struct branch_info *new)\n+static int prepare_linked_checkout(const struct checkout_opts *opts)\n {\n \tstruct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;\n \tstruct strbuf sb = STRBUF_INIT;\n@@ -1299,7 +1298,7 @@ static int checkout_branch(struct checkout_opts *opts,\n \tif (opts->new_worktree) {\n \t\tif (!new->commit)\n \t\t\tdie(_(\"no branch specified\"));\n-\t\treturn prepare_linked_checkout(opts, new);\n+\t\treturn prepare_linked_checkout(opts);\n \t}\n \n \tif (!new->commit && opts->new_branch) {\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265504","messageId":"1435969052-540-12-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 11/23] checkout: make --to unconditionally verbose","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:20Z","receivedAt":"2015-07-04T00:17:20Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"prepare_linked_checkout() respects git-checkout's --quiet flag, however,\nthe plan is to relocate \"git checkout --to\" functionality to \"git\nworktree add\", and git-worktree does not (yet) have a --quiet flag.\nConsequently, make prepare_linked_checkout() unconditionally verbose to\nease eventual code movement to worktree.c.\n\n(A --quiet flag can be added to git-worktree later if there is demand\nfor it.)\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n builtin/checkout.c | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 0dcdde2..86b1745 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -931,8 +931,7 @@ static int prepare_linked_checkout(const struct checkout_opts *opts)\n \tstrbuf_addf(&sb, \"%s/commondir\", sb_repo.buf);\n \twrite_file(sb.buf, 1, \"../..\\n\");\n \n-\tif (!opts->quiet)\n-\t\tfprintf_ln(stderr, _(\"Enter %s (identifier %s)\"), path, name);\n+\tfprintf_ln(stderr, _(\"Enter %s (identifier %s)\"), path, name);\n \n \tsetenv(\"GIT_CHECKOUT_NEW_WORKTREE\", \"1\", 1);\n \tsetenv(GIT_DIR_ENVIRONMENT, sb_git.buf, 1);\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265503","messageId":"1435969052-540-13-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 12/23] checkout: drop 'checkout_opts' dependency from prepare_linked_checkout","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:21Z","receivedAt":"2015-07-04T00:17:21Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"The plan is to relocate \"git checkout --to\" functionality to \"git\nworktree add\", however, worktree.c won't have access to the 'struct\ncheckout_opts' passed to prepare_linked_worktree(), which it consults\nfor the pathname of the new worktree and the argv[] of the command it\nshould run to populate the new worktree. Facilitate relocation of\nprepare_linked_worktree() by instead having it accept the pathname and\nargv[] directly, thus eliminating the final references to 'struct\ncheckout_opts'.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n builtin/checkout.c | 9 +++++----\n 1 file changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 86b1745..30fe786 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -854,11 +854,11 @@ static void remove_junk_on_signal(int signo)\n \traise(signo);\n }\n \n-static int prepare_linked_checkout(const struct checkout_opts *opts)\n+static int prepare_linked_checkout(const char *path, const char **child_argv)\n {\n \tstruct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;\n \tstruct strbuf sb = STRBUF_INIT;\n-\tconst char *path = opts->new_worktree, *name;\n+\tconst char *name;\n \tstruct stat st;\n \tstruct child_process cp;\n \tint counter = 0, len, ret;\n@@ -938,7 +938,7 @@ static int prepare_linked_checkout(const struct checkout_opts *opts)\n \tsetenv(GIT_WORK_TREE_ENVIRONMENT, path, 1);\n \tmemset(&cp, 0, sizeof(cp));\n \tcp.git_cmd = 1;\n-\tcp.argv = opts->saved_argv;\n+\tcp.argv = child_argv;\n \tret = run_command(&cp);\n \tif (!ret) {\n \t\tis_junk = 0;\n@@ -1297,7 +1297,8 @@ static int checkout_branch(struct checkout_opts *opts,\n \tif (opts->new_worktree) {\n \t\tif (!new->commit)\n \t\t\tdie(_(\"no branch specified\"));\n-\t\treturn prepare_linked_checkout(opts);\n+\t\treturn prepare_linked_checkout(opts->new_worktree,\n+\t\t\t\t\t       opts->saved_argv);\n \t}\n \n \tif (!new->commit && opts->new_branch) {\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265492","messageId":"1435969052-540-14-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 13/23] worktree: introduce \"add\" command","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:22Z","receivedAt":"2015-07-04T00:17:22Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"The plan is to relocate \"git checkout --to\" functionality to \"git\nworktree add\". As a first step, introduce a bare-bones git-worktree\n\"add\" command along with documentation. At this stage, \"git worktree\nadd\" merely invokes \"git checkout --to\" behind the scenes, but an\nupcoming patch will move the actual functionality\n(checkout.c:prepare_linked_checkout() and its helpers) to worktree.c.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n Documentation/git-worktree.txt | 21 +++++++++++----------\n builtin/worktree.c             | 32 ++++++++++++++++++++++++++++++++\n 2 files changed, 43 insertions(+), 10 deletions(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 028bbd9..59191f9 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -9,13 +9,13 @@ git-worktree - Manage multiple worktrees\n SYNOPSIS\n --------\n [verse]\n+'git worktree add' <path> <branch>\n 'git worktree prune' [-n] [-v] [--expire <expire>]\n \n DESCRIPTION\n -----------\n \n-Manage multiple worktrees attached to the same repository. These are\n-created by the command `git checkout --to`.\n+Manage multiple worktrees attached to the same repository.\n \n A git repository can support multiple working trees, allowing you to check\n out more than one branch at a time.  With `git checkout --to` a new working\n@@ -45,6 +45,13 @@ pruning should be suppressed. See section \"DETAILS\" for more information.\n \n COMMANDS\n --------\n+add <path> <branch>::\n+\n+Check out `<branch>` into a separate working directory, `<path>`, creating\n+`<path>` if necessary. The new working directory is linked to the current\n+repository, sharing everything except working directory specific files\n+such as HEAD, index, etc. If `<path>` already exists, it must be empty.\n+\n prune::\n \n Prune working tree information in $GIT_DIR/worktrees.\n@@ -118,7 +125,7 @@ refactoring session.\n \n ------------\n $ git branch emergency-fix master\n-$ git checkout --to ../temp emergency-fix\n+$ git worktree add ../temp emergency-fix\n $ pushd ../temp\n # ... hack hack hack ...\n $ git commit -a -m 'emergency fix for boss'\n@@ -133,20 +140,14 @@ Multiple checkout support for submodules is incomplete. It is NOT\n recommended to make multiple checkouts of a superproject.\n \n git-worktree could provide more automation for tasks currently\n-performed manually or via other commands, such as:\n+performed manually, such as:\n \n-- `add` to create a new linked worktree\n - `remove` to remove a linked worktree and its administrative files (and\n   warn if the worktree is dirty)\n - `mv` to move or rename a worktree and update its administrative files\n - `lock` to prevent automatic pruning of administrative files (for instance,\n   for a worktree on a portable device)\n \n-SEE ALSO\n---------\n-\n-linkgit:git-checkout[1]\n-\n GIT\n ---\n Part of the linkgit:git[1] suite\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 2a729c6..b82861e 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -2,8 +2,11 @@\n #include \"builtin.h\"\n #include \"dir.h\"\n #include \"parse-options.h\"\n+#include \"argv-array.h\"\n+#include \"run-command.h\"\n \n static const char * const worktree_usage[] = {\n+\tN_(\"git worktree add <path> <branch>\"),\n \tN_(\"git worktree prune [<options>]\"),\n \tNULL\n };\n@@ -119,6 +122,33 @@ static int prune(int ac, const char **av, const char *prefix)\n \treturn 0;\n }\n \n+\n+static int add(int ac, const char **av, const char *prefix)\n+{\n+\tstruct child_process c;\n+\tconst char *path, *branch;\n+\tstruct argv_array cmd = ARGV_ARRAY_INIT;\n+\tstruct option options[] = {\n+\t\tOPT_END()\n+\t};\n+\n+\tac = parse_options(ac, av, prefix, options, worktree_usage, 0);\n+\tif (ac != 2)\n+\t\tusage_with_options(worktree_usage, options);\n+\n+\tpath = prefix ? prefix_filename(prefix, strlen(prefix), av[0]) : av[0];\n+\tbranch = av[1];\n+\n+\targv_array_push(&cmd, \"checkout\");\n+\targv_array_pushl(&cmd, \"--to\", path, NULL);\n+\targv_array_push(&cmd, branch);\n+\n+\tmemset(&c, 0, sizeof(c));\n+\tc.git_cmd = 1;\n+\tc.argv = cmd.argv;\n+\treturn run_command(&c);\n+}\n+\n int cmd_worktree(int ac, const char **av, const char *prefix)\n {\n \tstruct option options[] = {\n@@ -127,6 +157,8 @@ int cmd_worktree(int ac, const char **av, const char *prefix)\n \n \tif (ac < 2)\n \t\tusage_with_options(worktree_usage, options);\n+\tif (!strcmp(av[1], \"add\"))\n+\t\treturn add(ac - 1, av + 1, prefix);\n \tif (!strcmp(av[1], \"prune\"))\n \t\treturn prune(ac - 1, av + 1, prefix);\n \tusage_with_options(worktree_usage, options);\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265493","messageId":"1435969052-540-15-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 14/23] worktree: add --force option","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:23Z","receivedAt":"2015-07-04T00:17:23Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"By default, \"git worktree add\" refuses to create a new worktree when\nthe requested branch is already checked out elsewhere. Add a --force\noption to override this safeguard.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n Documentation/git-worktree.txt | 8 +++++++-\n builtin/worktree.c             | 6 +++++-\n 2 files changed, 12 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 59191f9..552c8e4 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -9,7 +9,7 @@ git-worktree - Manage multiple worktrees\n SYNOPSIS\n --------\n [verse]\n-'git worktree add' <path> <branch>\n+'git worktree add' [-f] <path> <branch>\n 'git worktree prune' [-n] [-v] [--expire <expire>]\n \n DESCRIPTION\n@@ -59,6 +59,12 @@ Prune working tree information in $GIT_DIR/worktrees.\n OPTIONS\n -------\n \n+-f::\n+--force::\n+\tBy default, `add` refuses to create a new worktree when\t`<branch>`\n+\tis already checked out by another worktree. This option overrides\n+\tthat safeguard.\n+\n -n::\n --dry-run::\n \tWith `prune`, do not remove anything; just report what it would\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex b82861e..c9d6462 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -6,7 +6,7 @@\n #include \"run-command.h\"\n \n static const char * const worktree_usage[] = {\n-\tN_(\"git worktree add <path> <branch>\"),\n+\tN_(\"git worktree add [<options>] <path> <branch>\"),\n \tN_(\"git worktree prune [<options>]\"),\n \tNULL\n };\n@@ -126,9 +126,11 @@ static int prune(int ac, const char **av, const char *prefix)\n static int add(int ac, const char **av, const char *prefix)\n {\n \tstruct child_process c;\n+\tint force = 0;\n \tconst char *path, *branch;\n \tstruct argv_array cmd = ARGV_ARRAY_INIT;\n \tstruct option options[] = {\n+\t\tOPT__FORCE(&force, N_(\"checkout <branch> even if already checked out in other worktree\")),\n \t\tOPT_END()\n \t};\n \n@@ -141,6 +143,8 @@ static int add(int ac, const char **av, const char *prefix)\n \n \targv_array_push(&cmd, \"checkout\");\n \targv_array_pushl(&cmd, \"--to\", path, NULL);\n+\tif (force)\n+\t\targv_array_push(&cmd, \"--ignore-other-worktrees\");\n \targv_array_push(&cmd, branch);\n \n \tmemset(&c, 0, sizeof(c));\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265495","messageId":"1435969052-540-16-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 15/23] worktree: add --detach option","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:24Z","receivedAt":"2015-07-04T00:17:24Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"One of git-worktree's roles is to populate the new worktree, much like\ngit-checkout, and thus, for convenience, ought to support several of the\nsame shortcuts. Toward this goal, add a --detach option to detach HEAD\nin the new worktree.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n Documentation/git-worktree.txt | 6 +++++-\n builtin/worktree.c             | 5 ++++-\n 2 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 552c8e4..96e2142 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -9,7 +9,7 @@ git-worktree - Manage multiple worktrees\n SYNOPSIS\n --------\n [verse]\n-'git worktree add' [-f] <path> <branch>\n+'git worktree add' [-f] [--detach] <path> <branch>\n 'git worktree prune' [-n] [-v] [--expire <expire>]\n \n DESCRIPTION\n@@ -65,6 +65,10 @@ OPTIONS\n \tis already checked out by another worktree. This option overrides\n \tthat safeguard.\n \n+--detach::\n+\tWith `add`, detach HEAD in the new worktree. See \"DETACHED HEAD\" in\n+\tlinkgit:git-checkout[1].\n+\n -n::\n --dry-run::\n \tWith `prune`, do not remove anything; just report what it would\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex c9d6462..6967369 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -126,11 +126,12 @@ static int prune(int ac, const char **av, const char *prefix)\n static int add(int ac, const char **av, const char *prefix)\n {\n \tstruct child_process c;\n-\tint force = 0;\n+\tint force = 0, detach = 0;\n \tconst char *path, *branch;\n \tstruct argv_array cmd = ARGV_ARRAY_INIT;\n \tstruct option options[] = {\n \t\tOPT__FORCE(&force, N_(\"checkout <branch> even if already checked out in other worktree\")),\n+\t\tOPT_BOOL(0, \"detach\", &detach, N_(\"detach HEAD at named commit\")),\n \t\tOPT_END()\n \t};\n \n@@ -145,6 +146,8 @@ static int add(int ac, const char **av, const char *prefix)\n \targv_array_pushl(&cmd, \"--to\", path, NULL);\n \tif (force)\n \t\targv_array_push(&cmd, \"--ignore-other-worktrees\");\n+\tif (detach)\n+\t\targv_array_push(&cmd, \"--detach\");\n \targv_array_push(&cmd, branch);\n \n \tmemset(&c, 0, sizeof(c));\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265494","messageId":"1435969052-540-17-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 16/23] worktree: add -b/-B options","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:25Z","receivedAt":"2015-07-04T00:17:25Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"One of git-worktree's roles is to populate the new worktree, much like\ngit-checkout, and thus, for convenience, ought to support several of the\nsame shortcuts. Toward this goal, add -b/-B options to create a new\nbranch and check it out in the new worktree.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n\nFor brevity, I intentionally mentioned only -b in the synopsis, and\nomitted -B.\n\n Documentation/git-worktree.txt | 13 ++++++++++---\n builtin/worktree.c             | 11 +++++++++++\n 2 files changed, 21 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 96e2142..f6c3747 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -9,7 +9,7 @@ git-worktree - Manage multiple worktrees\n SYNOPSIS\n --------\n [verse]\n-'git worktree add' [-f] [--detach] <path> <branch>\n+'git worktree add' [-f] [--detach] [-b <new-branch>] <path> <branch>\n 'git worktree prune' [-n] [-v] [--expire <expire>]\n \n DESCRIPTION\n@@ -65,6 +65,14 @@ OPTIONS\n \tis already checked out by another worktree. This option overrides\n \tthat safeguard.\n \n+-b <new-branch>::\n+-B <new-branch>::\n+\tWith `add`, create a new branch named `<new-branch>` starting at\n+\t`<branch>`, and check out `<new-branch>` into the new worktree.\n+\tBy default, `-b` refuses to create a new branch if it already\n+\texists. `-B` overrides this safeguard, resetting `<new-branch>` to\n+\t`<branch>`.\n+\n --detach::\n \tWith `add`, detach HEAD in the new worktree. See \"DETACHED HEAD\" in\n \tlinkgit:git-checkout[1].\n@@ -134,8 +142,7 @@ make the emergency fix, remove it when done, and then resume your earlier\n refactoring session.\n \n ------------\n-$ git branch emergency-fix master\n-$ git worktree add ../temp emergency-fix\n+$ git worktree add -b emergency-fix ../temp master\n $ pushd ../temp\n # ... hack hack hack ...\n $ git commit -a -m 'emergency fix for boss'\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 6967369..d461d31 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -127,15 +127,22 @@ static int add(int ac, const char **av, const char *prefix)\n {\n \tstruct child_process c;\n \tint force = 0, detach = 0;\n+\tconst char *new_branch = NULL, *new_branch_force = NULL;\n \tconst char *path, *branch;\n \tstruct argv_array cmd = ARGV_ARRAY_INIT;\n \tstruct option options[] = {\n \t\tOPT__FORCE(&force, N_(\"checkout <branch> even if already checked out in other worktree\")),\n+\t\tOPT_STRING('b', NULL, &new_branch, N_(\"branch\"),\n+\t\t\t   N_(\"create a new branch\")),\n+\t\tOPT_STRING('B', NULL, &new_branch_force, N_(\"branch\"),\n+\t\t\t   N_(\"create or reset a branch\")),\n \t\tOPT_BOOL(0, \"detach\", &detach, N_(\"detach HEAD at named commit\")),\n \t\tOPT_END()\n \t};\n \n \tac = parse_options(ac, av, prefix, options, worktree_usage, 0);\n+\tif (new_branch && new_branch_force)\n+\t\tdie(_(\"-b and -B are mutually exclusive\"));\n \tif (ac != 2)\n \t\tusage_with_options(worktree_usage, options);\n \n@@ -146,6 +153,10 @@ static int add(int ac, const char **av, const char *prefix)\n \targv_array_pushl(&cmd, \"--to\", path, NULL);\n \tif (force)\n \t\targv_array_push(&cmd, \"--ignore-other-worktrees\");\n+\tif (new_branch)\n+\t\targv_array_pushl(&cmd, \"-b\", new_branch, NULL);\n+\tif (new_branch_force)\n+\t\targv_array_pushl(&cmd, \"-B\", new_branch_force, NULL);\n \tif (detach)\n \t\targv_array_push(&cmd, \"--detach\");\n \targv_array_push(&cmd, branch);\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265498","messageId":"1435969052-540-18-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 17/23] tests: worktree: retrofit \"checkout --to\" tests for \"worktree add\"","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:26Z","receivedAt":"2015-07-04T00:17:26Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"With the introduction of \"git worktree add\", \"git checkout --to\" is\nslated for removal. Therefore, retrofit linked worktree creation tests\nto use \"git worktree add\" instead.\n\n(The test to check exclusivity of \"checkout --to\" and \"checkout <paths>\"\nis dropped altogether since it becomes meaningless with retirement of\n\"checkout --to\".)\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n t/{t2025-checkout-to.sh => t2025-worktree-add.sh} | 48 +++++++++++------------\n t/t2026-prune-linked-checkouts.sh                 |  2 +-\n t/t7410-submodule-checkout-to.sh                  |  4 +-\n 3 files changed, 25 insertions(+), 29 deletions(-)\n rename t/{t2025-checkout-to.sh => t2025-worktree-add.sh} (59%)\n\ndiff --git a/t/t2025-checkout-to.sh b/t/t2025-worktree-add.sh\nsimilarity index 59%\nrename from t/t2025-checkout-to.sh\nrename to t/t2025-worktree-add.sh\nindex 0fd731b..192c936 100755\n--- a/t/t2025-checkout-to.sh\n+++ b/t/t2025-worktree-add.sh\n@@ -1,6 +1,6 @@\n #!/bin/sh\n \n-test_description='test git checkout --to'\n+test_description='test git worktree add'\n \n . ./test-lib.sh\n \n@@ -8,22 +8,18 @@ test_expect_success 'setup' '\n \ttest_commit init\n '\n \n-test_expect_success 'checkout --to not updating paths' '\n-\ttest_must_fail git checkout --to -- init.t\n-'\n-\n-test_expect_success 'checkout --to an existing worktree' '\n+test_expect_success '\"add\" an existing worktree' '\n \tmkdir -p existing/subtree &&\n-\ttest_must_fail git checkout --detach --to existing master\n+\ttest_must_fail git worktree add --detach existing master\n '\n \n-test_expect_success 'checkout --to an existing empty worktree' '\n+test_expect_success '\"add\" an existing empty worktree' '\n \tmkdir existing_empty &&\n-\tgit checkout --detach --to existing_empty master\n+\tgit worktree add --detach existing_empty master\n '\n \n-test_expect_success 'checkout --to refuses to checkout locked branch' '\n-\ttest_must_fail git checkout --to zere master &&\n+test_expect_success '\"add\" refuses to checkout locked branch' '\n+\ttest_must_fail git worktree add zere master &&\n \t! test -d zere &&\n \t! test -d .git/worktrees/zere\n '\n@@ -36,9 +32,9 @@ test_expect_success 'checking out paths not complaining about linked checkouts'\n \t)\n '\n \n-test_expect_success 'checkout --to a new worktree' '\n+test_expect_success '\"add\" worktree' '\n \tgit rev-parse HEAD >expect &&\n-\tgit checkout --detach --to here master &&\n+\tgit worktree add --detach here master &&\n \t(\n \t\tcd here &&\n \t\ttest_cmp ../init.t init.t &&\n@@ -49,27 +45,27 @@ test_expect_success 'checkout --to a new worktree' '\n \t)\n '\n \n-test_expect_success 'checkout --to a new worktree from a subdir' '\n+test_expect_success '\"add\" worktree from a subdir' '\n \t(\n \t\tmkdir sub &&\n \t\tcd sub &&\n-\t\tgit checkout --detach --to here master &&\n+\t\tgit worktree add --detach here master &&\n \t\tcd here &&\n \t\ttest_cmp ../../init.t init.t\n \t)\n '\n \n-test_expect_success 'checkout --to from a linked checkout' '\n+test_expect_success '\"add\" from a linked checkout' '\n \t(\n \t\tcd here &&\n-\t\tgit checkout --detach --to nested-here master &&\n+\t\tgit worktree add --detach nested-here master &&\n \t\tcd nested-here &&\n \t\tgit fsck\n \t)\n '\n \n-test_expect_success 'checkout --to a new worktree creating new branch' '\n-\tgit checkout --to there -b newmaster master &&\n+test_expect_success '\"add\" worktree creating new branch' '\n+\tgit worktree add -b newmaster there master &&\n \t(\n \t\tcd there &&\n \t\ttest_cmp ../init.t init.t &&\n@@ -90,7 +86,7 @@ test_expect_success 'die the same branch is already checked out' '\n test_expect_success 'not die the same branch is already checked out' '\n \t(\n \t\tcd here &&\n-\t\tgit checkout --ignore-other-worktrees --to anothernewmaster newmaster\n+\t\tgit worktree add --force anothernewmaster newmaster\n \t)\n '\n \n@@ -101,15 +97,15 @@ test_expect_success 'not die on re-checking out current branch' '\n \t)\n '\n \n-test_expect_success 'checkout --to from a bare repo' '\n+test_expect_success '\"add\" from a bare repo' '\n \t(\n \t\tgit clone --bare . bare &&\n \t\tcd bare &&\n-\t\tgit checkout --to ../there2 -b bare-master master\n+\t\tgit worktree add -b bare-master ../there2 master\n \t)\n '\n \n-test_expect_success 'checkout from a bare repo without --to' '\n+test_expect_success 'checkout from a bare repo without \"add\"' '\n \t(\n \t\tcd bare &&\n \t\ttest_must_fail git checkout master\n@@ -129,17 +125,17 @@ test_expect_success 'checkout with grafts' '\n \tEOF\n \tgit log --format=%s -2 >actual &&\n \ttest_cmp expected actual &&\n-\tgit checkout --detach --to grafted master &&\n+\tgit worktree add --detach grafted master &&\n \tgit --git-dir=grafted/.git log --format=%s -2 >actual &&\n \ttest_cmp expected actual\n '\n \n-test_expect_success 'checkout --to from relative HEAD' '\n+test_expect_success '\"add\" from relative HEAD' '\n \ttest_commit a &&\n \ttest_commit b &&\n \ttest_commit c &&\n \tgit rev-parse HEAD~1 >expected &&\n-\tgit checkout --to relhead HEAD~1 &&\n+\tgit worktree add relhead HEAD~1 &&\n \tgit -C relhead rev-parse HEAD >actual &&\n \ttest_cmp expected actual\n '\ndiff --git a/t/t2026-prune-linked-checkouts.sh b/t/t2026-prune-linked-checkouts.sh\nindex e872f02..a0f1e3b 100755\n--- a/t/t2026-prune-linked-checkouts.sh\n+++ b/t/t2026-prune-linked-checkouts.sh\n@@ -88,7 +88,7 @@ test_expect_success 'not prune recent checkouts' '\n \n test_expect_success 'not prune proper checkouts' '\n \ttest_when_finished rm -r .git/worktrees &&\n-\tgit checkout \"--to=$PWD/nop\" --detach master &&\n+\tgit worktree add --detach \"$PWD/nop\" master &&\n \tgit worktree prune &&\n \ttest -d .git/worktrees/nop\n '\ndiff --git a/t/t7410-submodule-checkout-to.sh b/t/t7410-submodule-checkout-to.sh\nindex 8f30aed..3f609e8 100755\n--- a/t/t7410-submodule-checkout-to.sh\n+++ b/t/t7410-submodule-checkout-to.sh\n@@ -33,7 +33,7 @@ rev1_hash_sub=$(git --git-dir=origin/sub/.git show --pretty=format:%h -q \"HEAD~1\n test_expect_success 'checkout main' \\\n     'mkdir default_checkout &&\n     (cd clone/main &&\n-\tgit checkout --to \"$base_path/default_checkout/main\" \"$rev1_hash_main\")'\n+\tgit worktree add \"$base_path/default_checkout/main\" \"$rev1_hash_main\")'\n \n test_expect_failure 'can see submodule diffs just after checkout' \\\n     '(cd default_checkout/main && git diff --submodule master\"^!\" | grep \"file1 updated\")'\n@@ -41,7 +41,7 @@ test_expect_failure 'can see submodule diffs just after checkout' \\\n test_expect_success 'checkout main and initialize independed clones' \\\n     'mkdir fully_cloned_submodule &&\n     (cd clone/main &&\n-\tgit checkout --to \"$base_path/fully_cloned_submodule/main\" \"$rev1_hash_main\") &&\n+\tgit worktree add \"$base_path/fully_cloned_submodule/main\" \"$rev1_hash_main\") &&\n     (cd fully_cloned_submodule/main && git submodule update)'\n \n test_expect_success 'can see submodule diffs after independed cloning' \\\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265500","messageId":"1435969052-540-19-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 18/23] checkout: retire --to option","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:27Z","receivedAt":"2015-07-04T00:17:27Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"Now that \"git worktree add\" has achieved user-facing feature-parity with\n\"git checkout --to\", retire the latter.\n\nMove the actual linked worktree creation functionality,\nprepare_linked_checkout() and its helpers, verbatim from checkout.c to\nworktree.c.\n\nThis effectively reverts changes to checkout.c by 529fef2 (checkout:\nsupport checking out into a new working directory, 2014-11-30) with the\nexception of merge_working_tree() and switch_branches() which still\nrequire specialized knowledge that a the checkout is occurring in a\nnewly-created linked worktree (signaled to them by the private\nGIT_CHECKOUT_NEW_WORKTREE environment variable).\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n builtin/checkout.c | 156 +----------------------------------------------------\n builtin/worktree.c | 138 ++++++++++++++++++++++++++++++++++++++++++++---\n 2 files changed, 133 insertions(+), 161 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 30fe786..b1e68b3 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -19,8 +19,6 @@\n #include \"ll-merge.h\"\n #include \"resolve-undo.h\"\n #include \"submodule.h\"\n-#include \"argv-array.h\"\n-#include \"sigchain.h\"\n \n static const char * const checkout_usage[] = {\n \tN_(\"git checkout [options] <branch>\"),\n@@ -51,8 +49,6 @@ struct checkout_opts {\n \tstruct pathspec pathspec;\n \tstruct tree *source_tree;\n \n-\tconst char *new_worktree;\n-\tconst char **saved_argv;\n \tint new_worktree_mode;\n };\n \n@@ -255,9 +251,6 @@ static int checkout_paths(const struct checkout_opts *opts,\n \t\tdie(_(\"Cannot update paths and switch to branch '%s' at the same time.\"),\n \t\t    opts->new_branch);\n \n-\tif (opts->new_worktree)\n-\t\tdie(_(\"'%s' cannot be used with updating paths\"), \"--to\");\n-\n \tif (opts->patch_mode)\n \t\treturn run_add_interactive(revision, \"--patch=checkout\",\n \t\t\t\t\t   &opts->pathspec);\n@@ -825,137 +818,6 @@ static int switch_branches(const struct checkout_opts *opts,\n \treturn ret || writeout_error;\n }\n \n-static char *junk_work_tree;\n-static char *junk_git_dir;\n-static int is_junk;\n-static pid_t junk_pid;\n-\n-static void remove_junk(void)\n-{\n-\tstruct strbuf sb = STRBUF_INIT;\n-\tif (!is_junk || getpid() != junk_pid)\n-\t\treturn;\n-\tif (junk_git_dir) {\n-\t\tstrbuf_addstr(&sb, junk_git_dir);\n-\t\tremove_dir_recursively(&sb, 0);\n-\t\tstrbuf_reset(&sb);\n-\t}\n-\tif (junk_work_tree) {\n-\t\tstrbuf_addstr(&sb, junk_work_tree);\n-\t\tremove_dir_recursively(&sb, 0);\n-\t}\n-\tstrbuf_release(&sb);\n-}\n-\n-static void remove_junk_on_signal(int signo)\n-{\n-\tremove_junk();\n-\tsigchain_pop(signo);\n-\traise(signo);\n-}\n-\n-static int prepare_linked_checkout(const char *path, const char **child_argv)\n-{\n-\tstruct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;\n-\tstruct strbuf sb = STRBUF_INIT;\n-\tconst char *name;\n-\tstruct stat st;\n-\tstruct child_process cp;\n-\tint counter = 0, len, ret;\n-\tunsigned char rev[20];\n-\n-\tif (file_exists(path) && !is_empty_dir(path))\n-\t\tdie(_(\"'%s' already exists\"), path);\n-\n-\tlen = strlen(path);\n-\twhile (len && is_dir_sep(path[len - 1]))\n-\t\tlen--;\n-\n-\tfor (name = path + len - 1; name > path; name--)\n-\t\tif (is_dir_sep(*name)) {\n-\t\t\tname++;\n-\t\t\tbreak;\n-\t\t}\n-\tstrbuf_addstr(&sb_repo,\n-\t\t      git_path(\"worktrees/%.*s\", (int)(path + len - name), name));\n-\tlen = sb_repo.len;\n-\tif (safe_create_leading_directories_const(sb_repo.buf))\n-\t\tdie_errno(_(\"could not create leading directories of '%s'\"),\n-\t\t\t  sb_repo.buf);\n-\twhile (!stat(sb_repo.buf, &st)) {\n-\t\tcounter++;\n-\t\tstrbuf_setlen(&sb_repo, len);\n-\t\tstrbuf_addf(&sb_repo, \"%d\", counter);\n-\t}\n-\tname = strrchr(sb_repo.buf, '/') + 1;\n-\n-\tjunk_pid = getpid();\n-\tatexit(remove_junk);\n-\tsigchain_push_common(remove_junk_on_signal);\n-\n-\tif (mkdir(sb_repo.buf, 0777))\n-\t\tdie_errno(_(\"could not create directory of '%s'\"), sb_repo.buf);\n-\tjunk_git_dir = xstrdup(sb_repo.buf);\n-\tis_junk = 1;\n-\n-\t/*\n-\t * lock the incomplete repo so prune won't delete it, unlock\n-\t * after the preparation is over.\n-\t */\n-\tstrbuf_addf(&sb, \"%s/locked\", sb_repo.buf);\n-\twrite_file(sb.buf, 1, \"initializing\\n\");\n-\n-\tstrbuf_addf(&sb_git, \"%s/.git\", path);\n-\tif (safe_create_leading_directories_const(sb_git.buf))\n-\t\tdie_errno(_(\"could not create leading directories of '%s'\"),\n-\t\t\t  sb_git.buf);\n-\tjunk_work_tree = xstrdup(path);\n-\n-\tstrbuf_reset(&sb);\n-\tstrbuf_addf(&sb, \"%s/gitdir\", sb_repo.buf);\n-\twrite_file(sb.buf, 1, \"%s\\n\", real_path(sb_git.buf));\n-\twrite_file(sb_git.buf, 1, \"gitdir: %s/worktrees/%s\\n\",\n-\t\t   real_path(get_git_common_dir()), name);\n-\t/*\n-\t * This is to keep resolve_ref() happy. We need a valid HEAD\n-\t * or is_git_directory() will reject the directory. Any valid\n-\t * value would do because this value will be ignored and\n-\t * replaced at the next (real) checkout.\n-\t */\n-\tif (!resolve_ref_unsafe(\"HEAD\", 0, rev, NULL))\n-\t\tdie(_(\"unable to resolve HEAD\"));\n-\tstrbuf_reset(&sb);\n-\tstrbuf_addf(&sb, \"%s/HEAD\", sb_repo.buf);\n-\twrite_file(sb.buf, 1, \"%s\\n\", sha1_to_hex(rev));\n-\tstrbuf_reset(&sb);\n-\tstrbuf_addf(&sb, \"%s/commondir\", sb_repo.buf);\n-\twrite_file(sb.buf, 1, \"../..\\n\");\n-\n-\tfprintf_ln(stderr, _(\"Enter %s (identifier %s)\"), path, name);\n-\n-\tsetenv(\"GIT_CHECKOUT_NEW_WORKTREE\", \"1\", 1);\n-\tsetenv(GIT_DIR_ENVIRONMENT, sb_git.buf, 1);\n-\tsetenv(GIT_WORK_TREE_ENVIRONMENT, path, 1);\n-\tmemset(&cp, 0, sizeof(cp));\n-\tcp.git_cmd = 1;\n-\tcp.argv = child_argv;\n-\tret = run_command(&cp);\n-\tif (!ret) {\n-\t\tis_junk = 0;\n-\t\tfree(junk_work_tree);\n-\t\tfree(junk_git_dir);\n-\t\tjunk_work_tree = NULL;\n-\t\tjunk_git_dir = NULL;\n-\t}\n-\tstrbuf_reset(&sb);\n-\tstrbuf_addf(&sb, \"%s/locked\", sb_repo.buf);\n-\tunlink_or_warn(sb.buf);\n-\tstrbuf_release(&sb);\n-\tstrbuf_release(&sb_repo);\n-\tstrbuf_release(&sb_git);\n-\treturn ret;\n-}\n-\n static int git_checkout_config(const char *var, const char *value, void *cb)\n {\n \tif (!strcmp(var, \"diff.ignoresubmodules\")) {\n@@ -1294,13 +1156,6 @@ static int checkout_branch(struct checkout_opts *opts,\n \t\tfree(head_ref);\n \t}\n \n-\tif (opts->new_worktree) {\n-\t\tif (!new->commit)\n-\t\t\tdie(_(\"no branch specified\"));\n-\t\treturn prepare_linked_checkout(opts->new_worktree,\n-\t\t\t\t\t       opts->saved_argv);\n-\t}\n-\n \tif (!new->commit && opts->new_branch) {\n \t\tunsigned char rev[20];\n \t\tint flag;\n@@ -1343,8 +1198,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t\t\t N_(\"do not limit pathspecs to sparse entries only\")),\n \t\tOPT_HIDDEN_BOOL(0, \"guess\", &dwim_new_local_branch,\n \t\t\t\tN_(\"second guess 'git checkout no-such-branch'\")),\n-\t\tOPT_FILENAME(0, \"to\", &opts.new_worktree,\n-\t\t\t   N_(\"check a branch out in a separate working directory\")),\n \t\tOPT_BOOL(0, \"ignore-other-worktrees\", &opts.ignore_other_worktrees,\n \t\t\t N_(\"do not check if another worktree is holding the given ref\")),\n \t\tOPT_END(),\n@@ -1355,9 +1208,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \topts.overwrite_ignore = 1;\n \topts.prefix = prefix;\n \n-\topts.saved_argv = xmalloc(sizeof(const char *) * (argc + 2));\n-\tmemcpy(opts.saved_argv, argv, sizeof(const char *) * (argc + 1));\n-\n \tgitmodules_config();\n \tgit_config(git_checkout_config, &opts);\n \n@@ -1366,13 +1216,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \targc = parse_options(argc, argv, prefix, options, checkout_usage,\n \t\t\t     PARSE_OPT_KEEP_DASHDASH);\n \n-\t/* recursive execution from checkout_new_worktree() */\n \topts.new_worktree_mode = getenv(\"GIT_CHECKOUT_NEW_WORKTREE\") != NULL;\n-\tif (opts.new_worktree_mode)\n-\t\topts.new_worktree = NULL;\n \n-\tif (!opts.new_worktree)\n-\t\tsetup_work_tree();\n+\tsetup_work_tree();\n \n \tif (conflict_style) {\n \t\topts.merge = 1; /* implied */\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex d461d31..7cfaec6 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -4,6 +4,7 @@\n #include \"parse-options.h\"\n #include \"argv-array.h\"\n #include \"run-command.h\"\n+#include \"sigchain.h\"\n \n static const char * const worktree_usage[] = {\n \tN_(\"git worktree add [<options>] <path> <branch>\"),\n@@ -122,10 +123,139 @@ static int prune(int ac, const char **av, const char *prefix)\n \treturn 0;\n }\n \n+static char *junk_work_tree;\n+static char *junk_git_dir;\n+static int is_junk;\n+static pid_t junk_pid;\n+\n+static void remove_junk(void)\n+{\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tif (!is_junk || getpid() != junk_pid)\n+\t\treturn;\n+\tif (junk_git_dir) {\n+\t\tstrbuf_addstr(&sb, junk_git_dir);\n+\t\tremove_dir_recursively(&sb, 0);\n+\t\tstrbuf_reset(&sb);\n+\t}\n+\tif (junk_work_tree) {\n+\t\tstrbuf_addstr(&sb, junk_work_tree);\n+\t\tremove_dir_recursively(&sb, 0);\n+\t}\n+\tstrbuf_release(&sb);\n+}\n+\n+static void remove_junk_on_signal(int signo)\n+{\n+\tremove_junk();\n+\tsigchain_pop(signo);\n+\traise(signo);\n+}\n+\n+static int add_worktree(const char *path, const char **child_argv)\n+{\n+\tstruct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tconst char *name;\n+\tstruct stat st;\n+\tstruct child_process cp;\n+\tint counter = 0, len, ret;\n+\tunsigned char rev[20];\n+\n+\tif (file_exists(path) && !is_empty_dir(path))\n+\t\tdie(_(\"'%s' already exists\"), path);\n+\n+\tlen = strlen(path);\n+\twhile (len && is_dir_sep(path[len - 1]))\n+\t\tlen--;\n+\n+\tfor (name = path + len - 1; name > path; name--)\n+\t\tif (is_dir_sep(*name)) {\n+\t\t\tname++;\n+\t\t\tbreak;\n+\t\t}\n+\tstrbuf_addstr(&sb_repo,\n+\t\t      git_path(\"worktrees/%.*s\", (int)(path + len - name), name));\n+\tlen = sb_repo.len;\n+\tif (safe_create_leading_directories_const(sb_repo.buf))\n+\t\tdie_errno(_(\"could not create leading directories of '%s'\"),\n+\t\t\t  sb_repo.buf);\n+\twhile (!stat(sb_repo.buf, &st)) {\n+\t\tcounter++;\n+\t\tstrbuf_setlen(&sb_repo, len);\n+\t\tstrbuf_addf(&sb_repo, \"%d\", counter);\n+\t}\n+\tname = strrchr(sb_repo.buf, '/') + 1;\n+\n+\tjunk_pid = getpid();\n+\tatexit(remove_junk);\n+\tsigchain_push_common(remove_junk_on_signal);\n+\n+\tif (mkdir(sb_repo.buf, 0777))\n+\t\tdie_errno(_(\"could not create directory of '%s'\"), sb_repo.buf);\n+\tjunk_git_dir = xstrdup(sb_repo.buf);\n+\tis_junk = 1;\n+\n+\t/*\n+\t * lock the incomplete repo so prune won't delete it, unlock\n+\t * after the preparation is over.\n+\t */\n+\tstrbuf_addf(&sb, \"%s/locked\", sb_repo.buf);\n+\twrite_file(sb.buf, 1, \"initializing\\n\");\n+\n+\tstrbuf_addf(&sb_git, \"%s/.git\", path);\n+\tif (safe_create_leading_directories_const(sb_git.buf))\n+\t\tdie_errno(_(\"could not create leading directories of '%s'\"),\n+\t\t\t  sb_git.buf);\n+\tjunk_work_tree = xstrdup(path);\n+\n+\tstrbuf_reset(&sb);\n+\tstrbuf_addf(&sb, \"%s/gitdir\", sb_repo.buf);\n+\twrite_file(sb.buf, 1, \"%s\\n\", real_path(sb_git.buf));\n+\twrite_file(sb_git.buf, 1, \"gitdir: %s/worktrees/%s\\n\",\n+\t\t   real_path(get_git_common_dir()), name);\n+\t/*\n+\t * This is to keep resolve_ref() happy. We need a valid HEAD\n+\t * or is_git_directory() will reject the directory. Any valid\n+\t * value would do because this value will be ignored and\n+\t * replaced at the next (real) checkout.\n+\t */\n+\tif (!resolve_ref_unsafe(\"HEAD\", 0, rev, NULL))\n+\t\tdie(_(\"unable to resolve HEAD\"));\n+\tstrbuf_reset(&sb);\n+\tstrbuf_addf(&sb, \"%s/HEAD\", sb_repo.buf);\n+\twrite_file(sb.buf, 1, \"%s\\n\", sha1_to_hex(rev));\n+\tstrbuf_reset(&sb);\n+\tstrbuf_addf(&sb, \"%s/commondir\", sb_repo.buf);\n+\twrite_file(sb.buf, 1, \"../..\\n\");\n+\n+\tfprintf_ln(stderr, _(\"Enter %s (identifier %s)\"), path, name);\n+\n+\tsetenv(\"GIT_CHECKOUT_NEW_WORKTREE\", \"1\", 1);\n+\tsetenv(GIT_DIR_ENVIRONMENT, sb_git.buf, 1);\n+\tsetenv(GIT_WORK_TREE_ENVIRONMENT, path, 1);\n+\tmemset(&cp, 0, sizeof(cp));\n+\tcp.git_cmd = 1;\n+\tcp.argv = child_argv;\n+\tret = run_command(&cp);\n+\tif (!ret) {\n+\t\tis_junk = 0;\n+\t\tfree(junk_work_tree);\n+\t\tfree(junk_git_dir);\n+\t\tjunk_work_tree = NULL;\n+\t\tjunk_git_dir = NULL;\n+\t}\n+\tstrbuf_reset(&sb);\n+\tstrbuf_addf(&sb, \"%s/locked\", sb_repo.buf);\n+\tunlink_or_warn(sb.buf);\n+\tstrbuf_release(&sb);\n+\tstrbuf_release(&sb_repo);\n+\tstrbuf_release(&sb_git);\n+\treturn ret;\n+}\n \n static int add(int ac, const char **av, const char *prefix)\n {\n-\tstruct child_process c;\n \tint force = 0, detach = 0;\n \tconst char *new_branch = NULL, *new_branch_force = NULL;\n \tconst char *path, *branch;\n@@ -150,7 +280,6 @@ static int add(int ac, const char **av, const char *prefix)\n \tbranch = av[1];\n \n \targv_array_push(&cmd, \"checkout\");\n-\targv_array_pushl(&cmd, \"--to\", path, NULL);\n \tif (force)\n \t\targv_array_push(&cmd, \"--ignore-other-worktrees\");\n \tif (new_branch)\n@@ -161,10 +290,7 @@ static int add(int ac, const char **av, const char *prefix)\n \t\targv_array_push(&cmd, \"--detach\");\n \targv_array_push(&cmd, branch);\n \n-\tmemset(&c, 0, sizeof(c));\n-\tc.git_cmd = 1;\n-\tc.argv = cmd.argv;\n-\treturn run_command(&c);\n+\treturn add_worktree(path, cmd.argv);\n }\n \n int cmd_worktree(int ac, const char **av, const char *prefix)\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265496","messageId":"1435969052-540-20-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 19/23] checkout: require worktree unconditionally","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:28Z","receivedAt":"2015-07-04T00:17:28Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"In order to allow linked worktree creation via \"git checkout -b\" from a\nbare repository, 3473ad0 (checkout: don't require a work tree when\nchecking out into a new one, 2014-11-30) dropped git-checkout's\nunconditional NEED_WORK_TREE requirement and instead performed worktree\nsetup conditionally based upon presence or absence of the --to option.\nNow that --to has been retired and git-checkout is no longer responsible\nfor linked worktree creation, the NEED_WORK_TREE requirement can once\nagain be unconditional.\n\nThis effectively reverts 3473ad0, except for the tests it added which\nnow check bare repository behavior of \"git worktree add\" instead.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n builtin/checkout.c | 2 --\n git.c              | 2 +-\n 2 files changed, 1 insertion(+), 3 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex b1e68b3..5754554 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -1218,8 +1218,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \n \topts.new_worktree_mode = getenv(\"GIT_CHECKOUT_NEW_WORKTREE\") != NULL;\n \n-\tsetup_work_tree();\n-\n \tif (conflict_style) {\n \t\topts.merge = 1; /* implied */\n \t\tgit_xmerge_config(\"merge.conflictstyle\", conflict_style, NULL);\ndiff --git a/git.c b/git.c\nindex f227838..21a6398 100644\n--- a/git.c\n+++ b/git.c\n@@ -383,7 +383,7 @@ static struct cmd_struct commands[] = {\n \t{ \"check-ignore\", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE },\n \t{ \"check-mailmap\", cmd_check_mailmap, RUN_SETUP },\n \t{ \"check-ref-format\", cmd_check_ref_format },\n-\t{ \"checkout\", cmd_checkout, RUN_SETUP },\n+\t{ \"checkout\", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },\n \t{ \"checkout-index\", cmd_checkout_index,\n \t\tRUN_SETUP | NEED_WORK_TREE},\n \t{ \"cherry\", cmd_cherry, RUN_SETUP },\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265497","messageId":"1435969052-540-21-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 20/23] worktree: extract basename computation to new function","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:29Z","receivedAt":"2015-07-04T00:17:29Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"A subsequent patch will also need to compute the basename of the new\nworktree, so factor out this logic into a new function.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n builtin/worktree.c | 29 ++++++++++++++++++++---------\n 1 file changed, 20 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 7cfaec6..a1d863d 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -152,6 +152,25 @@ static void remove_junk_on_signal(int signo)\n \traise(signo);\n }\n \n+static const char *worktree_basename(const char *path, int *olen)\n+{\n+\tconst char *name;\n+\tint len;\n+\n+\tlen = strlen(path);\n+\twhile (len && is_dir_sep(path[len - 1]))\n+\t\tlen--;\n+\n+\tfor (name = path + len - 1; name > path; name--)\n+\t\tif (is_dir_sep(*name)) {\n+\t\t\tname++;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t*olen = len;\n+\treturn name;\n+}\n+\n static int add_worktree(const char *path, const char **child_argv)\n {\n \tstruct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;\n@@ -165,15 +184,7 @@ static int add_worktree(const char *path, const char **child_argv)\n \tif (file_exists(path) && !is_empty_dir(path))\n \t\tdie(_(\"'%s' already exists\"), path);\n \n-\tlen = strlen(path);\n-\twhile (len && is_dir_sep(path[len - 1]))\n-\t\tlen--;\n-\n-\tfor (name = path + len - 1; name > path; name--)\n-\t\tif (is_dir_sep(*name)) {\n-\t\t\tname++;\n-\t\t\tbreak;\n-\t\t}\n+\tname = worktree_basename(path, &len);\n \tstrbuf_addstr(&sb_repo,\n \t\t      git_path(\"worktrees/%.*s\", (int)(path + len - name), name));\n \tlen = sb_repo.len;\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265499","messageId":"1435969052-540-22-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 21/23] worktree: add: make -b/-B default to HEAD when <branch> is omitted","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:30Z","receivedAt":"2015-07-04T00:17:30Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"As a convenience, like \"git branch\" and \"git checkout -b\", make\n\"git worktree add -b <newbranch> <path> <branch>\" default to HEAD when\n<branch> is omitted.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n Documentation/git-worktree.txt | 1 +\n builtin/worktree.c             | 6 ++++--\n t/t2025-worktree-add.sh        | 7 +++++++\n 3 files changed, 12 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex f6c3747..5ca11f6 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -69,6 +69,7 @@ OPTIONS\n -B <new-branch>::\n \tWith `add`, create a new branch named `<new-branch>` starting at\n \t`<branch>`, and check out `<new-branch>` into the new worktree.\n+\tIf `<branch>` is omitted, it defaults to HEAD.\n \tBy default, `-b` refuses to create a new branch if it already\n \texists. `-B` overrides this safeguard, resetting `<new-branch>` to\n \t`<branch>`.\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex a1d863d..bf634a6 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -284,11 +284,13 @@ static int add(int ac, const char **av, const char *prefix)\n \tac = parse_options(ac, av, prefix, options, worktree_usage, 0);\n \tif (new_branch && new_branch_force)\n \t\tdie(_(\"-b and -B are mutually exclusive\"));\n-\tif (ac != 2)\n+\tif (ac < 1 || ac > 2)\n+\t\tusage_with_options(worktree_usage, options);\n+\tif (ac < 2 && !new_branch && !new_branch_force)\n \t\tusage_with_options(worktree_usage, options);\n \n \tpath = prefix ? prefix_filename(prefix, strlen(prefix), av[0]) : av[0];\n-\tbranch = av[1];\n+\tbranch = ac < 2 ? \"HEAD\" : av[1];\n \n \targv_array_push(&cmd, \"checkout\");\n \tif (force)\ndiff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh\nindex 192c936..95a1141 100755\n--- a/t/t2025-worktree-add.sh\n+++ b/t/t2025-worktree-add.sh\n@@ -140,4 +140,11 @@ test_expect_success '\"add\" from relative HEAD' '\n \ttest_cmp expected actual\n '\n \n+test_expect_success '\"add -b\" with <branch> omitted' '\n+\tgit rev-parse HEAD >expected &&\n+\tgit worktree add -b burble flornk &&\n+\tgit rev-parse burble >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265502","messageId":"1435969052-540-23-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 22/23] worktree: add: auto-vivify new branch when <branch> is omitted","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:31Z","receivedAt":"2015-07-04T00:17:31Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"As a convenience, when <branch> is omitted from \"git worktree <path>\n<branch>\" and neither -b nor -B used, automatically create a new branch\nnamed after <path>, as if \"-b $(basename <path>)\" was specified. Thus,\n\"git worktree add ../hotfix\" creates a new branch named \"hotfix\" and\nassociates it with new worktree \"../hotfix\".\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n Documentation/git-worktree.txt | 8 ++++++--\n builtin/worktree.c             | 8 ++++++--\n t/t2025-worktree-add.sh        | 7 +++++++\n 3 files changed, 19 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 5ca11f6..938bdab 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -9,7 +9,7 @@ git-worktree - Manage multiple worktrees\n SYNOPSIS\n --------\n [verse]\n-'git worktree add' [-f] [--detach] [-b <new-branch>] <path> <branch>\n+'git worktree add' [-f] [--detach] [-b <new-branch>] <path> [<branch>]\n 'git worktree prune' [-n] [-v] [--expire <expire>]\n \n DESCRIPTION\n@@ -45,12 +45,16 @@ pruning should be suppressed. See section \"DETAILS\" for more information.\n \n COMMANDS\n --------\n-add <path> <branch>::\n+add <path> [<branch>]::\n \n Check out `<branch>` into a separate working directory, `<path>`, creating\n `<path>` if necessary. The new working directory is linked to the current\n repository, sharing everything except working directory specific files\n such as HEAD, index, etc. If `<path>` already exists, it must be empty.\n++\n+If `<branch>` is omitted and neither `-b` nor `-B` used, then, as a\n+convenience, a new branch rooted at HEAD is created automatically, as if\n+`-b $(basename <path>)` was specified.\n \n prune::\n \ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex bf634a6..c8c6fa7 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -286,12 +286,16 @@ static int add(int ac, const char **av, const char *prefix)\n \t\tdie(_(\"-b and -B are mutually exclusive\"));\n \tif (ac < 1 || ac > 2)\n \t\tusage_with_options(worktree_usage, options);\n-\tif (ac < 2 && !new_branch && !new_branch_force)\n-\t\tusage_with_options(worktree_usage, options);\n \n \tpath = prefix ? prefix_filename(prefix, strlen(prefix), av[0]) : av[0];\n \tbranch = ac < 2 ? \"HEAD\" : av[1];\n \n+\tif (ac < 2 && !new_branch && !new_branch_force) {\n+\t\tint n;\n+\t\tconst char *s = worktree_basename(path, &n);\n+\t\tnew_branch = xstrndup(s, n);\n+\t}\n+\n \targv_array_push(&cmd, \"checkout\");\n \tif (force)\n \t\targv_array_push(&cmd, \"--ignore-other-worktrees\");\ndiff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh\nindex 95a1141..59d73ff 100755\n--- a/t/t2025-worktree-add.sh\n+++ b/t/t2025-worktree-add.sh\n@@ -147,4 +147,11 @@ test_expect_success '\"add -b\" with <branch> omitted' '\n \ttest_cmp expected actual\n '\n \n+test_expect_success '\"add\" with <branch> omitted' '\n+\tgit rev-parse HEAD >expected &&\n+\tgit worktree add wiffle/bat &&\n+\tgit rev-parse bat >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265501","messageId":"1435969052-540-24-git-send-email-sunshine@sunshineco.com","threadId":"39777","inReplyTo":"1435969052-540-1-git-send-email-sunshine@sunshineco.com","subject":"[PATCH v2 23/23] checkout: retire --ignore-other-worktrees in favor of --force","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T00:17:32Z","receivedAt":"2015-07-04T00:17:32Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"As a safeguard, checking out a branch already checked out by a different\nworktree is disallowed. This behavior can be overridden with\n--ignore-other-worktrees, however, this option is neither obvious nor\nparticularly discoverable. As a common safeguard override, --force is\nmore likely to come to mind. Therefore, overload it to also suppress the\ncheck for a branch already checked out elsewhere.\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n\nI plopped this patch at the end of the series so that it can be dropped\neasily if desired since Junio indicated[1] that he would \"moderately\nobject\" to this change.\n\n[1]: http://thread.gmane.org/gmane.comp.version-control.git/273032/focus=273108\n\n Documentation/git-checkout.txt | 9 +++------\n builtin/checkout.c             | 8 +++-----\n builtin/worktree.c             | 2 +-\n 3 files changed, 7 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\nindex 77b7141..41148ce 100644\n--- a/Documentation/git-checkout.txt\n+++ b/Documentation/git-checkout.txt\n@@ -111,6 +111,9 @@ OPTIONS\n +\n When checking out paths from the index, do not fail upon unmerged\n entries; instead, unmerged entries are ignored.\n++\n+By default, checking out a branch already checked out in another worktree\n+is disallowed. This overrides that safeguard.\n \n --ours::\n --theirs::\n@@ -232,12 +235,6 @@ section of linkgit:git-add[1] to learn how to operate the `--patch` mode.\n \tspecific files such as HEAD, index, etc. See\n \tlinkgit:git-worktree[1] for a description of linked worktrees.\n \n---ignore-other-worktrees::\n-\t`git checkout` refuses when the wanted ref is already checked\n-\tout by another worktree. This option makes it check the ref\n-\tout anyway. In other words, the ref can be held by more than one\n-\tworktree.\n-\n <branch>::\n \tBranch to checkout; if it refers to a branch (i.e., a name that,\n \twhen prepended with \"refs/heads/\", is a valid ref), then that\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 5754554..01c7c30 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -35,7 +35,6 @@ struct checkout_opts {\n \tint writeout_stage;\n \tint overwrite_ignore;\n \tint ignore_skipworktree;\n-\tint ignore_other_worktrees;\n \n \tconst char *new_branch;\n \tconst char *new_branch_force;\n@@ -903,7 +902,8 @@ static void check_linked_checkout(struct branch_info *new, const char *id)\n \t\tstrbuf_rtrim(&gitdir);\n \t} else\n \t\tstrbuf_addstr(&gitdir, get_git_common_dir());\n-\tdie(_(\"'%s' is already checked out at '%s'\"), new->name, gitdir.buf);\n+\tdie(_(\"'%s' is already checked out at '%s'; use --force to override\"),\n+\t    new->name, gitdir.buf);\n done:\n \tstrbuf_release(&path);\n \tstrbuf_release(&sb);\n@@ -1151,7 +1151,7 @@ static int checkout_branch(struct checkout_opts *opts,\n \t\tchar *head_ref = resolve_refdup(\"HEAD\", 0, sha1, &flag);\n \t\tif (head_ref &&\n \t\t    (!(flag & REF_ISSYMREF) || strcmp(head_ref, new->path)) &&\n-\t\t    !opts->ignore_other_worktrees)\n+\t\t    !opts->force)\n \t\t\tcheck_linked_checkouts(new);\n \t\tfree(head_ref);\n \t}\n@@ -1198,8 +1198,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t\t\t N_(\"do not limit pathspecs to sparse entries only\")),\n \t\tOPT_HIDDEN_BOOL(0, \"guess\", &dwim_new_local_branch,\n \t\t\t\tN_(\"second guess 'git checkout no-such-branch'\")),\n-\t\tOPT_BOOL(0, \"ignore-other-worktrees\", &opts.ignore_other_worktrees,\n-\t\t\t N_(\"do not check if another worktree is holding the given ref\")),\n \t\tOPT_END(),\n \t};\n \ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex c8c6fa7..8a6c7fa 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -298,7 +298,7 @@ static int add(int ac, const char **av, const char *prefix)\n \n \targv_array_push(&cmd, \"checkout\");\n \tif (force)\n-\t\targv_array_push(&cmd, \"--ignore-other-worktrees\");\n+\t\targv_array_push(&cmd, \"--force\");\n \tif (new_branch)\n \t\targv_array_pushl(&cmd, \"-b\", new_branch, NULL);\n \tif (new_branch_force)\n-- \n2.5.0.rc1.197.g417e668\n"},{"id":"265511","messageId":"CAPig+cRM=MA=1DtTrFA0PoHkmvZK8y7Y4gLLxSsHA+5sU47tow@mail.gmail.com","threadId":"39777","inReplyTo":"1435969052-540-8-git-send-email-sunshine@sunshineco.com","subject":"Re: [PATCH v2 07/23] Documentation/git-worktree: add EXAMPLES section","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T02:23:00Z","receivedAt":"2015-07-04T02:23:00Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Jul 3, 2015 at 8:17 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>\n> ---\n> +EXAMPLES\n> +--------\n> +You are middle of a refactoring session and your boss comes in and demands\n\ns/middle/in the &/\n\n> +that you fix something immediately. You might typically use\n> +linkgit:git-stash[1] to store your changes away temporarily, however, your\n> +worktree is in such a state of disarray (with new, removed, moved files,\n> +and other bits and pieces strewn around) that you don't want to risk\n> +disturbing any of it. Instead, you create a temporary linked worktree to\n> +make the emergency fix, remove it when done, and then resume your earlier\n> +refactoring session.\n> +\n> +------------\n> +$ git branch emergency-fix master\n> +$ git checkout --to ../temp emergency-fix\n> +$ pushd ../temp\n> +# ... hack hack hack ...\n> +$ git commit -a -m 'emergency fix for boss'\n> +$ popd\n> +$ rm -rf ../temp\n> +$ git worktree prune\n> +------------\n> +\n>  BUGS\n>  ----\n>  Multiple checkout support for submodules is incomplete. It is NOT\n> --\n> 2.5.0.rc1.197.g417e668\n"},{"id":"265512","messageId":"CAPig+cRr322OrZkTRfk7fxCR8X2P7mXaBZSDA2_79bxBpWQK6g@mail.gmail.com","threadId":"39777","inReplyTo":"1435969052-540-20-git-send-email-sunshine@sunshineco.com","subject":"Re: [PATCH v2 19/23] checkout: require worktree unconditionally","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T02:33:00Z","receivedAt":"2015-07-04T02:33:00Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Jul 3, 2015 at 8:17 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> In order to allow linked worktree creation via \"git checkout -b\" from a\n\ns/-b/--to/\n\n> bare repository, 3473ad0 (checkout: don't require a work tree when\n> checking out into a new one, 2014-11-30) dropped git-checkout's\n> unconditional NEED_WORK_TREE requirement and instead performed worktree\n> setup conditionally based upon presence or absence of the --to option.\n> Now that --to has been retired and git-checkout is no longer responsible\n> for linked worktree creation, the NEED_WORK_TREE requirement can once\n> again be unconditional.\n>\n> This effectively reverts 3473ad0, except for the tests it added which\n> now check bare repository behavior of \"git worktree add\" instead.\n>\n> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>\n> ---\n>  builtin/checkout.c | 2 --\n>  git.c              | 2 +-\n>  2 files changed, 1 insertion(+), 3 deletions(-)\n>\n> diff --git a/builtin/checkout.c b/builtin/checkout.c\n> index b1e68b3..5754554 100644\n> --- a/builtin/checkout.c\n> +++ b/builtin/checkout.c\n> @@ -1218,8 +1218,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n>\n>         opts.new_worktree_mode = getenv(\"GIT_CHECKOUT_NEW_WORKTREE\") != NULL;\n>\n> -       setup_work_tree();\n> -\n>         if (conflict_style) {\n>                 opts.merge = 1; /* implied */\n>                 git_xmerge_config(\"merge.conflictstyle\", conflict_style, NULL);\n> diff --git a/git.c b/git.c\n> index f227838..21a6398 100644\n> --- a/git.c\n> +++ b/git.c\n> @@ -383,7 +383,7 @@ static struct cmd_struct commands[] = {\n>         { \"check-ignore\", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE },\n>         { \"check-mailmap\", cmd_check_mailmap, RUN_SETUP },\n>         { \"check-ref-format\", cmd_check_ref_format },\n> -       { \"checkout\", cmd_checkout, RUN_SETUP },\n> +       { \"checkout\", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },\n>         { \"checkout-index\", cmd_checkout_index,\n>                 RUN_SETUP | NEED_WORK_TREE},\n>         { \"cherry\", cmd_cherry, RUN_SETUP },\n> --\n> 2.5.0.rc1.197.g417e668\n"},{"id":"265513","messageId":"CACsJy8ANDUjfN=ePPz6+LXPf7q+NVhFpBa2w5NLX2VXeatEvRg@mail.gmail.com","threadId":"39777","inReplyTo":"1435969052-540-5-git-send-email-sunshine@sunshineco.com","subject":"Re: [PATCH v2 04/23] Documentation/git-worktree: add BUGS section","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-07-04T02:41:38Z","receivedAt":"2015-07-04T02:41:38Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> +git-worktree could provide more automation for tasks currently\n> +performed manually or via other commands, such as:\n> +\n> +- `add` to create a new linked worktree\n> +- `remove` to remove a linked worktree and its administrative files (and\n> +  warn if the worktree is dirty)\n> +- `mv` to move or rename a worktree and update its administrative files\n> +- `lock` to prevent automatic pruning of administrative files (for instance,\n> +  for a worktree on a portable device)\n\nNo need to re-roll if this is the only change in the series, but we\nalso need \"list/ls\" here.\n-- \nDuy\n"},{"id":"265514","messageId":"CACsJy8C=BZF57GqRxO6CfBAYOxywEd4zHay4cgSZMrKCv6u77w@mail.gmail.com","threadId":"39777","inReplyTo":"1435969052-540-9-git-send-email-sunshine@sunshineco.com","subject":"Re: [PATCH v2 08/23] checkout: fix bug with --to and relative HEAD","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-07-04T02:45:01Z","receivedAt":"2015-07-04T02:45:01Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> Given \"git checkout --to <path> HEAD~1\", the new worktree's HEAD should\n> begin life at the current branch's HEAD~1, however, it actually ends up\n> at HEAD~2. The happens because:\n>\n>     1. git-checkout resolves HEAD~1\n>\n>     2. to satisfy is_git_directory, prepare_linked_worktree() creates a\n>        HEAD in the new worktree with the value of the resolved HEAD~1\n>\n>     3. git-checkout re-invokes itself with the same arguments within the\n>        new worktree to populate the worktree\n>\n>     4. the sub git-checkout resolves HEAD~1 relative to its own HEAD,\n>        which is the resolved HEAD~1 from the original invocation,\n>        resulting unexpectedly and incorrectly in HEAD~2 (relative to the\n>        original)\n>\n> Fix this by unconditionally assigning the current worktree's HEAD as the\n> value of the new worktree's HEAD.\n\nGood catch!\n\n> @@ -924,9 +925,11 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,\n>          * value would do because this value will be ignored and\n>          * replaced at the next (real) checkout.\n>          */\n\nThis comment \"any valid value would do.. will be ignored\" is proved incorrect.\n\n> +       if (!resolve_ref_unsafe(\"HEAD\", 0, rev, NULL))\n> +               die(_(\"unable to resolve HEAD\"));\n>         strbuf_reset(&sb);\n>         strbuf_addf(&sb, \"%s/HEAD\", sb_repo.buf);\n> -       write_file(sb.buf, 1, \"%s\\n\", sha1_to_hex(new->commit->object.sha1));\n> +       write_file(sb.buf, 1, \"%s\\n\", sha1_to_hex(rev));\n>         strbuf_reset(&sb);\n>         strbuf_addf(&sb, \"%s/commondir\", sb_repo.buf);\n>         write_file(sb.buf, 1, \"../..\\n\");\n-- \nDuy\n"},{"id":"265515","messageId":"CACsJy8A2eB2-t4t4oxvWiTnEFr7jJxcVBnn+zHq4uNNTk3sypg@mail.gmail.com","threadId":"39777","inReplyTo":"1435969052-540-14-git-send-email-sunshine@sunshineco.com","subject":"Re: [PATCH v2 13/23] worktree: introduce \"add\" command","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-07-04T02:53:38Z","receivedAt":"2015-07-04T02:53:38Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>  COMMANDS\n>  --------\n> +add <path> <branch>::\n> +\n> +Check out `<branch>` into a separate working directory, `<path>`, creating\n> +`<path>` if necessary. The new working directory is linked to the current\n> +repository, sharing everything except working directory specific files\n> +such as HEAD, index, etc. If `<path>` already exists, it must be empty.\n\nSide note, \"must be empty\" is an implementation limitation. I think\nthe two-way merge employed by git-checkout can deal with dirty <path>\nand only perform the checkout if there is no data loss. But we can\nleave this for later.\n-- \nDuy\n"},{"id":"265516","messageId":"CACsJy8Cog302k+-tFVJqneh3ShWYL57qhHQk8cFqvYX9Qc9q8Q@mail.gmail.com","threadId":"39777","inReplyTo":"1435969052-540-19-git-send-email-sunshine@sunshineco.com","subject":"Re: [PATCH v2 18/23] checkout: retire --to option","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-07-04T03:04:50Z","receivedAt":"2015-07-04T03:04:50Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> Now that \"git worktree add\" has achieved user-facing feature-parity with\n> \"git checkout --to\", retire the latter.\n>\n> Move the actual linked worktree creation functionality,\n> prepare_linked_checkout() and its helpers, verbatim from checkout.c to\n> worktree.c.\n>\n> This effectively reverts changes to checkout.c by 529fef2 (checkout:\n> support checking out into a new working directory, 2014-11-30) with the\n> exception of merge_working_tree() and switch_branches() which still\n> require specialized knowledge that a the checkout is occurring in a\n> newly-created linked worktree (signaled to them by the private\n> GIT_CHECKOUT_NEW_WORKTREE environment variable).\n>\n> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>\n> ---\n>  builtin/checkout.c | 156 +----------------------------------------------------\n>  builtin/worktree.c | 138 ++++++++++++++++++++++++++++++++++++++++++++---\n>  2 files changed, 133 insertions(+), 161 deletions(-)\n\nIf I didn't lose track of changes, \"--to\" is still described in\ngit-checkout.txt?\n-- \nDuy\n"},{"id":"265517","messageId":"CACsJy8AYFC+FW1bgSJwW34p6s2zn_6A4GhBaJjB8o8rxUvY72g@mail.gmail.com","threadId":"39777","inReplyTo":"1435969052-540-17-git-send-email-sunshine@sunshineco.com","subject":"Re: [PATCH v2 16/23] worktree: add -b/-B options","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-07-04T03:19:23Z","receivedAt":"2015-07-04T03:19:23Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> One of git-worktree's roles is to populate the new worktree, much like\n> git-checkout, and thus, for convenience, ought to support several of the\n> same shortcuts. Toward this goal, add -b/-B options to create a new\n> branch and check it out in the new worktree.\n\nThere are some other  ref manipulation options we can bring over like\n--orphan and --track. But you can totally leave them out and we can\nadd them back when people actually need them.\n-- \nDuy\n"},{"id":"265524","messageId":"CAPig+cR1uL=GgjGTCTpb7vmCHqs0k3pWUV2ZGWms+2CjPoW7Pw@mail.gmail.com","threadId":"39777","inReplyTo":"CACsJy8ANDUjfN=ePPz6+LXPf7q+NVhFpBa2w5NLX2VXeatEvRg@mail.gmail.com","subject":"Re: [PATCH v2 04/23] Documentation/git-worktree: add BUGS section","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T08:48:27Z","receivedAt":"2015-07-04T08:48:27Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Jul 3, 2015 at 10:41 PM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>> +git-worktree could provide more automation for tasks currently\n>> +performed manually or via other commands, such as:\n>> +\n>> +- `add` to create a new linked worktree\n>> +- `remove` to remove a linked worktree and its administrative files (and\n>> +  warn if the worktree is dirty)\n>> +- `mv` to move or rename a worktree and update its administrative files\n>> +- `lock` to prevent automatic pruning of administrative files (for instance,\n>> +  for a worktree on a portable device)\n>\n> No need to re-roll if this is the only change in the series, but we\n> also need \"list/ls\" here.\n\nOops, yes. That was the very first item I had in mind (mentioned by\nyou in the commentary of your \"git worktree prune\" patch), yet I\nsomehow omitted it.\n"},{"id":"265526","messageId":"CAPig+cSQ6K7noQiKJbwHpY4tO2hzQMH9q-0nqkWUX_ecJkCTEg@mail.gmail.com","threadId":"39777","inReplyTo":"CACsJy8C=BZF57GqRxO6CfBAYOxywEd4zHay4cgSZMrKCv6u77w@mail.gmail.com","subject":"Re: [PATCH v2 08/23] checkout: fix bug with --to and relative HEAD","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T08:49:12Z","receivedAt":"2015-07-04T08:49:12Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Jul 3, 2015 at 10:45 PM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>> Given \"git checkout --to <path> HEAD~1\", the new worktree's HEAD should\n>> begin life at the current branch's HEAD~1, however, it actually ends up\n>> at HEAD~2. The happens because:\n>>\n>>     1. git-checkout resolves HEAD~1\n>>\n>>     2. to satisfy is_git_directory, prepare_linked_worktree() creates a\n>>        HEAD in the new worktree with the value of the resolved HEAD~1\n>>\n>>     3. git-checkout re-invokes itself with the same arguments within the\n>>        new worktree to populate the worktree\n>>\n>>     4. the sub git-checkout resolves HEAD~1 relative to its own HEAD,\n>>        which is the resolved HEAD~1 from the original invocation,\n>>        resulting unexpectedly and incorrectly in HEAD~2 (relative to the\n>>        original)\n>>\n>> Fix this by unconditionally assigning the current worktree's HEAD as the\n>> value of the new worktree's HEAD.\n>\n> Good catch!\n>\n>> @@ -924,9 +925,11 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,\n>>          * value would do because this value will be ignored and\n>>          * replaced at the next (real) checkout.\n>>          */\n>\n> This comment \"any valid value would do.. will be ignored\" is proved incorrect.\n\nYup, and I meant to update the comment but promptly forgot about it.\nThanks for the reminder.\n"},{"id":"265525","messageId":"CAPig+cSKDUr2GjVqNLKQ7Cb7LooE9bvUzZXEv3cEr3kzyCuSTw@mail.gmail.com","threadId":"39777","inReplyTo":"CACsJy8A2eB2-t4t4oxvWiTnEFr7jJxcVBnn+zHq4uNNTk3sypg@mail.gmail.com","subject":"Re: [PATCH v2 13/23] worktree: introduce \"add\" command","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T08:54:20Z","receivedAt":"2015-07-04T08:54:20Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Jul 3, 2015 at 10:53 PM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>>  COMMANDS\n>>  --------\n>> +add <path> <branch>::\n>> +\n>> +Check out `<branch>` into a separate working directory, `<path>`, creating\n>> +`<path>` if necessary. The new working directory is linked to the current\n>> +repository, sharing everything except working directory specific files\n>> +such as HEAD, index, etc. If `<path>` already exists, it must be empty.\n>\n> Side note, \"must be empty\" is an implementation limitation. I think\n> the two-way merge employed by git-checkout can deal with dirty <path>\n> and only perform the checkout if there is no data loss. But we can\n> leave this for later.\n\nPerhaps we should omit the bit about an existing but empty directory\nfor now? Like this:\n\n    Create `<path>` and checkout `<branch>` into it. The new working\n    directory is linked to the current repository, sharing everything\n    except working directory specific files such as HEAD, index, etc.\n"},{"id":"265527","messageId":"CAPig+cQiJnrnz4jsGdT0=8kYogWfsNkjq5WQCGC4Zk6res5mtg@mail.gmail.com","threadId":"39777","inReplyTo":"CACsJy8AYFC+FW1bgSJwW34p6s2zn_6A4GhBaJjB8o8rxUvY72g@mail.gmail.com","subject":"Re: [PATCH v2 16/23] worktree: add -b/-B options","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T08:57:17Z","receivedAt":"2015-07-04T08:57:17Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Jul 3, 2015 at 11:19 PM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>> One of git-worktree's roles is to populate the new worktree, much like\n>> git-checkout, and thus, for convenience, ought to support several of the\n>> same shortcuts. Toward this goal, add -b/-B options to create a new\n>> branch and check it out in the new worktree.\n>\n> There are some other  ref manipulation options we can bring over like\n> --orphan and --track. But you can totally leave them out and we can\n> add them back when people actually need them.\n\nYes. I added --force, -b/-B, and --detach because they are used by the\ntests; and I considered --orphan and --track to be good candidates, as\nwell, but decided to omit them for now since the series is already\noverly long.\n"},{"id":"265523","messageId":"CAPig+cT0H=Pj8Wt5Xhpj=MApfDby66EyO6WW7pCjYQnfNHi7aA@mail.gmail.com","threadId":"39777","inReplyTo":"CACsJy8Cog302k+-tFVJqneh3ShWYL57qhHQk8cFqvYX9Qc9q8Q@mail.gmail.com","subject":"Re: [PATCH v2 18/23] checkout: retire --to option","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-07-04T08:59:06Z","receivedAt":"2015-07-04T08:59:06Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Jul 3, 2015 at 11:04 PM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>> Now that \"git worktree add\" has achieved user-facing feature-parity with\n>> \"git checkout --to\", retire the latter.\n>>\n>> Move the actual linked worktree creation functionality,\n>> prepare_linked_checkout() and its helpers, verbatim from checkout.c to\n>> worktree.c.\n>>\n>> This effectively reverts changes to checkout.c by 529fef2 (checkout:\n>> support checking out into a new working directory, 2014-11-30) with the\n>> exception of merge_working_tree() and switch_branches() which still\n>> require specialized knowledge that a the checkout is occurring in a\n>> newly-created linked worktree (signaled to them by the private\n>> GIT_CHECKOUT_NEW_WORKTREE environment variable).\n>>\n>> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>\n>> ---\n>>  builtin/checkout.c | 156 +----------------------------------------------------\n>>  builtin/worktree.c | 138 ++++++++++++++++++++++++++++++++++++++++++++---\n>>  2 files changed, 133 insertions(+), 161 deletions(-)\n>\n> If I didn't lose track of changes, \"--to\" is still described in\n> git-checkout.txt?\n\nYou're right. v1 did remove --to from git-checkout.txt, but somehow I\noverlooked it in v2. Thanks for pointing out this oversight.\n"},{"id":"265546","messageId":"CACsJy8D6jye_JqkU0ZfQvxZfK9vspcrVWJvwpmqXyJ=6Q9_SOg@mail.gmail.com","threadId":"39777","inReplyTo":"CAPig+cSKDUr2GjVqNLKQ7Cb7LooE9bvUzZXEv3cEr3kzyCuSTw@mail.gmail.com","subject":"Re: [PATCH v2 13/23] worktree: introduce \"add\" command","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-07-06T09:24:37Z","receivedAt":"2015-07-06T09:24:37Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Jul 4, 2015 at 3:54 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Fri, Jul 3, 2015 at 10:53 PM, Duy Nguyen <pclouds@gmail.com> wrote:\n>> On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>>>  COMMANDS\n>>>  --------\n>>> +add <path> <branch>::\n>>> +\n>>> +Check out `<branch>` into a separate working directory, `<path>`, creating\n>>> +`<path>` if necessary. The new working directory is linked to the current\n>>> +repository, sharing everything except working directory specific files\n>>> +such as HEAD, index, etc. If `<path>` already exists, it must be empty.\n>>\n>> Side note, \"must be empty\" is an implementation limitation. I think\n>> the two-way merge employed by git-checkout can deal with dirty <path>\n>> and only perform the checkout if there is no data loss. But we can\n>> leave this for later.\n>\n> Perhaps we should omit the bit about an existing but empty directory\n> for now? Like this:\n>\n>     Create `<path>` and checkout `<branch>` into it. The new working\n>     directory is linked to the current repository, sharing everything\n>     except working directory specific files such as HEAD, index, etc.\n\nI think either way is ok.\n-- \nDuy\n"},{"id":"265616","messageId":"xmqqtwthyu6p.fsf@gitster.dls.corp.google.com","threadId":"39777","inReplyTo":"1435969052-540-22-git-send-email-sunshine@sunshineco.com","subject":"Re: [PATCH v2 21/23] worktree: add: make -b/-B default to HEAD when <branch> is omitted","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-07-06T19:14:54Z","receivedAt":"2015-07-06T19:14:54Z","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> As a convenience, like \"git branch\" and \"git checkout -b\", make\n> \"git worktree add -b <newbranch> <path> <branch>\" default to HEAD when\n> <branch> is omitted.\n>\n> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>\n> ---\n>  Documentation/git-worktree.txt | 1 +\n>  builtin/worktree.c             | 6 ++++--\n>  t/t2025-worktree-add.sh        | 7 +++++++\n>  3 files changed, 12 insertions(+), 2 deletions(-)\n>\n> diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\n> index f6c3747..5ca11f6 100644\n> --- a/Documentation/git-worktree.txt\n> +++ b/Documentation/git-worktree.txt\n> @@ -69,6 +69,7 @@ OPTIONS\n>  -B <new-branch>::\n>  \tWith `add`, create a new branch named `<new-branch>` starting at\n>  \t`<branch>`, and check out `<new-branch>` into the new worktree.\n> +\tIf `<branch>` is omitted, it defaults to HEAD.\n\nWhat would be the SYNOPSIS change to adjust for this, I wonder.\n\n'git worktree add' [-f] [--detach] [-b <new-branch>] <path> [<branch>]\n\nor something?  Can I omit <branch> without giving -b <new-branch>?\n"}]}