git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH v2 00/23] replace "checkout --to" with "worktree add"
@ 2015-07-04  0:17 Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 01/23] Documentation/git-checkout: fix incorrect worktree prune command Eric Sunshine
                   ` (22 more replies)
  0 siblings, 23 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

This is v2 of the series to replace "git checkout --to" with "git
worktree add". It's built atop Duy's df0b6cf (worktree: new place for
"git prune --worktrees", 2015-06-29) which introduces the git-worktree
command and replaces "git prune --worktrees" with "git worktree prune".

Although v1[*1*] consisted of only 1 patch, v2 is just a wee bit
longer at 23 patches. Sorry for the length. Fortunately, most patches
are quite small, thus (hopefully) easy to review.

v2 goes a bit beyond v1 by implementing Duy's suggestion[*2*] of
allowing <branch> in "git worktree add <path> <branch>" to be omitted,
in which case, as a convenience, it auto-vivifies a new branch named
after <path>, as if it had been invoked as "git worktree add -b
$(basename <path>) <path> HEAD". Moreover, unlike "git checkout -b
<newbranch> --to <path> <branch>", the <branch> in "git worktree add -b
<newbranch> <path> <branch>" is also optional, and defaults to HEAD.

v2 does not attempt either of the suggestions by Junio[*3*] or Duy[*4*]
for eliminating git-checkout from the equation, which would allow us to
remove the final couple bits of code in git-checkout which require
intimate knowledge that the checkout is occurring in a newly created
linked worktree. This series is already too long, and I didn't want it
to grow further by implementing either of those ideas. Instead, this
series leaves git-worktree at a state where one or the other of those
suggestions can be done as follow-on patches touching only the
underlying machinery, without affecting the user-facing interface.

[*1*]: http://thread.gmane.org/gmane.comp.version-control.git/273032
[*2*]: http://thread.gmane.org/gmane.comp.version-control.git/273032/focus=273035
[*3*]: via private email which suggested using "git-reset --hard" rather
       than "git checkout" to populate the new linked worktree.
[*4*]: http://thread.gmane.org/gmane.comp.version-control.git/273032/focus=273226

Eric Sunshine (23):
  Documentation/git-checkout: fix incorrect worktree prune command
  Documentation/git-worktree: associate options with commands
  Documentation: move linked worktree description from checkout to
    worktree
  Documentation/git-worktree: add BUGS section
  Documentation/git-worktree: split technical info from general
    description
  Documentation/git-worktree: add high-level 'lock' overview
  Documentation/git-worktree: add EXAMPLES section
  checkout: fix bug with --to and relative HEAD
  checkout: relocate --to's "no branch specified" check
  checkout: prepare_linked_checkout: drop now-unused 'new' argument
  checkout: make --to unconditionally verbose
  checkout: drop 'checkout_opts' dependency from prepare_linked_checkout
  worktree: introduce "add" command
  worktree: add --force option
  worktree: add --detach option
  worktree: add -b/-B options
  tests: worktree: retrofit "checkout --to" tests for "worktree add"
  checkout: retire --to option
  checkout: require worktree unconditionally
  worktree: extract basename computation to new function
  worktree: add: make -b/-B default to HEAD when <branch> is omitted
  worktree: add: auto-vivify new branch when <branch> is omitted
  checkout: retire --ignore-other-worktrees in favor of --force

 Documentation/git-checkout.txt                    |  78 +--------
 Documentation/git-worktree.txt                    | 141 +++++++++++++++-
 builtin/checkout.c                                | 161 +-----------------
 builtin/worktree.c                                | 193 ++++++++++++++++++++++
 git.c                                             |   2 +-
 t/{t2025-checkout-to.sh => t2025-worktree-add.sh} |  68 +++++---
 t/t2026-prune-linked-checkouts.sh                 |   2 +-
 t/t7410-submodule-checkout-to.sh                  |   4 +-
 8 files changed, 383 insertions(+), 266 deletions(-)
 rename t/{t2025-checkout-to.sh => t2025-worktree-add.sh} (51%)

-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v2 01/23] Documentation/git-checkout: fix incorrect worktree prune command
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 02/23] Documentation/git-worktree: associate options with commands Eric Sunshine
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

This was missed when "git prune --worktrees" became "git worktree prune".

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 Documentation/git-checkout.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 72def5b..ce223e6 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -444,7 +444,7 @@ When you are done with a linked working tree you can simply delete it.
 The working tree's entry in the repository's $GIT_DIR/worktrees
 directory will eventually be removed automatically (see
 `gc.pruneworktreesexpire` in linkgit::git-config[1]), or you can run
-`git prune --worktrees` in the main or any linked working tree to
+`git worktree prune` in the main or any linked working tree to
 clean up any stale entries in $GIT_DIR/worktrees.
 
 If you move a linked working directory to another file system, or
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 02/23] Documentation/git-worktree: associate options with commands
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 01/23] Documentation/git-checkout: fix incorrect worktree prune command Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 03/23] Documentation: move linked worktree description from checkout to worktree Eric Sunshine
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

git-worktree options affect some worktree commands but not others, but
this is not necessarily obvious from the option descriptions. Make this
clear by indicating explicitly which commands are affected by which
options.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 Documentation/git-worktree.txt | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 41103e5..1ac1217 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -28,15 +28,15 @@ OPTIONS
 
 -n::
 --dry-run::
-	Do not remove anything; just report what it would
+	With `prune`, do not remove anything; just report what it would
 	remove.
 
 -v::
 --verbose::
-	Report all removals.
+	With `prune`, report all removals.
 
 --expire <time>::
-	Only expire unused worktrees older than <time>.
+	With `prune`, only expire unused worktrees older than <time>.
 
 SEE ALSO
 --------
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 03/23] Documentation: move linked worktree description from checkout to worktree
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 01/23] Documentation/git-checkout: fix incorrect worktree prune command Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 02/23] Documentation/git-worktree: associate options with commands Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 04/23] Documentation/git-worktree: add BUGS section Eric Sunshine
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

Now that the git-worktree command exists, its documentation page is the
natural place for the linked worktree description to reside. Relocate
the "MULTIPLE WORKING TREES" description verbatim from git-checkout.txt
to git-worktree.txt.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---

When Junio queued v1[1] on 'pu', he changed the second sentence of the
first paragraph of the description to say "...a new working tree is
created and associated..." in place of the original "...a new working
tree is associated...". I wanted this to be a pure documentation-
movement patch, so I did not carry over his modification. Moreover, his
text is not quite accurate since, although <path> will be created if
missing, <path> can also be pre-existing, provided that it is an empty
directory. Patch 13/23 adds documentation which states this explicitly.

[1]: http://thread.gmane.org/gmane.comp.version-control.git/273032

 Documentation/git-checkout.txt | 69 ++----------------------------------------
 Documentation/git-worktree.txt | 62 +++++++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+), 67 deletions(-)

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index ce223e6..77b7141 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -229,8 +229,8 @@ section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
 	Check out a branch in a separate working directory at
 	`<path>`. A new working directory is linked to the current
 	repository, sharing everything except working directory
-	specific files such as HEAD, index... See "MULTIPLE WORKING
-	TREES" section for more information.
+	specific files such as HEAD, index, etc. See
+	linkgit:git-worktree[1] for a description of linked worktrees.
 
 --ignore-other-worktrees::
 	`git checkout` refuses when the wanted ref is already checked
@@ -401,71 +401,6 @@ $ git reflog -2 HEAD # or
 $ git log -g -2 HEAD
 ------------
 
-MULTIPLE WORKING TREES
-----------------------
-
-A git repository can support multiple working trees, allowing you to check
-out more than one branch at a time.  With `git checkout --to` a new working
-tree is associated with the repository.  This new working tree is called a
-"linked working tree" as opposed to the "main working tree" prepared by "git
-init" or "git clone".  A repository has one main working tree (if it's not a
-bare repository) and zero or more linked working trees.
-
-Each linked working tree has a private sub-directory in the repository's
-$GIT_DIR/worktrees directory.  The private sub-directory's name is usually
-the base name of the linked working tree's path, possibly appended with a
-number to make it unique.  For example, when `$GIT_DIR=/path/main/.git` the
-command `git checkout --to /path/other/test-next next` creates the linked
-working tree in `/path/other/test-next` and also creates a
-`$GIT_DIR/worktrees/test-next` directory (or `$GIT_DIR/worktrees/test-next1`
-if `test-next` is already taken).
-
-Within a linked working tree, $GIT_DIR is set to point to this private
-directory (e.g. `/path/main/.git/worktrees/test-next` in the example) and
-$GIT_COMMON_DIR is set to point back to the main working tree's $GIT_DIR
-(e.g. `/path/main/.git`). These settings are made in a `.git` file located at
-the top directory of the linked working tree.
-
-Path resolution via `git rev-parse --git-path` uses either
-$GIT_DIR or $GIT_COMMON_DIR depending on the path. For example, in the
-linked working tree `git rev-parse --git-path HEAD` returns
-`/path/main/.git/worktrees/test-next/HEAD` (not
-`/path/other/test-next/.git/HEAD` or `/path/main/.git/HEAD`) while `git
-rev-parse --git-path refs/heads/master` uses
-$GIT_COMMON_DIR and returns `/path/main/.git/refs/heads/master`,
-since refs are shared across all working trees.
-
-See linkgit:gitrepository-layout[5] for more information. The rule of
-thumb is do not make any assumption about whether a path belongs to
-$GIT_DIR or $GIT_COMMON_DIR when you need to directly access something
-inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path.
-
-When you are done with a linked working tree you can simply delete it.
-The working tree's entry in the repository's $GIT_DIR/worktrees
-directory will eventually be removed automatically (see
-`gc.pruneworktreesexpire` in linkgit::git-config[1]), or you can run
-`git worktree prune` in the main or any linked working tree to
-clean up any stale entries in $GIT_DIR/worktrees.
-
-If you move a linked working directory to another file system, or
-within a file system that does not support hard links, you need to run
-at least one git command inside the linked working directory
-(e.g. `git status`) in order to update its entry in $GIT_DIR/worktrees
-so that it does not get automatically removed.
-
-To prevent a $GIT_DIR/worktrees entry from from being pruned (which
-can be useful in some situations, such as when the
-entry's working tree is stored on a portable device), add a file named
-'locked' to the entry's directory. The file contains the reason in
-plain text. For example, if a linked working tree's `.git` file points
-to `/path/main/.git/worktrees/test-next` then a file named
-`/path/main/.git/worktrees/test-next/locked` will prevent the
-`test-next` entry from being pruned.  See
-linkgit:gitrepository-layout[5] for details.
-
-Multiple checkout support for submodules is incomplete. It is NOT
-recommended to make multiple checkouts of a superproject.
-
 EXAMPLES
 --------
 
diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 1ac1217..3d28896 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -17,6 +17,68 @@ DESCRIPTION
 Manage multiple worktrees attached to the same repository. These are
 created by the command `git checkout --to`.
 
+A git repository can support multiple working trees, allowing you to check
+out more than one branch at a time.  With `git checkout --to` a new working
+tree is associated with the repository.  This new working tree is called a
+"linked working tree" as opposed to the "main working tree" prepared by "git
+init" or "git clone".  A repository has one main working tree (if it's not a
+bare repository) and zero or more linked working trees.
+
+Each linked working tree has a private sub-directory in the repository's
+$GIT_DIR/worktrees directory.  The private sub-directory's name is usually
+the base name of the linked working tree's path, possibly appended with a
+number to make it unique.  For example, when `$GIT_DIR=/path/main/.git` the
+command `git checkout --to /path/other/test-next next` creates the linked
+working tree in `/path/other/test-next` and also creates a
+`$GIT_DIR/worktrees/test-next` directory (or `$GIT_DIR/worktrees/test-next1`
+if `test-next` is already taken).
+
+Within a linked working tree, $GIT_DIR is set to point to this private
+directory (e.g. `/path/main/.git/worktrees/test-next` in the example) and
+$GIT_COMMON_DIR is set to point back to the main working tree's $GIT_DIR
+(e.g. `/path/main/.git`). These settings are made in a `.git` file located at
+the top directory of the linked working tree.
+
+Path resolution via `git rev-parse --git-path` uses either
+$GIT_DIR or $GIT_COMMON_DIR depending on the path. For example, in the
+linked working tree `git rev-parse --git-path HEAD` returns
+`/path/main/.git/worktrees/test-next/HEAD` (not
+`/path/other/test-next/.git/HEAD` or `/path/main/.git/HEAD`) while `git
+rev-parse --git-path refs/heads/master` uses
+$GIT_COMMON_DIR and returns `/path/main/.git/refs/heads/master`,
+since refs are shared across all working trees.
+
+See linkgit:gitrepository-layout[5] for more information. The rule of
+thumb is do not make any assumption about whether a path belongs to
+$GIT_DIR or $GIT_COMMON_DIR when you need to directly access something
+inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path.
+
+When you are done with a linked working tree you can simply delete it.
+The working tree's entry in the repository's $GIT_DIR/worktrees
+directory will eventually be removed automatically (see
+`gc.pruneworktreesexpire` in linkgit::git-config[1]), or you can run
+`git worktree prune` in the main or any linked working tree to
+clean up any stale entries in $GIT_DIR/worktrees.
+
+If you move a linked working directory to another file system, or
+within a file system that does not support hard links, you need to run
+at least one git command inside the linked working directory
+(e.g. `git status`) in order to update its entry in $GIT_DIR/worktrees
+so that it does not get automatically removed.
+
+To prevent a $GIT_DIR/worktrees entry from from being pruned (which
+can be useful in some situations, such as when the
+entry's working tree is stored on a portable device), add a file named
+'locked' to the entry's directory. The file contains the reason in
+plain text. For example, if a linked working tree's `.git` file points
+to `/path/main/.git/worktrees/test-next` then a file named
+`/path/main/.git/worktrees/test-next/locked` will prevent the
+`test-next` entry from being pruned.  See
+linkgit:gitrepository-layout[5] for details.
+
+Multiple checkout support for submodules is incomplete. It is NOT
+recommended to make multiple checkouts of a superproject.
+
 COMMANDS
 --------
 prune::
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 04/23] Documentation/git-worktree: add BUGS section
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (2 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 03/23] Documentation: move linked worktree description from checkout to worktree Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  2:41   ` Duy Nguyen
  2015-07-04  0:17 ` [PATCH v2 05/23] Documentation/git-worktree: split technical info from general description Eric Sunshine
                   ` (18 subsequent siblings)
  22 siblings, 1 reply; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

