2015-10-08 19:01:05 +02:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='test git worktree list'
|
|
|
|
|
2020-11-19 00:44:22 +01:00
|
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
tests: mark tests relying on the current default for `init.defaultBranch`
In addition to the manual adjustment to let the `linux-gcc` CI job run
the test suite with `master` and then with `main`, this patch makes sure
that GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME is set in all test scripts
that currently rely on the initial branch name being `master by default.
To determine which test scripts to mark up, the first step was to
force-set the default branch name to `master` in
- all test scripts that contain the keyword `master`,
- t4211, which expects `t/t4211/history.export` with a hard-coded ref to
initialize the default branch,
- t5560 because it sources `t/t556x_common` which uses `master`,
- t8002 and t8012 because both source `t/annotate-tests.sh` which also
uses `master`)
This trick was performed by this command:
$ sed -i '/^ *\. \.\/\(test-lib\|lib-\(bash\|cvs\|git-svn\)\|gitweb-lib\)\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' $(git grep -l master t/t[0-9]*.sh) \
t/t4211*.sh t/t5560*.sh t/t8002*.sh t/t8012*.sh
After that, careful, manual inspection revealed that some of the test
scripts containing the needle `master` do not actually rely on a
specific default branch name: either they mention `master` only in a
comment, or they initialize that branch specificially, or they do not
actually refer to the current default branch. Therefore, the
aforementioned modification was undone in those test scripts thusly:
$ git checkout HEAD -- \
t/t0027-auto-crlf.sh t/t0060-path-utils.sh \
t/t1011-read-tree-sparse-checkout.sh \
t/t1305-config-include.sh t/t1309-early-config.sh \
t/t1402-check-ref-format.sh t/t1450-fsck.sh \
t/t2024-checkout-dwim.sh \
t/t2106-update-index-assume-unchanged.sh \
t/t3040-subprojects-basic.sh t/t3301-notes.sh \
t/t3308-notes-merge.sh t/t3423-rebase-reword.sh \
t/t3436-rebase-more-options.sh \
t/t4015-diff-whitespace.sh t/t4257-am-interactive.sh \
t/t5323-pack-redundant.sh t/t5401-update-hooks.sh \
t/t5511-refspec.sh t/t5526-fetch-submodules.sh \
t/t5529-push-errors.sh t/t5530-upload-pack-error.sh \
t/t5548-push-porcelain.sh \
t/t5552-skipping-fetch-negotiator.sh \
t/t5572-pull-submodule.sh t/t5608-clone-2gb.sh \
t/t5614-clone-submodules-shallow.sh \
t/t7508-status.sh t/t7606-merge-custom.sh \
t/t9302-fast-import-unpack-limit.sh
We excluded one set of test scripts in these commands, though: the range
of `git p4` tests. The reason? `git p4` stores the (foreign) remote
branch in the branch called `p4/master`, which is obviously not the
default branch. Manual analysis revealed that only five of these tests
actually require a specific default branch name to pass; They were
modified thusly:
$ sed -i '/^ *\. \.\/lib-git-p4\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' t/t980[0167]*.sh t/t9811*.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-19 00:44:19 +01:00
|
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
|
2023-02-07 00:07:54 +01:00
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
2015-10-08 19:01:05 +02:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
test_expect_success 'setup' '
|
|
|
|
test_commit init
|
|
|
|
'
|
|
|
|
|
rev-parse: fix several options when running in a subdirectory
In addition to making git_path() aware of certain file names that need
to be handled differently e.g. when running in worktrees, the commit
557bd833bb (git_path(): be aware of file relocation in $GIT_DIR,
2014-11-30) also snuck in a new option for `git rev-parse`:
`--git-path`.
On the face of it, there is no obvious bug in that commit's diff: it
faithfully calls git_path() on the argument and prints it out, i.e. `git
rev-parse --git-path <filename>` has the same precise behavior as
calling `git_path("<filename>")` in C.
The problem lies deeper, much deeper. In hindsight (which is always
unfair), implementing the .git/ directory discovery in
`setup_git_directory()` by changing the working directory may have
allowed us to avoid passing around a struct that contains information
about the current repository, but it bought us many, many problems.
In this case, when being called in a subdirectory, `git rev-parse`
changes the working directory to the top-level directory before calling
`git_path()`. In the new working directory, the result is correct. But
in the working directory of the calling script, it is incorrect.
Example: when calling `git rev-parse --git-path HEAD` in, say, the
Documentation/ subdirectory of Git's own source code, the string
`.git/HEAD` is printed.
Side note: that bug is hidden when running in a subdirectory of a
worktree that was added by the `git worktree` command: in that case, the
(correct) absolute path of the `HEAD` file is printed.
In the interest of time, this patch does not go the "correct" route to
introduce a struct with repository information (and removing global
state in the process), instead this patch chooses to detect when the
command was called in a subdirectory and forces the result to be an
absolute path.
While at it, we are also fixing the output of --git-common-dir and
--shared-index-path.
Lastly, please note that we reuse the same strbuf for all of the
relative_path() calls; this avoids frequent allocation (and duplicated
code), and it does not risk memory leaks, for two reasons: 1) the
cmd_rev_parse() function does not return anywhere between the use of
the new strbuf instance and its final release, and 2) git-rev-parse is
one of these "one-shot" programs in Git, i.e. it exits after running
for a very short time, meaning that all allocated memory is released
with the exit() call anyway.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-17 17:59:06 +01:00
|
|
|
test_expect_success 'rev-parse --git-common-dir on main worktree' '
|
2016-02-12 05:31:45 +01:00
|
|
|
git rev-parse --git-common-dir >actual &&
|
|
|
|
echo .git >expected &&
|
|
|
|
test_cmp expected actual &&
|
|
|
|
mkdir sub &&
|
|
|
|
git -C sub rev-parse --git-common-dir >actual2 &&
|
2017-02-17 17:59:02 +01:00
|
|
|
echo ../.git >expected2 &&
|
2016-02-12 05:31:45 +01:00
|
|
|
test_cmp expected2 actual2
|
|
|
|
'
|
|
|
|
|
rev-parse: fix several options when running in a subdirectory
In addition to making git_path() aware of certain file names that need
to be handled differently e.g. when running in worktrees, the commit
557bd833bb (git_path(): be aware of file relocation in $GIT_DIR,
2014-11-30) also snuck in a new option for `git rev-parse`:
`--git-path`.
On the face of it, there is no obvious bug in that commit's diff: it
faithfully calls git_path() on the argument and prints it out, i.e. `git
rev-parse --git-path <filename>` has the same precise behavior as
calling `git_path("<filename>")` in C.
The problem lies deeper, much deeper. In hindsight (which is always
unfair), implementing the .git/ directory discovery in
`setup_git_directory()` by changing the working directory may have
allowed us to avoid passing around a struct that contains information
about the current repository, but it bought us many, many problems.
In this case, when being called in a subdirectory, `git rev-parse`
changes the working directory to the top-level directory before calling
`git_path()`. In the new working directory, the result is correct. But
in the working directory of the calling script, it is incorrect.
Example: when calling `git rev-parse --git-path HEAD` in, say, the
Documentation/ subdirectory of Git's own source code, the string
`.git/HEAD` is printed.
Side note: that bug is hidden when running in a subdirectory of a
worktree that was added by the `git worktree` command: in that case, the
(correct) absolute path of the `HEAD` file is printed.
In the interest of time, this patch does not go the "correct" route to
introduce a struct with repository information (and removing global
state in the process), instead this patch chooses to detect when the
command was called in a subdirectory and forces the result to be an
absolute path.
While at it, we are also fixing the output of --git-common-dir and
--shared-index-path.
Lastly, please note that we reuse the same strbuf for all of the
relative_path() calls; this avoids frequent allocation (and duplicated
code), and it does not risk memory leaks, for two reasons: 1) the
cmd_rev_parse() function does not return anywhere between the use of
the new strbuf instance and its final release, and 2) git-rev-parse is
one of these "one-shot" programs in Git, i.e. it exits after running
for a very short time, meaning that all allocated memory is released
with the exit() call anyway.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-17 17:59:06 +01:00
|
|
|
test_expect_success 'rev-parse --git-path objects linked worktree' '
|
2017-02-17 17:59:02 +01:00
|
|
|
echo "$(git rev-parse --show-toplevel)/.git/objects" >expect &&
|
2017-04-03 23:35:57 +02:00
|
|
|
test_when_finished "rm -rf linked-tree actual expect && git worktree prune" &&
|
2020-11-19 00:44:22 +01:00
|
|
|
git worktree add --detach linked-tree main &&
|
2017-02-17 17:59:02 +01:00
|
|
|
git -C linked-tree rev-parse --git-path objects >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2015-10-08 19:01:05 +02:00
|
|
|
test_expect_success '"list" all worktrees from main' '
|
|
|
|
echo "$(git rev-parse --show-toplevel) $(git rev-parse --short HEAD) [$(git symbolic-ref --short HEAD)]" >expect &&
|
2017-04-03 23:35:57 +02:00
|
|
|
test_when_finished "rm -rf here out actual expect && git worktree prune" &&
|
2020-11-19 00:44:22 +01:00
|
|
|
git worktree add --detach here main &&
|
2015-10-08 19:01:05 +02:00
|
|
|
echo "$(git -C here rev-parse --show-toplevel) $(git rev-parse --short HEAD) (detached HEAD)" >>expect &&
|
2017-04-03 23:35:57 +02:00
|
|
|
git worktree list >out &&
|
|
|
|
sed "s/ */ /g" <out >actual &&
|
2015-10-08 19:01:05 +02:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"list" all worktrees from linked' '
|
|
|
|
echo "$(git rev-parse --show-toplevel) $(git rev-parse --short HEAD) [$(git symbolic-ref --short HEAD)]" >expect &&
|
2017-04-03 23:35:57 +02:00
|
|
|
test_when_finished "rm -rf here out actual expect && git worktree prune" &&
|
2020-11-19 00:44:22 +01:00
|
|
|
git worktree add --detach here main &&
|
2015-10-08 19:01:05 +02:00
|
|
|
echo "$(git -C here rev-parse --show-toplevel) $(git rev-parse --short HEAD) (detached HEAD)" >>expect &&
|
2017-04-03 23:35:57 +02:00
|
|
|
git -C here worktree list >out &&
|
|
|
|
sed "s/ */ /g" <out >actual &&
|
2015-10-08 19:01:05 +02:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"list" all worktrees --porcelain' '
|
|
|
|
echo "worktree $(git rev-parse --show-toplevel)" >expect &&
|
|
|
|
echo "HEAD $(git rev-parse HEAD)" >>expect &&
|
|
|
|
echo "branch $(git symbolic-ref HEAD)" >>expect &&
|
|
|
|
echo >>expect &&
|
2017-04-03 23:35:57 +02:00
|
|
|
test_when_finished "rm -rf here actual expect && git worktree prune" &&
|
2020-11-19 00:44:22 +01:00
|
|
|
git worktree add --detach here main &&
|
2015-10-08 19:01:05 +02:00
|
|
|
echo "worktree $(git -C here rev-parse --show-toplevel)" >>expect &&
|
|
|
|
echo "HEAD $(git rev-parse HEAD)" >>expect &&
|
|
|
|
echo "detached" >>expect &&
|
|
|
|
echo >>expect &&
|
|
|
|
git worktree list --porcelain >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2022-03-31 18:21:28 +02:00
|
|
|
test_expect_success '"list" all worktrees --porcelain -z' '
|
|
|
|
test_when_finished "rm -rf here _actual actual expect &&
|
|
|
|
git worktree prune" &&
|
|
|
|
printf "worktree %sQHEAD %sQbranch %sQQ" \
|
|
|
|
"$(git rev-parse --show-toplevel)" \
|
|
|
|
$(git rev-parse HEAD --symbolic-full-name HEAD) >expect &&
|
|
|
|
git worktree add --detach here main &&
|
|
|
|
printf "worktree %sQHEAD %sQdetachedQQ" \
|
|
|
|
"$(git -C here rev-parse --show-toplevel)" \
|
|
|
|
"$(git rev-parse HEAD)" >>expect &&
|
|
|
|
git worktree list --porcelain -z >_actual &&
|
|
|
|
nul_to_q <_actual >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"list" -z fails without --porcelain' '
|
|
|
|
test_must_fail git worktree list -z
|
|
|
|
'
|
|
|
|
|
2020-11-03 12:48:07 +01:00
|
|
|
test_expect_success '"list" all worktrees with locked annotation' '
|
2020-10-11 12:11:52 +02:00
|
|
|
test_when_finished "rm -rf locked unlocked out && git worktree prune" &&
|
2020-11-19 00:44:22 +01:00
|
|
|
git worktree add --detach locked main &&
|
|
|
|
git worktree add --detach unlocked main &&
|
2020-10-11 12:11:52 +02:00
|
|
|
git worktree lock locked &&
|
2021-01-27 09:03:07 +01:00
|
|
|
test_when_finished "git worktree unlock locked" &&
|
2020-10-11 12:11:52 +02:00
|
|
|
git worktree list >out &&
|
|
|
|
grep "/locked *[0-9a-f].* locked$" out &&
|
|
|
|
! grep "/unlocked *[0-9a-f].* locked$" out
|
|
|
|
'
|
|
|
|
|
2021-01-27 09:03:08 +01:00
|
|
|
test_expect_success '"list" all worktrees --porcelain with locked' '
|
|
|
|
test_when_finished "rm -rf locked1 locked2 unlocked out actual expect && git worktree prune" &&
|
|
|
|
echo "locked" >expect &&
|
|
|
|
echo "locked with reason" >>expect &&
|
|
|
|
git worktree add --detach locked1 &&
|
|
|
|
git worktree add --detach locked2 &&
|
|
|
|
# unlocked worktree should not be annotated with "locked"
|
|
|
|
git worktree add --detach unlocked &&
|
|
|
|
git worktree lock locked1 &&
|
|
|
|
test_when_finished "git worktree unlock locked1" &&
|
|
|
|
git worktree lock locked2 --reason "with reason" &&
|
|
|
|
test_when_finished "git worktree unlock locked2" &&
|
|
|
|
git worktree list --porcelain >out &&
|
|
|
|
grep "^locked" out >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"list" all worktrees --porcelain with locked reason newline escaped' '
|
|
|
|
test_when_finished "rm -rf locked_lf locked_crlf out actual expect && git worktree prune" &&
|
|
|
|
printf "locked \"locked\\\\r\\\\nreason\"\n" >expect &&
|
|
|
|
printf "locked \"locked\\\\nreason\"\n" >>expect &&
|
|
|
|
git worktree add --detach locked_lf &&
|
|
|
|
git worktree add --detach locked_crlf &&
|
|
|
|
git worktree lock locked_lf --reason "$(printf "locked\nreason")" &&
|
|
|
|
test_when_finished "git worktree unlock locked_lf" &&
|
|
|
|
git worktree lock locked_crlf --reason "$(printf "locked\r\nreason")" &&
|
|
|
|
test_when_finished "git worktree unlock locked_crlf" &&
|
|
|
|
git worktree list --porcelain >out &&
|
|
|
|
grep "^locked" out >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2021-01-27 09:03:09 +01:00
|
|
|
test_expect_success '"list" all worktrees with prunable annotation' '
|
|
|
|
test_when_finished "rm -rf prunable unprunable out && git worktree prune" &&
|
|
|
|
git worktree add --detach prunable &&
|
|
|
|
git worktree add --detach unprunable &&
|
|
|
|
rm -rf prunable &&
|
|
|
|
git worktree list >out &&
|
|
|
|
grep "/prunable *[0-9a-f].* prunable$" out &&
|
|
|
|
! grep "/unprunable *[0-9a-f].* prunable$"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"list" all worktrees --porcelain with prunable' '
|
|
|
|
test_when_finished "rm -rf prunable out && git worktree prune" &&
|
|
|
|
git worktree add --detach prunable &&
|
|
|
|
rm -rf prunable &&
|
|
|
|
git worktree list --porcelain >out &&
|
|
|
|
sed -n "/^worktree .*\/prunable$/,/^$/p" <out >only_prunable &&
|
|
|
|
test_i18ngrep "^prunable gitdir file points to non-existent location$" only_prunable
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"list" all worktrees with prunable consistent with "prune"' '
|
|
|
|
test_when_finished "rm -rf prunable unprunable out && git worktree prune" &&
|
|
|
|
git worktree add --detach prunable &&
|
|
|
|
git worktree add --detach unprunable &&
|
|
|
|
rm -rf prunable &&
|
|
|
|
git worktree list >out &&
|
|
|
|
grep "/prunable *[0-9a-f].* prunable$" out &&
|
|
|
|
! grep "/unprunable *[0-9a-f].* unprunable$" out &&
|
worktree: send "chatty" messages to stderr
The order in which the stdout and stderr streams are flushed is not
guaranteed to be the same across platforms or `libc` implementations.
This lack of determinism can lead to anomalous and potentially confusing
output if normal (stdout) output is flushed after error (stderr) output.
For instance, the following output which clearly indicates a failure due
to a fatal error:
% git worktree add ../foo bar
Preparing worktree (checking out 'bar')
fatal: 'bar' is already checked out at '.../wherever'
has been reported[1] on Microsoft Windows to appear as:
% git worktree add ../foo bar
fatal: 'bar' is already checked out at '.../wherever'
Preparing worktree (checking out 'bar')
which may confuse the reader into thinking that the command somehow
recovered and ran to completion despite the error.
This problem crops up because the "chatty" status message "Preparing
worktree" is sent to stdout, whereas the "fatal" error message is sent
to stderr. One way to fix this would be to flush stdout manually before
git-worktree reports any errors to stderr.
However, common practice in Git is for "chatty" messages to be sent to
stderr. Therefore, a more appropriate fix is to adjust git-worktree to
conform to that practice by sending its "chatty" messages to stderr
rather than stdout as is currently the case.
There may be concern that relocating messages from stdout to stderr
could break existing tooling, however, these messages are already
internationalized, thus are unstable. And, indeed, the "Preparing
worktree" message has already been the subject of somewhat significant
changes in 2c27002a0a (worktree: improve message when creating a new
worktree, 2018-04-24). Moreover, there is existing precedent, such as
68b939b2f0 (clone: send diagnostic messages to stderr, 2013-09-18) which
likewise relocated "chatty" messages from stdout to stderr for
git-clone.
[1]: https://lore.kernel.org/git/CA+34VNLj6VB1kCkA=MfM7TZR+6HgqNi5-UaziAoCXacSVkch4A@mail.gmail.com/T/
Reported-by: Baruch Burstein <bmburstein@gmail.com>
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-03 04:44:19 +01:00
|
|
|
git worktree prune --verbose 2>out &&
|
2021-01-27 09:03:09 +01:00
|
|
|
test_i18ngrep "^Removing worktrees/prunable" out &&
|
|
|
|
test_i18ngrep ! "^Removing worktrees/unprunable" out
|
|
|
|
'
|
|
|
|
|
2021-01-27 09:03:10 +01:00
|
|
|
test_expect_success '"list" --verbose and --porcelain mutually exclusive' '
|
|
|
|
test_must_fail git worktree list --verbose --porcelain
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"list" all worktrees --verbose with locked' '
|
|
|
|
test_when_finished "rm -rf locked1 locked2 out actual expect && git worktree prune" &&
|
|
|
|
git worktree add locked1 --detach &&
|
|
|
|
git worktree add locked2 --detach &&
|
|
|
|
git worktree lock locked1 &&
|
|
|
|
test_when_finished "git worktree unlock locked1" &&
|
|
|
|
git worktree lock locked2 --reason "with reason" &&
|
|
|
|
test_when_finished "git worktree unlock locked2" &&
|
|
|
|
echo "$(git -C locked2 rev-parse --show-toplevel) $(git rev-parse --short HEAD) (detached HEAD)" >expect &&
|
|
|
|
printf "\tlocked: with reason\n" >>expect &&
|
|
|
|
git worktree list --verbose >out &&
|
|
|
|
grep "/locked1 *[0-9a-f].* locked$" out &&
|
|
|
|
sed -n "s/ */ /g;/\/locked2 *[0-9a-f].*$/,/locked: .*$/p" <out >actual &&
|
|
|
|
test_cmp actual expect
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"list" all worktrees --verbose with prunable' '
|
|
|
|
test_when_finished "rm -rf prunable out actual expect && git worktree prune" &&
|
|
|
|
git worktree add prunable --detach &&
|
|
|
|
echo "$(git -C prunable rev-parse --show-toplevel) $(git rev-parse --short HEAD) (detached HEAD)" >expect &&
|
|
|
|
printf "\tprunable: gitdir file points to non-existent location\n" >>expect &&
|
|
|
|
rm -rf prunable &&
|
|
|
|
git worktree list --verbose >out &&
|
|
|
|
sed -n "s/ */ /g;/\/prunable *[0-9a-f].*$/,/prunable: .*$/p" <out >actual &&
|
2021-02-11 02:53:53 +01:00
|
|
|
test_cmp actual expect
|
2021-01-27 09:03:10 +01:00
|
|
|
'
|
|
|
|
|
2015-10-08 19:01:05 +02:00
|
|
|
test_expect_success 'bare repo setup' '
|
|
|
|
git init --bare bare1 &&
|
|
|
|
echo "data" >file1 &&
|
|
|
|
git add file1 &&
|
|
|
|
git commit -m"File1: add data" &&
|
2020-11-19 00:44:22 +01:00
|
|
|
git push bare1 main &&
|
2015-10-08 19:01:05 +02:00
|
|
|
git reset --hard HEAD^
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"list" all worktrees from bare main' '
|
2017-04-03 23:35:57 +02:00
|
|
|
test_when_finished "rm -rf there out actual expect && git -C bare1 worktree prune" &&
|
2020-11-19 00:44:22 +01:00
|
|
|
git -C bare1 worktree add --detach ../there main &&
|
2015-10-08 19:01:05 +02:00
|
|
|
echo "$(pwd)/bare1 (bare)" >expect &&
|
|
|
|
echo "$(git -C there rev-parse --show-toplevel) $(git -C there rev-parse --short HEAD) (detached HEAD)" >>expect &&
|
2017-04-03 23:35:57 +02:00
|
|
|
git -C bare1 worktree list >out &&
|
|
|
|
sed "s/ */ /g" <out >actual &&
|
2015-10-08 19:01:05 +02:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"list" all worktrees --porcelain from bare main' '
|
2017-04-03 23:35:57 +02:00
|
|
|
test_when_finished "rm -rf there actual expect && git -C bare1 worktree prune" &&
|
2020-11-19 00:44:22 +01:00
|
|
|
git -C bare1 worktree add --detach ../there main &&
|
2015-10-08 19:01:05 +02:00
|
|
|
echo "worktree $(pwd)/bare1" >expect &&
|
|
|
|
echo "bare" >>expect &&
|
|
|
|
echo >>expect &&
|
|
|
|
echo "worktree $(git -C there rev-parse --show-toplevel)" >>expect &&
|
|
|
|
echo "HEAD $(git -C there rev-parse HEAD)" >>expect &&
|
|
|
|
echo "detached" >>expect &&
|
|
|
|
echo >>expect &&
|
|
|
|
git -C bare1 worktree list --porcelain >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"list" all worktrees from linked with a bare main' '
|
2017-04-03 23:35:57 +02:00
|
|
|
test_when_finished "rm -rf there out actual expect && git -C bare1 worktree prune" &&
|
2020-11-19 00:44:22 +01:00
|
|
|
git -C bare1 worktree add --detach ../there main &&
|
2015-10-08 19:01:05 +02:00
|
|
|
echo "$(pwd)/bare1 (bare)" >expect &&
|
|
|
|
echo "$(git -C there rev-parse --show-toplevel) $(git -C there rev-parse --short HEAD) (detached HEAD)" >>expect &&
|
2017-04-03 23:35:57 +02:00
|
|
|
git -C there worktree list >out &&
|
|
|
|
sed "s/ */ /g" <out >actual &&
|
2015-10-08 19:01:05 +02:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'bare repo cleanup' '
|
|
|
|
rm -rf bare1
|
|
|
|
'
|
|
|
|
|
get_worktrees() must return main worktree as first item even on error
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>
2016-11-28 10:36:54 +01:00
|
|
|
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)
|
2018-05-13 04:24:13 +02:00
|
|
|
HEAD $ZERO_OID
|
get_worktrees() must return main worktree as first item even on error
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>
2016-11-28 10:36:54 +01:00
|
|
|
|
|
|
|
EOF
|
|
|
|
cd linked &&
|
|
|
|
echo "worktree $(pwd)" >expected &&
|
2021-08-02 18:53:30 +02:00
|
|
|
(cd ../ && test-tool ref-store main create-symref HEAD .broken ) &&
|
2017-04-03 23:35:57 +02:00
|
|
|
git worktree list --porcelain >out &&
|
|
|
|
head -n 3 out >actual &&
|
get_worktrees() must return main worktree as first item even on error
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>
2016-11-28 10:36:54 +01:00
|
|
|
test_cmp ../expected actual &&
|
2017-04-03 23:35:57 +02:00
|
|
|
git worktree list >out &&
|
|
|
|
head -n 1 out >actual.2 &&
|
get_worktrees() must return main worktree as first item even on error
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>
2016-11-28 10:36:54 +01:00
|
|
|
grep -F "(error)" actual.2
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2016-11-28 10:36:56 +01:00
|
|
|
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 &&
|
2017-04-03 23:35:57 +02:00
|
|
|
git worktree list --porcelain >out &&
|
|
|
|
grep ^worktree out >actual
|
2016-11-28 10:36:56 +01:00
|
|
|
) &&
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
worktree $(pwd)/sorted/main
|
|
|
|
worktree $(pwd)/sorted/first
|
|
|
|
worktree $(pwd)/sorted/second
|
|
|
|
EOF
|
|
|
|
test_cmp expected sorted/main/actual
|
|
|
|
'
|
|
|
|
|
2020-03-04 08:00:00 +01:00
|
|
|
test_expect_success 'worktree path when called in .git directory' '
|
2020-03-22 22:14:22 +01:00
|
|
|
git worktree list >list1 &&
|
2020-03-04 08:00:00 +01:00
|
|
|
git -C .git worktree list >list2 &&
|
|
|
|
test_cmp list1 list2
|
|
|
|
'
|
|
|
|
|
2015-10-08 19:01:05 +02:00
|
|
|
test_done
|