summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2018-02-12 09:49:37 (GMT)
committerJunio C Hamano <gitster@pobox.com>2018-02-12 21:13:35 (GMT)
commitc64a8d200f4109df86c6d4716ea4da58df450e34 (patch)
treeeaf8198f7aa5a888178e7a807dcc482c988b30fe
parent9f792bb4721066ce27ee98c4ad38d6d146b64fcf (diff)
downloadgit-c64a8d200f4109df86c6d4716ea4da58df450e34.zip
git-c64a8d200f4109df86c6d4716ea4da58df450e34.tar.gz
git-c64a8d200f4109df86c6d4716ea4da58df450e34.tar.bz2
worktree move: accept destination as directory
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>
-rw-r--r--builtin/worktree.c11
-rw-r--r--strbuf.c8
-rw-r--r--strbuf.h3
-rwxr-xr-xt/t2028-worktree-move.sh11
4 files changed, 32 insertions, 1 deletions
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 8b9482d..6fe4131 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -631,8 +631,17 @@ static int move_worktree(int ac, const char **av, const char *prefix)
die(_("'%s' is not a working tree"), av[0]);
if (is_main_worktree(wt))
die(_("'%s' is a main working tree"), av[0]);
+ 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_trim_trailing_dir_sep(&dst);
+ strbuf_addstr(&dst, sep);
+ }
if (file_exists(dst.buf))
- die(_("target '%s' already exists"), av[1]);
+ die(_("target '%s' already exists"), dst.buf);
reason = is_worktree_locked(wt);
if (reason) {
diff --git a/strbuf.c b/strbuf.c
index 1df674e..46930ad 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -95,6 +95,7 @@ void strbuf_trim(struct strbuf *sb)
strbuf_rtrim(sb);
strbuf_ltrim(sb);
}
+
void strbuf_rtrim(struct strbuf *sb)
{
while (sb->len > 0 && isspace((unsigned char)sb->buf[sb->len - 1]))
@@ -102,6 +103,13 @@ void strbuf_rtrim(struct strbuf *sb)
sb->buf[sb->len] = '\0';
}
+void strbuf_trim_trailing_dir_sep(struct strbuf *sb)
+{
+ while (sb->len > 0 && is_dir_sep((unsigned char)sb->buf[sb->len - 1]))
+ sb->len--;
+ sb->buf[sb->len] = '\0';
+}
+
void strbuf_ltrim(struct strbuf *sb)
{
char *b = sb->buf;
diff --git a/strbuf.h b/strbuf.h
index 14c8c10..e6cae5f 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -179,6 +179,9 @@ extern void strbuf_trim(struct strbuf *);
extern void strbuf_rtrim(struct strbuf *);
extern void strbuf_ltrim(struct strbuf *);
+/* Strip trailing directory separators */
+extern void strbuf_trim_trailing_dir_sep(struct strbuf *);
+
/**
* Replace the contents of the strbuf with a reencoded form. Returns -1
* on error, 0 on success.
diff --git a/t/t2028-worktree-move.sh b/t/t2028-worktree-move.sh
index 0f8abc0..deb486c 100755
--- a/t/t2028-worktree-move.sh
+++ b/t/t2028-worktree-move.sh
@@ -85,4 +85,15 @@ test_expect_success 'move main worktree' '
test_must_fail git worktree move . def
'
+test_expect_success 'move worktree to another dir' '
+ toplevel="$(pwd)" &&
+ mkdir some-dir &&
+ git worktree move destination some-dir &&
+ test_path_is_missing source &&
+ git worktree list --porcelain | grep "^worktree.*/some-dir/destination" &&
+ git -C some-dir/destination log --format=%s >actual2 &&
+ echo init >expected2 &&
+ test_cmp expected2 actual2
+'
+
test_done