Relocate submodule warning to BUGS and enumerate missing commands.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 Documentation/git-worktree.txt | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 3d28896..4fbcdd2 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -76,9 +76,6 @@ to `/path/main/.git/worktrees/test-next` then a file named
 `test-next` entry from being pruned.  See
 linkgit:gitrepository-layout[5] for details.
 
-Multiple checkout support for submodules is incomplete. It is NOT
-recommended to make multiple checkouts of a superproject.
-
 COMMANDS
 --------
 prune::
@@ -100,6 +97,21 @@ OPTIONS
 --expire <time>::
 	With `prune`, only expire unused worktrees older than <time>.
 
+BUGS
+----
+Multiple checkout support for submodules is incomplete. It is NOT
+recommended to make multiple checkouts of a superproject.
+
+git-worktree could provide more automation for tasks currently
+performed manually or via other commands, such as:
+
+- `add` to create a new linked worktree
+- `remove` to remove a linked worktree and its administrative files (and
+  warn if the worktree is dirty)
+- `mv` to move or rename a worktree and update its administrative files
+- `lock` to prevent automatic pruning of administrative files (for instance,
+  for a worktree on a portable device)
+
 SEE ALSO
 --------
 
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 05/23] Documentation/git-worktree: split technical info from general description
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (3 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 04/23] Documentation/git-worktree: add BUGS section Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 06/23] Documentation/git-worktree: add high-level 'lock' overview Eric Sunshine
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

The DESCRIPTION section should provide a high-level overview of linked
worktree functionality to bring users up to speed quickly, without
overloading them with low-level details, so relocate the technical
information to a new DETAILS section.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 Documentation/git-worktree.txt | 70 ++++++++++++++++++++++--------------------
 1 file changed, 36 insertions(+), 34 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 4fbcdd2..2fdfb3e 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -24,47 +24,18 @@ tree is associated with the repository.  This new working tree is called a
 init" or "git clone".  A repository has one main working tree (if it's not a
 bare repository) and zero or more linked working trees.
 
-Each linked working tree has a private sub-directory in the repository's
-$GIT_DIR/worktrees directory.  The private sub-directory's name is usually
-the base name of the linked working tree's path, possibly appended with a
-number to make it unique.  For example, when `$GIT_DIR=/path/main/.git` the
-command `git checkout --to /path/other/test-next next` creates the linked
-working tree in `/path/other/test-next` and also creates a
-`$GIT_DIR/worktrees/test-next` directory (or `$GIT_DIR/worktrees/test-next1`
-if `test-next` is already taken).
-
-Within a linked working tree, $GIT_DIR is set to point to this private
-directory (e.g. `/path/main/.git/worktrees/test-next` in the example) and
-$GIT_COMMON_DIR is set to point back to the main working tree's $GIT_DIR
-(e.g. `/path/main/.git`). These settings are made in a `.git` file located at
-the top directory of the linked working tree.
-
-Path resolution via `git rev-parse --git-path` uses either
-$GIT_DIR or $GIT_COMMON_DIR depending on the path. For example, in the
-linked working tree `git rev-parse --git-path HEAD` returns
-`/path/main/.git/worktrees/test-next/HEAD` (not
-`/path/other/test-next/.git/HEAD` or `/path/main/.git/HEAD`) while `git
-rev-parse --git-path refs/heads/master` uses
-$GIT_COMMON_DIR and returns `/path/main/.git/refs/heads/master`,
-since refs are shared across all working trees.
-
-See linkgit:gitrepository-layout[5] for more information. The rule of
-thumb is do not make any assumption about whether a path belongs to
-$GIT_DIR or $GIT_COMMON_DIR when you need to directly access something
-inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path.
-
 When you are done with a linked working tree you can simply delete it.
-The working tree's entry in the repository's $GIT_DIR/worktrees
-directory will eventually be removed automatically (see
+The working tree's administrative files in the repository (see
+"DETAILS" below) will eventually be removed automatically (see
 `gc.pruneworktreesexpire` in linkgit::git-config[1]), or you can run
 `git worktree prune` in the main or any linked working tree to
-clean up any stale entries in $GIT_DIR/worktrees.
+clean up any stale administrative files.
 
 If you move a linked working directory to another file system, or
 within a file system that does not support hard links, you need to run
 at least one git command inside the linked working directory
-(e.g. `git status`) in order to update its entry in $GIT_DIR/worktrees
-so that it does not get automatically removed.
+(e.g. `git status`) in order to update its administrative files in the
+repository so that they do not get automatically pruned.
 
 To prevent a $GIT_DIR/worktrees entry from from being pruned (which
 can be useful in some situations, such as when the
@@ -97,6 +68,37 @@ OPTIONS
 --expire <time>::
 	With `prune`, only expire unused worktrees older than <time>.
 
+DETAILS
+-------
+Each linked working tree has a private sub-directory in the repository's
+$GIT_DIR/worktrees directory.  The private sub-directory's name is usually
+the base name of the linked working tree's path, possibly appended with a
+number to make it unique.  For example, when `$GIT_DIR=/path/main/.git` the
+command `git checkout --to /path/other/test-next next` creates the linked
+working tree in `/path/other/test-next` and also creates a
+`$GIT_DIR/worktrees/test-next` directory (or `$GIT_DIR/worktrees/test-next1`
+if `test-next` is already taken).
+
+Within a linked working tree, $GIT_DIR is set to point to this private
+directory (e.g. `/path/main/.git/worktrees/test-next` in the example) and
+$GIT_COMMON_DIR is set to point back to the main working tree's $GIT_DIR
+(e.g. `/path/main/.git`). These settings are made in a `.git` file located at
+the top directory of the linked working tree.
+
+Path resolution via `git rev-parse --git-path` uses either
+$GIT_DIR or $GIT_COMMON_DIR depending on the path. For example, in the
+linked working tree `git rev-parse --git-path HEAD` returns
+`/path/main/.git/worktrees/test-next/HEAD` (not
+`/path/other/test-next/.git/HEAD` or `/path/main/.git/HEAD`) while `git
+rev-parse --git-path refs/heads/master` uses
+$GIT_COMMON_DIR and returns `/path/main/.git/refs/heads/master`,
+since refs are shared across all working trees.
+
+See linkgit:gitrepository-layout[5] for more information. The rule of
+thumb is do not make any assumption about whether a path belongs to
+$GIT_DIR or $GIT_COMMON_DIR when you need to directly access something
+inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path.
+
 BUGS
 ----
 Multiple checkout support for submodules is incomplete. It is NOT
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 06/23] Documentation/git-worktree: add high-level 'lock' overview
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (4 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 05/23] Documentation/git-worktree: split technical info from general description Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 07/23] Documentation/git-worktree: add EXAMPLES section Eric Sunshine
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

Due to the (current) absence of a "git worktree lock" command, locking
a worktree's administrative files to prevent automatic pruning is a
manual task, necessarily requiring low-level understanding of linked
worktree functionality. However, this level of detail does not belong
in the high-level DESCRIPTION section, so add a generalized discussion
of locking to DESCRIPTION and move the technical information to DETAILS.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 Documentation/git-worktree.txt | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 2fdfb3e..410f0b4 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -37,15 +37,11 @@ at least one git command inside the linked working directory
 (e.g. `git status`) in order to update its administrative files in the
 repository so that they do not get automatically pruned.
 
-To prevent a $GIT_DIR/worktrees entry from from being pruned (which
-can be useful in some situations, such as when the
-entry's working tree is stored on a portable device), add a file named
-'locked' to the entry's directory. The file contains the reason in
-plain text. For example, if a linked working tree's `.git` file points
-to `/path/main/.git/worktrees/test-next` then a file named
-`/path/main/.git/worktrees/test-next/locked` will prevent the
-`test-next` entry from being pruned.  See
-linkgit:gitrepository-layout[5] for details.
+If a linked working tree is stored on a portable device or network share
+which is not always mounted, you can prevent its administrative files from
+being pruned by creating a file named 'lock' alongside the other
+administrative files, optionally containing a plain text reason that
+pruning should be suppressed. See section "DETAILS" for more information.
 
 COMMANDS
 --------
@@ -99,6 +95,16 @@ thumb is do not make any assumption about whether a path belongs to
 $GIT_DIR or $GIT_COMMON_DIR when you need to directly access something
 inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path.
 
+To prevent a $GIT_DIR/worktrees entry from from being pruned (which
+can be useful in some situations, such as when the
+entry's working tree is stored on a portable device), add a file named
+'locked' to the entry's directory. The file contains the reason in
+plain text. For example, if a linked working tree's `.git` file points
+to `/path/main/.git/worktrees/test-next` then a file named
+`/path/main/.git/worktrees/test-next/locked` will prevent the
+`test-next` entry from being pruned.  See
+linkgit:gitrepository-layout[5] for details.
+
 BUGS
 ----
 Multiple checkout support for submodules is incomplete. It is NOT
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 07/23] Documentation/git-worktree: add EXAMPLES section
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (5 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 06/23] Documentation/git-worktree: add high-level 'lock' overview Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  2:23   ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 08/23] checkout: fix bug with --to and relative HEAD Eric Sunshine
                   ` (15 subsequent siblings)
  22 siblings, 1 reply; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 Documentation/git-worktree.txt | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 410f0b4..028bbd9 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -105,6 +105,28 @@ to `/path/main/.git/worktrees/test-next` then a file named
 `test-next` entry from being pruned.  See
 linkgit:gitrepository-layout[5] for details.
 
+EXAMPLES
+--------
+You are middle of a refactoring session and your boss comes in and demands
+that you fix something immediately. You might typically use
+linkgit:git-stash[1] to store your changes away temporarily, however, your
+worktree is in such a state of disarray (with new, removed, moved files,
+and other bits and pieces strewn around) that you don't want to risk
+disturbing any of it. Instead, you create a temporary linked worktree to
+make the emergency fix, remove it when done, and then resume your earlier
+refactoring session.
+
+------------
+$ git branch emergency-fix master
+$ git checkout --to ../temp emergency-fix
+$ pushd ../temp
+# ... hack hack hack ...
+$ git commit -a -m 'emergency fix for boss'
+$ popd
+$ rm -rf ../temp
+$ git worktree prune
+------------
+
 BUGS
 ----
 Multiple checkout support for submodules is incomplete. It is NOT
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 08/23] checkout: fix bug with --to and relative HEAD
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (6 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 07/23] Documentation/git-worktree: add EXAMPLES section Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  2:45   ` Duy Nguyen
  2015-07-04  0:17 ` [PATCH v2 09/23] checkout: relocate --to's "no branch specified" check Eric Sunshine
                   ` (14 subsequent siblings)
  22 siblings, 1 reply; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

Given "git checkout --to <path> HEAD~1", the new worktree's HEAD should
begin life at the current branch's HEAD~1, however, it actually ends up
at HEAD~2. The happens because:

    1. git-checkout resolves HEAD~1

    2. to satisfy is_git_directory, prepare_linked_worktree() creates a
       HEAD in the new worktree with the value of the resolved HEAD~1

    3. git-checkout re-invokes itself with the same arguments within the
       new worktree to populate the worktree

    4. the sub git-checkout resolves HEAD~1 relative to its own HEAD,
       which is the resolved HEAD~1 from the original invocation,
       resulting unexpectedly and incorrectly in HEAD~2 (relative to the
       original)

Fix this by unconditionally assigning the current worktree's HEAD as the
value of the new worktree's HEAD.

As a side-effect, this change also eliminates a dependence within
prepare_linked_checkout() upon 'struct branch_info'. The eventual plan
is to relocate "git checkout --to" functionality to "git worktree add",
and worktree.c won't have knowledge of 'struct branch_info', so removal
of this dependency is a step toward that goal.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 builtin/checkout.c     |  5 ++++-
 t/t2025-checkout-to.sh | 10 ++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 2079aa4..f5f953d 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -863,6 +863,7 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
 	struct stat st;
 	struct child_process cp;
 	int counter = 0, len, ret;
