git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 00/11] nd/worktree-move update
@ 2017-02-02  8:49 Nguyễn Thái Ngọc Duy
  2017-02-02  8:49 ` [PATCH 01/11] worktree.c: zero new 'struct worktree' on allocation Nguyễn Thái Ngọc Duy
                   ` (11 more replies)
  0 siblings, 12 replies; 25+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2017-02-02  8:49 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

This squashes two changes from Johannes and Ramsay:

diff --git a/builtin/worktree.c b/builtin/worktree.c
index 339c622e20..a1c91f1542 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -528,7 +528,7 @@ static int unlock_worktree(int ac, const char **av, const char *prefix)
 
 static void validate_no_submodules(const struct worktree *wt)
 {
-	struct index_state istate = {0};
+	struct index_state istate = { NULL };
 	int i, found_submodules = 0;
 
 	if (read_index_from(&istate, worktree_git_path(wt, "index")) > 0) {
diff --git a/t/t2028-worktree-move.sh b/t/t2028-worktree-move.sh
index 084acc6c6d..b3105eaaed 100755
--- a/t/t2028-worktree-move.sh
+++ b/t/t2028-worktree-move.sh
@@ -71,13 +71,14 @@ test_expect_success 'move locked worktree' '
 '
 
 test_expect_success 'move worktree' '
+	toplevel="$(pwd)" &&
 	git worktree move source destination &&
 	test_path_is_missing source &&
 	git worktree list --porcelain | grep "^worktree" >actual &&
 	cat <<-EOF >expected &&
-	worktree $TRASH_DIRECTORY
-	worktree $TRASH_DIRECTORY/destination
-	worktree $TRASH_DIRECTORY/elsewhere
+	worktree $toplevel
+	worktree $toplevel/destination
+	worktree $toplevel/elsewhere
 	EOF
 	test_cmp expected actual &&
 	git -C destination log --format=%s >actual2 &&


Nguyễn Thái Ngọc Duy (11):
  worktree.c: zero new 'struct worktree' on allocation
  worktree: reorder an if statement
  get_worktrees() must return main worktree as first item even on error
  worktree.c: get_worktrees() takes a new flag argument
  worktree list: keep the list sorted
  worktree.c: add validate_worktree()
  worktree.c: add update_worktree_location()
  worktree move: new command
  worktree move: accept destination as directory
  worktree move: refuse to move worktrees with submodules
  worktree remove: new command

 Documentation/git-worktree.txt         |  28 ++++--
 branch.c                               |   2 +-
 builtin/branch.c                       |   2 +-
 builtin/worktree.c                     | 176 +++++++++++++++++++++++++++++++--
 contrib/completion/git-completion.bash |   5 +-
 t/t2027-worktree-list.sh               |  40 ++++++++
 t/t2028-worktree-move.sh               |  57 +++++++++++
 worktree.c                             | 126 +++++++++++++++++++----
 worktree.h                             |  15 ++-
 9 files changed, 410 insertions(+), 41 deletions(-)

-- 
2.11.0.157.gd943d85


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

* [PATCH 01/11] worktree.c: zero new 'struct worktree' on allocation
  2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
@ 2017-02-02  8:49 ` Nguyễn Thái Ngọc Duy
  2017-02-02  8:49 ` [PATCH 02/11] worktree: reorder an if statement Nguyễn Thái Ngọc Duy
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2017-02-02  8:49 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

This keeps things a bit simpler when we add more fields, knowing that
default values are always zero.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 worktree.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/worktree.c b/worktree.c
index f7869f8d60..f7c1b5e24d 100644
--- a/worktree.c
+++ b/worktree.c
@@ -91,16 +91,11 @@ static struct worktree *get_main_worktree(void)
 	if (parse_ref(path.buf, &head_ref, &is_detached) < 0)
 		goto done;
 
-	worktree = xmalloc(sizeof(struct worktree));
+	worktree = xcalloc(1, sizeof(*worktree));
 	worktree->path = strbuf_detach(&worktree_path, NULL);
-	worktree->id = NULL;
 	worktree->is_bare = is_bare;
-	worktree->head_ref = NULL;
 	worktree->is_detached = is_detached;
-	worktree->is_current = 0;
 	add_head_info(&head_ref, worktree);
-	worktree->lock_reason = NULL;
-	worktree->lock_reason_valid = 0;
 
 done:
 	strbuf_release(&path);
@@ -138,16 +133,11 @@ static struct worktree *get_linked_worktree(const char *id)
 	if (parse_ref(path.buf, &head_ref, &is_detached) < 0)
 		goto done;
 
-	worktree = xmalloc(sizeof(struct worktree));
+	worktree = xcalloc(1, sizeof(*worktree));
 	worktree->path = strbuf_detach(&worktree_path, NULL);
 	worktree->id = xstrdup(id);
-	worktree->is_bare = 0;
-	worktree->head_ref = NULL;
 	worktree->is_detached = is_detached;
-	worktree->is_current = 0;
 	add_head_info(&head_ref, worktree);
-	worktree->lock_reason = NULL;
-	worktree->lock_reason_valid = 0;
 
 done:
 	strbuf_release(&path);
-- 
2.11.0.157.gd943d85


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

* [PATCH 02/11] worktree: reorder an if statement
  2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
  2017-02-02  8:49 ` [PATCH 01/11] worktree.c: zero new 'struct worktree' on allocation Nguyễn Thái Ngọc Duy
@ 2017-02-02  8:49 ` Nguyễn Thái Ngọc Duy
  2017-02-02  8:49 ` [PATCH 03/11] get_worktrees() must return main worktree as first item even on error Nguyễn Thái Ngọc Duy
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2017-02-02  8:49 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

This is no-op. But it helps reduce diff noise in the next patch.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/worktree.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index 5c4854d3e4..8a654e4ad3 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -406,10 +406,10 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)
 	else {
 		strbuf_addf(&sb, "%-*s ", abbrev_len,
 				find_unique_abbrev(wt->head_sha1, DEFAULT_ABBREV));
-		if (!wt->is_detached)
-			strbuf_addf(&sb, "[%s]", shorten_unambiguous_ref(wt->head_ref, 0));
-		else
+		if (wt->is_detached)
 			strbuf_addstr(&sb, "(detached HEAD)");
+		else
+			strbuf_addf(&sb, "[%s]", shorten_unambiguous_ref(wt->head_ref, 0));
 	}
 	printf("%s\n", sb.buf);
 
-- 
2.11.0.157.gd943d85


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

* [PATCH 03/11] get_worktrees() must return main worktree as first item even on error
  2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
  2017-02-02  8:49 ` [PATCH 01/11] worktree.c: zero new 'struct worktree' on allocation Nguyễn Thái Ngọc Duy
  2017-02-02  8:49 ` [PATCH 02/11] worktree: reorder an if statement Nguyễn Thái Ngọc Duy
@ 2017-02-02  8:49 ` Nguyễn Thái Ngọc Duy
  2017-02-02  8:50 ` [PATCH 04/11] worktree.c: get_worktrees() takes a new flag argument Nguyễn Thái Ngọc Duy
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2017-02-02  8:49 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

This is required by git-worktree.txt, stating that the main worktree is
the first line (especially in --porcelain mode when we can't just change
behavior at will).

There's only one case when get_worktrees() may skip main worktree, when
parse_ref() fails. Update the code so that we keep first item as main
worktree and return something sensible in this case:

 - In user-friendly mode, since we're not constraint by anything,
   returning "(error)" should do the job (we already show "(detached
   HEAD)" which is not machine-friendly). Actually errors should be
   printed on stderr by parse_ref() (*)

 - In plumbing mode, we do not show neither 'bare', 'detached' or
   'branch ...', which is possible by the format description if I read
   it right.

Careful readers may realize that when the local variable "head_ref" in
get_main_worktree() is emptied, add_head_info() will do nothing to
wt->head_sha1. But that's ok because head_sha1 is zero-ized in the
previous patch.

(*) Well, it does not. But it's supposed to be a stop gap implementation
    until we can reuse refs code to parse "ref: " stuff in HEAD, from
    resolve_refs_unsafe(). Now may be the time since refs refactoring is
    mostly done.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/worktree.c       |  6 ++++--
 t/t2027-worktree-list.sh | 21 +++++++++++++++++++++
 worktree.c               | 10 +++-------
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index 8a654e4ad3..b835b91f63 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -388,7 +388,7 @@ static void show_worktree_porcelain(struct worktree *wt)
 		printf("HEAD %s\n", sha1_to_hex(wt->head_sha1));
 		if (wt->is_detached)
 			printf("detached\n");
-		else
+		else if (wt->head_ref)
 			printf("branch %s\n", wt->head_ref);
 	}
 	printf("\n");
@@ -408,8 +408,10 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)
 				find_unique_abbrev(wt->head_sha1, DEFAULT_ABBREV));
 		if (wt->is_detached)
 			strbuf_addstr(&sb, "(detached HEAD)");
-		else
+		else if (wt->head_ref)
 			strbuf_addf(&sb, "[%s]", shorten_unambiguous_ref(wt->head_ref, 0));
+		else
+			strbuf_addstr(&sb, "(error)");
 	}
 	printf("%s\n", sb.buf);
 
diff --git a/t/t2027-worktree-list.sh b/t/t2027-worktree-list.sh
index 1b1b65a6b0..98b5f340e5 100755
--- a/t/t2027-worktree-list.sh
+++ b/t/t2027-worktree-list.sh
@@ -96,4 +96,25 @@ test_expect_success 'bare repo cleanup' '
 	rm -rf bare1
 '
 
+test_expect_success 'broken main worktree still at the top' '
+	git init broken-main &&
+	(
+		cd broken-main &&
+		test_commit new &&
+		git worktree add linked &&
+		cat >expected <<-EOF &&
+		worktree $(pwd)
+		HEAD $_z40
+
+		EOF
+		cd linked &&
+		echo "worktree $(pwd)" >expected &&
+		echo "ref: .broken" >../.git/HEAD &&
+		git worktree list --porcelain | head -n 3 >actual &&
+		test_cmp ../expected actual &&
+		git worktree list | head -n 1 >actual.2 &&
+		grep -F "(error)" actual.2
+	)
+'
+
 test_done
diff --git a/worktree.c b/worktree.c
index f7c1b5e24d..3145522536 100644
--- a/worktree.c
+++ b/worktree.c
@@ -88,16 +88,13 @@ static struct worktree *get_main_worktree(void)
 
 	strbuf_addf(&path, "%s/HEAD", get_git_common_dir());
 
-	if (parse_ref(path.buf, &head_ref, &is_detached) < 0)
-		goto done;
-
 	worktree = xcalloc(1, sizeof(*worktree));
 	worktree->path = strbuf_detach(&worktree_path, NULL);
 	worktree->is_bare = is_bare;
 	worktree->is_detached = is_detached;
-	add_head_info(&head_ref, worktree);
+	if (!parse_ref(path.buf, &head_ref, &is_detached))
+		add_head_info(&head_ref, worktree);
 
-done:
 	strbuf_release(&path);
 	strbuf_release(&worktree_path);
 	strbuf_release(&head_ref);
@@ -173,8 +170,7 @@ struct worktree **get_worktrees(void)
 
 	list = xmalloc(alloc * sizeof(struct worktree *));
 
-	if ((list[counter] = get_main_worktree()))
-		counter++;
+	list[counter++] = get_main_worktree();
 
 	strbuf_addf(&path, "%s/worktrees", get_git_common_dir());
 	dir = opendir(path.buf);
-- 
2.11.0.157.gd943d85


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

* [PATCH 04/11] worktree.c: get_worktrees() takes a new flag argument
  2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
                   ` (2 preceding siblings ...)
  2017-02-02  8:49 ` [PATCH 03/11] get_worktrees() must return main worktree as first item even on error Nguyễn Thái Ngọc Duy
@ 2017-02-02  8:50 ` Nguyễn Thái Ngọc Duy
  2017-02-02  8:50 ` [PATCH 05/11] worktree list: keep the list sorted Nguyễn Thái Ngọc Duy
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2017-02-02  8:50 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

This is another no-op patch, in preparation for get_worktrees() to do
optional things, like sorting.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 branch.c           | 2 +-
 builtin/branch.c   | 2 +-
 builtin/worktree.c | 6 +++---
 worktree.c         | 4 ++--
 worktree.h         | 2 +-
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/branch.c b/branch.c
index 0d459b3cfe..c431cbf6a9 100644
--- a/branch.c
+++ b/branch.c
@@ -348,7 +348,7 @@ void die_if_checked_out(const char *branch, int ignore_current_worktree)
 int replace_each_worktree_head_symref(const char *oldref, const char *newref)
 {
 	int ret = 0;
-	struct worktree **worktrees = get_worktrees();
+	struct worktree **worktrees = get_worktrees(0);
 	int i;
 
 	for (i = 0; worktrees[i]; i++) {
diff --git a/builtin/branch.c b/builtin/branch.c
index 60cc5c8e8d..475707528a 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -531,7 +531,7 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
 
 static void reject_rebase_or_bisect_branch(const char *target)
 {
-	struct worktree **worktrees = get_worktrees();
+	struct worktree **worktrees = get_worktrees(0);
 	int i;
 
 	for (i = 0; worktrees[i]; i++) {
diff --git a/builtin/worktree.c b/builtin/worktree.c
index b835b91f63..d7d195cd95 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -447,7 +447,7 @@ static int list(int ac, const char **av, const char *prefix)
 	if (ac)
 		usage_with_options(worktree_usage, options);
 	else {
-		struct worktree **worktrees = get_worktrees();
+		struct worktree **worktrees = get_worktrees(0);
 		int path_maxlen = 0, abbrev = DEFAULT_ABBREV, i;
 
 		if (!porcelain)
@@ -478,7 +478,7 @@ static int lock_worktree(int ac, const char **av, const char *prefix)
 	if (ac != 1)
 		usage_with_options(worktree_usage, options);
 
-	worktrees = get_worktrees();
+	worktrees = get_worktrees(0);
 	wt = find_worktree(worktrees, prefix, av[0]);
 	if (!wt)
 		die(_("'%s' is not a working tree"), av[0]);
@@ -511,7 +511,7 @@ static int unlock_worktree(int ac, const char **av, const char *prefix)
 	if (ac != 1)
 		usage_with_options(worktree_usage, options);
 
-	worktrees = get_worktrees();
+	worktrees = get_worktrees(0);
 	wt = find_worktree(worktrees, prefix, av[0]);
 	if (!wt)
 		die(_("'%s' is not a working tree"), av[0]);
diff --git a/worktree.c b/worktree.c
index 3145522536..ead088e43c 100644
--- a/worktree.c
+++ b/worktree.c
@@ -160,7 +160,7 @@ static void mark_current_worktree(struct worktree **worktrees)
 	free(git_dir);
 }
 
-struct worktree **get_worktrees(void)
+struct worktree **get_worktrees(unsigned flags)
 {
 	struct worktree **list = NULL;
 	struct strbuf path = STRBUF_INIT;
@@ -327,7 +327,7 @@ const struct worktree *find_shared_symref(const char *symref,
 
 	if (worktrees)
 		free_worktrees(worktrees);
-	worktrees = get_worktrees();
+	worktrees = get_worktrees(0);
 
 	for (i = 0; worktrees[i]; i++) {
 		struct worktree *wt = worktrees[i];
diff --git a/worktree.h b/worktree.h
index 90e1311fa7..2e68d4ad86 100644
--- a/worktree.h
+++ b/worktree.h
@@ -23,7 +23,7 @@ struct worktree {
  * The caller is responsible for freeing the memory from the returned
  * worktree(s).
  */
-extern struct worktree **get_worktrees(void);
+extern struct worktree **get_worktrees(unsigned flags);
 
 /*
  * Return git dir of the worktree. Note that the path may be relative.
-- 
2.11.0.157.gd943d85


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

* [PATCH 05/11] worktree list: keep the list sorted
  2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
                   ` (3 preceding siblings ...)
  2017-02-02  8:50 ` [PATCH 04/11] worktree.c: get_worktrees() takes a new flag argument Nguyễn Thái Ngọc Duy
@ 2017-02-02  8:50 ` Nguyễn Thái Ngọc Duy
  2017-02-02  8:50 ` [PATCH 06/11] worktree.c: add validate_worktree() Nguyễn Thái Ngọc Duy
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2017-02-02  8:50 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

It makes it easier to write tests for. But it should also be good for
the user since locating a worktree by eye would be easier once they
notice this.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/worktree.c       |  2 +-
 t/t2027-worktree-list.sh | 19 +++++++++++++++++++
 worktree.c               | 14 ++++++++++++++
 worktree.h               |  2 ++
 4 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index d7d195cd95..9a97e37a3f 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -447,7 +447,7 @@ static int list(int ac, const char **av, const char *prefix)
 	if (ac)
 		usage_with_options(worktree_usage, options);
 	else {
-		struct worktree **worktrees = get_worktrees(0);
+		struct worktree **worktrees = get_worktrees(GWT_SORT_LINKED);
 		int path_maxlen = 0, abbrev = DEFAULT_ABBREV, i;
 
 		if (!porcelain)
diff --git a/t/t2027-worktree-list.sh b/t/t2027-worktree-list.sh
index 98b5f340e5..465eeeacd3 100755
--- a/t/t2027-worktree-list.sh
+++ b/t/t2027-worktree-list.sh
@@ -117,4 +117,23 @@ test_expect_success 'broken main worktree still at the top' '
 	)
 '
 
+test_expect_success 'linked worktrees are sorted' '
+	mkdir sorted &&
+	git init sorted/main &&
+	(
+		cd sorted/main &&
+		test_tick &&
+		test_commit new &&
+		git worktree add ../first &&
+		git worktree add ../second &&
+		git worktree list --porcelain | grep ^worktree >actual
+	) &&
+	cat >expected <<-EOF &&
+	worktree $(pwd)/sorted/main
+	worktree $(pwd)/sorted/first
+	worktree $(pwd)/sorted/second
+	EOF
+	test_cmp expected sorted/main/actual
+'
+
 test_done
diff --git a/worktree.c b/worktree.c
index ead088e43c..eb6121263b 100644
--- a/worktree.c
+++ b/worktree.c
@@ -160,6 +160,13 @@ static void mark_current_worktree(struct worktree **worktrees)
 	free(git_dir);
 }
 
+static int compare_worktree(const void *a_, const void *b_)
+{
+	const struct worktree *const *a = a_;
+	const struct worktree *const *b = b_;
+	return fspathcmp((*a)->path, (*b)->path);
+}
+
 struct worktree **get_worktrees(unsigned flags)
 {
 	struct worktree **list = NULL;
@@ -191,6 +198,13 @@ struct worktree **get_worktrees(unsigned flags)
 	ALLOC_GROW(list, counter + 1, alloc);
 	list[counter] = NULL;
 
+	if (flags & GWT_SORT_LINKED)
+		/*
+		 * don't sort the first item (main worktree), which will
+		 * always be the first
+		 */
+		QSORT(list + 1, counter - 1, compare_worktree);
+
 	mark_current_worktree(list);
 	return list;
 }
diff --git a/worktree.h b/worktree.h
index 2e68d4ad86..d59ce1fee8 100644
--- a/worktree.h
+++ b/worktree.h
@@ -15,6 +15,8 @@ struct worktree {
 
 /* Functions for acting on the information about worktrees. */
 
+#define GWT_SORT_LINKED (1 << 0) /* keeps linked worktrees sorted */
+
 /*
  * Get the worktrees.  The primary worktree will always be the first returned,
  * and linked worktrees will be pointed to by 'next' in each subsequent
-- 
2.11.0.157.gd943d85


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

* [PATCH 06/11] worktree.c: add validate_worktree()
  2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
                   ` (4 preceding siblings ...)
  2017-02-02  8:50 ` [PATCH 05/11] worktree list: keep the list sorted Nguyễn Thái Ngọc Duy
@ 2017-02-02  8:50 ` Nguyễn Thái Ngọc Duy
  2017-02-02  8:50 ` [PATCH 07/11] worktree.c: add update_worktree_location() Nguyễn Thái Ngọc Duy
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2017-02-02  8:50 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

This function is later used by "worktree move" and "worktree remove"
to ensure that we have a good connection between the repository and
the worktree. For example, if a worktree is moved manually, the
worktree location recorded in $GIT_DIR/worktrees/.../gitdir is
incorrect and we should not move that one.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 worktree.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 worktree.h |  5 +++++
 2 files changed, 68 insertions(+)

diff --git a/worktree.c b/worktree.c
index eb6121263b..929072ad89 100644
--- a/worktree.c
+++ b/worktree.c
@@ -291,6 +291,69 @@ const char *is_worktree_locked(struct worktree *wt)
 	return wt->lock_reason;
 }
 
+static int report(int quiet, const char *fmt, ...)
+{
+	va_list params;
+
+	if (quiet)
+		return -1;
+
+	va_start(params, fmt);
+	vfprintf(stderr, fmt, params);
+	fputc('\n', stderr);
+	va_end(params);
+	return -1;
+}
+
+int validate_worktree(const struct worktree *wt, int quiet)
+{
+	struct strbuf sb = STRBUF_INIT;
+	const char *path;
+	int err;
+
+	if (is_main_worktree(wt)) {
+		/*
+		 * Main worktree using .git file to point to the
+		 * repository would make it impossible to know where
+		 * the actual worktree is if this function is executed
+		 * from another worktree. No .git file support for now.
+		 */
+		strbuf_addf(&sb, "%s/.git", wt->path);
+		if (!is_directory(sb.buf)) {
+			strbuf_release(&sb);
+			return report(quiet, _("'%s/.git' at main worktree is not the repository directory"),
+				      wt->path);
+		}
+		return 0;
+	}
+
+	/*
+	 * Make sure "gitdir" file points to a real .git file and that
+	 * file points back here.
+	 */
+	if (!is_absolute_path(wt->path))
+		return report(quiet, _("'%s' file does not contain absolute path to the worktree location"),
+			      git_common_path("worktrees/%s/gitdir", wt->id));
+
+	strbuf_addf(&sb, "%s/.git", wt->path);
+	if (!file_exists(sb.buf)) {
+		strbuf_release(&sb);
+		return report(quiet, _("'%s/.git' does not exist"), wt->path);
+	}
+
+	path = read_gitfile_gently(sb.buf, &err);
+	strbuf_release(&sb);
+	if (!path)
+		return report(quiet, _("'%s/.git' is not a .git file, error code %d"),
+			      wt->path, err);
+
+	if (fspathcmp(path, real_path(git_common_path("worktrees/%s", wt->id))))
+		return report(quiet, _("'%s' does not point back to"),
+			      wt->path, git_common_path("worktrees/%s", wt->id));
+
+	return 0;
+}
+
 int is_worktree_being_rebased(const struct worktree *wt,
 			      const char *target)
 {
diff --git a/worktree.h b/worktree.h
index d59ce1fee8..4433db2eb3 100644
--- a/worktree.h
+++ b/worktree.h
@@ -53,6 +53,11 @@ extern int is_main_worktree(const struct worktree *wt);
 extern const char *is_worktree_locked(struct worktree *wt);
 
 /*
+ * Return zero if the worktree is in good condition.
+ */
+extern int validate_worktree(const struct worktree *wt, int quiet);
+
+/*
  * Free up the memory for worktree(s)
  */
 extern void free_worktrees(struct worktree **);
-- 
2.11.0.157.gd943d85


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

* [PATCH 07/11] worktree.c: add update_worktree_location()
  2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
                   ` (5 preceding siblings ...)
  2017-02-02  8:50 ` [PATCH 06/11] worktree.c: add validate_worktree() Nguyễn Thái Ngọc Duy
@ 2017-02-02  8:50 ` Nguyễn Thái Ngọc Duy
  2017-02-02  8:50 ` [PATCH 08/11] worktree move: new command Nguyễn Thái Ngọc Duy
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2017-02-02  8:50 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 worktree.c | 21 +++++++++++++++++++++
 worktree.h |  6 ++++++
 2 files changed, 27 insertions(+)

diff --git a/worktree.c b/worktree.c
index 929072ad89..7684951da5 100644
--- a/worktree.c
+++ b/worktree.c
@@ -354,6 +354,27 @@ int validate_worktree(const struct worktree *wt, int quiet)
 	return 0;
 }
 
+int update_worktree_location(struct worktree *wt, const char *path_)
+{
+	struct strbuf path = STRBUF_INIT;
+	int ret = 0;
+
+	if (is_main_worktree(wt))
+		return 0;
+
+	strbuf_add_absolute_path(&path, path_);
+	if (fspathcmp(wt->path, path.buf)) {
+		write_file(git_common_path("worktrees/%s/gitdir",
+					   wt->id),
+			   "%s/.git", real_path(path.buf));
+		free(wt->path);
+		wt->path = strbuf_detach(&path, NULL);
+		ret = 0;
+	}
+	strbuf_release(&path);
+	return ret;
+}
+
 int is_worktree_being_rebased(const struct worktree *wt,
 			      const char *target)
 {
diff --git a/worktree.h b/worktree.h
index 4433db2eb3..1ee03f4d06 100644
--- a/worktree.h
+++ b/worktree.h
@@ -58,6 +58,12 @@ extern const char *is_worktree_locked(struct worktree *wt);
 extern int validate_worktree(const struct worktree *wt, int quiet);
 
 /*
+ * Update worktrees/xxx/gitdir with the new path.
+ */
+extern int update_worktree_location(struct worktree *wt,
+				    const char *path_);
+
+/*
  * Free up the memory for worktree(s)
  */
 extern void free_worktrees(struct worktree **);
-- 
2.11.0.157.gd943d85


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

* [PATCH 08/11] worktree move: new command
  2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
                   ` (6 preceding siblings ...)
  2017-02-02  8:50 ` [PATCH 07/11] worktree.c: add update_worktree_location() Nguyễn Thái Ngọc Duy
@ 2017-02-02  8:50 ` Nguyễn Thái Ngọc Duy
  2017-02-02  8:50 ` [PATCH 09/11] worktree move: accept destination as directory Nguyễn Thái Ngọc Duy
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2017-02-02  8:50 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

There are two options to move the main worktree, but both have
complications, so it's not implemented yet. Anyway the options are:

 - convert the main worktree to a linked one and move it away, leave the
   git repository where it is. The repo essentially becomes bare after
   this move.

 - move the repository with the main worktree. The tricky part is make
   sure all file descriptors to the repository are closed, or it may
   fail on Windows.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/git-worktree.txt         |  7 +++++-
 builtin/worktree.c                     | 43 ++++++++++++++++++++++++++++++++++
 contrib/completion/git-completion.bash |  2 +-
 t/t2028-worktree-move.sh               | 31 ++++++++++++++++++++++++
 4 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index e257c19ebe..13105138a7 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -12,6 +12,7 @@ SYNOPSIS
 'git worktree add' [-f] [--detach] [--checkout] [-b <new-branch>] <path> [<branch>]
 'git worktree list' [--porcelain]
 'git worktree lock' [--reason <string>] <worktree>
+'git worktree move' <worktree> <new-path>
 'git worktree prune' [-n] [-v] [--expire <expire>]
 'git worktree unlock' <worktree>
 
@@ -71,6 +72,11 @@ files from being pruned automatically. This also prevents it from
 being moved or deleted. Optionally, specify a reason for the lock
 with `--reason`.
 
+move::
+
+Move a working tree to a new location. Note that the main working tree
+cannot be moved yet.
+
 prune::
 
 Prune working tree information in $GIT_DIR/worktrees.
@@ -252,7 +258,6 @@ performed manually, such as:
 
 - `remove` to remove a linked working tree and its administrative files (and
   warn if the working tree is dirty)
-- `mv` to move or rename a working tree and update its administrative files
 
 GIT
 ---
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 9a97e37a3f..0d8b57ceb3 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -15,6 +15,7 @@ static const char * const worktree_usage[] = {
 	N_("git worktree add [<options>] <path> [<branch>]"),
 	N_("git worktree list [<options>]"),
 	N_("git worktree lock [<options>] <path>"),
+	N_("git worktree move <worktree> <new-path>"),
 	N_("git worktree prune [<options>]"),
 	N_("git worktree unlock <path>"),
 	NULL
@@ -524,6 +525,46 @@ static int unlock_worktree(int ac, const char **av, const char *prefix)
 	return ret;
 }
 
+static int move_worktree(int ac, const char **av, const char *prefix)
+{
+	struct option options[] = {
+		OPT_END()
+	};
+	struct worktree **worktrees, *wt;
+	struct strbuf dst = STRBUF_INIT;
+	const char *reason;
+
+	ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+	if (ac != 2)
+		usage_with_options(worktree_usage, options);
+
+	strbuf_addstr(&dst, prefix_filename(prefix,
+					    strlen(prefix),
+					    av[1]));
+	if (file_exists(dst.buf))
+		die(_("target '%s' already exists"), av[1]);
+
+	worktrees = get_worktrees(0);
+	wt = find_worktree(worktrees, prefix, av[0]);
+	if (!wt)
+		die(_("'%s' is not a working directory"), av[0]);
+	if (is_main_worktree(wt))
+		die(_("'%s' is a main working directory"), av[0]);
+	reason = is_worktree_locked(wt);
+	if (reason) {
+		if (*reason)
+			die(_("already locked, reason: %s"), reason);
+		die(_("already locked, no reason"));
+	}
+	if (validate_worktree(wt, 0))
+		return -1;
+
+	if (rename(wt->path, dst.buf) == -1)
+		die_errno(_("failed to move '%s' to '%s'"), wt->path, dst.buf);
+
+	return update_worktree_location(wt, dst.buf);
+}
+
 int cmd_worktree(int ac, const char **av, const char *prefix)
 {
 	struct option options[] = {
@@ -546,5 +587,7 @@ int cmd_worktree(int ac, const char **av, const char *prefix)
 		return lock_worktree(ac - 1, av + 1, prefix);
 	if (!strcmp(av[1], "unlock"))
 		return unlock_worktree(ac - 1, av + 1, prefix);
+	if (!strcmp(av[1], "move"))
+		return move_worktree(ac - 1, av + 1, prefix);
 	usage_with_options(worktree_usage, options);
 }
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 21016bf8df..613e03b879 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2715,7 +2715,7 @@ _git_whatchanged ()
 
 _git_worktree ()
 {
-	local subcommands="add list lock prune unlock"
+	local subcommands="add list lock move prune unlock"
 	local subcommand="$(__git_find_on_cmdline "$subcommands")"
 	if [ -z "$subcommand" ]; then
 		__gitcomp "$subcommands"
diff --git a/t/t2028-worktree-move.sh b/t/t2028-worktree-move.sh
index 8298aaf97f..bef420a086 100755
--- a/t/t2028-worktree-move.sh
+++ b/t/t2028-worktree-move.sh
@@ -59,4 +59,35 @@ test_expect_success 'unlock worktree twice' '
 	test_path_is_missing .git/worktrees/source/locked
 '
 
+test_expect_success 'move non-worktree' '
+	mkdir abc &&
+	test_must_fail git worktree move abc def
+'
+
+test_expect_success 'move locked worktree' '
+	git worktree lock source &&
+	test_must_fail git worktree move source destination &&
+	git worktree unlock source
+'
+
+test_expect_success 'move worktree' '
+	toplevel="$(pwd)" &&
+	git worktree move source destination &&
+	test_path_is_missing source &&
+	git worktree list --porcelain | grep "^worktree" >actual &&
+	cat <<-EOF >expected &&
+	worktree $toplevel
+	worktree $toplevel/destination
+	worktree $toplevel/elsewhere
+	EOF
+	test_cmp expected actual &&
+	git -C destination log --format=%s >actual2 &&
+	echo init >expected2 &&
+	test_cmp expected2 actual2
+'
+
+test_expect_success 'move main worktree' '
+	test_must_fail git worktree move . def
+'
+
 test_done
-- 
2.11.0.157.gd943d85


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

* [PATCH 09/11] worktree move: accept destination as directory
  2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
                   ` (7 preceding siblings ...)
  2017-02-02  8:50 ` [PATCH 08/11] worktree move: new command Nguyễn Thái Ngọc Duy
@ 2017-02-02  8:50 ` Nguyễn Thái Ngọc Duy
  2017-02-02  8:50 ` [PATCH 10/11] worktree move: refuse to move worktrees with submodules Nguyễn Thái Ngọc Duy
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2017-02-02  8:50 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

Similar to "mv a b/", which is actually "mv a b/a", we extract basename
of source worktree and create a directory of the same name at
destination if dst path is a directory.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/worktree.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index 0d8b57ceb3..900b68bb5d 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -541,7 +541,13 @@ static int move_worktree(int ac, const char **av, const char *prefix)
 	strbuf_addstr(&dst, prefix_filename(prefix,
 					    strlen(prefix),
 					    av[1]));
-	if (file_exists(dst.buf))
+	if (is_directory(dst.buf))
+		/*
+		 * keep going, dst will be appended after we get the
+		 * source's absolute path
+		 */
+		;
+	else if (file_exists(dst.buf))
 		die(_("target '%s' already exists"), av[1]);
 
 	worktrees = get_worktrees(0);
@@ -559,6 +565,17 @@ static int move_worktree(int ac, const char **av, const char *prefix)
 	if (validate_worktree(wt, 0))
 		return -1;
 
+	if (is_directory(dst.buf)) {
+		const char *sep = find_last_dir_sep(wt->path);
+
+		if (!sep)
+			die(_("could not figure out destination name from '%s'"),
+			    wt->path);
+		strbuf_addstr(&dst, sep);
+		if (file_exists(dst.buf))
+			die(_("target '%s' already exists"), dst.buf);
+	}
+
 	if (rename(wt->path, dst.buf) == -1)
 		die_errno(_("failed to move '%s' to '%s'"), wt->path, dst.buf);
 
-- 
2.11.0.157.gd943d85


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

* [PATCH 10/11] worktree move: refuse to move worktrees with submodules
  2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
                   ` (8 preceding siblings ...)
  2017-02-02  8:50 ` [PATCH 09/11] worktree move: accept destination as directory Nguyễn Thái Ngọc Duy
@ 2017-02-02  8:50 ` Nguyễn Thái Ngọc Duy
  2017-02-02  8:50 ` [PATCH 11/11] worktree remove: new command Nguyễn Thái Ngọc Duy
  2017-02-02  9:16 ` [PATCH 00/11] nd/worktree-move update Johannes Schindelin
  11 siblings, 0 replies; 25+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2017-02-02  8:50 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

Submodules contains .git files with relative paths. After a worktree
move, these files need to be updated or they may point to nowhere.

This is a bandage patch to make sure "worktree move" don't break
people's worktrees by accident. When .git file update code is in
place, this validate_no_submodules() could be removed.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/worktree.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index 900b68bb5d..6c58d620ce 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -525,6 +525,27 @@ static int unlock_worktree(int ac, const char **av, const char *prefix)
 	return ret;
 }
 
+static void validate_no_submodules(const struct worktree *wt)
+{
+	struct index_state istate = { NULL };
+	int i, found_submodules = 0;
+
+	if (read_index_from(&istate, worktree_git_path(wt, "index")) > 0) {
+		for (i = 0; i < istate.cache_nr; i++) {
+			struct cache_entry *ce = istate.cache[i];
+
+			if (S_ISGITLINK(ce->ce_mode)) {
+				found_submodules = 1;
+				break;
+			}
+		}
+	}
+	discard_index(&istate);
+
+	if (found_submodules)
+		die(_("This working tree contains submodules and cannot be moved yet"));
+}
+
 static int move_worktree(int ac, const char **av, const char *prefix)
 {
 	struct option options[] = {
@@ -565,6 +586,8 @@ static int move_worktree(int ac, const char **av, const char *prefix)
 	if (validate_worktree(wt, 0))
 		return -1;
 
+	validate_no_submodules(wt);
+
 	if (is_directory(dst.buf)) {
 		const char *sep = find_last_dir_sep(wt->path);
 
-- 
2.11.0.157.gd943d85


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

* [PATCH 11/11] worktree remove: new command
  2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
                   ` (9 preceding siblings ...)
  2017-02-02  8:50 ` [PATCH 10/11] worktree move: refuse to move worktrees with submodules Nguyễn Thái Ngọc Duy
@ 2017-02-02  8:50 ` Nguyễn Thái Ngọc Duy
  2017-02-02  9:16 ` [PATCH 00/11] nd/worktree-move update Johannes Schindelin
  11 siblings, 0 replies; 25+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2017-02-02  8:50 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git-worktree.txt         | 21 +++++----
 builtin/worktree.c                     | 79 ++++++++++++++++++++++++++++++++++
 contrib/completion/git-completion.bash |  5 ++-
 t/t2028-worktree-move.sh               | 26 +++++++++++
 4 files changed, 121 insertions(+), 10 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 13105138a7..bbde6b8110 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -14,6 +14,7 @@ SYNOPSIS
 'git worktree lock' [--reason <string>] <worktree>
 'git worktree move' <worktree> <new-path>
 'git worktree prune' [-n] [-v] [--expire <expire>]
+'git worktree remove' [--force] <worktree>
 'git worktree unlock' <worktree>
 
 DESCRIPTION
@@ -81,6 +82,13 @@ prune::
 
 Prune working tree information in $GIT_DIR/worktrees.
 
+remove::
+
+Remove a working tree. Only clean working trees (no untracked files
+and no modification in tracked files) can be removed. Unclean working
+trees can be removed with `--force`. The main working tree cannot be
+removed.
+
 unlock::
 
 Unlock a working tree, allowing it to be pruned, moved or deleted.
@@ -90,9 +98,10 @@ OPTIONS
 
 -f::
 --force::
-	By default, `add` refuses to create a new working tree when `<branch>`
-	is already checked out by another working tree. This option overrides
-	that safeguard.
+	By default, `add` refuses to create a new working tree when
+	`<branch>` is already checked out by another working tree and
+	`remove` refuses to remove an unclean working tree. This option
+	overrides that safeguard.
 
 -b <new-branch>::
 -B <new-branch>::
@@ -253,12 +262,6 @@ Multiple checkout in general is still experimental, and the 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, such as:
-
-- `remove` to remove a linked working tree and its administrative files (and
-  warn if the working tree is dirty)
-
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 6c58d620ce..a1c91f1542 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -17,6 +17,7 @@ static const char * const worktree_usage[] = {
 	N_("git worktree lock [<options>] <path>"),
 	N_("git worktree move <worktree> <new-path>"),
 	N_("git worktree prune [<options>]"),
+	N_("git worktree remove [<options>] <worktree>"),
 	N_("git worktree unlock <path>"),
 	NULL
 };
@@ -605,6 +606,82 @@ static int move_worktree(int ac, const char **av, const char *prefix)
 	return update_worktree_location(wt, dst.buf);
 }
 
+static int remove_worktree(int ac, const char **av, const char *prefix)
+{
+	int force = 0;
+	struct option options[] = {
+		OPT_BOOL(0, "force", &force,
+			 N_("force removing even if the worktree is dirty")),
+		OPT_END()
+	};
+	struct worktree **worktrees, *wt;
+	struct strbuf sb = STRBUF_INIT;
+	const char *reason;
+	int ret = 0;
+
+	ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+	if (ac != 1)
+		usage_with_options(worktree_usage, options);
+
+	worktrees = get_worktrees(0);
+	wt = find_worktree(worktrees, prefix, av[0]);
+	if (!wt)
+		die(_("'%s' is not a working directory"), av[0]);
+	if (is_main_worktree(wt))
+		die(_("'%s' is a main working directory"), av[0]);
+	reason = is_worktree_locked(wt);
+	if (reason) {
+		if (*reason)
+			die(_("already locked, reason: %s"), reason);
+		die(_("already locked, no reason"));
+	}
+	if (validate_worktree(wt, 0))
+		return -1;
+
+	if (!force) {
+		struct argv_array child_env = ARGV_ARRAY_INIT;
+		struct child_process cp;
+		char buf[1];
+
+		argv_array_pushf(&child_env, "%s=%s/.git",
+				 GIT_DIR_ENVIRONMENT, wt->path);
+		argv_array_pushf(&child_env, "%s=%s",
+				 GIT_WORK_TREE_ENVIRONMENT, wt->path);
+		memset(&cp, 0, sizeof(cp));
+		argv_array_pushl(&cp.args, "status", "--porcelain", NULL);
+		cp.env = child_env.argv;
+		cp.git_cmd = 1;
+		cp.dir = wt->path;
+		cp.out = -1;
+		ret = start_command(&cp);
+		if (ret)
+			die_errno(_("failed to run git-status on '%s', code %d"),
+				  av[0], ret);
+		ret = xread(cp.out, buf, sizeof(buf));
+		if (ret)
+			die(_("'%s' is dirty, use --force to delete it"), av[0]);
+		close(cp.out);
+		ret = finish_command(&cp);
+		if (ret)
+			die_errno(_("failed to run git-status on '%s', code %d"),
+				  av[0], ret);
+	}
+	strbuf_addstr(&sb, wt->path);
+	if (remove_dir_recursively(&sb, 0)) {
+		error_errno(_("failed to delete '%s'"), sb.buf);
+		ret = -1;
+	}
+	strbuf_reset(&sb);
+	strbuf_addstr(&sb, git_common_path("worktrees/%s", wt->id));
+	if (remove_dir_recursively(&sb, 0)) {
+		error_errno(_("failed to delete '%s'"), sb.buf);
+		ret = -1;
+	}
+	strbuf_release(&sb);
+	free_worktrees(worktrees);
+	return ret;
+}
+
 int cmd_worktree(int ac, const char **av, const char *prefix)
 {
 	struct option options[] = {
@@ -629,5 +706,7 @@ int cmd_worktree(int ac, const char **av, const char *prefix)
 		return unlock_worktree(ac - 1, av + 1, prefix);
 	if (!strcmp(av[1], "move"))
 		return move_worktree(ac - 1, av + 1, prefix);
+	if (!strcmp(av[1], "remove"))
+		return remove_worktree(ac - 1, av + 1, prefix);
 	usage_with_options(worktree_usage, options);
 }
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 613e03b879..f6855af1f6 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2715,7 +2715,7 @@ _git_whatchanged ()
 
 _git_worktree ()
 {
-	local subcommands="add list lock move prune unlock"
+	local subcommands="add list lock move prune remove unlock"
 	local subcommand="$(__git_find_on_cmdline "$subcommands")"
 	if [ -z "$subcommand" ]; then
 		__gitcomp "$subcommands"
@@ -2733,6 +2733,9 @@ _git_worktree ()
 		prune,--*)
 			__gitcomp "--dry-run --expire --verbose"
 			;;
+		remove,--*)
+			__gitcomp "--force"
+			;;
 		*)
 			;;
 		esac
diff --git a/t/t2028-worktree-move.sh b/t/t2028-worktree-move.sh
index bef420a086..b3105eaaed 100755
--- a/t/t2028-worktree-move.sh
+++ b/t/t2028-worktree-move.sh
@@ -90,4 +90,30 @@ test_expect_success 'move main worktree' '
 	test_must_fail git worktree move . def
 '
 
+test_expect_success 'remove main worktree' '
+	test_must_fail git worktree remove .
+'
+
+test_expect_success 'remove locked worktree' '
+	git worktree lock destination &&
+	test_must_fail git worktree remove destination &&
+	git worktree unlock destination
+'
+
+test_expect_success 'remove worktree with dirty tracked file' '
+	echo dirty >>destination/init.t &&
+	test_must_fail git worktree remove destination
+'
+
+test_expect_success 'remove worktree with untracked file' '
+	git -C destination checkout init.t &&
+	: >destination/untracked &&
+	test_must_fail git worktree remove destination
+'
+
+test_expect_success 'force remove worktree with untracked file' '
+	git worktree remove --force destination &&
+	test_path_is_missing destination
+'
+
 test_done
-- 
2.11.0.157.gd943d85


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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
                   ` (10 preceding siblings ...)
  2017-02-02  8:50 ` [PATCH 11/11] worktree remove: new command Nguyễn Thái Ngọc Duy
@ 2017-02-02  9:16 ` Johannes Schindelin
  2017-02-02  9:27   ` Duy Nguyen
  11 siblings, 1 reply; 25+ messages in thread
From: Johannes Schindelin @ 2017-02-02  9:16 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy; +Cc: git, Junio C Hamano

[-- Attachment #1: Type: text/plain, Size: 283 bytes --]

Hi Duy,

On Thu, 2 Feb 2017, Nguyễn Thái Ngọc Duy wrote:

> This squashes two changes from Johannes and Ramsay: [...]

Sorry, I lost track of the worktree discussions... Could you remind me
which patch is supposed to fix my continuous reflog corruption?

Thanks,
Dscho

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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-02  9:16 ` [PATCH 00/11] nd/worktree-move update Johannes Schindelin
@ 2017-02-02  9:27   ` Duy Nguyen
  2017-02-02  9:43     ` Johannes Schindelin
  0 siblings, 1 reply; 25+ messages in thread
From: Duy Nguyen @ 2017-02-02  9:27 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Git Mailing List, Junio C Hamano

On Thu, Feb 2, 2017 at 4:16 PM, Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
> Hi Duy,
>
> On Thu, 2 Feb 2017, Nguyễn Thái Ngọc Duy wrote:
>
>> This squashes two changes from Johannes and Ramsay: [...]
>
> Sorry, I lost track of the worktree discussions... Could you remind me
> which patch is supposed to fix my continuous reflog corruption?

The corruption caused by git-gc? It's not fixed. All the changes in
this series is shown here.
-- 
Duy

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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-02  9:27   ` Duy Nguyen
@ 2017-02-02  9:43     ` Johannes Schindelin
  2017-02-02  9:50       ` Duy Nguyen
  0 siblings, 1 reply; 25+ messages in thread
From: Johannes Schindelin @ 2017-02-02  9:43 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Git Mailing List, Junio C Hamano

[-- Attachment #1: Type: text/plain, Size: 701 bytes --]

Hi Duy,

On Thu, 2 Feb 2017, Duy Nguyen wrote:

> On Thu, Feb 2, 2017 at 4:16 PM, Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
> > Hi Duy,
> >
> > On Thu, 2 Feb 2017, Nguyễn Thái Ngọc Duy wrote:
> >
> >> This squashes two changes from Johannes and Ramsay: [...]
> >
> > Sorry, I lost track of the worktree discussions... Could you remind me
> > which patch is supposed to fix my continuous reflog corruption?
> 
> The corruption caused by git-gc? It's not fixed. All the changes in
> this series is shown here.

Oh sorry, I meant to ask "and if it is not in this patch series, would you
mind pointing me at the patch series that has that fix?"

Thanks,
Johannes

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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-02  9:43     ` Johannes Schindelin
@ 2017-02-02  9:50       ` Duy Nguyen
  2017-02-02 10:37         ` Johannes Schindelin
  0 siblings, 1 reply; 25+ messages in thread
From: Duy Nguyen @ 2017-02-02  9:50 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Git Mailing List, Junio C Hamano

On Thu, Feb 2, 2017 at 4:43 PM, Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
> Hi Duy,
>
> On Thu, 2 Feb 2017, Duy Nguyen wrote:
>
>> On Thu, Feb 2, 2017 at 4:16 PM, Johannes Schindelin
>> <Johannes.Schindelin@gmx.de> wrote:
>> > Hi Duy,
>> >
>> > On Thu, 2 Feb 2017, Nguyễn Thái Ngọc Duy wrote:
>> >
>> >> This squashes two changes from Johannes and Ramsay: [...]
>> >
>> > Sorry, I lost track of the worktree discussions... Could you remind me
>> > which patch is supposed to fix my continuous reflog corruption?
>>
>> The corruption caused by git-gc? It's not fixed. All the changes in
>> this series is shown here.
>
> Oh sorry, I meant to ask "and if it is not in this patch series, would you
> mind pointing me at the patch series that has that fix?"

You meant this one [1]? There is nothing substantial since then.

[1] https://public-inbox.org/git/%3C20160601104519.16563-1-pclouds@gmail.com%3E/

-- 
Duy

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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-02  9:50       ` Duy Nguyen
@ 2017-02-02 10:37         ` Johannes Schindelin
  2017-02-02 11:22           ` Duy Nguyen
  0 siblings, 1 reply; 25+ messages in thread
From: Johannes Schindelin @ 2017-02-02 10:37 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Git Mailing List, Junio C Hamano

[-- Attachment #1: Type: text/plain, Size: 1221 bytes --]

Hi Duy,

On Thu, 2 Feb 2017, Duy Nguyen wrote:

> On Thu, Feb 2, 2017 at 4:43 PM, Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
> >
> > On Thu, 2 Feb 2017, Duy Nguyen wrote:
> >
> >> On Thu, Feb 2, 2017 at 4:16 PM, Johannes Schindelin
> >> <Johannes.Schindelin@gmx.de> wrote:
> >> >
> >> > On Thu, 2 Feb 2017, Nguyễn Thái Ngọc Duy wrote:
> >> >
> >> >> This squashes two changes from Johannes and Ramsay: [...]
> >> >
> >> > Sorry, I lost track of the worktree discussions... Could you remind
> >> > me which patch is supposed to fix my continuous reflog corruption?
> >>
> >> The corruption caused by git-gc? It's not fixed. All the changes in
> >> this series is shown here.
> >
> > Oh sorry, I meant to ask "and if it is not in this patch series, would you
> > mind pointing me at the patch series that has that fix?"
> 
> You meant this one [1]? There is nothing substantial since then.
> 
> [1] https://public-inbox.org/git/%3C20160601104519.16563-1-pclouds@gmail.com%3E/

I guess I mean that.

Given that this results in real data loss, it is surprising that this has
not made it even into `pu` yet!

Would you mind rebasing and re-submitting?

Thanks,
Johannes

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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-02 10:37         ` Johannes Schindelin
@ 2017-02-02 11:22           ` Duy Nguyen
  2017-02-02 11:31             ` Johannes Schindelin
  0 siblings, 1 reply; 25+ messages in thread
From: Duy Nguyen @ 2017-02-02 11:22 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Git Mailing List, Junio C Hamano

On Thu, Feb 2, 2017 at 5:37 PM, Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
> Hi Duy,
>
> On Thu, 2 Feb 2017, Duy Nguyen wrote:
>
>> On Thu, Feb 2, 2017 at 4:43 PM, Johannes Schindelin
>> <Johannes.Schindelin@gmx.de> wrote:
>> >
>> > On Thu, 2 Feb 2017, Duy Nguyen wrote:
>> >
>> >> On Thu, Feb 2, 2017 at 4:16 PM, Johannes Schindelin
>> >> <Johannes.Schindelin@gmx.de> wrote:
>> >> >
>> >> > On Thu, 2 Feb 2017, Nguyễn Thái Ngọc Duy wrote:
>> >> >
>> >> >> This squashes two changes from Johannes and Ramsay: [...]
>> >> >
>> >> > Sorry, I lost track of the worktree discussions... Could you remind
>> >> > me which patch is supposed to fix my continuous reflog corruption?
>> >>
>> >> The corruption caused by git-gc? It's not fixed. All the changes in
>> >> this series is shown here.
>> >
>> > Oh sorry, I meant to ask "and if it is not in this patch series, would you
>> > mind pointing me at the patch series that has that fix?"
>>
>> You meant this one [1]? There is nothing substantial since then.
>>
>> [1] https://public-inbox.org/git/%3C20160601104519.16563-1-pclouds@gmail.com%3E/
>
> I guess I mean that.
>
> Given that this results in real data loss, it is surprising that this has
> not made it even into `pu` yet!

I  could rebase and clean it up a bit if you need it, but I don't
think it'll end up in 'pu' or anywhere near since Junio wanted a
cleaner approach [1]. That means (as far as I can see) a lot more work
around refs store and backend area before it's ready to handle "get
refs from this worktree store" (or "get refs from every reachable
stores").

[1] https://public-inbox.org/git/xmqqshwwzyee.fsf@gitster.mtv.corp.google.com/

-- 
Duy

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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-02 11:22           ` Duy Nguyen
@ 2017-02-02 11:31             ` Johannes Schindelin
  2017-02-02 12:33               ` Johannes Schindelin
  0 siblings, 1 reply; 25+ messages in thread
From: Johannes Schindelin @ 2017-02-02 11:31 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Git Mailing List, Junio C Hamano

[-- Attachment #1: Type: text/plain, Size: 2071 bytes --]

Hi Duy,

On Thu, 2 Feb 2017, Duy Nguyen wrote:

> On Thu, Feb 2, 2017 at 5:37 PM, Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
> >
> > On Thu, 2 Feb 2017, Duy Nguyen wrote:
> >
> >> On Thu, Feb 2, 2017 at 4:43 PM, Johannes Schindelin
> >> <Johannes.Schindelin@gmx.de> wrote:
> >> >
> >> > On Thu, 2 Feb 2017, Duy Nguyen wrote:
> >> >
> >> >> On Thu, Feb 2, 2017 at 4:16 PM, Johannes Schindelin
> >> >> <Johannes.Schindelin@gmx.de> wrote:
> >> >> >
> >> >> > On Thu, 2 Feb 2017, Nguyễn Thái Ngọc Duy wrote:
> >> >> >
> >> >> >> This squashes two changes from Johannes and Ramsay: [...]
> >> >> >
> >> >> > Sorry, I lost track of the worktree discussions... Could you
> >> >> > remind me which patch is supposed to fix my continuous reflog
> >> >> > corruption?
> >> >>
> >> >> The corruption caused by git-gc? It's not fixed. All the changes
> >> >> in this series is shown here.
> >> >
> >> > Oh sorry, I meant to ask "and if it is not in this patch series,
> >> > would you mind pointing me at the patch series that has that fix?"
> >>
> >> You meant this one [1]? There is nothing substantial since then.
> >>
> >> [1] https://public-inbox.org/git/%3C20160601104519.16563-1-pclouds@gmail.com%3E/
> >
> > I guess I mean that.
> >
> > Given that this results in real data loss, it is surprising that this
> > has not made it even into `pu` yet!
> 
> I  could rebase and clean it up a bit if you need it, but I don't think
> it'll end up in 'pu' or anywhere near since Junio wanted a cleaner
> approach [1]. That means (as far as I can see) a lot more work around
> refs store and backend area before it's ready to handle "get refs from
> this worktree store" (or "get refs from every reachable stores").
> 
> [1] https://public-inbox.org/git/xmqqshwwzyee.fsf@gitster.mtv.corp.google.com/

That is a big, big bummer.

We are talking about a data corrupting bug here, yes? It should be
possible to do that redesign work while having a small workaround in place
that unbreaks, say, me?

Ciao,
Johannes

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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-02 11:31             ` Johannes Schindelin
@ 2017-02-02 12:33               ` Johannes Schindelin
  2017-02-02 20:21                 ` Junio C Hamano
  0 siblings, 1 reply; 25+ messages in thread
From: Johannes Schindelin @ 2017-02-02 12:33 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Git Mailing List, Junio C Hamano

Hi Duy,

On Thu, 2 Feb 2017, Johannes Schindelin wrote:

> Hi Duy,
> 
> On Thu, 2 Feb 2017, Duy Nguyen wrote:
> 
> > On Thu, Feb 2, 2017 at 5:37 PM, Johannes Schindelin
> > <Johannes.Schindelin@gmx.de> wrote:
> > >
> > > On Thu, 2 Feb 2017, Duy Nguyen wrote:
> > >
> > >> You meant this one [1]? There is nothing substantial since then.
> > >>
> > >> [1] https://public-inbox.org/git/%3C20160601104519.16563-1-pclouds@gmail.com%3E/
> > 
> > I  could rebase and clean it up a bit if you need it, but I don't
> > think it'll end up in 'pu' or anywhere near since Junio wanted a
> > cleaner approach [1]. That means (as far as I can see) a lot more work
> > around refs store and backend area before it's ready to handle "get
> > refs from this worktree store" (or "get refs from every reachable
> > stores").
> > 
> > [1] https://public-inbox.org/git/xmqqshwwzyee.fsf@gitster.mtv.corp.google.com/

Given that
https://public-inbox.org/git/xmqqy46ntrhk.fsf@gitster.mtv.corp.google.com/
seems to have expected something to happen within a reasonable time frame,
and that 8 months is substantially longer than a reasonable time frame, I
am not sure that that position can still be defended.

Also, the more important reply was Peff's reply that suggested that the
proposed fix was incomplete, as it misses --unpack-unreachable:
https://public-inbox.org/git/20160601160143.GA9219@sigill.intra.peff.net/

Ciao,
Johannes

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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-02 12:33               ` Johannes Schindelin
@ 2017-02-02 20:21                 ` Junio C Hamano
  2017-02-03  8:59                   ` Duy Nguyen
  0 siblings, 1 reply; 25+ messages in thread
From: Junio C Hamano @ 2017-02-02 20:21 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Duy Nguyen, Git Mailing List

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Also, the more important reply was Peff's reply that suggested that the
> proposed fix was incomplete, as it misses --unpack-unreachable:
> https://public-inbox.org/git/20160601160143.GA9219@sigill.intra.peff.net/

While I think that --unpack-unreachable thing is a symptom of the
basic approach of patching things up at the wrong level, if you are
hinting that fix to the issue that gc does not pay attention to
various anchoring point in other worktrees is more important than
adding new commands to "worktree", I fully agree with that.  

We have a basic structure of "worktree" working well enough to allow
adventurous folks to experiment (there is a reason why we keep
calling it experimental).  mv and other additions are primarily to
make things _easier_ to use, but we shouldn't be encouraging its use
to general public by making it easier for them to hurt themselves,
if we know there still are sharp edges.

Thanks for bringing it up.

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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-02 20:21                 ` Junio C Hamano
@ 2017-02-03  8:59                   ` Duy Nguyen
  2017-02-03 18:25                     ` Junio C Hamano
  0 siblings, 1 reply; 25+ messages in thread
From: Duy Nguyen @ 2017-02-03  8:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, Git Mailing List

On Fri, Feb 3, 2017 at 3:21 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
>> Also, the more important reply was Peff's reply that suggested that the
>> proposed fix was incomplete, as it misses --unpack-unreachable:
>> https://public-inbox.org/git/20160601160143.GA9219@sigill.intra.peff.net/
>
> While I think that --unpack-unreachable thing is a symptom of the
> basic approach of patching things up at the wrong level, if you are
> hinting that fix to the issue that gc does not pay attention to
> various anchoring point in other worktrees is more important than
> adding new commands to "worktree", I fully agree with that.

Just to make it clear. It's not like I put new worktree commands on
higher priority. "worktree move/remove" was more or less ready for a
long time and the gc problem was blocked by ref-iterator series (which
entered master a few moths ago, but then I was busy with other things
and couldn't get right back to the gc issue).

You didn't answer Johannes's rhetoric question though: "It should be
possible to do that redesign work while having a small workaround in
place that unbreaks, say, me?"

I assume "the right way" is still updating refs subsystem so that we
can have a ref iterator to traverse all refs, or just one worktree,
etc. Should I keep looking for a middle ground (maybe better than the
linked series) to "unbreak Johannes"? I ignored all those comments
(about --unpack-reachable and bisect refs) because I saw no chance of
an updated series getting in git.git anyway.
-- 
Duy

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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-03  8:59                   ` Duy Nguyen
@ 2017-02-03 18:25                     ` Junio C Hamano
  2017-02-03 18:56                       ` Junio C Hamano
  2017-02-04 11:57                       ` Duy Nguyen
  0 siblings, 2 replies; 25+ messages in thread
From: Junio C Hamano @ 2017-02-03 18:25 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Johannes Schindelin, Git Mailing List

Duy Nguyen <pclouds@gmail.com> writes:

> On Fri, Feb 3, 2017 at 3:21 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>>
>>> Also, the more important reply was Peff's reply that suggested that the
>>> proposed fix was incomplete, as it misses --unpack-unreachable:
>>> https://public-inbox.org/git/20160601160143.GA9219@sigill.intra.peff.net/
>>
>> While I think that --unpack-unreachable thing is a symptom of the
>> basic approach of patching things up at the wrong level, if you are
>> hinting that fix to the issue that gc does not pay attention to
>> various anchoring point in other worktrees is more important than
>> adding new commands to "worktree", I fully agree with that.
>
> Just to make it clear. It's not like I put new worktree commands on
> higher priority.

Good; we are on the same page.

> "worktree move/remove" was more or less ready for a
> long time and the gc problem was blocked by ref-iterator series (which
> entered master a few moths ago, but then I was busy with other things
> and couldn't get right back to the gc issue).

OK.

> You didn't answer Johannes's rhetoric question though: "It should be
> possible to do that redesign work while having a small workaround in
> place that unbreaks, say, me?"

I do not recall seeing that.  I however deliberately ignored another
statement because I thought it enough to answer, which was:

    Given that
    https://public-inbox.org/git/xmqqy46ntrhk.fsf@gitster.mtv.corp.google.com/
    seems to have expected something to happen within a reasonable time frame,
    and that 8 months is substantially longer than a reasonable time frame, I
    am not sure that that position can still be defended.

In the message xmqqy46ntrhk is a response to, Michael enumerated the
issues need to be solved with priorities, and listed reachability
from the index and per-worktree detached HEAD are more important
than others.  I was hoping that even these "relatively more
important" ones would turn out be of less importance compared to
fixing all on the right foundation as long as it won't take forever,
but I do agree with Dscho that 8 months is way too long.

> I assume "the right way" is still updating refs subsystem so that we
> can have a ref iterator to traverse all refs, or just one worktree,
> etc. Should I keep looking for a middle ground (maybe better than the
> linked series) to "unbreak Johannes"? I ignored all those comments
> (about --unpack-reachable and bisect refs) because I saw no chance of
> an updated series getting in git.git anyway.

So, you may have seen no chance 8 months ago; after we have been
waiting for a better fix, which hadn't materialized for a while, I
am very much open to change the priority.

Even if you think "the right way" is to add to the iterators, I
suspect that we can still do incremental fixes?  I agree with the
order of importance Michael listed in his message (i.e. the index
and the HEAD first, and then other per-worktree hierarchies at lower
priority), and I suspect you do, too.  I am not sure that is what
you called "middle ground", but I think such an incremental approach
is totally fine.


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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-03 18:25                     ` Junio C Hamano
@ 2017-02-03 18:56                       ` Junio C Hamano
  2017-02-04 11:57                       ` Duy Nguyen
  1 sibling, 0 replies; 25+ messages in thread
From: Junio C Hamano @ 2017-02-03 18:56 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Johannes Schindelin, Git Mailing List

Junio C Hamano <gitster@pobox.com> writes:

> I do not recall seeing that.  I however deliberately ignored another
> statement because I thought it enough to answer, which was:

Oops.  "because I didn't think I thought it enough to answer" was
what I meant.

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

* Re: [PATCH 00/11] nd/worktree-move update
  2017-02-03 18:25                     ` Junio C Hamano
  2017-02-03 18:56                       ` Junio C Hamano
@ 2017-02-04 11:57                       ` Duy Nguyen
  1 sibling, 0 replies; 25+ messages in thread
From: Duy Nguyen @ 2017-02-04 11:57 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, Git Mailing List

On Sat, Feb 4, 2017 at 1:25 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Even if you think "the right way" is to add to the iterators, I
> suspect that we can still do incremental fixes?  I agree with the
> order of importance Michael listed in his message (i.e. the index
> and the HEAD first, and then other per-worktree hierarchies at lower
> priority), and I suspect you do, too.  I am not sure that is what
> you called "middle ground", but I think such an incremental approach
> is totally fine.

Yeah index should be fixed independently. Sorry that thought did not
occur to me. I counted HEAD as a ref too (i.e. to be managed/iterated
by refs subsystem) but I guess it's special enough to be dealt with
without ref iterator. I will try to fix these two first.

By middle ground, I was thinking that, now that we have ref iterator
interface, we more or less know what the api should look like for a
ref user like rev-list, so perhaps we could add a custom (ugly)
iterator for per-worktree refs (including reflog). The ugliness is
probably buried in refs/files-backend.c again until we clean it up.
-- 
Duy

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

end of thread, other threads:[~2017-02-04 11:57 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
2017-02-02  8:49 ` [PATCH 01/11] worktree.c: zero new 'struct worktree' on allocation Nguyễn Thái Ngọc Duy
2017-02-02  8:49 ` [PATCH 02/11] worktree: reorder an if statement Nguyễn Thái Ngọc Duy
2017-02-02  8:49 ` [PATCH 03/11] get_worktrees() must return main worktree as first item even on error Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 04/11] worktree.c: get_worktrees() takes a new flag argument Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 05/11] worktree list: keep the list sorted Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 06/11] worktree.c: add validate_worktree() Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 07/11] worktree.c: add update_worktree_location() Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 08/11] worktree move: new command Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 09/11] worktree move: accept destination as directory Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 10/11] worktree move: refuse to move worktrees with submodules Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 11/11] worktree remove: new command Nguyễn Thái Ngọc Duy
2017-02-02  9:16 ` [PATCH 00/11] nd/worktree-move update Johannes Schindelin
2017-02-02  9:27   ` Duy Nguyen
2017-02-02  9:43     ` Johannes Schindelin
2017-02-02  9:50       ` Duy Nguyen
2017-02-02 10:37         ` Johannes Schindelin
2017-02-02 11:22           ` Duy Nguyen
2017-02-02 11:31             ` Johannes Schindelin
2017-02-02 12:33               ` Johannes Schindelin
2017-02-02 20:21                 ` Junio C Hamano
2017-02-03  8:59                   ` Duy Nguyen
2017-02-03 18:25                     ` Junio C Hamano
2017-02-03 18:56                       ` Junio C Hamano
2017-02-04 11:57                       ` Duy Nguyen

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).