2009-02-19 11:34:44 +08:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='git branch display tests'
|
2024-05-27 19:46:54 +08:00
|
|
|
|
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
2009-02-19 11:34:44 +08:00
|
|
|
. ./test-lib.sh
|
ref-filter: consult want_color() before emitting colors
When color placeholders like %(color:red) are used in a
ref-filter format, we unconditionally output the colors,
even if the user has asked us for no colors. This usually
isn't a problem when the user is constructing a --format on
the command line, but it means we may do the wrong thing
when the format is fed from a script or alias. For example:
$ git config alias.b 'branch --format=%(color:green)%(refname)'
$ git b --no-color
should probably omit the green color. Likewise, running:
$ git b >branches
should probably also omit the color, just as we would for
all baked-in coloring (and as we recently started to do for
user-specified colors in --pretty formats).
This commit makes both of those cases work by teaching
the ref-filter code to consult want_color() before
outputting any color. The color flag in ref_format defaults
to "-1", which means we'll consult color.ui, which in turn
defaults to the usual isatty() check on stdout. However,
callers like git-branch which support their own color config
(and command-line options) can override that.
The new tests independently cover all three of the callers
of ref-filter (for-each-ref, tag, and branch). Even though
these seem redundant, it confirms that we've correctly
plumbed through all of the necessary config to make colors
work by default.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-13 23:09:32 +08:00
|
|
|
. "$TEST_DIRECTORY"/lib-terminal.sh
|
2009-02-19 11:34:44 +08:00
|
|
|
|
|
|
|
test_expect_success 'make commits' '
|
|
|
|
echo content >file &&
|
|
|
|
git add file &&
|
|
|
|
git commit -m one &&
|
2020-12-17 09:07:03 +08:00
|
|
|
git branch -M main &&
|
2009-02-19 11:34:44 +08:00
|
|
|
echo content >>file &&
|
|
|
|
git commit -a -m two
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'make branches' '
|
2010-10-31 09:46:54 +08:00
|
|
|
git branch branch-one &&
|
2009-02-19 11:34:44 +08:00
|
|
|
git branch branch-two HEAD^
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'make remote branches' '
|
2010-10-31 09:46:54 +08:00
|
|
|
git update-ref refs/remotes/origin/branch-one branch-one &&
|
|
|
|
git update-ref refs/remotes/origin/branch-two branch-two &&
|
2009-02-19 11:34:44 +08:00
|
|
|
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/branch-one
|
|
|
|
'
|
|
|
|
|
|
|
|
cat >expect <<'EOF'
|
|
|
|
branch-one
|
|
|
|
branch-two
|
2020-12-17 09:07:03 +08:00
|
|
|
* main
|
2009-02-19 11:34:44 +08:00
|
|
|
EOF
|
|
|
|
test_expect_success 'git branch shows local branches' '
|
|
|
|
git branch >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2011-08-28 22:54:31 +08:00
|
|
|
test_expect_success 'git branch --list shows local branches' '
|
|
|
|
git branch --list >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2011-08-28 22:54:32 +08:00
|
|
|
cat >expect <<'EOF'
|
|
|
|
branch-one
|
|
|
|
branch-two
|
|
|
|
EOF
|
|
|
|
test_expect_success 'git branch --list pattern shows matching local branches' '
|
|
|
|
git branch --list branch* >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2009-02-19 11:34:44 +08:00
|
|
|
cat >expect <<'EOF'
|
|
|
|
origin/HEAD -> origin/branch-one
|
|
|
|
origin/branch-one
|
|
|
|
origin/branch-two
|
|
|
|
EOF
|
|
|
|
test_expect_success 'git branch -r shows remote branches' '
|
|
|
|
git branch -r >actual &&
|
2023-07-19 02:27:49 +08:00
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
git branch --remotes >actual &&
|
2009-02-19 11:34:44 +08:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2023-07-19 02:27:49 +08:00
|
|
|
test_expect_success 'git branch --no-remotes is rejected' '
|
|
|
|
test_must_fail git branch --no-remotes 2>err &&
|
|
|
|
grep "unknown option .no-remotes." err
|
|
|
|
'
|
|
|
|
|
2009-02-19 11:34:44 +08:00
|
|
|
cat >expect <<'EOF'
|
|
|
|
branch-one
|
|
|
|
branch-two
|
2020-12-17 09:07:03 +08:00
|
|
|
* main
|
2009-02-19 11:34:44 +08:00
|
|
|
remotes/origin/HEAD -> origin/branch-one
|
|
|
|
remotes/origin/branch-one
|
|
|
|
remotes/origin/branch-two
|
|
|
|
EOF
|
|
|
|
test_expect_success 'git branch -a shows local and remote branches' '
|
|
|
|
git branch -a >actual &&
|
2023-07-19 02:27:49 +08:00
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
git branch --all >actual &&
|
2009-02-19 11:34:44 +08:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2023-07-19 02:27:49 +08:00
|
|
|
test_expect_success 'git branch --no-all is rejected' '
|
|
|
|
test_must_fail git branch --no-all 2>err &&
|
|
|
|
grep "unknown option .no-all." err
|
|
|
|
'
|
|
|
|
|
2009-02-19 11:34:44 +08:00
|
|
|
cat >expect <<'EOF'
|
|
|
|
two
|
|
|
|
one
|
|
|
|
two
|
|
|
|
EOF
|
|
|
|
test_expect_success 'git branch -v shows branch summaries' '
|
|
|
|
git branch -v >tmp &&
|
|
|
|
awk "{print \$NF}" <tmp >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2011-08-28 22:54:32 +08:00
|
|
|
cat >expect <<'EOF'
|
|
|
|
two
|
|
|
|
one
|
|
|
|
EOF
|
2011-09-09 05:09:50 +08:00
|
|
|
test_expect_success 'git branch --list -v pattern shows branch summaries' '
|
|
|
|
git branch --list -v branch* >tmp &&
|
2011-08-28 22:54:32 +08:00
|
|
|
awk "{print \$NF}" <tmp >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
2016-12-04 10:52:25 +08:00
|
|
|
test_expect_success 'git branch --ignore-case --list -v pattern shows branch summaries' '
|
|
|
|
git branch --list --ignore-case -v BRANCH* >tmp &&
|
|
|
|
awk "{print \$NF}" <tmp >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
2011-08-28 22:54:32 +08:00
|
|
|
|
2011-09-09 05:09:50 +08:00
|
|
|
test_expect_success 'git branch -v pattern does not show branch summaries' '
|
|
|
|
test_must_fail git branch -v branch*
|
|
|
|
'
|
|
|
|
|
2018-10-26 03:04:21 +08:00
|
|
|
test_expect_success 'git branch `--show-current` shows current branch' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
branch-two
|
|
|
|
EOF
|
|
|
|
git checkout branch-two &&
|
|
|
|
git branch --show-current >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'git branch `--show-current` is silent when detached HEAD' '
|
|
|
|
git checkout HEAD^0 &&
|
|
|
|
git branch --show-current >actual &&
|
|
|
|
test_must_be_empty actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'git branch `--show-current` works properly when tag exists' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
branch-and-tag-name
|
|
|
|
EOF
|
|
|
|
test_when_finished "
|
|
|
|
git checkout branch-one
|
|
|
|
git branch -D branch-and-tag-name
|
|
|
|
" &&
|
|
|
|
git checkout -b branch-and-tag-name &&
|
|
|
|
test_when_finished "git tag -d branch-and-tag-name" &&
|
|
|
|
git tag branch-and-tag-name &&
|
|
|
|
git branch --show-current >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'git branch `--show-current` works properly with worktrees' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
branch-one
|
|
|
|
branch-two
|
|
|
|
EOF
|
|
|
|
git checkout branch-one &&
|
2019-07-10 06:25:33 +08:00
|
|
|
test_when_finished "
|
|
|
|
git worktree remove worktree_dir
|
|
|
|
" &&
|
2019-04-29 13:19:43 +08:00
|
|
|
git worktree add worktree_dir branch-two &&
|
2018-10-26 03:04:21 +08:00
|
|
|
{
|
|
|
|
git branch --show-current &&
|
2019-04-29 13:19:43 +08:00
|
|
|
git -C worktree_dir branch --show-current
|
2018-10-26 03:04:21 +08:00
|
|
|
} >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2013-03-13 19:42:53 +08:00
|
|
|
test_expect_success 'git branch shows detached HEAD properly' '
|
|
|
|
cat >expect <<EOF &&
|
2015-03-06 23:04:07 +08:00
|
|
|
* (HEAD detached at $(git rev-parse --short HEAD^0))
|
2009-02-19 11:34:44 +08:00
|
|
|
branch-one
|
|
|
|
branch-two
|
2020-12-17 09:07:03 +08:00
|
|
|
main
|
2009-02-19 11:34:44 +08:00
|
|
|
EOF
|
|
|
|
git checkout HEAD^0 &&
|
|
|
|
git branch >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2009-02-19 11:34:44 +08:00
|
|
|
'
|
|
|
|
|
2015-09-27 23:13:42 +08:00
|
|
|
test_expect_success 'git branch shows detached HEAD properly after checkout --detach' '
|
2020-12-17 09:07:03 +08:00
|
|
|
git checkout main &&
|
2015-09-27 23:13:41 +08:00
|
|
|
cat >expect <<EOF &&
|
|
|
|
* (HEAD detached at $(git rev-parse --short HEAD^0))
|
|
|
|
branch-one
|
|
|
|
branch-two
|
2020-12-17 09:07:03 +08:00
|
|
|
main
|
2015-09-27 23:13:41 +08:00
|
|
|
EOF
|
|
|
|
git checkout --detach &&
|
|
|
|
git branch >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2015-09-27 23:13:41 +08:00
|
|
|
'
|
|
|
|
|
2015-03-06 23:04:07 +08:00
|
|
|
test_expect_success 'git branch shows detached HEAD properly after moving' '
|
|
|
|
cat >expect <<EOF &&
|
|
|
|
* (HEAD detached from $(git rev-parse --short HEAD))
|
|
|
|
branch-one
|
|
|
|
branch-two
|
2020-12-17 09:07:03 +08:00
|
|
|
main
|
2015-03-06 23:04:07 +08:00
|
|
|
EOF
|
|
|
|
git reset --hard HEAD^1 &&
|
|
|
|
git branch >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2015-03-06 23:04:07 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'git branch shows detached HEAD properly from tag' '
|
|
|
|
cat >expect <<EOF &&
|
|
|
|
* (HEAD detached at fromtag)
|
|
|
|
branch-one
|
|
|
|
branch-two
|
2020-12-17 09:07:03 +08:00
|
|
|
main
|
2015-03-06 23:04:07 +08:00
|
|
|
EOF
|
2020-12-17 09:07:03 +08:00
|
|
|
git tag fromtag main &&
|
2015-03-06 23:04:07 +08:00
|
|
|
git checkout fromtag &&
|
|
|
|
git branch >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2015-03-06 23:04:07 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'git branch shows detached HEAD properly after moving from tag' '
|
|
|
|
cat >expect <<EOF &&
|
|
|
|
* (HEAD detached from fromtag)
|
|
|
|
branch-one
|
|
|
|
branch-two
|
2020-12-17 09:07:03 +08:00
|
|
|
main
|
2015-03-06 23:04:07 +08:00
|
|
|
EOF
|
|
|
|
git reset --hard HEAD^1 &&
|
|
|
|
git branch >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2015-03-06 23:04:07 +08:00
|
|
|
'
|
|
|
|
|
2021-01-06 18:01:36 +08:00
|
|
|
test_expect_success 'git branch `--sort=[-]objectsize` option' '
|
2015-09-24 02:11:12 +08:00
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
* (HEAD detached from fromtag)
|
2015-10-30 16:45:28 +08:00
|
|
|
branch-two
|
2015-09-24 02:11:12 +08:00
|
|
|
branch-one
|
2020-12-17 09:07:03 +08:00
|
|
|
main
|
2015-09-24 02:11:12 +08:00
|
|
|
EOF
|
|
|
|
git branch --sort=objectsize >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual &&
|
2021-01-06 18:01:36 +08:00
|
|
|
|
|
|
|
cat >expect <<-\EOF &&
|
2021-01-07 17:51:53 +08:00
|
|
|
* (HEAD detached from fromtag)
|
2021-01-06 18:01:36 +08:00
|
|
|
branch-one
|
|
|
|
main
|
|
|
|
branch-two
|
|
|
|
EOF
|
|
|
|
git branch --sort=-objectsize >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2021-01-06 18:01:36 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'git branch `--sort=[-]type` option' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
* (HEAD detached from fromtag)
|
|
|
|
branch-one
|
|
|
|
branch-two
|
|
|
|
main
|
|
|
|
EOF
|
|
|
|
git branch --sort=type >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual &&
|
2021-01-06 18:01:36 +08:00
|
|
|
|
|
|
|
cat >expect <<-\EOF &&
|
2021-01-07 17:51:53 +08:00
|
|
|
* (HEAD detached from fromtag)
|
2021-01-06 18:01:36 +08:00
|
|
|
branch-one
|
|
|
|
branch-two
|
|
|
|
main
|
|
|
|
EOF
|
|
|
|
git branch --sort=-type >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2021-01-06 18:01:36 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'git branch `--sort=[-]version:refname` option' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
* (HEAD detached from fromtag)
|
|
|
|
branch-one
|
|
|
|
branch-two
|
|
|
|
main
|
|
|
|
EOF
|
|
|
|
git branch --sort=version:refname >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual &&
|
2021-01-06 18:01:36 +08:00
|
|
|
|
|
|
|
cat >expect <<-\EOF &&
|
2021-01-07 17:51:53 +08:00
|
|
|
* (HEAD detached from fromtag)
|
2021-01-06 18:01:36 +08:00
|
|
|
main
|
|
|
|
branch-two
|
|
|
|
branch-one
|
|
|
|
EOF
|
|
|
|
git branch --sort=-version:refname >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2015-09-24 02:11:12 +08:00
|
|
|
'
|
|
|
|
|
2015-09-24 02:11:13 +08:00
|
|
|
test_expect_success 'git branch --points-at option' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
branch-one
|
2020-12-17 09:07:03 +08:00
|
|
|
main
|
2015-09-24 02:11:13 +08:00
|
|
|
EOF
|
|
|
|
git branch --points-at=branch-one >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
tag: do not show ambiguous tag names as "tags/foo"
Since b7cc53e9 (tag.c: use 'ref-filter' APIs, 2015-07-11),
git-tag has started showing tags with ambiguous names (i.e.,
when both "heads/foo" and "tags/foo" exists) as "tags/foo"
instead of just "foo". This is both:
- pointless; the output of "git tag" includes only
refs/tags, so we know that "foo" means the one in
"refs/tags".
and
- ambiguous; in the original output, we know that the line
"foo" means that "refs/tags/foo" exists. In the new
output, it is unclear whether we mean "refs/tags/foo" or
"refs/tags/tags/foo".
The reason this happens is that commit b7cc53e9 switched
git-tag to use ref-filter's "%(refname:short)" output
formatting, which was adapted from for-each-ref. This more
general code does not know that we care only about tags, and
uses shorten_unambiguous_ref to get the short-name. We need
to tell it that we care only about "refs/tags/", and it
should shorten with respect to that value.
In theory, the ref-filter code could figure this out by us
passing FILTER_REFS_TAGS. But there are two complications
there:
1. The handling of refname:short is deep in formatting
code that does not even have our ref_filter struct, let
alone the arguments to the filter_ref struct.
2. In git v2.7.0, we expose the formatting language to the
user. If we follow this path, it will mean that
"%(refname:short)" behaves differently for "tag" versus
"for-each-ref" (including "for-each-ref refs/tags/"),
which can lead to confusion.
Instead, let's add a new modifier to the formatting
language, "strip", to remove a specific set of prefix
components. This fixes "git tag", and lets users invoke the
same behavior from their own custom formats (for "tag" or
"for-each-ref") while leaving ":short" with its same
consistent meaning in all places.
We introduce a test in t7004 for "git tag", which fails
without this patch. We also add a similar test in t3203 for
"git branch", which does not actually fail. But since it is
likely that "branch" will eventually use the same formatting
code, the test helps defend against future regressions.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-01-26 11:00:05 +08:00
|
|
|
test_expect_success 'ambiguous branch/tag not marked' '
|
|
|
|
git tag ambiguous &&
|
|
|
|
git branch ambiguous &&
|
|
|
|
echo " ambiguous" >expect &&
|
|
|
|
git branch --list ambiguous >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
branch: fix shortening of non-remote symrefs
Commit aedcb7d (branch.c: use 'ref-filter' APIs, 2015-09-23)
adjusted the symref-printing code to look like this:
if (item->symref) {
skip_prefix(item->symref, "refs/remotes/", &desc);
strbuf_addf(&out, " -> %s", desc);
}
This has three bugs in it:
1. It always skips past "refs/remotes/", instead of
skipping past the prefix associated with the branch we
are showing (so commonly we see "refs/remotes/" for the
refs/remotes/origin/HEAD symref, but the previous code
would skip "refs/heads/" when showing a symref it found
in refs/heads/.
2. If skip_prefix() does not match, it leaves "desc"
untouched, and we show whatever happened to be in it
(which is the refname from a call to skip_prefix()
earlier in the function).
3. If we do match with skip_prefix(), we stomp on the
"desc" variable, which is later passed to
add_verbose_info(). We probably want to retain the
original refname there (though it likely doesn't matter
in practice, since after all, one points to the other).
The fix to match the original code is fairly easy: record
the prefix to strip based on item->kind, and use it here.
However, since we already have a local variable named "prefix",
let's give the two prefixes verbose names so we don't
confuse them.
Signed-off-by: Jeff King <peff@peff.net>
Acked-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-03 12:14:26 +08:00
|
|
|
test_expect_success 'local-branch symrefs shortened properly' '
|
|
|
|
git symbolic-ref refs/heads/ref-to-branch refs/heads/branch-one &&
|
|
|
|
git symbolic-ref refs/heads/ref-to-remote refs/remotes/origin/branch-one &&
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
ref-to-branch -> branch-one
|
2017-01-10 16:49:52 +08:00
|
|
|
ref-to-remote -> origin/branch-one
|
branch: fix shortening of non-remote symrefs
Commit aedcb7d (branch.c: use 'ref-filter' APIs, 2015-09-23)
adjusted the symref-printing code to look like this:
if (item->symref) {
skip_prefix(item->symref, "refs/remotes/", &desc);
strbuf_addf(&out, " -> %s", desc);
}
This has three bugs in it:
1. It always skips past "refs/remotes/", instead of
skipping past the prefix associated with the branch we
are showing (so commonly we see "refs/remotes/" for the
refs/remotes/origin/HEAD symref, but the previous code
would skip "refs/heads/" when showing a symref it found
in refs/heads/.
2. If skip_prefix() does not match, it leaves "desc"
untouched, and we show whatever happened to be in it
(which is the refname from a call to skip_prefix()
earlier in the function).
3. If we do match with skip_prefix(), we stomp on the
"desc" variable, which is later passed to
add_verbose_info(). We probably want to retain the
original refname there (though it likely doesn't matter
in practice, since after all, one points to the other).
The fix to match the original code is fairly easy: record
the prefix to strip based on item->kind, and use it here.
However, since we already have a local variable named "prefix",
let's give the two prefixes verbose names so we don't
confuse them.
Signed-off-by: Jeff King <peff@peff.net>
Acked-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-03 12:14:26 +08:00
|
|
|
EOF
|
|
|
|
git branch >actual.raw &&
|
|
|
|
grep ref-to <actual.raw >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2016-12-04 10:52:25 +08:00
|
|
|
test_expect_success 'sort branches, ignore case' '
|
|
|
|
(
|
2020-12-17 09:07:03 +08:00
|
|
|
git init -b main sort-icase &&
|
2016-12-04 10:52:25 +08:00
|
|
|
cd sort-icase &&
|
|
|
|
test_commit initial &&
|
|
|
|
git branch branch-one &&
|
|
|
|
git branch BRANCH-two &&
|
|
|
|
git branch --list | awk "{print \$NF}" >actual &&
|
|
|
|
cat >expected <<-\EOF &&
|
|
|
|
BRANCH-two
|
|
|
|
branch-one
|
2020-12-17 09:07:03 +08:00
|
|
|
main
|
2016-12-04 10:52:25 +08:00
|
|
|
EOF
|
|
|
|
test_cmp expected actual &&
|
|
|
|
git branch --list -i | awk "{print \$NF}" >actual &&
|
|
|
|
cat >expected <<-\EOF &&
|
|
|
|
branch-one
|
|
|
|
BRANCH-two
|
2020-12-17 09:07:03 +08:00
|
|
|
main
|
2016-12-04 10:52:25 +08:00
|
|
|
EOF
|
|
|
|
test_cmp expected actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2017-01-10 16:49:53 +08:00
|
|
|
test_expect_success 'git branch --format option' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
Refname is (HEAD detached from fromtag)
|
|
|
|
Refname is refs/heads/ambiguous
|
|
|
|
Refname is refs/heads/branch-one
|
|
|
|
Refname is refs/heads/branch-two
|
2020-12-17 09:07:03 +08:00
|
|
|
Refname is refs/heads/main
|
2017-01-10 16:49:53 +08:00
|
|
|
Refname is refs/heads/ref-to-branch
|
|
|
|
Refname is refs/heads/ref-to-remote
|
|
|
|
EOF
|
|
|
|
git branch --format="Refname is %(refname)" >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2017-01-10 16:49:53 +08:00
|
|
|
'
|
|
|
|
|
for-each-ref: add ahead-behind format atom
The previous change implemented the ahead_behind() method, including an
algorithm to compute the ahead/behind values for a number of commit tips
relative to a number of commit bases. Now, integrate that algorithm as
part of 'git for-each-ref' hidden behind a new format atom,
ahead-behind. This naturally extends to 'git branch' and 'git tag'
builtins, as well.
This format allows specifying multiple bases, if so desired, and all
matching references are compared against all of those bases. For this
reason, failing to read a reference provided from these atoms results in
an error.
In order to translate the ahead_behind() method information to the
format output code in ref-filter.c, we must populate arrays of
ahead_behind_count structs. In struct ref_array, we store the full array
that will be passed to ahead_behind(). In struct ref_array_item, we
store an array of pointers that point to the relvant items within the
full array. In this way, we can pull all relevant ahead/behind values
directly when formatting output for a specific item. It also ensures the
lifetime of the ahead_behind_count structs matches the time that the
array is being used.
Add specific tests of the ahead/behind counts in t6600-test-reach.sh, as
it has an interesting repository shape. In particular, its merging
strategy and its use of different commit-graphs would demonstrate over-
counting if the ahead_behind() method did not already account for that
possibility.
Also add tests for the specific for-each-ref, branch, and tag builtins.
In the case of 'git tag', there are intersting cases that happen when
some of the selected tips are not commits. This requires careful logic
around commits_nr in the second loop of filter_ahead_behind(). Also, the
test in t7004 is carefully located to avoid being dependent on the GPG
prereq. It also avoids using the test_commit helper, as that will add
ticks to the time and disrupt the expected timestamps in later tag
tests.
Also add performance tests in a new p1300-graph-walks.sh script. This
will be useful for more uses in the future, but for now compare the
ahead-behind counting algorithm in 'git for-each-ref' to the naive
implementation by running 'git rev-list --count' processes for each
input.
For the Git source code repository, the improvement is already obvious:
Test this tree
---------------------------------------------------------------
1500.2: ahead-behind counts: git for-each-ref 0.07(0.07+0.00)
1500.3: ahead-behind counts: git branch 0.07(0.06+0.00)
1500.4: ahead-behind counts: git tag 0.07(0.06+0.00)
1500.5: ahead-behind counts: git rev-list 1.32(1.04+0.27)
But the standard performance benchmark is the Linux kernel repository,
which demosntrates a significant improvement:
Test this tree
---------------------------------------------------------------
1500.2: ahead-behind counts: git for-each-ref 0.27(0.24+0.02)
1500.3: ahead-behind counts: git branch 0.27(0.24+0.03)
1500.4: ahead-behind counts: git tag 0.28(0.27+0.01)
1500.5: ahead-behind counts: git rev-list 4.57(4.03+0.54)
The 'git rev-list' test exists in this change as a demonstration, but it
will be removed in the next change to avoid wasting time on this
comparison.
Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-20 19:26:54 +08:00
|
|
|
test_expect_success 'git branch --format with ahead-behind' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
(HEAD detached from fromtag) 0 0
|
|
|
|
refs/heads/ambiguous 0 0
|
|
|
|
refs/heads/branch-one 1 0
|
|
|
|
refs/heads/branch-two 0 0
|
|
|
|
refs/heads/main 1 0
|
|
|
|
refs/heads/ref-to-branch 1 0
|
|
|
|
refs/heads/ref-to-remote 1 0
|
|
|
|
EOF
|
|
|
|
git branch --format="%(refname) %(ahead-behind:HEAD)" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2021-07-26 11:26:50 +08:00
|
|
|
test_expect_success 'git branch with --format=%(rest) must fail' '
|
|
|
|
test_must_fail git branch --format="%(rest)" >actual
|
|
|
|
'
|
|
|
|
|
2023-04-08 01:53:16 +08:00
|
|
|
test_expect_success 'git branch --format --omit-empty' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
Refname is (HEAD detached from fromtag)
|
|
|
|
Refname is refs/heads/ambiguous
|
|
|
|
Refname is refs/heads/branch-one
|
|
|
|
Refname is refs/heads/branch-two
|
|
|
|
|
|
|
|
Refname is refs/heads/ref-to-branch
|
|
|
|
Refname is refs/heads/ref-to-remote
|
|
|
|
EOF
|
|
|
|
git branch --format="%(if:notequals=refs/heads/main)%(refname)%(then)Refname is %(refname)%(end)" >actual &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
Refname is (HEAD detached from fromtag)
|
|
|
|
Refname is refs/heads/ambiguous
|
|
|
|
Refname is refs/heads/branch-one
|
|
|
|
Refname is refs/heads/branch-two
|
|
|
|
Refname is refs/heads/ref-to-branch
|
|
|
|
Refname is refs/heads/ref-to-remote
|
|
|
|
EOF
|
|
|
|
git branch --omit-empty --format="%(if:notequals=refs/heads/main)%(refname)%(then)Refname is %(refname)%(end)" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2019-04-29 13:19:43 +08:00
|
|
|
test_expect_success 'worktree colors correct' '
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
* <GREEN>(HEAD detached from fromtag)<RESET>
|
|
|
|
ambiguous<RESET>
|
|
|
|
branch-one<RESET>
|
|
|
|
+ <CYAN>branch-two<RESET>
|
2020-12-17 09:07:03 +08:00
|
|
|
main<RESET>
|
2019-04-29 13:19:43 +08:00
|
|
|
ref-to-branch<RESET> -> branch-one
|
|
|
|
ref-to-remote<RESET> -> origin/branch-one
|
|
|
|
EOF
|
|
|
|
git worktree add worktree_dir branch-two &&
|
|
|
|
git branch --color >actual.raw &&
|
|
|
|
rm -r worktree_dir &&
|
|
|
|
git worktree prune &&
|
|
|
|
test_decode_color <actual.raw >actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2019-04-29 13:19:43 +08:00
|
|
|
'
|
|
|
|
|
ref-filter: consult want_color() before emitting colors
When color placeholders like %(color:red) are used in a
ref-filter format, we unconditionally output the colors,
even if the user has asked us for no colors. This usually
isn't a problem when the user is constructing a --format on
the command line, but it means we may do the wrong thing
when the format is fed from a script or alias. For example:
$ git config alias.b 'branch --format=%(color:green)%(refname)'
$ git b --no-color
should probably omit the green color. Likewise, running:
$ git b >branches
should probably also omit the color, just as we would for
all baked-in coloring (and as we recently started to do for
user-specified colors in --pretty formats).
This commit makes both of those cases work by teaching
the ref-filter code to consult want_color() before
outputting any color. The color flag in ref_format defaults
to "-1", which means we'll consult color.ui, which in turn
defaults to the usual isatty() check on stdout. However,
callers like git-branch which support their own color config
(and command-line options) can override that.
The new tests independently cover all three of the callers
of ref-filter (for-each-ref, tag, and branch). Even though
these seem redundant, it confirms that we've correctly
plumbed through all of the necessary config to make colors
work by default.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-13 23:09:32 +08:00
|
|
|
test_expect_success "set up color tests" '
|
2020-12-17 09:07:03 +08:00
|
|
|
echo "<RED>main<RESET>" >expect.color &&
|
|
|
|
echo "main" >expect.bare &&
|
|
|
|
color_args="--format=%(color:red)%(refname:short) --list main"
|
ref-filter: consult want_color() before emitting colors
When color placeholders like %(color:red) are used in a
ref-filter format, we unconditionally output the colors,
even if the user has asked us for no colors. This usually
isn't a problem when the user is constructing a --format on
the command line, but it means we may do the wrong thing
when the format is fed from a script or alias. For example:
$ git config alias.b 'branch --format=%(color:green)%(refname)'
$ git b --no-color
should probably omit the green color. Likewise, running:
$ git b >branches
should probably also omit the color, just as we would for
all baked-in coloring (and as we recently started to do for
user-specified colors in --pretty formats).
This commit makes both of those cases work by teaching
the ref-filter code to consult want_color() before
outputting any color. The color flag in ref_format defaults
to "-1", which means we'll consult color.ui, which in turn
defaults to the usual isatty() check on stdout. However,
callers like git-branch which support their own color config
(and command-line options) can override that.
The new tests independently cover all three of the callers
of ref-filter (for-each-ref, tag, and branch). Even though
these seem redundant, it confirms that we've correctly
plumbed through all of the necessary config to make colors
work by default.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-13 23:09:32 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '%(color) omitted without tty' '
|
|
|
|
TERM=vt100 git branch $color_args >actual.raw &&
|
|
|
|
test_decode_color <actual.raw >actual &&
|
|
|
|
test_cmp expect.bare actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success TTY '%(color) present with tty' '
|
2017-10-03 21:39:34 +08:00
|
|
|
test_terminal git branch $color_args >actual.raw &&
|
ref-filter: consult want_color() before emitting colors
When color placeholders like %(color:red) are used in a
ref-filter format, we unconditionally output the colors,
even if the user has asked us for no colors. This usually
isn't a problem when the user is constructing a --format on
the command line, but it means we may do the wrong thing
when the format is fed from a script or alias. For example:
$ git config alias.b 'branch --format=%(color:green)%(refname)'
$ git b --no-color
should probably omit the green color. Likewise, running:
$ git b >branches
should probably also omit the color, just as we would for
all baked-in coloring (and as we recently started to do for
user-specified colors in --pretty formats).
This commit makes both of those cases work by teaching
the ref-filter code to consult want_color() before
outputting any color. The color flag in ref_format defaults
to "-1", which means we'll consult color.ui, which in turn
defaults to the usual isatty() check on stdout. However,
callers like git-branch which support their own color config
(and command-line options) can override that.
The new tests independently cover all three of the callers
of ref-filter (for-each-ref, tag, and branch). Even though
these seem redundant, it confirms that we've correctly
plumbed through all of the necessary config to make colors
work by default.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-13 23:09:32 +08:00
|
|
|
test_decode_color <actual.raw >actual &&
|
|
|
|
test_cmp expect.color actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '--color overrides auto-color' '
|
|
|
|
git branch --color $color_args >actual.raw &&
|
|
|
|
test_decode_color <actual.raw >actual &&
|
|
|
|
test_cmp expect.color actual
|
|
|
|
'
|
|
|
|
|
2020-12-17 09:07:03 +08:00
|
|
|
test_expect_success 'verbose output lists worktree path' '
|
2019-04-29 13:19:44 +08:00
|
|
|
one=$(git rev-parse --short HEAD) &&
|
2020-12-17 09:07:03 +08:00
|
|
|
two=$(git rev-parse --short main) &&
|
2019-04-29 13:19:44 +08:00
|
|
|
cat >expect <<-EOF &&
|
|
|
|
* (HEAD detached from fromtag) $one one
|
|
|
|
ambiguous $one one
|
|
|
|
branch-one $two two
|
|
|
|
+ branch-two $one ($(pwd)/worktree_dir) one
|
2020-10-23 22:00:05 +08:00
|
|
|
main $two two
|
2019-04-29 13:19:44 +08:00
|
|
|
ref-to-branch $two two
|
|
|
|
ref-to-remote $two two
|
|
|
|
EOF
|
|
|
|
git worktree add worktree_dir branch-two &&
|
|
|
|
git branch -vv >actual &&
|
|
|
|
rm -r worktree_dir &&
|
|
|
|
git worktree prune &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2019-04-29 13:19:44 +08:00
|
|
|
'
|
|
|
|
|
2009-02-19 11:34:44 +08:00
|
|
|
test_done
|