+	unsigned char rev[20];
 
 	if (!new->commit)
 		die(_("no branch specified"));
@@ -924,9 +925,11 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
 	 * value would do because this value will be ignored and
 	 * replaced at the next (real) checkout.
 	 */
+	if (!resolve_ref_unsafe("HEAD", 0, rev, NULL))
+		die(_("unable to resolve HEAD"));
 	strbuf_reset(&sb);
 	strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
-	write_file(sb.buf, 1, "%s\n", sha1_to_hex(new->commit->object.sha1));
+	write_file(sb.buf, 1, "%s\n", sha1_to_hex(rev));
 	strbuf_reset(&sb);
 	strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
 	write_file(sb.buf, 1, "../..\n");
diff --git a/t/t2025-checkout-to.sh b/t/t2025-checkout-to.sh
index a8d9336..0fd731b 100755
--- a/t/t2025-checkout-to.sh
+++ b/t/t2025-checkout-to.sh
@@ -134,4 +134,14 @@ test_expect_success 'checkout with grafts' '
 	test_cmp expected actual
 '
 
+test_expect_success 'checkout --to from relative HEAD' '
+	test_commit a &&
+	test_commit b &&
+	test_commit c &&
+	git rev-parse HEAD~1 >expected &&
+	git checkout --to relhead HEAD~1 &&
+	git -C relhead rev-parse HEAD >actual &&
+	test_cmp expected actual
+'
+
 test_done
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 09/23] checkout: relocate --to's "no branch specified" check
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (7 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 08/23] checkout: fix bug with --to and relative HEAD Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 10/23] checkout: prepare_linked_checkout: drop now-unused 'new' argument Eric Sunshine
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

The plan is to relocate "git checkout --to" functionality to "git
worktree add", however, this check expects a 'struct branch_info' which
git-worktree won't have at hand. It will, however, have access to its
own command-line from which it can pick up the branch name. Therefore,
as a preparatory step, rather than having prepare_linked_checkout()
perform this check, make it the caller's responsibility.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 builtin/checkout.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index f5f953d..0cb81ee 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -865,8 +865,6 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
 	int counter = 0, len, ret;
 	unsigned char rev[20];
 
-	if (!new->commit)
-		die(_("no branch specified"));
 	if (file_exists(path) && !is_empty_dir(path))
 		die(_("'%s' already exists"), path);
 
@@ -1298,8 +1296,11 @@ static int checkout_branch(struct checkout_opts *opts,
 		free(head_ref);
 	}
 
-	if (opts->new_worktree)
+	if (opts->new_worktree) {
+		if (!new->commit)
+			die(_("no branch specified"));
 		return prepare_linked_checkout(opts, new);
+	}
 
 	if (!new->commit && opts->new_branch) {
 		unsigned char rev[20];
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 10/23] checkout: prepare_linked_checkout: drop now-unused 'new' argument
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (8 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 09/23] checkout: relocate --to's "no branch specified" check Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 11/23] checkout: make --to unconditionally verbose Eric Sunshine
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

The only references to 'new' were folded out by the last two patches.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 builtin/checkout.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 0cb81ee..0dcdde2 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -854,8 +854,7 @@ static void remove_junk_on_signal(int signo)
 	raise(signo);
 }
 
-static int prepare_linked_checkout(const struct checkout_opts *opts,
-				   struct branch_info *new)
+static int prepare_linked_checkout(const struct checkout_opts *opts)
 {
 	struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;
 	struct strbuf sb = STRBUF_INIT;
@@ -1299,7 +1298,7 @@ static int checkout_branch(struct checkout_opts *opts,
 	if (opts->new_worktree) {
 		if (!new->commit)
 			die(_("no branch specified"));
-		return prepare_linked_checkout(opts, new);
+		return prepare_linked_checkout(opts);
 	}
 
 	if (!new->commit && opts->new_branch) {
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 11/23] checkout: make --to unconditionally verbose
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (9 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 10/23] checkout: prepare_linked_checkout: drop now-unused 'new' argument Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 12/23] checkout: drop 'checkout_opts' dependency from prepare_linked_checkout Eric Sunshine
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

prepare_linked_checkout() respects git-checkout's --quiet flag, however,
the plan is to relocate "git checkout --to" functionality to "git
worktree add", and git-worktree does not (yet) have a --quiet flag.
Consequently, make prepare_linked_checkout() unconditionally verbose to
ease eventual code movement to worktree.c.

(A --quiet flag can be added to git-worktree later if there is demand
for it.)

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 builtin/checkout.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 0dcdde2..86b1745 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -931,8 +931,7 @@ static int prepare_linked_checkout(const struct checkout_opts *opts)
 	strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
 	write_file(sb.buf, 1, "../..\n");
 
-	if (!opts->quiet)
-		fprintf_ln(stderr, _("Enter %s (identifier %s)"), path, name);
+	fprintf_ln(stderr, _("Enter %s (identifier %s)"), path, name);
 
 	setenv("GIT_CHECKOUT_NEW_WORKTREE", "1", 1);
 	setenv(GIT_DIR_ENVIRONMENT, sb_git.buf, 1);
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 12/23] checkout: drop 'checkout_opts' dependency from prepare_linked_checkout
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (10 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 11/23] checkout: make --to unconditionally verbose Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 13/23] worktree: introduce "add" command Eric Sunshine
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

The plan is to relocate "git checkout --to" functionality to "git
worktree add", however, worktree.c won't have access to the 'struct
checkout_opts' passed to prepare_linked_worktree(), which it consults
for the pathname of the new worktree and the argv[] of the command it
should run to populate the new worktree. Facilitate relocation of
prepare_linked_worktree() by instead having it accept the pathname and
argv[] directly, thus eliminating the final references to 'struct
checkout_opts'.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 builtin/checkout.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 86b1745..30fe786 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -854,11 +854,11 @@ static void remove_junk_on_signal(int signo)
 	raise(signo);
 }
 
