Running "git check-ref-format --branch @{-1}" from outside any
repository produces
$ git check-ref-format --branch @{-1}
BUG: environment.c:182: git environment hasn't been setup
This is because the expansion of @{-1} must come from the HEAD reflog,
which involves opening the repository. @{u} and @{push} (which are
more unusual because they typically would not expand to a local
branch) trigger the same assertion.
This has been broken since day one. Before v2.13.0-rc0~48^2
(setup_git_env: avoid blind fall-back to ".git", 2016-10-02), the
breakage was more subtle: Git would read reflogs from ".git" within
the current directory even if it was not a valid repository. Usually
that is harmless because Git is not being run from the root directory
of an invalid repository, but in edge cases such accesses can be
confusing or harmful. Since v2.13.0, the problem is easier to
diagnose because Git aborts with a BUG message.
Erroring out is the right behavior: when asked to interpret a branch
name like "@{-1}", there is no reasonable answer in this context.
But we should print a message saying so instead of an assertion failure.
We do not forbid "check-ref-format --branch" from outside a repository
altogether because it is ok for a script to pre-process branch
arguments without @{...} in such a context. For example, with
pre-2.13 Git, a script that does
branch='master'; # default value
parse_options
branch=$(git check-ref-format --branch "$branch")
to normalize an optional branch name provided by the user would work
both inside a repository (where the user could provide '@{-1}') and
outside (where '@{-1}' should not be accepted).
So disable the "expand @{...}" half of the feature when run outside a
repository, but keep the check of the syntax of a proposed branch
name. This way, when run from outside a repository, "git
check-ref-format --branch @{-1}" will gracefully fail:
$ git check-ref-format --branch @{-1}
fatal: '@{-1}' is not a valid branch name
and "git check-ref-format --branch master" will succeed as before:
$ git check-ref-format --branch master
master
restoring the usual pre-2.13 behavior.
[jn: split out from a larger patch; moved conditional to
strbuf_check_branch_ref instead of its caller; fleshed out commit
message; some style tweaks in tests]
Reported-by: Marko Kungla <marko.kungla@gmail.com>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Loosen restrictions on refspecs by allowing patterns that have a "*"
within a component instead of only as the whole component.
Remove the logic to accept a single "*" as a whole component from
check_refname_format(), and implement an extended form of that logic
in check_refname_component(). Pass the pointer to the flags argument
to the latter, as it has to clear REFNAME_REFSPEC_PATTERN bit when
it sees "*".
Teach check_refname_component() function to allow an asterisk "*"
only when REFNAME_REFSPEC_PATTERN is set in the flags, and drop the
bit after seeing a "*", to ensure that one side of a refspec
contains at most one asterisk.
This will allow us to accept refspecs such as `for/bar*:foo/baz*`.
Any refspec which functioned before shall continue functioning with
the new logic.
Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
We have been using NOT_{MINGW,CYGWIN} test prerequisites long
before Peff invented support for negated prerequisites e.g. !MINGW
and we still add more uses of the former. Convert them to the
latter to avoid confusion.
* jc/not-mingw-cygwin:
test prerequisites: enumerate with commas
test prerequisites: eradicate NOT_FOO
This has been illegal since cbdffe4 (check_ref_format(): tighten
refname rules, 2009-03-21), but we never tested it.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Support for Back when bdccd3c1 (test-lib: allow negation of
prerequisites, 2012-11-14) introduced negated predicates
(e.g. "!MINGW,!CYGWIN"), we already had 5 test files that use
NOT_MINGW (and a few MINGW) as prerequisites.
Let's not add NOT_FOO and rewrite existing ones as !FOO for both
MINGW and CYGWIN.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Optimize check_refname_component using SSE2 on x86_64.
git rev-parse HEAD is a good test-case for this, since it does almost
nothing except parse refs. For one particular repo with about 60k
refs, almost all packed, the timings are:
Look up table: 29 ms
SSE2: 23 ms
This cuts about 20% off of the runtime.
Ondřej Bílka <neleai@seznam.cz> suggested an SSE2 approach to the
substring searches, which netted a speed boost over the SSE4.2 code I
had initially written.
Signed-off-by: David Turner <dturner@twitter.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The test fails for me on NetBSD 6.0.1 and reports:
ok 1 - ref name '' is invalid
ok 2 - ref name '/' is invalid
ok 3 - ref name '/' is invalid with options --allow-onelevel
ok 4 - ref name '/' is invalid with options --normalize
error: bug in the test script: not 2 or 3 parameters to test-expect-success
The alleged bug is in this line:
invalid_ref NOT_MINGW '/' '--allow-onelevel --normalize'
invalid_ref() constructs a test case description using its last argument,
but the shell seems to split it up into two pieces if it contains a
space. Minimal test case:
# on NetBSD with /bin/sh
$ a() { echo $#-$1-$2; }
$ t="x"; a "${t:+$t}"
1-x-
$ t="x y"; a "${t:+$t}"
2-x-y
$ t="x y"; a "${t:+x y}"
1-x y-
# and with bash
$ t="x y"; a "${t:+$t}"
1-x y-
$ t="x y"; a "${t:+x y}"
1-x y-
This may be a bug in the shell, but here's a simple workaround: Construct
the description string first and store it in a variable, and then use
that to call test_expect_success().
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Bash on Windows converts program arguments that look like absolute POSIX
paths to their Windows form, i.e., drive-letter-colon format. For this
reason, those tests in t1402 that check refs that begin with a slash do not
work as expected on Windows: valid_ref tests are doomed to fail, and
invalid_ref tests fail for the wrong reason (that there is a colon rather
than that they begin with a slash).
Skip these tests.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Since much of the infrastructure does not work correctly with
unnormalized refnames, change check_refname_format() to reject them.
Similarly, change "git check-ref-format" to reject unnormalized
refnames by default. But add an option --normalize, which causes "git
check-ref-format" to normalize the refname before checking its format,
and print the normalized refname. This is exactly the behavior of the
old --print option, which is retained but deprecated.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Allowing any refname component to end with ".lock" is looking for
trouble; for example,
$ git br foo.lock/bar
$ git br foo
fatal: Unable to create '[...]/.git/refs/heads/foo.lock': File exists.
Therefore, do not allow any refname component to end with ".lock".
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Change check_ref_format() to take a flags argument that indicates what
is acceptable in the reference name (analogous to "git
check-ref-format"'s "--allow-onelevel" and "--refspec-pattern"). This
is more convenient for callers and also fixes a failure in the test
suite (and likely elsewhere in the code) by enabling "onelevel" and
"refspec-pattern" to be allowed independently of each other.
Also rename check_ref_format() to check_refname_format() to make it
obvious that it deals with refnames rather than references themselves.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Also add tests of the new options. (Actually, one big reason to add
the new options is to make it easy to test check_ref_format(), though
the options should also be useful to other scripts.)
Interpret the result of check_ref_format() based on which types of
refnames are allowed. However, because check_ref_format() can only
return a single value, one test case is still broken. Specifically,
the case "git check-ref-format --onelevel '*'" incorrectly succeeds
because check_ref_format() returns CHECK_REF_FORMAT_ONELEVEL for this
refname even though the refname is also CHECK_REF_FORMAT_WILDCARD.
The type of check that leads to this failure is used elsewhere in
"real" code and could lead to bugs; it will be fixed over the next few
commits.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The new tests reflect the status quo. Soon the rule for "*.lock" in
refname components will be tightened up.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
DEL is an ASCII control character and therefore should not be
permitted in reference names. Add tests for this and other unusual
characters.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When asked if "refs///heads/master" is valid, check-ref-format says "Yes,
it is well formed", and when asked to print canonical form, it shows
"refs/heads/master". This is so that it can be tucked after "$GIT_DIR/"
to form a valid pathname for a loose ref, and we normalize a pathname like
"$GIT_DIR/refs///heads/master" to de-dup the slashes in it.
Similarly, when asked if "/refs/heads/master" is valid, check-ref-format
says "Yes, it is Ok", but the leading slash is not removed when printing,
leading to "$GIT_DIR//refs/heads/master".
Fix it to make sure such leading slashes are removed. Add tests that such
refnames are accepted and normalized correctly.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Breaks in a test assertion's && chain can potentially hide
failures from earlier commands in the chain.
Commands intended to fail should be marked with !, test_must_fail, or
test_might_fail. The examples in this patch do not require that.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
check-ref-format --branch requires access to the repository
to resolve refs like @{-1}.
Noticed by Nguyễn Thái Ngọc Duy.
Cc: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Tolerating empty path components in ref names means each ref does
not have a unique name. This creates difficulty for porcelains
that want to see if two branches are equal. Add a helper associating
to each ref a canonical name.
If a user asks a porcelain to create a ref "refs/heads//master",
the porcelain can run "git check-ref-format --print refs/heads//master"
and only deal with "refs/heads/master" from then on.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The "git check-ref-format" command is a basic command various
porcelains rely on. Test its functionality to make sure it does
not unintentionally change.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>