-static int prepare_linked_checkout(const struct checkout_opts *opts)
+static int prepare_linked_checkout(const char *path, const char **child_argv)
 {
 	struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;
 	struct strbuf sb = STRBUF_INIT;
-	const char *path = opts->new_worktree, *name;
+	const char *name;
 	struct stat st;
 	struct child_process cp;
 	int counter = 0, len, ret;
@@ -938,7 +938,7 @@ static int prepare_linked_checkout(const struct checkout_opts *opts)
 	setenv(GIT_WORK_TREE_ENVIRONMENT, path, 1);
 	memset(&cp, 0, sizeof(cp));
 	cp.git_cmd = 1;
-	cp.argv = opts->saved_argv;
+	cp.argv = child_argv;
 	ret = run_command(&cp);
 	if (!ret) {
 		is_junk = 0;
@@ -1297,7 +1297,8 @@ static int checkout_branch(struct checkout_opts *opts,
 	if (opts->new_worktree) {
 		if (!new->commit)
 			die(_("no branch specified"));
-		return prepare_linked_checkout(opts);
+		return prepare_linked_checkout(opts->new_worktree,
+					       opts->saved_argv);
 	}
 
 	if (!new->commit && opts->new_branch) {
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 13/23] worktree: introduce "add" command
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (11 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 12/23] checkout: drop 'checkout_opts' dependency from prepare_linked_checkout Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  2:53   ` Duy Nguyen
  2015-07-04  0:17 ` [PATCH v2 14/23] worktree: add --force option Eric Sunshine
                   ` (9 subsequent siblings)
  22 siblings, 1 reply; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

The plan is to relocate "git checkout --to" functionality to "git
worktree add". As a first step, introduce a bare-bones git-worktree
"add" command along with documentation. At this stage, "git worktree
add" merely invokes "git checkout --to" behind the scenes, but an
upcoming patch will move the actual functionality
(checkout.c:prepare_linked_checkout() and its helpers) to worktree.c.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 Documentation/git-worktree.txt | 21 +++++++++++----------
 builtin/worktree.c             | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 028bbd9..59191f9 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -9,13 +9,13 @@ git-worktree - Manage multiple worktrees
 SYNOPSIS
 --------
 [verse]
+'git worktree add' <path> <branch>
 'git worktree prune' [-n] [-v] [--expire <expire>]
 
 DESCRIPTION
 -----------
 
-Manage multiple worktrees attached to the same repository. These are
-created by the command `git checkout --to`.
+Manage multiple worktrees attached to the same repository.
 
 A git repository can support multiple working trees, allowing you to check
 out more than one branch at a time.  With `git checkout --to` a new working
@@ -45,6 +45,13 @@ pruning should be suppressed. See section "DETAILS" for more information.
 
 COMMANDS
 --------
+add <path> <branch>::
+
+Check out `<branch>` into a separate working directory, `<path>`, creating
+`<path>` if necessary. The new working directory is linked to the current
+repository, sharing everything except working directory specific files
+such as HEAD, index, etc. If `<path>` already exists, it must be empty.
+
 prune::
 
 Prune working tree information in $GIT_DIR/worktrees.
@@ -118,7 +125,7 @@ refactoring session.
 
 ------------
 $ git branch emergency-fix master
-$ git checkout --to ../temp emergency-fix
+$ git worktree add ../temp emergency-fix
 $ pushd ../temp
 # ... hack hack hack ...
 $ git commit -a -m 'emergency fix for boss'
@@ -133,20 +140,14 @@ Multiple checkout support for submodules is incomplete. It is NOT
 recommended to make multiple checkouts of a superproject.
 
 git-worktree could provide more automation for tasks currently
-performed manually or via other commands, such as:
+performed manually, such as:
 
-- `add` to create a new linked worktree
 - `remove` to remove a linked worktree and its administrative files (and
   warn if the worktree is dirty)
 - `mv` to move or rename a worktree and update its administrative files
 - `lock` to prevent automatic pruning of administrative files (for instance,
   for a worktree on a portable device)
 
-SEE ALSO
---------
-
-linkgit:git-checkout[1]
-
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 2a729c6..b82861e 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -2,8 +2,11 @@
 #include "builtin.h"
 #include "dir.h"
 #include "parse-options.h"
+#include "argv-array.h"
+#include "run-command.h"
 
 static const char * const worktree_usage[] = {
+	N_("git worktree add <path> <branch>"),
 	N_("git worktree prune [<options>]"),
 	NULL
 };
@@ -119,6 +122,33 @@ static int prune(int ac, const char **av, const char *prefix)
 	return 0;
 }
 
+
+static int add(int ac, const char **av, const char *prefix)
+{
+	struct child_process c;
+	const char *path, *branch;
+	struct argv_array cmd = ARGV_ARRAY_INIT;
+	struct option options[] = {
+		OPT_END()
+	};
+
+	ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+	if (ac != 2)
+		usage_with_options(worktree_usage, options);
+
+	path = prefix ? prefix_filename(prefix, strlen(prefix), av[0]) : av[0];
+	branch = av[1];
+
+	argv_array_push(&cmd, "checkout");
+	argv_array_pushl(&cmd, "--to", path, NULL);
+	argv_array_push(&cmd, branch);
+
+	memset(&c, 0, sizeof(c));
+	c.git_cmd = 1;
+	c.argv = cmd.argv;
+	return run_command(&c);
+}
+
 int cmd_worktree(int ac, const char **av, const char *prefix)
 {
 	struct option options[] = {
@@ -127,6 +157,8 @@ int cmd_worktree(int ac, const char **av, const char *prefix)
 
 	if (ac < 2)
 		usage_with_options(worktree_usage, options);
+	if (!strcmp(av[1], "add"))
+		return add(ac - 1, av + 1, prefix);
 	if (!strcmp(av[1], "prune"))
 		return prune(ac - 1, av + 1, prefix);
 	usage_with_options(worktree_usage, options);
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 14/23] worktree: add --force option
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (12 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 13/23] worktree: introduce "add" command Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 15/23] worktree: add --detach option Eric Sunshine
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

By default, "git worktree add" refuses to create a new worktree when
the requested branch is already checked out elsewhere. Add a --force
option to override this safeguard.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 Documentation/git-worktree.txt | 8 +++++++-
 builtin/worktree.c             | 6 +++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 59191f9..552c8e4 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -9,7 +9,7 @@ git-worktree - Manage multiple worktrees
 SYNOPSIS
 --------
 [verse]
-'git worktree add' <path> <branch>
+'git worktree add' [-f] <path> <branch>
 'git worktree prune' [-n] [-v] [--expire <expire>]
 
 DESCRIPTION
@@ -59,6 +59,12 @@ Prune working tree information in $GIT_DIR/worktrees.
 OPTIONS
 -------
 
+-f::
+--force::
+	By default, `add` refuses to create a new worktree when	`<branch>`
+	is already checked out by another worktree. This option overrides
+	that safeguard.
+
 -n::
 --dry-run::
 	With `prune`, do not remove anything; just report what it would
diff --git a/builtin/worktree.c b/builtin/worktree.c
index b82861e..c9d6462 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -6,7 +6,7 @@
 #include "run-command.h"
 
 static const char * const worktree_usage[] = {
-	N_("git worktree add <path> <branch>"),
+	N_("git worktree add [<options>] <path> <branch>"),
 	N_("git worktree prune [<options>]"),
 	NULL
 };
@@ -126,9 +126,11 @@ static int prune(int ac, const char **av, const char *prefix)
 static int add(int ac, const char **av, const char *prefix)
 {
 	struct child_process c;
+	int force = 0;
 	const char *path, *branch;
 	struct argv_array cmd = ARGV_ARRAY_INIT;
 	struct option options[] = {
+		OPT__FORCE(&force, N_("checkout <branch> even if already checked out in other worktree")),
 		OPT_END()
 	};
 
@@ -141,6 +143,8 @@ static int add(int ac, const char **av, const char *prefix)
 
 	argv_array_push(&cmd, "checkout");
 	argv_array_pushl(&cmd, "--to", path, NULL);
+	if (force)
+		argv_array_push(&cmd, "--ignore-other-worktrees");
 	argv_array_push(&cmd, branch);
 
 	memset(&c, 0, sizeof(c));
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 15/23] worktree: add --detach option
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (13 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 14/23] worktree: add --force option Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 16/23] worktree: add -b/-B options Eric Sunshine
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

One of git-worktree's roles is to populate the new worktree, much like
git-checkout, and thus, for convenience, ought to support several of the
same shortcuts. Toward this goal, add a --detach option to detach HEAD
in the new worktree.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 Documentation/git-worktree.txt | 6 +++++-
 builtin/worktree.c             | 5 ++++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 552c8e4..96e2142 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -9,7 +9,7 @@ git-worktree - Manage multiple worktrees
 SYNOPSIS
 --------
 [verse]
-'git worktree add' [-f] <path> <branch>
+'git worktree add' [-f] [--detach] <path> <branch>
 'git worktree prune' [-n] [-v] [--expire <expire>]
 
 DESCRIPTION
@@ -65,6 +65,10 @@ OPTIONS
 	is already checked out by another worktree. This option overrides
 	that safeguard.
 
+--detach::
+	With `add`, detach HEAD in the new worktree. See "DETACHED HEAD" in
+	linkgit:git-checkout[1].
+
 -n::
 --dry-run::
 	With `prune`, do not remove anything; just report what it would
diff --git a/builtin/worktree.c b/builtin/worktree.c
index c9d6462..6967369 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -126,11 +126,12 @@ static int prune(int ac, const char **av, const char *prefix)
 static int add(int ac, const char **av, const char *prefix)
 {
 	struct child_process c;
-	int force = 0;
+	int force = 0, detach = 0;
 	const char *path, *branch;
 	struct argv_array cmd = ARGV_ARRAY_INIT;
 	struct option options[] = {
 		OPT__FORCE(&force, N_("checkout <branch> even if already checked out in other worktree")),
+		OPT_BOOL(0, "detach", &detach, N_("detach HEAD at named commit")),
 		OPT_END()
 	};
 
@@ -145,6 +146,8 @@ static int add(int ac, const char **av, const char *prefix)
 	argv_array_pushl(&cmd, "--to", path, NULL);
 	if (force)
 		argv_array_push(&cmd, "--ignore-other-worktrees");
+	if (detach)
+		argv_array_push(&cmd, "--detach");
 	argv_array_push(&cmd, branch);
 
 	memset(&c, 0, sizeof(c));
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 16/23] worktree: add -b/-B options
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (14 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 15/23] worktree: add --detach option Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  3:19   ` Duy Nguyen
  2015-07-04  0:17 ` [PATCH v2 17/23] tests: worktree: retrofit "checkout --to" tests for "worktree add" Eric Sunshine
                   ` (6 subsequent siblings)
  22 siblings, 1 reply; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

One of git-worktree's roles is to populate the new worktree, much like
git-checkout, and thus, for convenience, ought to support several of the
same shortcuts. Toward this goal, add -b/-B options to create a new
branch and check it out in the new worktree.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---

For brevity, I intentionally mentioned only -b in the synopsis, and
omitted -B.

 Documentation/git-worktree.txt | 13 ++++++++++---
 builtin/worktree.c             | 11 +++++++++++
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 96e2142..f6c3747 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -9,7 +9,7 @@ git-worktree - Manage multiple worktrees
 SYNOPSIS
 --------
 [verse]
-'git worktree add' [-f] [--detach] <path> <branch>
+'git worktree add' [-f] [--detach] [-b <new-branch>] <path> <branch>
 'git worktree prune' [-n] [-v] [--expire <expire>]
 
 DESCRIPTION
@@ -65,6 +65,14 @@ OPTIONS
 	is already checked out by another worktree. This option overrides
 	that safeguard.
 
+-b <new-branch>::
+-B <new-branch>::
+	With `add`, create a new branch named `<new-branch>` starting at
+	`<branch>`, and check out `<new-branch>` into the new worktree.
+	By default, `-b` refuses to create a new branch if it already
+	exists. `-B` overrides this safeguard, resetting `<new-branch>` to
+	`<branch>`.
+
 --detach::
 	With `add`, detach HEAD in the new worktree. See "DETACHED HEAD" in
 	linkgit:git-checkout[1].
@@ -134,8 +142,7 @@ make the emergency fix, remove it when done, and then resume your earlier
 refactoring session.
 
 ------------
-$ git branch emergency-fix master
-$ git worktree add ../temp emergency-fix
+$ git worktree add -b emergency-fix ../temp master
 $ pushd ../temp
 # ... hack hack hack ...
 $ git commit -a -m 'emergency fix for boss'
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 6967369..d461d31 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -127,15 +127,22 @@ static int add(int ac, const char **av, const char *prefix)
 {
 	struct child_process c;
 	int force = 0, detach = 0;
+	const char *new_branch = NULL, *new_branch_force = NULL;
 	const char *path, *branch;
 	struct argv_array cmd = ARGV_ARRAY_INIT;
 	struct option options[] = {
 		OPT__FORCE(&force, N_("checkout <branch> even if already checked out in other worktree")),
+		OPT_STRING('b', NULL, &new_branch, N_("branch"),
+			   N_("create a new branch")),
+		OPT_STRING('B', NULL, &new_branch_force, N_("branch"),
+			   N_("create or reset a branch")),
 		OPT_BOOL(0, "detach", &detach, N_("detach HEAD at named commit")),
 		OPT_END()
 	};
 
 	ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+	if (new_branch && new_branch_force)
+		die(_("-b and -B are mutually exclusive"));
 	if (ac != 2)
 		usage_with_options(worktree_usage, options);
 
@@ -146,6 +153,10 @@ static int add(int ac, const char **av, const char *prefix)
 	argv_array_pushl(&cmd, "--to", path, NULL);
 	if (force)
 		argv_array_push(&cmd, "--ignore-other-worktrees");
+	if (new_branch)
+		argv_array_pushl(&cmd, "-b", new_branch, NULL);
+	if (new_branch_force)
+		argv_array_pushl(&cmd, "-B", new_branch_force, NULL);
 	if (detach)
 		argv_array_push(&cmd, "--detach");
 	argv_array_push(&cmd, branch);
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 17/23] tests: worktree: retrofit "checkout --to" tests for "worktree add"
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (15 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 16/23] worktree: add -b/-B options Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 18/23] checkout: retire --to option Eric Sunshine
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

With the introduction of "git worktree add", "git checkout --to" is
slated for removal. Therefore, retrofit linked worktree creation tests
to use "git worktree add" instead.

(The test to check exclusivity of "checkout --to" and "checkout <paths>"
is dropped altogether since it becomes meaningless with retirement of
"checkout --to".)

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 t/{t2025-checkout-to.sh => t2025-worktree-add.sh} | 48 +++++++++++------------
 t/t2026-prune-linked-checkouts.sh                 |  2 +-
 t/t7410-submodule-checkout-to.sh                  |  4 +-
 3 files changed, 25 insertions(+), 29 deletions(-)
 rename t/{t2025-checkout-to.sh => t2025-worktree-add.sh} (59%)

diff --git a/t/t2025-checkout-to.sh b/t/t2025-worktree-add.sh
similarity index 59%
rename from t/t2025-checkout-to.sh
rename to t/t2025-worktree-add.sh
index 0fd731b..192c936 100755
--- a/t/t2025-checkout-to.sh
+++ b/t/t2025-worktree-add.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-test_description='test git checkout --to'
+test_description='test git worktree add'
 
 . ./test-lib.sh
 
@@ -8,22 +8,18 @@ test_expect_success 'setup' '
 	test_commit init
 '
 
-test_expect_success 'checkout --to not updating paths' '
-	test_must_fail git checkout --to -- init.t
-'
-
-test_expect_success 'checkout --to an existing worktree' '
+test_expect_success '"add" an existing worktree' '
 	mkdir -p existing/subtree &&
-	test_must_fail git checkout --detach --to existing master
+	test_must_fail git worktree add --detach existing master
 '
 
-test_expect_success 'checkout --to an existing empty worktree' '
+test_expect_success '"add" an existing empty worktree' '
 	mkdir existing_empty &&
-	git checkout --detach --to existing_empty master
+	git worktree add --detach existing_empty master
 '
 
-test_expect_success 'checkout --to refuses to checkout locked branch' '
-	test_must_fail git checkout --to zere master &&
+test_expect_success '"add" refuses to checkout locked branch' '
+	test_must_fail git worktree add zere master &&
 	! test -d zere &&
 	! test -d .git/worktrees/zere
 '
@@ -36,9 +32,9 @@ test_expect_success 'checking out paths not complaining about linked checkouts'
 	)
 '
 
-test_expect_success 'checkout --to a new worktree' '
+test_expect_success '"add" worktree' '
 	git rev-parse HEAD >expect &&
-	git checkout --detach --to here master &&
+	git worktree add --detach here master &&
 	(
 		cd here &&
 		test_cmp ../init.t init.t &&
@@ -49,27 +45,27 @@ test_expect_success 'checkout --to a new worktree' '
 	)
 '
 
-test_expect_success 'checkout --to a new worktree from a subdir' '
+test_expect_success '"add" worktree from a subdir' '
 	(
 		mkdir sub &&
 		cd sub &&
-		git checkout --detach --to here master &&
+		git worktree add --detach here master &&
 		cd here &&
 		test_cmp ../../init.t init.t
 	)
 '
 
-test_expect_success 'checkout --to from a linked checkout' '
+test_expect_success '"add" from a linked checkout' '
 	(
 		cd here &&
-		git checkout --detach --to nested-here master &&
+		git worktree add --detach nested-here master &&
 		cd nested-here &&
 		git fsck
 	)
 '
 
-test_expect_success 'checkout --to a new worktree creating new branch' '
-	git checkout --to there -b newmaster master &&
+test_expect_success '"add" worktree creating new branch' '
+	git worktree add -b newmaster there master &&
 	(
 		cd there &&
 		test_cmp ../init.t init.t &&
@@ -90,7 +86,7 @@ test_expect_success 'die the same branch is already checked out' '
 test_expect_success 'not die the same branch is already checked out' '
 	(
 		cd here &&
-		git checkout --ignore-other-worktrees --to anothernewmaster newmaster
+		git worktree add --force anothernewmaster newmaster
 	)
 '
 
@@ -101,15 +97,15 @@ test_expect_success 'not die on re-checking out current branch' '
 	)
 '
 
-test_expect_success 'checkout --to from a bare repo' '
+test_expect_success '"add" from a bare repo' '
 	(
 		git clone --bare . bare &&
 		cd bare &&
-		git checkout --to ../there2 -b bare-master master
+		git worktree add -b bare-master ../there2 master
 	)
 '
 
-test_expect_success 'checkout from a bare repo without --to' '
+test_expect_success 'checkout from a bare repo without "add"' '
 	(
 		cd bare &&
 		test_must_fail git checkout master
@@ -129,17 +125,17 @@ test_expect_success 'checkout with grafts' '
 	EOF
 	git log --format=%s -2 >actual &&
 	test_cmp expected actual &&
-	git checkout --detach --to grafted master &&
+	git worktree add --detach grafted master &&
 	git --git-dir=grafted/.git log --format=%s -2 >actual &&
 	test_cmp expected actual
 '
 
-test_expect_success 'checkout --to from relative HEAD' '
+test_expect_success '"add" from relative HEAD' '
 	test_commit a &&
 	test_commit b &&
 	test_commit c &&
 	git rev-parse HEAD~1 >expected &&
-	git checkout --to relhead HEAD~1 &&
+	git worktree add relhead HEAD~1 &&
 	git -C relhead rev-parse HEAD >actual &&
 	test_cmp expected actual
 '
diff --git a/t/t2026-prune-linked-checkouts.sh b/t/t2026-prune-linked-checkouts.sh
index e872f02..a0f1e3b 100755
--- a/t/t2026-prune-linked-checkouts.sh
+++ b/t/t2026-prune-linked-checkouts.sh
@@ -88,7 +88,7 @@ test_expect_success 'not prune recent checkouts' '
 
 test_expect_success 'not prune proper checkouts' '
 	test_when_finished rm -r .git/worktrees &&
-	git checkout "--to=$PWD/nop" --detach master &&
+	git worktree add --detach "$PWD/nop" master &&
 	git worktree prune &&
 	test -d .git/worktrees/nop
 '
diff --git a/t/t7410-submodule-checkout-to.sh b/t/t7410-submodule-checkout-to.sh
index 8f30aed..3f609e8 100755
--- a/t/t7410-submodule-checkout-to.sh
+++ b/t/t7410-submodule-checkout-to.sh
@@ -33,7 +33,7 @@ rev1_hash_sub=$(git --git-dir=origin/sub/.git show --pretty=format:%h -q "HEAD~1
 test_expect_success 'checkout main' \
     'mkdir default_checkout &&
     (cd clone/main &&
-	git checkout --to "$base_path/default_checkout/main" "$rev1_hash_main")'
+	git worktree add "$base_path/default_checkout/main" "$rev1_hash_main")'
 
 test_expect_failure 'can see submodule diffs just after checkout' \
     '(cd default_checkout/main && git diff --submodule master"^!" | grep "file1 updated")'
@@ -41,7 +41,7 @@ test_expect_failure 'can see submodule diffs just after checkout' \
 test_expect_success 'checkout main and initialize independed clones' \
     'mkdir fully_cloned_submodule &&
     (cd clone/main &&
-	git checkout --to "$base_path/fully_cloned_submodule/main" "$rev1_hash_main") &&
+	git worktree add "$base_path/fully_cloned_submodule/main" "$rev1_hash_main") &&
     (cd fully_cloned_submodule/main && git submodule update)'
 
 test_expect_success 'can see submodule diffs after independed cloning' \
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 18/23] checkout: retire --to option
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (16 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 17/23] tests: worktree: retrofit "checkout --to" tests for "worktree add" Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  3:04   ` Duy Nguyen
  2015-07-04  0:17 ` [PATCH v2 19/23] checkout: require worktree unconditionally Eric Sunshine
                   ` (4 subsequent siblings)
  22 siblings, 1 reply; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

Now that "git worktree add" has achieved user-facing feature-parity with
"git checkout --to", retire the latter.

Move the actual linked worktree creation functionality,
prepare_linked_checkout() and its helpers, verbatim from checkout.c to
worktree.c.

This effectively reverts changes to checkout.c by 529fef2 (checkout:
support checking out into a new working directory, 2014-11-30) with the
exception of merge_working_tree() and switch_branches() which still
require specialized knowledge that a the checkout is occurring in a
newly-created linked worktree (signaled to them by the private
GIT_CHECKOUT_NEW_WORKTREE environment variable).

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 builtin/checkout.c | 156 +----------------------------------------------------
 builtin/worktree.c | 138 ++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 133 insertions(+), 161 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 30fe786..b1e68b3 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -19,8 +19,6 @@
 #include "ll-merge.h"
 #include "resolve-undo.h"
 #include "submodule.h"
-#include "argv-array.h"
-#include "sigchain.h"
 
 static const char * const checkout_usage[] = {
 	N_("git checkout [options] <branch>"),
@@ -51,8 +49,6 @@ struct checkout_opts {
 	struct pathspec pathspec;
 	struct tree *source_tree;
 
-	const char *new_worktree;
-	const char **saved_argv;
 	int new_worktree_mode;
 };
 
@@ -255,9 +251,6 @@ static int checkout_paths(const struct checkout_opts *opts,
 		die(_("Cannot update paths and switch to branch '%s' at the same time."),
 		    opts->new_branch);
 
-	if (opts->new_worktree)
-		die(_("'%s' cannot be used with updating paths"), "--to");
-
 	if (opts->patch_mode)
 		return run_add_interactive(revision, "--patch=checkout",
 					   &opts->pathspec);
@@ -825,137 +818,6 @@ static int switch_branches(const struct checkout_opts *opts,
 	return ret || writeout_error;
 }
 
-static char *junk_work_tree;
-static char *junk_git_dir;
-static int is_junk;
-static pid_t junk_pid;
-
-static void remove_junk(void)
-{
-	struct strbuf sb = STRBUF_INIT;
-	if (!is_junk || getpid() != junk_pid)
-		return;
-	if (junk_git_dir) {
-		strbuf_addstr(&sb, junk_git_dir);
-		remove_dir_recursively(&sb, 0);
-		strbuf_reset(&sb);
-	}
-	if (junk_work_tree) {
-		strbuf_addstr(&sb, junk_work_tree);
-		remove_dir_recursively(&sb, 0);
-	}
-	strbuf_release(&sb);
-}
-
-static void remove_junk_on_signal(int signo)
-{
-	remove_junk();
-	sigchain_pop(signo);
-	raise(signo);
-}
-
-static int prepare_linked_checkout(const char *path, const char **child_argv)
-{
-	struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;
-	struct strbuf sb = STRBUF_INIT;
-	const char *name;
-	struct stat st;
-	struct child_process cp;
-	int counter = 0, len, ret;
-	unsigned char rev[20];
-
-	if (file_exists(path) && !is_empty_dir(path))
-		die(_("'%s' already exists"), path);
-
-	len = strlen(path);
-	while (len && is_dir_sep(path[len - 1]))
-		len--;
-
-	for (name = path + len - 1; name > path; name--)
-		if (is_dir_sep(*name)) {
-			name++;
-			break;
-		}
-	strbuf_addstr(&sb_repo,
-		      git_path("worktrees/%.*s", (int)(path + len - name), name));
-	len = sb_repo.len;
-	if (safe_create_leading_directories_const(sb_repo.buf))
-		die_errno(_("could not create leading directories of '%s'"),
-			  sb_repo.buf);
-	while (!stat(sb_repo.buf, &st)) {
-		counter++;
-		strbuf_setlen(&sb_repo, len);
-		strbuf_addf(&sb_repo, "%d", counter);
-	}
-	name = strrchr(sb_repo.buf, '/') + 1;
-
-	junk_pid = getpid();
-	atexit(remove_junk);
-	sigchain_push_common(remove_junk_on_signal);
-
-	if (mkdir(sb_repo.buf, 0777))
-		die_errno(_("could not create directory of '%s'"), sb_repo.buf);
-	junk_git_dir = xstrdup(sb_repo.buf);
-	is_junk = 1;
-
-	/*
-	 * lock the incomplete repo so prune won't delete it, unlock
-	 * after the preparation is over.
-	 */
-	strbuf_addf(&sb, "%s/locked", sb_repo.buf);
-	write_file(sb.buf, 1, "initializing\n");
-
-	strbuf_addf(&sb_git, "%s/.git", path);
-	if (safe_create_leading_directories_const(sb_git.buf))
-		die_errno(_("could not create leading directories of '%s'"),
-			  sb_git.buf);
-	junk_work_tree = xstrdup(path);
-
-	strbuf_reset(&sb);
-	strbuf_addf(&sb, "%s/gitdir", sb_repo.buf);
-	write_file(sb.buf, 1, "%s\n", real_path(sb_git.buf));
-	write_file(sb_git.buf, 1, "gitdir: %s/worktrees/%s\n",
-		   real_path(get_git_common_dir()), name);
-	/*
-	 * This is to keep resolve_ref() happy. We need a valid HEAD
-	 * or is_git_directory() will reject the directory. Any valid
-	 * value would do because this value will be ignored and
-	 * replaced at the next (real) checkout.
-	 */
-	if (!resolve_ref_unsafe("HEAD", 0, rev, NULL))
-		die(_("unable to resolve HEAD"));
-	strbuf_reset(&sb);
-	strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
-	write_file(sb.buf, 1, "%s\n", sha1_to_hex(rev));
-	strbuf_reset(&sb);
-	strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
-	write_file(sb.buf, 1, "../..\n");
-
-	fprintf_ln(stderr, _("Enter %s (identifier %s)"), path, name);
-
-	setenv("GIT_CHECKOUT_NEW_WORKTREE", "1", 1);
-	setenv(GIT_DIR_ENVIRONMENT, sb_git.buf, 1);
-	setenv(GIT_WORK_TREE_ENVIRONMENT, path, 1);
-	memset(&cp, 0, sizeof(cp));
-	cp.git_cmd = 1;
-	cp.argv = child_argv;
-	ret = run_command(&cp);
-	if (!ret) {
-		is_junk = 0;
-		free(junk_work_tree);
-		free(junk_git_dir);
-		junk_work_tree = NULL;
-		junk_git_dir = NULL;
-	}
-	strbuf_reset(&sb);
-	strbuf_addf(&sb, "%s/locked", sb_repo.buf);
-	unlink_or_warn(sb.buf);
-	strbuf_release(&sb);
-	strbuf_release(&sb_repo);
-	strbuf_release(&sb_git);
-	return ret;
-}
-
 static int git_checkout_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "diff.ignoresubmodules")) {
@@ -1294,13 +1156,6 @@ static int checkout_branch(struct checkout_opts *opts,
 		free(head_ref);
 	}
 
-	if (opts->new_worktree) {
-		if (!new->commit)
-			die(_("no branch specified"));
-		return prepare_linked_checkout(opts->new_worktree,
-					       opts->saved_argv);
-	}
-
 	if (!new->commit && opts->new_branch) {
 		unsigned char rev[20];
 		int flag;
@@ -1343,8 +1198,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 			 N_("do not limit pathspecs to sparse entries only")),
 		OPT_HIDDEN_BOOL(0, "guess", &dwim_new_local_branch,
 				N_("second guess 'git checkout no-such-branch'")),
-		OPT_FILENAME(0, "to", &opts.new_worktree,
-			   N_("check a branch out in a separate working directory")),
 		OPT_BOOL(0, "ignore-other-worktrees", &opts.ignore_other_worktrees,
 			 N_("do not check if another worktree is holding the given ref")),
 		OPT_END(),
@@ -1355,9 +1208,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 	opts.overwrite_ignore = 1;
 	opts.prefix = prefix;
 
-	opts.saved_argv = xmalloc(sizeof(const char *) * (argc + 2));
-	memcpy(opts.saved_argv, argv, sizeof(const char *) * (argc + 1));
-
 	gitmodules_config();
 	git_config(git_checkout_config, &opts);
 
@@ -1366,13 +1216,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 	argc = parse_options(argc, argv, prefix, options, checkout_usage,
 			     PARSE_OPT_KEEP_DASHDASH);
 
-	/* recursive execution from checkout_new_worktree() */
 	opts.new_worktree_mode = getenv("GIT_CHECKOUT_NEW_WORKTREE") != NULL;
-	if (opts.new_worktree_mode)
-		opts.new_worktree = NULL;
 
-	if (!opts.new_worktree)
-		setup_work_tree();
+	setup_work_tree();
 
 	if (conflict_style) {
 		opts.merge = 1; /* implied */
diff --git a/builtin/worktree.c b/builtin/worktree.c
index d461d31..7cfaec6 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -4,6 +4,7 @@
 #include "parse-options.h"
 #include "argv-array.h"
 #include "run-command.h"
+#include "sigchain.h"
 
 static const char * const worktree_usage[] = {
 	N_("git worktree add [<options>] <path> <branch>"),
@@ -122,10 +123,139 @@ static int prune(int ac, const char **av, const char *prefix)
 	return 0;
 }
 
+static char *junk_work_tree;
+static char *junk_git_dir;
+static int is_junk;
+static pid_t junk_pid;
+
+static void remove_junk(void)
+{
+	struct strbuf sb = STRBUF_INIT;
+	if (!is_junk || getpid() != junk_pid)
+		return;
+	if (junk_git_dir) {
+		strbuf_addstr(&sb, junk_git_dir);
+		remove_dir_recursively(&sb, 0);
+		strbuf_reset(&sb);
+	}
+	if (junk_work_tree) {
+		strbuf_addstr(&sb, junk_work_tree);
+		remove_dir_recursively(&sb, 0);
+	}
+	strbuf_release(&sb);
+}
+
+static void remove_junk_on_signal(int signo)
+{
+	remove_junk();
+	sigchain_pop(signo);
+	raise(signo);
+}
+
+static int add_worktree(const char *path, const char **child_argv)
+{
+	struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;
+	struct strbuf sb = STRBUF_INIT;
+	const char *name;
+	struct stat st;
+	struct child_process cp;
+	int counter = 0, len, ret;
+	unsigned char rev[20];
+
+	if (file_exists(path) && !is_empty_dir(path))
+		die(_("'%s' already exists"), path);
+
+	len = strlen(path);
+	while (len && is_dir_sep(path[len - 1]))
+		len--;
+
+	for (name = path + len - 1; name > path; name--)
+		if (is_dir_sep(*name)) {
+			name++;
+			break;
+		}
+	strbuf_addstr(&sb_repo,
+		      git_path("worktrees/%.*s", (int)(path + len - name), name));
+	len = sb_repo.len;
+	if (safe_create_leading_directories_const(sb_repo.buf))
+		die_errno(_("could not create leading directories of '%s'"),
+			  sb_repo.buf);
+	while (!stat(sb_repo.buf, &st)) {
+		counter++;
+		strbuf_setlen(&sb_repo, len);
+		strbuf_addf(&sb_repo, "%d", counter);
+	}
+	name = strrchr(sb_repo.buf, '/') + 1;
+
+	junk_pid = getpid();
+	atexit(remove_junk);
+	sigchain_push_common(remove_junk_on_signal);
+
+	if (mkdir(sb_repo.buf, 0777))
+		die_errno(_("could not create directory of '%s'"), sb_repo.buf);
+	junk_git_dir = xstrdup(sb_repo.buf);
+	is_junk = 1;
+
+	/*
+	 * lock the incomplete repo so prune won't delete it, unlock
+	 * after the preparation is over.
+	 */
+	strbuf_addf(&sb, "%s/locked", sb_repo.buf);
+	write_file(sb.buf, 1, "initializing\n");
+
+	strbuf_addf(&sb_git, "%s/.git", path);
+	if (safe_create_leading_directories_const(sb_git.buf))
+		die_errno(_("could not create leading directories of '%s'"),
+			  sb_git.buf);
+	junk_work_tree = xstrdup(path);
+
+	strbuf_reset(&sb);
+	strbuf_addf(&sb, "%s/gitdir", sb_repo.buf);
+	write_file(sb.buf, 1, "%s\n", real_path(sb_git.buf));
+	write_file(sb_git.buf, 1, "gitdir: %s/worktrees/%s\n",
+		   real_path(get_git_common_dir()), name);
+	/*
+	 * This is to keep resolve_ref() happy. We need a valid HEAD
+	 * or is_git_directory() will reject the directory. Any valid
+	 * value would do because this value will be ignored and
+	 * replaced at the next (real) checkout.
+	 */
+	if (!resolve_ref_unsafe("HEAD", 0, rev, NULL))
+		die(_("unable to resolve HEAD"));
+	strbuf_reset(&sb);
+	strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
+	write_file(sb.buf, 1, "%s\n", sha1_to_hex(rev));
+	strbuf_reset(&sb);
+	strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
+	write_file(sb.buf, 1, "../..\n");
+
+	fprintf_ln(stderr, _("Enter %s (identifier %s)"), path, name);
+
+	setenv("GIT_CHECKOUT_NEW_WORKTREE", "1", 1);
+	setenv(GIT_DIR_ENVIRONMENT, sb_git.buf, 1);
+	setenv(GIT_WORK_TREE_ENVIRONMENT, path, 1);
+	memset(&cp, 0, sizeof(cp));
+	cp.git_cmd = 1;
+	cp.argv = child_argv;
+	ret = run_command(&cp);
+	if (!ret) {
+		is_junk = 0;
+		free(junk_work_tree);
+		free(junk_git_dir);
+		junk_work_tree = NULL;
+		junk_git_dir = NULL;
+	}
+	strbuf_reset(&sb);
+	strbuf_addf(&sb, "%s/locked", sb_repo.buf);
+	unlink_or_warn(sb.buf);
+	strbuf_release(&sb);
+	strbuf_release(&sb_repo);
+	strbuf_release(&sb_git);
+	return ret;
+}
 
 static int add(int ac, const char **av, const char *prefix)
 {
-	struct child_process c;
 	int force = 0, detach = 0;
 	const char *new_branch = NULL, *new_branch_force = NULL;
 	const char *path, *branch;
@@ -150,7 +280,6 @@ static int add(int ac, const char **av, const char *prefix)
 	branch = av[1];
 
 	argv_array_push(&cmd, "checkout");
-	argv_array_pushl(&cmd, "--to", path, NULL);
 	if (force)
 		argv_array_push(&cmd, "--ignore-other-worktrees");
 	if (new_branch)
@@ -161,10 +290,7 @@ static int add(int ac, const char **av, const char *prefix)
 		argv_array_push(&cmd, "--detach");
 	argv_array_push(&cmd, branch);
 
-	memset(&c, 0, sizeof(c));
-	c.git_cmd = 1;
-	c.argv = cmd.argv;
-	return run_command(&c);
+	return add_worktree(path, cmd.argv);
 }
 
 int cmd_worktree(int ac, const char **av, const char *prefix)
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 19/23] checkout: require worktree unconditionally
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (17 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 18/23] checkout: retire --to option Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  2:33   ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 20/23] worktree: extract basename computation to new function Eric Sunshine
                   ` (3 subsequent siblings)
  22 siblings, 1 reply; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

In order to allow linked worktree creation via "git checkout -b" from a
bare repository, 3473ad0 (checkout: don't require a work tree when
checking out into a new one, 2014-11-30) dropped git-checkout's
unconditional NEED_WORK_TREE requirement and instead performed worktree
setup conditionally based upon presence or absence of the --to option.
Now that --to has been retired and git-checkout is no longer responsible
for linked worktree creation, the NEED_WORK_TREE requirement can once
again be unconditional.

This effectively reverts 3473ad0, except for the tests it added which
now check bare repository behavior of "git worktree add" instead.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 builtin/checkout.c | 2 --
 git.c              | 2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index b1e68b3..5754554 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1218,8 +1218,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 
 	opts.new_worktree_mode = getenv("GIT_CHECKOUT_NEW_WORKTREE") != NULL;
 
-	setup_work_tree();
-
 	if (conflict_style) {
 		opts.merge = 1; /* implied */
 		git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
diff --git a/git.c b/git.c
index f227838..21a6398 100644
--- a/git.c
+++ b/git.c
@@ -383,7 +383,7 @@ static struct cmd_struct commands[] = {
 	{ "check-ignore", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE },
 	{ "check-mailmap", cmd_check_mailmap, RUN_SETUP },
 	{ "check-ref-format", cmd_check_ref_format },
-	{ "checkout", cmd_checkout, RUN_SETUP },
+	{ "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
 	{ "checkout-index", cmd_checkout_index,
 		RUN_SETUP | NEED_WORK_TREE},
 	{ "cherry", cmd_cherry, RUN_SETUP },
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 20/23] worktree: extract basename computation to new function
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (18 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 19/23] checkout: require worktree unconditionally Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 21/23] worktree: add: make -b/-B default to HEAD when <branch> is omitted Eric Sunshine
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

A subsequent patch will also need to compute the basename of the new
worktree, so factor out this logic into a new function.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 builtin/worktree.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index 7cfaec6..a1d863d 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -152,6 +152,25 @@ static void remove_junk_on_signal(int signo)
 	raise(signo);
 }
 
+static const char *worktree_basename(const char *path, int *olen)
+{
+	const char *name;
+	int len;
+
+	len = strlen(path);
+	while (len && is_dir_sep(path[len - 1]))
+		len--;
+
+	for (name = path + len - 1; name > path; name--)
+		if (is_dir_sep(*name)) {
+			name++;
+			break;
+		}
+
+	*olen = len;
+	return name;
+}
+
 static int add_worktree(const char *path, const char **child_argv)
 {
 	struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;
@@ -165,15 +184,7 @@ static int add_worktree(const char *path, const char **child_argv)
 	if (file_exists(path) && !is_empty_dir(path))
 		die(_("'%s' already exists"), path);
 
-	len = strlen(path);
-	while (len && is_dir_sep(path[len - 1]))
-		len--;
-
-	for (name = path + len - 1; name > path; name--)
-		if (is_dir_sep(*name)) {
-			name++;
-			break;
-		}
+	name = worktree_basename(path, &len);
 	strbuf_addstr(&sb_repo,
 		      git_path("worktrees/%.*s", (int)(path + len - name), name));
 	len = sb_repo.len;
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 21/23] worktree: add: make -b/-B default to HEAD when <branch> is omitted
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (19 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 20/23] worktree: extract basename computation to new function Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-06 19:14   ` Junio C Hamano
  2015-07-04  0:17 ` [PATCH v2 22/23] worktree: add: auto-vivify new branch " Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 23/23] checkout: retire --ignore-other-worktrees in favor of --force Eric Sunshine
  22 siblings, 1 reply; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

As a convenience, like "git branch" and "git checkout -b", make
"git worktree add -b <newbranch> <path> <branch>" default to HEAD when
<branch> is omitted.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 Documentation/git-worktree.txt | 1 +
 builtin/worktree.c             | 6 ++++--
 t/t2025-worktree-add.sh        | 7 +++++++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index f6c3747..5ca11f6 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -69,6 +69,7 @@ OPTIONS
 -B <new-branch>::
 	With `add`, create a new branch named `<new-branch>` starting at
 	`<branch>`, and check out `<new-branch>` into the new worktree.
+	If `<branch>` is omitted, it defaults to HEAD.
 	By default, `-b` refuses to create a new branch if it already
 	exists. `-B` overrides this safeguard, resetting `<new-branch>` to
 	`<branch>`.
diff --git a/builtin/worktree.c b/builtin/worktree.c
index a1d863d..bf634a6 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -284,11 +284,13 @@ static int add(int ac, const char **av, const char *prefix)
 	ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
 	if (new_branch && new_branch_force)
 		die(_("-b and -B are mutually exclusive"));
-	if (ac != 2)
+	if (ac < 1 || ac > 2)
+		usage_with_options(worktree_usage, options);
+	if (ac < 2 && !new_branch && !new_branch_force)
 		usage_with_options(worktree_usage, options);
 
 	path = prefix ? prefix_filename(prefix, strlen(prefix), av[0]) : av[0];
-	branch = av[1];
+	branch = ac < 2 ? "HEAD" : av[1];
 
 	argv_array_push(&cmd, "checkout");
 	if (force)
diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh
index 192c936..95a1141 100755
--- a/t/t2025-worktree-add.sh
+++ b/t/t2025-worktree-add.sh
@@ -140,4 +140,11 @@ test_expect_success '"add" from relative HEAD' '
 	test_cmp expected actual
 '
 
+test_expect_success '"add -b" with <branch> omitted' '
+	git rev-parse HEAD >expected &&
+	git worktree add -b burble flornk &&
+	git rev-parse burble >actual &&
+	test_cmp expected actual
+'
+
 test_done
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 22/23] worktree: add: auto-vivify new branch when <branch> is omitted
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (20 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 21/23] worktree: add: make -b/-B default to HEAD when <branch> is omitted Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  2015-07-04  0:17 ` [PATCH v2 23/23] checkout: retire --ignore-other-worktrees in favor of --force Eric Sunshine
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

As a convenience, when <branch> is omitted from "git worktree <path>
<branch>" and neither -b nor -B used, automatically create a new branch
named after <path>, as if "-b $(basename <path>)" was specified. Thus,
"git worktree add ../hotfix" creates a new branch named "hotfix" and
associates it with new worktree "../hotfix".

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 Documentation/git-worktree.txt | 8 ++++++--
 builtin/worktree.c             | 8 ++++++--
 t/t2025-worktree-add.sh        | 7 +++++++
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 5ca11f6..938bdab 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -9,7 +9,7 @@ git-worktree - Manage multiple worktrees
 SYNOPSIS
 --------
 [verse]
-'git worktree add' [-f] [--detach] [-b <new-branch>] <path> <branch>
+'git worktree add' [-f] [--detach] [-b <new-branch>] <path> [<branch>]
 'git worktree prune' [-n] [-v] [--expire <expire>]
 
 DESCRIPTION
@@ -45,12 +45,16 @@ pruning should be suppressed. See section "DETAILS" for more information.
 
 COMMANDS
 --------
-add <path> <branch>::
+add <path> [<branch>]::
 
 Check out `<branch>` into a separate working directory, `<path>`, creating
 `<path>` if necessary. The new working directory is linked to the current
 repository, sharing everything except working directory specific files
 such as HEAD, index, etc. If `<path>` already exists, it must be empty.
++
+If `<branch>` is omitted and neither `-b` nor `-B` used, then, as a
+convenience, a new branch rooted at HEAD is created automatically, as if
+`-b $(basename <path>)` was specified.
 
 prune::
 
diff --git a/builtin/worktree.c b/builtin/worktree.c
index bf634a6..c8c6fa7 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -286,12 +286,16 @@ static int add(int ac, const char **av, const char *prefix)
 		die(_("-b and -B are mutually exclusive"));
 	if (ac < 1 || ac > 2)
 		usage_with_options(worktree_usage, options);
-	if (ac < 2 && !new_branch && !new_branch_force)
-		usage_with_options(worktree_usage, options);
 
 	path = prefix ? prefix_filename(prefix, strlen(prefix), av[0]) : av[0];
 	branch = ac < 2 ? "HEAD" : av[1];
 
+	if (ac < 2 && !new_branch && !new_branch_force) {
+		int n;
+		const char *s = worktree_basename(path, &n);
+		new_branch = xstrndup(s, n);
+	}
+
 	argv_array_push(&cmd, "checkout");
 	if (force)
 		argv_array_push(&cmd, "--ignore-other-worktrees");
diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh
index 95a1141..59d73ff 100755
--- a/t/t2025-worktree-add.sh
+++ b/t/t2025-worktree-add.sh
@@ -147,4 +147,11 @@ test_expect_success '"add -b" with <branch> omitted' '
 	test_cmp expected actual
 '
 
+test_expect_success '"add" with <branch> omitted' '
+	git rev-parse HEAD >expected &&
+	git worktree add wiffle/bat &&
+	git rev-parse bat >actual &&
+	test_cmp expected actual
+'
+
 test_done
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 23/23] checkout: retire --ignore-other-worktrees in favor of --force
  2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
                   ` (21 preceding siblings ...)
  2015-07-04  0:17 ` [PATCH v2 22/23] worktree: add: auto-vivify new branch " Eric Sunshine
@ 2015-07-04  0:17 ` Eric Sunshine
  22 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  0:17 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

As a safeguard, checking out a branch already checked out by a different
worktree is disallowed. This behavior can be overridden with
--ignore-other-worktrees, however, this option is neither obvious nor
particularly discoverable. As a common safeguard override, --force is
more likely to come to mind. Therefore, overload it to also suppress the
check for a branch already checked out elsewhere.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---

I plopped this patch at the end of the series so that it can be dropped
easily if desired since Junio indicated[1] that he would "moderately
object" to this change.

[1]: http://thread.gmane.org/gmane.comp.version-control.git/273032/focus=273108

 Documentation/git-checkout.txt | 9 +++------
 builtin/checkout.c             | 8 +++-----
 builtin/worktree.c             | 2 +-
 3 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 77b7141..41148ce 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -111,6 +111,9 @@ OPTIONS
 +
 When checking out paths from the index, do not fail upon unmerged
 entries; instead, unmerged entries are ignored.
++
+By default, checking out a branch already checked out in another worktree
+is disallowed. This overrides that safeguard.
 
 --ours::
 --theirs::
@@ -232,12 +235,6 @@ section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
 	specific files such as HEAD, index, etc. See
 	linkgit:git-worktree[1] for a description of linked worktrees.
 
---ignore-other-worktrees::
-	`git checkout` refuses when the wanted ref is already checked
-	out by another worktree. This option makes it check the ref
-	out anyway. In other words, the ref can be held by more than one
-	worktree.
-
 <branch>::
 	Branch to checkout; if it refers to a branch (i.e., a name that,
 	when prepended with "refs/heads/", is a valid ref), then that
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5754554..01c7c30 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -35,7 +35,6 @@ struct checkout_opts {
 	int writeout_stage;
 	int overwrite_ignore;
 	int ignore_skipworktree;
-	int ignore_other_worktrees;
 
 	const char *new_branch;
 	const char *new_branch_force;
@@ -903,7 +902,8 @@ static void check_linked_checkout(struct branch_info *new, const char *id)
 		strbuf_rtrim(&gitdir);
 	} else
 		strbuf_addstr(&gitdir, get_git_common_dir());
-	die(_("'%s' is already checked out at '%s'"), new->name, gitdir.buf);
+	die(_("'%s' is already checked out at '%s'; use --force to override"),
+	    new->name, gitdir.buf);
 done:
 	strbuf_release(&path);
 	strbuf_release(&sb);
@@ -1151,7 +1151,7 @@ static int checkout_branch(struct checkout_opts *opts,
 		char *head_ref = resolve_refdup("HEAD", 0, sha1, &flag);
 		if (head_ref &&
 		    (!(flag & REF_ISSYMREF) || strcmp(head_ref, new->path)) &&
-		    !opts->ignore_other_worktrees)
+		    !opts->force)
 			check_linked_checkouts(new);
 		free(head_ref);
 	}
@@ -1198,8 +1198,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 			 N_("do not limit pathspecs to sparse entries only")),
 		OPT_HIDDEN_BOOL(0, "guess", &dwim_new_local_branch,
 				N_("second guess 'git checkout no-such-branch'")),
-		OPT_BOOL(0, "ignore-other-worktrees", &opts.ignore_other_worktrees,
-			 N_("do not check if another worktree is holding the given ref")),
 		OPT_END(),
 	};
 
diff --git a/builtin/worktree.c b/builtin/worktree.c
index c8c6fa7..8a6c7fa 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -298,7 +298,7 @@ static int add(int ac, const char **av, const char *prefix)
 
 	argv_array_push(&cmd, "checkout");
 	if (force)
-		argv_array_push(&cmd, "--ignore-other-worktrees");
+		argv_array_push(&cmd, "--force");
 	if (new_branch)
 		argv_array_pushl(&cmd, "-b", new_branch, NULL);
 	if (new_branch_force)
-- 
2.5.0.rc1.197.g417e668

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 07/23] Documentation/git-worktree: add EXAMPLES section
  2015-07-04  0:17 ` [PATCH v2 07/23] Documentation/git-worktree: add EXAMPLES section Eric Sunshine
@ 2015-07-04  2:23   ` Eric Sunshine
  0 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  2:23 UTC (permalink / raw)
  To: Git List
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

On Fri, Jul 3, 2015 at 8:17 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:
> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
> ---
> +EXAMPLES
> +--------
> +You are middle of a refactoring session and your boss comes in and demands

s/middle/in the &/

> +that you fix something immediately. You might typically use
> +linkgit:git-stash[1] to store your changes away temporarily, however, your
> +worktree is in such a state of disarray (with new, removed, moved files,
> +and other bits and pieces strewn around) that you don't want to risk
> +disturbing any of it. Instead, you create a temporary linked worktree to
> +make the emergency fix, remove it when done, and then resume your earlier
> +refactoring session.
> +
> +------------
> +$ git branch emergency-fix master
> +$ git checkout --to ../temp emergency-fix
> +$ pushd ../temp
> +# ... hack hack hack ...
> +$ git commit -a -m 'emergency fix for boss'
> +$ popd
> +$ rm -rf ../temp
> +$ git worktree prune
> +------------
> +
>  BUGS
>  ----
>  Multiple checkout support for submodules is incomplete. It is NOT
> --
> 2.5.0.rc1.197.g417e668

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 19/23] checkout: require worktree unconditionally
  2015-07-04  0:17 ` [PATCH v2 19/23] checkout: require worktree unconditionally Eric Sunshine
@ 2015-07-04  2:33   ` Eric Sunshine
  0 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  2:33 UTC (permalink / raw)
  To: Git List
  Cc: Junio C Hamano, Duy Nguyen, Mark Levedahl, Mikael Magnusson,
	Eric Sunshine

On Fri, Jul 3, 2015 at 8:17 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:
> In order to allow linked worktree creation via "git checkout -b" from a

s/-b/--to/

> bare repository, 3473ad0 (checkout: don't require a work tree when
> checking out into a new one, 2014-11-30) dropped git-checkout's
> unconditional NEED_WORK_TREE requirement and instead performed worktree
> setup conditionally based upon presence or absence of the --to option.
> Now that --to has been retired and git-checkout is no longer responsible
> for linked worktree creation, the NEED_WORK_TREE requirement can once
> again be unconditional.
>
> This effectively reverts 3473ad0, except for the tests it added which
> now check bare repository behavior of "git worktree add" instead.
>
> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
> ---
>  builtin/checkout.c | 2 --
>  git.c              | 2 +-
>  2 files changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/builtin/checkout.c b/builtin/checkout.c
> index b1e68b3..5754554 100644
> --- a/builtin/checkout.c
> +++ b/builtin/checkout.c
> @@ -1218,8 +1218,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
>
>         opts.new_worktree_mode = getenv("GIT_CHECKOUT_NEW_WORKTREE") != NULL;
>
> -       setup_work_tree();
> -
>         if (conflict_style) {
>                 opts.merge = 1; /* implied */
>                 git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
> diff --git a/git.c b/git.c
> index f227838..21a6398 100644
> --- a/git.c
> +++ b/git.c
> @@ -383,7 +383,7 @@ static struct cmd_struct commands[] = {
>         { "check-ignore", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE },
>         { "check-mailmap", cmd_check_mailmap, RUN_SETUP },
>         { "check-ref-format", cmd_check_ref_format },
> -       { "checkout", cmd_checkout, RUN_SETUP },
> +       { "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
>         { "checkout-index", cmd_checkout_index,
>                 RUN_SETUP | NEED_WORK_TREE},
>         { "cherry", cmd_cherry, RUN_SETUP },
> --
> 2.5.0.rc1.197.g417e668

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 04/23] Documentation/git-worktree: add BUGS section
  2015-07-04  0:17 ` [PATCH v2 04/23] Documentation/git-worktree: add BUGS section Eric Sunshine
@ 2015-07-04  2:41   ` Duy Nguyen
  2015-07-04  8:48     ` Eric Sunshine
  0 siblings, 1 reply; 38+ messages in thread
From: Duy Nguyen @ 2015-07-04  2:41 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Git Mailing List, Junio C Hamano, Mark Levedahl, Mikael Magnusson

On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:
> +git-worktree could provide more automation for tasks currently
> +performed manually or via other commands, such as:
> +
> +- `add` to create a new linked worktree
> +- `remove` to remove a linked worktree and its administrative files (and
> +  warn if the worktree is dirty)
> +- `mv` to move or rename a worktree and update its administrative files
> +- `lock` to prevent automatic pruning of administrative files (for instance,
> +  for a worktree on a portable device)

No need to re-roll if this is the only change in the series, but we
also need "list/ls" here.
-- 
Duy

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 08/23] checkout: fix bug with --to and relative HEAD
  2015-07-04  0:17 ` [PATCH v2 08/23] checkout: fix bug with --to and relative HEAD Eric Sunshine
@ 2015-07-04  2:45   ` Duy Nguyen
  2015-07-04  8:49     ` Eric Sunshine
  0 siblings, 1 reply; 38+ messages in thread
From: Duy Nguyen @ 2015-07-04  2:45 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Git Mailing List, Junio C Hamano, Mark Levedahl, Mikael Magnusson

On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:
> Given "git checkout --to <path> HEAD~1", the new worktree's HEAD should
> begin life at the current branch's HEAD~1, however, it actually ends up
> at HEAD~2. The happens because:
>
>     1. git-checkout resolves HEAD~1
>
>     2. to satisfy is_git_directory, prepare_linked_worktree() creates a
>        HEAD in the new worktree with the value of the resolved HEAD~1
>
>     3. git-checkout re-invokes itself with the same arguments within the
>        new worktree to populate the worktree
>
>     4. the sub git-checkout resolves HEAD~1 relative to its own HEAD,
>        which is the resolved HEAD~1 from the original invocation,
>        resulting unexpectedly and incorrectly in HEAD~2 (relative to the
>        original)
>
> Fix this by unconditionally assigning the current worktree's HEAD as the
> value of the new worktree's HEAD.

Good catch!

> @@ -924,9 +925,11 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
>          * value would do because this value will be ignored and
>          * replaced at the next (real) checkout.
>          */

This comment "any valid value would do.. will be ignored" is proved incorrect.

> +       if (!resolve_ref_unsafe("HEAD", 0, rev, NULL))
> +               die(_("unable to resolve HEAD"));
>         strbuf_reset(&sb);
>         strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
> -       write_file(sb.buf, 1, "%s\n", sha1_to_hex(new->commit->object.sha1));
> +       write_file(sb.buf, 1, "%s\n", sha1_to_hex(rev));
>         strbuf_reset(&sb);
>         strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
>         write_file(sb.buf, 1, "../..\n");
-- 
Duy

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 13/23] worktree: introduce "add" command
  2015-07-04  0:17 ` [PATCH v2 13/23] worktree: introduce "add" command Eric Sunshine
@ 2015-07-04  2:53   ` Duy Nguyen
  2015-07-04  8:54     ` Eric Sunshine
  0 siblings, 1 reply; 38+ messages in thread
From: Duy Nguyen @ 2015-07-04  2:53 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Git Mailing List, Junio C Hamano, Mark Levedahl, Mikael Magnusson

On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:
>  COMMANDS
>  --------
> +add <path> <branch>::
> +
> +Check out `<branch>` into a separate working directory, `<path>`, creating
> +`<path>` if necessary. The new working directory is linked to the current
> +repository, sharing everything except working directory specific files
> +such as HEAD, index, etc. If `<path>` already exists, it must be empty.

Side note, "must be empty" is an implementation limitation. I think
the two-way merge employed by git-checkout can deal with dirty <path>
and only perform the checkout if there is no data loss. But we can
leave this for later.
-- 
Duy

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 18/23] checkout: retire --to option
  2015-07-04  0:17 ` [PATCH v2 18/23] checkout: retire --to option Eric Sunshine
@ 2015-07-04  3:04   ` Duy Nguyen
  2015-07-04  8:59     ` Eric Sunshine
  0 siblings, 1 reply; 38+ messages in thread
From: Duy Nguyen @ 2015-07-04  3:04 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Git Mailing List, Junio C Hamano, Mark Levedahl, Mikael Magnusson

On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:
> Now that "git worktree add" has achieved user-facing feature-parity with
> "git checkout --to", retire the latter.
>
> Move the actual linked worktree creation functionality,
> prepare_linked_checkout() and its helpers, verbatim from checkout.c to
> worktree.c.
>
> This effectively reverts changes to checkout.c by 529fef2 (checkout:
> support checking out into a new working directory, 2014-11-30) with the
> exception of merge_working_tree() and switch_branches() which still
> require specialized knowledge that a the checkout is occurring in a
> newly-created linked worktree (signaled to them by the private
> GIT_CHECKOUT_NEW_WORKTREE environment variable).
>
> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
> ---
>  builtin/checkout.c | 156 +----------------------------------------------------
>  builtin/worktree.c | 138 ++++++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 133 insertions(+), 161 deletions(-)

If I didn't lose track of changes, "--to" is still described in
git-checkout.txt?
-- 
Duy

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 16/23] worktree: add -b/-B options
  2015-07-04  0:17 ` [PATCH v2 16/23] worktree: add -b/-B options Eric Sunshine
@ 2015-07-04  3:19   ` Duy Nguyen
  2015-07-04  8:57     ` Eric Sunshine
  0 siblings, 1 reply; 38+ messages in thread
From: Duy Nguyen @ 2015-07-04  3:19 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Git Mailing List, Junio C Hamano, Mark Levedahl, Mikael Magnusson

On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:
> One of git-worktree's roles is to populate the new worktree, much like
> git-checkout, and thus, for convenience, ought to support several of the
> same shortcuts. Toward this goal, add -b/-B options to create a new
> branch and check it out in the new worktree.

There are some other  ref manipulation options we can bring over like
--orphan and --track. But you can totally leave them out and we can
add them back when people actually need them.
-- 
Duy

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 04/23] Documentation/git-worktree: add BUGS section
  2015-07-04  2:41   ` Duy Nguyen
@ 2015-07-04  8:48     ` Eric Sunshine
  0 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  8:48 UTC (permalink / raw)
  To: Duy Nguyen
  Cc: Git Mailing List, Junio C Hamano, Mark Levedahl, Mikael Magnusson

On Fri, Jul 3, 2015 at 10:41 PM, Duy Nguyen <pclouds@gmail.com> wrote:
> On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:
>> +git-worktree could provide more automation for tasks currently
>> +performed manually or via other commands, such as:
>> +
>> +- `add` to create a new linked worktree
>> +- `remove` to remove a linked worktree and its administrative files (and
>> +  warn if the worktree is dirty)
>> +- `mv` to move or rename a worktree and update its administrative files
>> +- `lock` to prevent automatic pruning of administrative files (for instance,
>> +  for a worktree on a portable device)
>
> No need to re-roll if this is the only change in the series, but we
> also need "list/ls" here.

Oops, yes. That was the very first item I had in mind (mentioned by
you in the commentary of your "git worktree prune" patch), yet I
somehow omitted it.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 08/23] checkout: fix bug with --to and relative HEAD
  2015-07-04  2:45   ` Duy Nguyen
@ 2015-07-04  8:49     ` Eric Sunshine
  0 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  8:49 UTC (permalink / raw)
  To: Duy Nguyen
  Cc: Git Mailing List, Junio C Hamano, Mark Levedahl, Mikael Magnusson

On Fri, Jul 3, 2015 at 10:45 PM, Duy Nguyen <pclouds@gmail.com> wrote:
> On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:
>> Given "git checkout --to <path> HEAD~1", the new worktree's HEAD should
>> begin life at the current branch's HEAD~1, however, it actually ends up
>> at HEAD~2. The happens because:
>>
>>     1. git-checkout resolves HEAD~1
>>
>>     2. to satisfy is_git_directory, prepare_linked_worktree() creates a
>>        HEAD in the new worktree with the value of the resolved HEAD~1
>>
>>     3. git-checkout re-invokes itself with the same arguments within the
>>        new worktree to populate the worktree
>>
>>     4. the sub git-checkout resolves HEAD~1 relative to its own HEAD,
>>        which is the resolved HEAD~1 from the original invocation,
>>        resulting unexpectedly and incorrectly in HEAD~2 (relative to the
>>        original)
>>
>> Fix this by unconditionally assigning the current worktree's HEAD as the
>> value of the new worktree's HEAD.
>
> Good catch!
>
>> @@ -924,9 +925,11 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
>>          * value would do because this value will be ignored and
>>          * replaced at the next (real) checkout.
>>          */
>
> This comment "any valid value would do.. will be ignored" is proved incorrect.

Yup, and I meant to update the comment but promptly forgot about it.
Thanks for the reminder.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 13/23] worktree: introduce "add" command
  2015-07-04  2:53   ` Duy Nguyen
@ 2015-07-04  8:54     ` Eric Sunshine
  2015-07-06  9:24       ` Duy Nguyen
  0 siblings, 1 reply; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  8:54 UTC (permalink / raw)
  To: Duy Nguyen
  Cc: Git Mailing List, Junio C Hamano, Mark Levedahl, Mikael Magnusson

On Fri, Jul 3, 2015 at 10:53 PM, Duy Nguyen <pclouds@gmail.com> wrote:
> On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:
>>  COMMANDS
>>  --------
>> +add <path> <branch>::
>> +
>> +Check out `<branch>` into a separate working directory, `<path>`, creating
>> +`<path>` if necessary. The new working directory is linked to the current
>> +repository, sharing everything except working directory specific files
>> +such as HEAD, index, etc. If `<path>` already exists, it must be empty.
>
> Side note, "must be empty" is an implementation limitation. I think
> the two-way merge employed by git-checkout can deal with dirty <path>
> and only perform the checkout if there is no data loss. But we can
> leave this for later.

Perhaps we should omit the bit about an existing but empty directory
for now? Like this:

    Create `<path>` and checkout `<branch>` into it. The new working
    directory is linked to the current repository, sharing everything
    except working directory specific files such as HEAD, index, etc.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 16/23] worktree: add -b/-B options
  2015-07-04  3:19   ` Duy Nguyen
@ 2015-07-04  8:57     ` Eric Sunshine
  0 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  8:57 UTC (permalink / raw)
  To: Duy Nguyen
  Cc: Git Mailing List, Junio C Hamano, Mark Levedahl, Mikael Magnusson

On Fri, Jul 3, 2015 at 11:19 PM, Duy Nguyen <pclouds@gmail.com> wrote:
> On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:
>> One of git-worktree's roles is to populate the new worktree, much like
>> git-checkout, and thus, for convenience, ought to support several of the
>> same shortcuts. Toward this goal, add -b/-B options to create a new
>> branch and check it out in the new worktree.
>
> There are some other  ref manipulation options we can bring over like
> --orphan and --track. But you can totally leave them out and we can
> add them back when people actually need them.

Yes. I added --force, -b/-B, and --detach because they are used by the
tests; and I considered --orphan and --track to be good candidates, as
well, but decided to omit them for now since the series is already
overly long.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 18/23] checkout: retire --to option
  2015-07-04  3:04   ` Duy Nguyen
@ 2015-07-04  8:59     ` Eric Sunshine
  0 siblings, 0 replies; 38+ messages in thread
From: Eric Sunshine @ 2015-07-04  8:59 UTC (permalink / raw)
  To: Duy Nguyen
  Cc: Git Mailing List, Junio C Hamano, Mark Levedahl, Mikael Magnusson

On Fri, Jul 3, 2015 at 11:04 PM, Duy Nguyen <pclouds@gmail.com> wrote:
> On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:
>> Now that "git worktree add" has achieved user-facing feature-parity with
>> "git checkout --to", retire the latter.
>>
>> Move the actual linked worktree creation functionality,
>> prepare_linked_checkout() and its helpers, verbatim from checkout.c to
>> worktree.c.
>>
>> This effectively reverts changes to checkout.c by 529fef2 (checkout:
>> support checking out into a new working directory, 2014-11-30) with the
>> exception of merge_working_tree() and switch_branches() which still
>> require specialized knowledge that a the checkout is occurring in a
>> newly-created linked worktree (signaled to them by the private
>> GIT_CHECKOUT_NEW_WORKTREE environment variable).
>>
>> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
>> ---
>>  builtin/checkout.c | 156 +----------------------------------------------------
>>  builtin/worktree.c | 138 ++++++++++++++++++++++++++++++++++++++++++++---
>>  2 files changed, 133 insertions(+), 161 deletions(-)
>
> If I didn't lose track of changes, "--to" is still described in
> git-checkout.txt?

You're right. v1 did remove --to from git-checkout.txt, but somehow I
overlooked it in v2. Thanks for pointing out this oversight.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 13/23] worktree: introduce "add" command
  2015-07-04  8:54     ` Eric Sunshine
@ 2015-07-06  9:24       ` Duy Nguyen
  0 siblings, 0 replies; 38+ messages in thread
From: Duy Nguyen @ 2015-07-06  9:24 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Git Mailing List, Junio C Hamano, Mark Levedahl, Mikael Magnusson

On Sat, Jul 4, 2015 at 3:54 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:
> On Fri, Jul 3, 2015 at 10:53 PM, Duy Nguyen <pclouds@gmail.com> wrote:
>> On Sat, Jul 4, 2015 at 7:17 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:
>>>  COMMANDS
>>>  --------
>>> +add <path> <branch>::
>>> +
>>> +Check out `<branch>` into a separate working directory, `<path>`, creating
>>> +`<path>` if necessary. The new working directory is linked to the current
>>> +repository, sharing everything except working directory specific files
>>> +such as HEAD, index, etc. If `<path>` already exists, it must be empty.
>>
>> Side note, "must be empty" is an implementation limitation. I think
>> the two-way merge employed by git-checkout can deal with dirty <path>
>> and only perform the checkout if there is no data loss. But we can
>> leave this for later.
>
> Perhaps we should omit the bit about an existing but empty directory
> for now? Like this:
>
>     Create `<path>` and checkout `<branch>` into it. The new working
>     directory is linked to the current repository, sharing everything
>     except working directory specific files such as HEAD, index, etc.

I think either way is ok.
-- 
Duy

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 21/23] worktree: add: make -b/-B default to HEAD when <branch> is omitted
  2015-07-04  0:17 ` [PATCH v2 21/23] worktree: add: make -b/-B default to HEAD when <branch> is omitted Eric Sunshine
@ 2015-07-06 19:14   ` Junio C Hamano
  0 siblings, 0 replies; 38+ messages in thread
From: Junio C Hamano @ 2015-07-06 19:14 UTC (permalink / raw)
  To: Eric Sunshine; +Cc: git, Duy Nguyen, Mark Levedahl, Mikael Magnusson

Eric Sunshine <sunshine@sunshineco.com> writes:

> As a convenience, like "git branch" and "git checkout -b", make
> "git worktree add -b <newbranch> <path> <branch>" default to HEAD when
> <branch> is omitted.
>
> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
> ---
>  Documentation/git-worktree.txt | 1 +
>  builtin/worktree.c             | 6 ++++--
>  t/t2025-worktree-add.sh        | 7 +++++++
>  3 files changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
> index f6c3747..5ca11f6 100644
> --- a/Documentation/git-worktree.txt
> +++ b/Documentation/git-worktree.txt
> @@ -69,6 +69,7 @@ OPTIONS
>  -B <new-branch>::
>  	With `add`, create a new branch named `<new-branch>` starting at
>  	`<branch>`, and check out `<new-branch>` into the new worktree.
> +	If `<branch>` is omitted, it defaults to HEAD.

What would be the SYNOPSIS change to adjust for this, I wonder.

'git worktree add' [-f] [--detach] [-b <new-branch>] <path> [<branch>]

or something?  Can I omit <branch> without giving -b <new-branch>?

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2015-07-06 19:15 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-04  0:17 [PATCH v2 00/23] replace "checkout --to" with "worktree add" Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 01/23] Documentation/git-checkout: fix incorrect worktree prune command Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 02/23] Documentation/git-worktree: associate options with commands Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 03/23] Documentation: move linked worktree description from checkout to worktree Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 04/23] Documentation/git-worktree: add BUGS section Eric Sunshine
2015-07-04  2:41   ` Duy Nguyen
2015-07-04  8:48     ` Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 05/23] Documentation/git-worktree: split technical info from general description Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 06/23] Documentation/git-worktree: add high-level 'lock' overview Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 07/23] Documentation/git-worktree: add EXAMPLES section Eric Sunshine
2015-07-04  2:23   ` Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 08/23] checkout: fix bug with --to and relative HEAD Eric Sunshine
2015-07-04  2:45   ` Duy Nguyen
2015-07-04  8:49     ` Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 09/23] checkout: relocate --to's "no branch specified" check Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 10/23] checkout: prepare_linked_checkout: drop now-unused 'new' argument Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 11/23] checkout: make --to unconditionally verbose Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 12/23] checkout: drop 'checkout_opts' dependency from prepare_linked_checkout Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 13/23] worktree: introduce "add" command Eric Sunshine
2015-07-04  2:53   ` Duy Nguyen
2015-07-04  8:54     ` Eric Sunshine
2015-07-06  9:24       ` Duy Nguyen
2015-07-04  0:17 ` [PATCH v2 14/23] worktree: add --force option Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 15/23] worktree: add --detach option Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 16/23] worktree: add -b/-B options Eric Sunshine
2015-07-04  3:19   ` Duy Nguyen
2015-07-04  8:57     ` Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 17/23] tests: worktree: retrofit "checkout --to" tests for "worktree add" Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 18/23] checkout: retire --to option Eric Sunshine
2015-07-04  3:04   ` Duy Nguyen
2015-07-04  8:59     ` Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 19/23] checkout: require worktree unconditionally Eric Sunshine
2015-07-04  2:33   ` Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 20/23] worktree: extract basename computation to new function Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 21/23] worktree: add: make -b/-B default to HEAD when <branch> is omitted Eric Sunshine
2015-07-06 19:14   ` Junio C Hamano
2015-07-04  0:17 ` [PATCH v2 22/23] worktree: add: auto-vivify new branch " Eric Sunshine
2015-07-04  0:17 ` [PATCH v2 23/23] checkout: retire --ignore-other-worktrees in favor of --force Eric Sunshine

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).