Commit Graph

11867 Commits

Author SHA1 Message Date
Allan Xavier
aaae0bf787 line-log.c: prevent crash during union of too many ranges
The existing implementation of range_set_union does not correctly
reallocate memory, leading to a heap overflow when it attempts to union
more than 24 separate line ranges.

For struct range_set *out to grow correctly it must have out->nr set to
the current size of the buffer when it is passed to range_set_grow.
However, the existing implementation of range_set_union only updates
out->nr at the end of the function, meaning that it is always zero
before this. This results in range_set_grow never growing the buffer, as
well as some of the union logic itself being incorrect as !out->nr is
always true.

The reason why 24 is the limit is that the first allocation of size 1
ends up allocating a buffer of size 24 (due to the call to alloc_nr in
ALLOC_GROW). This goes some way to explain why this hasn't been
caught before.

Fix the problem by correctly updating out->nr after reallocating the
range_set. As this results in out->nr containing the same value as the
variable o, replace o with out->nr as well.

Finally, add a new test to help prevent the problem reoccurring in the
future. Thanks to Vegard Nossum for writing the test.

Signed-off-by: Allan Xavier <allan.x.xavier@oracle.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-03 11:16:20 -08:00
Jeff King
28e1fb5466 t/perf: add fallback for pre-bin-wrappers versions of git
It's tempting to say:

  ./run v1.0.0 HEAD

to see how we've sped up Git over the years. Unfortunately,
this doesn't quite work because versions of Git prior to
v1.7.0 lack bin-wrappers, so our "run" script doesn't
correctly put them in the PATH.

Worse, it means we silently find whatever other "git" is in
the PATH, and produce test results that have no bearing on
what we asked for.

Let's fallback to the main git directory when bin-wrappers
isn't present. Many modern perf scripts won't run with such
an antique version of Git, of course, but at least those
failures are detected and reported (and you're free to write
a limited perf script that works across many versions).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-03 10:55:27 -08:00
Jeff King
83d4a409d3 t/perf: use $MODERN_GIT for all repo-copying steps
Since 1a0962dee (t/perf: fix regression in testing older
versions of git, 2016-06-22), we point "$MODERN_GIT" to a
copy of git that matches the t/perf script itself, and which
can be used for tasks outside of the actual timings. This is
needed because the setup done by perf scripts keeps moving
forward in time, and may use features that the older
versions of git we are testing do not have.

That commit used $MODERN_GIT to fix a case where we relied
on the relatively recent --git-path option. But if you go
back further still, there are more problems.

Since 7501b5921 (perf: make the tests work in worktrees,
2016-05-13), we use "git -C", but versions of git older than
44e1e4d67 (git: run in a directory given with -C option,
2013-09-09) don't know about "-C". So testing an old version
of git with a new version of t/perf will fail the setup
step.

We can fix this by using $MODERN_GIT during the setup;
there's no need to use the antique version, since it doesn't
affect the timings. Likewise, we'll adjust the "init"
invocation; antique versions of git called this "init-db".

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-03 10:55:26 -08:00
Jonathan Tan
67f2825174 t/perf: export variable used in other blocks
In p0001, a variable was created in a test_expect_success block to be
used in later test_perf blocks, but was not exported. This caused the
variable to not appear in those blocks (this can be verified by writing
'test -n "$commit"' in those blocks), resulting in a slightly different
invocation than what was intended. Export that variable.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-03 10:54:42 -08:00
Matt McCutchen
d56583ded6 fetch-pack: add specific error for fetching an unadvertised object
Enhance filter_refs (which decides whether a request for an unadvertised
object should be sent to the server) to record a new match status on the
"struct ref" when a request is not allowed, and have
report_unmatched_refs check for this status and print a special error
message, "Server does not allow request for unadvertised object".

Signed-off-by: Matt McCutchen <matt@mattmccutchen.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-02 11:12:53 -08:00
Matt McCutchen
e70a65c5d8 fetch_refs_via_pack: call report_unmatched_refs
"git fetch" currently doesn't bother to check that it got all refs it
sought, because the common case of requesting a nonexistent ref triggers
a die() in get_fetch_map.  However, there's at least one case that
slipped through: "git fetch REMOTE SHA1" if the server doesn't allow
requests for unadvertised objects.  Make fetch_refs_via_pack (which is
on the "git fetch" code path) call report_unmatched_refs so that we at
least get an error message in that case.

Signed-off-by: Matt McCutchen <matt@mattmccutchen.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-02 11:12:53 -08:00
Matt McCutchen
e860d96bf8 fetch-pack: move code to report unmatched refs to a function
Prepare to reuse this code in transport.c for "git fetch".

While we're here, internationalize the existing error message.

Signed-off-by: Matt McCutchen <matt@mattmccutchen.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-02 11:12:53 -08:00
Jeff King
fd4692ff70 checkout: restrict @-expansions when finding branch
When we parse "git checkout $NAME", we try to interpret
$NAME as a local branch-name. If it is, then we point HEAD
to that branch. Otherwise, we detach the HEAD at whatever
commit $NAME points to.

We do the interpretation by calling strbuf_branchname(), and
then blindly sticking "refs/heads/" on the front. This leads
to nonsense results when expansions like "@{upstream}" or
"@" point to something besides a local branch. We end up
with a local branch name like "refs/heads/origin/master" or
"refs/heads/HEAD".

Normally this has no user-visible effect because those
branches don't exist, and so we fallback to feeding the
result to get_sha1(), which resolves them correctly.

But as the new test in t3204 shows, there are corner cases
where the effect is observable, and we check out the wrong
local branch rather than detaching to the correct one.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-02 11:05:04 -08:00
Jeff King
7d5c960bf6 strbuf_check_ref_format(): expand only local branches
This function asks strbuf_branchname() to expand any @-marks
in the branchname, and then we blindly stick refs/heads/ in
front of the result. This is obviously nonsense if the
expansion is "HEAD" or a ref in refs/remotes/.

The most obvious end-user effect is that creating or
renaming a branch with an expansion may have confusing
results (e.g., creating refs/heads/origin/master from
"@{upstream}" when the operation should be disallowed).

We can fix this by telling strbuf_branchname() that we are
only interested in local expansions. Any unexpanded bits are
then fed to check_ref_format(), which either disallows them
(in the case of "@{upstream}") or lets them through
("refs/heads/@" is technically valid, if a bit silly).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-02 11:05:04 -08:00
Jeff King
6b145e016a branch: restrict @-expansions when deleting
We use strbuf_branchname() to expand the branch name from
the command line, so you can delete the branch given by
@{-1}, for example.  However, we allow other nonsense like
"@", and we do not respect our "-r" flag (so we may end up
deleting an oddly-named local ref instead of a remote one).

We can fix this by passing the appropriate "allowed" flag to
strbuf_branchname().

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-02 11:05:04 -08:00
Jeff King
a356e8e2a7 t3204: test git-branch @-expansion corner cases
git-branch feeds the branch names from the command line to
strbuf_branchname(), but we do not yet tell that function
which kinds of expansions should be allowed. Let's create a
set of tests that cover both the allowed and disallowed
cases.

That shows off some breakages where we currently create or
delete the wrong ref (and will make sure that we do not
break any cases that _should_ be working when we do add more
restrictions).

Note that we check branch creation and deletion, but do not
bother with renames. Those follow the same code path as
creation.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-02 11:05:04 -08:00
Jeff King
13228c30a6 interpret_branch_name(): handle auto-namelen for @{-1}
The interpret_branch_name() function takes a ptr/len pair
for the name, but you can pass "0" for "namelen", which will
cause it to check the length with strlen().

However, before we do that auto-namelen magic, we call
interpret_nth_prior_checkout(), which gets fed the bogus
"0". This was broken by 8cd4249c4 (interpret_branch_name:
always respect "namelen" parameter, 2014-01-15).  Though to
be fair to that commit, it was broken in the _opposite_
direction before, where we would always treat "name" as a
string even if a length was passed.

You can see the bug with "git log -g @{-1}". That code path
always passes "0", and without this patch it cannot figure
out which branch's reflog to show.

We can fix it by a small reordering of the code.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-02 11:04:57 -08:00
Junio C Hamano
12426e114b diff: do not short-cut CHECK_SIZE_ONLY check in diff_populate_filespec()
Callers of diff_populate_filespec() can choose to ask only for the
size of the blob without grabbing the blob data, and the function,
after running lstat() when the filespec points at a working tree
file, returns by copying the value in size field of the stat
structure into the size field of the filespec when this is the case.

However, this short-cut cannot be taken if the contents from the
path needs to go through convert_to_git(), whose resulting real blob
data may be different from what is in the working tree file.

As "git diff --quiet" compares the .size fields of filespec
structures to skip content comparison, this bug manifests as a
false "there are differences" for a file that needs eol conversion,
for example.

Reported-by: Mike Crowe <mac@mcrowe.com>
Helped-by: Torsten Bögershausen <tboegi@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-02 10:48:06 -08:00
Jeff King
c852bd54bd add--interactive: fix missing file prompt for patch mode with "-i"
When invoked as "git add -i", each menu interactive menu
option prompts the user to select a list of files. This
includes the "patch" option, which gets the list before
starting the hunk-selection loop.

As "git add -p", it behaves differently, and jumps straight
to the hunk selection loop.

Since 0539d5e6d (i18n: add--interactive: mark patch prompt
for translation, 2016-12-14), the "add -i" case mistakenly
jumps to straight to the hunk-selection loop. Prior to that
commit the distinction between the two cases was managed by
the $patch_mode variable. That commit used $patch_mode for
something else, and moved the old meaning to the "$cmd"
variable.  But it forgot to update the $patch_mode check
inside patch_update_cmd() which controls the file-list
behavior.

The simplest fix would be to change that line to check $cmd.
But while we're here, let's use a less obscure name for this
flag: $patch_mode_only, a boolean which tells whether we are
in full-interactive mode or only in patch-mode.

Reported-by: Henrik Grubbström <grubba@grubba.org>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-02 10:10:38 -08:00
Ævar Arnfjörð Bjarmason
c6507484a2 gitweb tests: skip tests when we don't have Time::HiRes
Change the gitweb tests to skip when we can't load the Time::HiRes
module.

Gitweb needs this module to work. It has been in perl core since v5.8,
which is the oldest version we support. However CentOS (and perhaps
some other distributions) carve it into its own non-core-perl package
that's not installed along with /usr/bin/perl by default. Without this
we'll hard fail the gitweb tests when trying to load the module.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-01 14:39:50 -08:00
Ævar Arnfjörð Bjarmason
0b69e4fa0a gitweb tests: change confusing "skip_all" phrasing
Change the phrasing so that instead of saying that the CGI module is
unusable, we say that it's not available.

This came up on the git mailing list in
<4b34e3a0-3da7-d821-2a7f-9a420ac1d3f6@gmail.com> from Jakub Narębski.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-01 14:39:00 -08:00
Christian Couder
fcdbd9540b t1700: add tests for splitIndex.maxPercentChange
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-01 13:24:22 -08:00
Christian Couder
e6a1dd77e1 read-cache: regenerate shared index if necessary
When writing a new split-index and there is a big number of cache
entries in the split-index compared to the shared index, it is a
good idea to regenerate the shared index.

By default when the ratio reaches 20%, we will push back all
the entries from the split-index into a new shared index file
instead of just creating a new split-index file.

The threshold can be configured using the
"splitIndex.maxPercentChange" config variable.

We need to adjust the existing tests in t1700 by setting
"splitIndex.maxPercentChange" to 100 at the beginning of t1700,
as the existing tests are assuming that the shared index is
regenerated only when `git update-index --split-index` is used.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-01 13:24:22 -08:00
Christian Couder
b8923bf611 t1700: add tests for core.splitIndex
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-01 13:24:21 -08:00
Christian Couder
5662176313 t1700: change here document style
This improves test indentation by getting rid of the outdated
here document style.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-01 13:24:21 -08:00
Thomas Gummerer
9e140909f6 stash: allow pathspecs in the no verb form
Now that stash_push is used in the no verb form of stash, allow
specifying the command line for this form as well.  Always use -- to
disambiguate pathspecs from other non-option arguments.

Also make git stash -p an alias for git stash push -p.  This allows
users to use git stash -p <pathspec>.

Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-28 14:21:10 -08:00
Thomas Gummerer
1ada5020b3 stash: use stash_push for no verb form
Now that we have stash_push, which accepts pathspec arguments, use
it instead of stash_save in git stash without any additional verbs.

Previously we allowed git stash -- -message, which is no longer allowed
after this patch.  Messages starting with a hyphen was allowed since
3c2eb80f, ("stash: simplify defaulting to "save" and reject unknown
options").  However it was never the intent to allow that, but rather it
was allowed accidentally.

Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-28 14:21:10 -08:00
Thomas Gummerer
df6bba0937 stash: teach 'push' (and 'create_stash') to honor pathspec
While working on a repository, it's often helpful to stash the changes
of a single or multiple files, and leave others alone.  Unfortunately
git currently offers no such option.  git stash -p can be used to work
around this, but it's often impractical when there are a lot of changes
over multiple files.

Allow 'git stash push' to take pathspec to specify which paths to stash.

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-28 14:21:05 -08:00
Jonathan Tan
8e27391a5f http: attempt updating base URL only if no error
http.c supports HTTP redirects of the form

  http://foo/info/refs?service=git-upload-pack
  -> http://anything
  -> http://bar/info/refs?service=git-upload-pack

(that is to say, as long as the Git part of the path and the query
string is preserved in the final redirect destination, the intermediate
steps can have any URL). However, if one of the intermediate steps
results in an HTTP exception, a confusing "unable to update url base
from redirection" message is printed instead of a Curl error message
with the HTTP exception code.

This was introduced by 2 commits. Commit c93c92f ("http: update base
URLs when we see redirects", 2013-09-28) introduced a best-effort
optimization that required checking if only the "base" part of the URL
differed between the initial request and the final redirect destination,
but it performed the check before any HTTP status checking was done. If
something went wrong, the normal code path was still followed, so this
did not cause any confusing error messages until commit 6628eb4 ("http:
always update the base URL for redirects", 2016-12-06), which taught
http to die if the non-"base" part of the URL differed.

Therefore, teach http to check the HTTP status before attempting to
check if only the "base" part of the URL differed. This commit teaches
http_request_reauth to return early without updating options->base_url
upon an error; the only invoker of this function that passes a non-NULL
"options" is remote-curl.c (through "http_get_strbuf"), which only uses
options->base_url for an informational message in the situations that
this commit cares about (that is, when the return value is not HTTP_OK).

The included test checks that the redirect scheme at the beginning of
this commit message works, and that returning a 502 in the middle of the
redirect scheme produces the correct result. Note that this is different
from the test in commit 6628eb4 ("http: always update the base URL for
redirects", 2016-12-06) in that this commit tests that a Git-shaped URL
(http://.../info/refs?service=git-upload-pack) works, whereas commit
6628eb4 tests that a non-Git-shaped URL
(http://.../info/refs/foo?service=git-upload-pack) does not work (even
though Git is processing that URL) and is an error that is fatal, not
silently swallowed.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-28 11:35:53 -08:00
Junio C Hamano
3e5c63943d Merge branch 'rl/remote-allow-missing-branch-name-merge'
"git remote rm X", when a branch has remote X configured as the
value of its branch.*.remote, tried to remove branch.*.remote and
branch.*.merge and failed if either is unset.

* rl/remote-allow-missing-branch-name-merge:
  remote: ignore failure to remove missing branch.<name>.merge
2017-02-27 13:57:18 -08:00
Junio C Hamano
c13c783c9d Merge branch 'km/delete-ref-reflog-message'
"git update-ref -d" and other operations to delete references did
not leave any entry in HEAD's reflog when the reference being
deleted was the current branch.  This is not a problem in practice
because you do not want to delete the branch you are currently on,
but caused renaming of the current branch to something else not to
be logged in a useful way.

* km/delete-ref-reflog-message:
  branch: record creation of renamed branch in HEAD's log
  rename_ref: replace empty message in HEAD's log
  update-ref: pass reflog message to delete_ref()
  delete_ref: accept a reflog message argument
2017-02-27 13:57:18 -08:00
Junio C Hamano
39b8980bb9 Merge branch 'js/git-path-in-subdir'
The "--git-path", "--git-common-dir", and "--shared-index-path"
options of "git rev-parse" did not produce usable output.  They are
now updated to show the path to the correct file, relative to where
the caller is.

* js/git-path-in-subdir:
  rev-parse: fix several options when running in a subdirectory
  rev-parse tests: add tests executed from a subdirectory
2017-02-27 13:57:17 -08:00
Junio C Hamano
ace83dc26a Merge branch 'jn/remote-helpers-with-git-dir'
"git ls-remote" and "git archive --remote" are designed to work
without being in a directory under Git's control.  However, recent
updates revealed that we randomly look into a directory called
.git/ without actually doing necessary set-up when working in a
repository.  Stop doing so.

* jn/remote-helpers-with-git-dir:
  remote helpers: avoid blind fall-back to ".git" when setting GIT_DIR
  remote: avoid reading $GIT_DIR config in non-repo
2017-02-27 13:57:16 -08:00
Junio C Hamano
036465a248 Merge branch 'jk/grep-no-index-fix'
The code to parse the command line "git grep <patterns>... <rev>
[[--] <pathspec>...]" has been cleaned up, and a handful of bugs
have been fixed (e.g. we used to check "--" if it is a rev).

* jk/grep-no-index-fix:
  grep: treat revs the same for --untracked as for --no-index
  grep: do not diagnose misspelt revs with --no-index
  grep: avoid resolving revision names in --no-index case
  grep: fix "--" rev/pathspec disambiguation
  grep: re-order rev-parsing loop
  grep: do not unnecessarily query repo for "--"
  grep: move thread initialization a little lower
2017-02-27 13:57:16 -08:00
Junio C Hamano
c96bc189b5 Merge branch 'dt/gc-ignore-old-gc-logs'
A "gc.log" file left by a backgrounded "gc --auto" disables further
automatic gc; it has been taught to run at least once a day (by
default) by ignoring a stale "gc.log" file that is too old.

* dt/gc-ignore-old-gc-logs:
  gc: ignore old gc.log files
2017-02-27 13:57:15 -08:00
Junio C Hamano
be6ab596a8 Merge branch 'sf/putty-w-args'
The command line options for ssh invocation needs to be tweaked for
some implementations of SSH (e.g. PuTTY plink wants "-P <port>"
while OpenSSH wants "-p <port>" to specify port to connect to), and
the variant was guessed when GIT_SSH environment variable is used
to specify it.  The logic to guess now applies to the command
specified by the newer GIT_SSH_COMMAND and also core.sshcommand
configuration variable, and comes with an escape hatch for users to
deal with misdetected cases.

* sf/putty-w-args:
  connect.c: stop conflating ssh command names and overrides
  connect: Add the envvar GIT_SSH_VARIANT and ssh.variant config
  git_connect(): factor out SSH variant handling
  connect: rename tortoiseplink and putty variables
  connect: handle putty/plink also in GIT_SSH_COMMAND
2017-02-27 13:57:15 -08:00
Junio C Hamano
098ed50e8a Merge branch 'js/rebase-helper'
"git rebase -i" starts using the recently updated "sequencer" code.

* js/rebase-helper:
  rebase -i: use the rebase--helper builtin
  rebase--helper: add a builtin helper for interactive rebases
2017-02-27 13:57:14 -08:00
Junio C Hamano
a04855bae8 Merge branch 'bw/attr'
The gitattributes machinery is being taught to work better in a
multi-threaded environment.

* bw/attr: (27 commits)
  attr: reformat git_attr_set_direction() function
  attr: push the bare repo check into read_attr()
  attr: store attribute stack in attr_check structure
  attr: tighten const correctness with git_attr and match_attr
  attr: remove maybe-real, maybe-macro from git_attr
  attr: eliminate global check_all_attr array
  attr: use hashmap for attribute dictionary
  attr: change validity check for attribute names to use positive logic
  attr: pass struct attr_check to collect_some_attrs
  attr: retire git_check_attrs() API
  attr: convert git_check_attrs() callers to use the new API
  attr: convert git_all_attrs() to use "struct attr_check"
  attr: (re)introduce git_check_attr() and struct attr_check
  attr: rename function and struct related to checking attributes
  attr.c: outline the future plans by heavily commenting
  Documentation: fix a typo
  attr.c: add push_stack() helper
  attr: support quoting pathname patterns in C style
  attr.c: plug small leak in parse_attr_line()
  attr.c: tighten constness around "git_attr" structure
  ...
2017-02-27 13:57:14 -08:00
Junio C Hamano
fdeb89fdeb Merge branch 'sg/completion'
Clean-up and updates to command line completion (in contrib/).

* sg/completion: (22 commits)
  completion: restore removed line continuating backslash
  completion: cache the path to the repository
  completion: extract repository discovery from __gitdir()
  completion: don't guard git executions with __gitdir()
  completion: consolidate silencing errors from git commands
  completion: don't use __gitdir() for git commands
  completion: respect 'git -C <path>'
  rev-parse: add '--absolute-git-dir' option
  completion: fix completion after 'git -C <path>'
  completion: don't offer commands when 'git --opt' needs an argument
  completion: list short refs from a remote given as a URL
  completion: don't list 'HEAD' when trying refs completion outside of a repo
  completion: list refs from remote when remote's name matches a directory
  completion: respect 'git --git-dir=<path>' when listing remote refs
  completion: fix most spots not respecting 'git --git-dir=<path>'
  completion: ensure that the repository path given on the command line exists
  completion tests: add tests for the __git_refs() helper function
  completion tests: check __gitdir()'s output in the error cases
  completion tests: consolidate getting path of current working directory
  completion tests: make the $cur variable local to the test helper functions
  ...
2017-02-27 13:57:14 -08:00
Junio C Hamano
015fba3834 Merge branch 'lt/pathspec-negative'
The "negative" pathspec feature was somewhat more cumbersome to use
than necessary in that its short-hand used "!" which needed to be
escaped from shells, and it required "exclude from what?" specified.

* lt/pathspec-negative:
  pathspec: don't error out on all-exclusionary pathspec patterns
  pathspec magic: add '^' as alias for '!'
2017-02-27 13:57:13 -08:00
Junio C Hamano
fb75e31761 Merge branch 'cw/tag-reflog-message'
"git tag" did not leave useful message when adding a new entry to
reflog; this was left unnoticed for a long time because refs/tags/*
doesn't keep reflog by default.

* cw/tag-reflog-message:
  tag: generate useful reflog message
2017-02-27 13:57:13 -08:00
Junio C Hamano
b9c2919f9b Merge branch 'jk/alternate-ref-optim'
Optimizes resource usage while enumerating refs from alternate
object store, to help receiving end of "push" that hosts a
repository with many "forks".

* jk/alternate-ref-optim:
  receive-pack: avoid duplicates between our refs and alternates
  receive-pack: treat namespace .have lines like alternates
  receive-pack: fix misleading namespace/.have comment
  receive-pack: use oidset to de-duplicate .have lines
  add oidset API
  fetch-pack: cache results of for_each_alternate_ref
  for_each_alternate_ref: replace transport code with for-each-ref
  for_each_alternate_ref: pass name/oid instead of ref struct
  for_each_alternate_ref: use strbuf for path allocation
  for_each_alternate_ref: stop trimming trailing slashes
  for_each_alternate_ref: handle failure from real_pathdup()
2017-02-27 13:57:13 -08:00
Junio C Hamano
93e8cd8b6e Merge branch 'kn/ref-filter-branch-list'
The code to list branches in "git branch" has been consolidated
with the more generic ref-filter API.

* kn/ref-filter-branch-list: (21 commits)
  ref-filter: resurrect "strip" as a synonym to "lstrip"
  branch: implement '--format' option
  branch: use ref-filter printing APIs
  branch, tag: use porcelain output
  ref-filter: allow porcelain to translate messages in the output
  ref-filter: add an 'rstrip=<N>' option to atoms which deal with refnames
  ref-filter: modify the 'lstrip=<N>' option to work with negative '<N>'
  ref-filter: Do not abruptly die when using the 'lstrip=<N>' option
  ref-filter: rename the 'strip' option to 'lstrip'
  ref-filter: make remote_ref_atom_parser() use refname_atom_parser_internal()
  ref-filter: introduce refname_atom_parser()
  ref-filter: introduce refname_atom_parser_internal()
  ref-filter: make "%(symref)" atom work with the ':short' modifier
  ref-filter: add support for %(upstream:track,nobracket)
  ref-filter: make %(upstream:track) prints "[gone]" for invalid upstreams
  ref-filter: introduce format_ref_array_item()
  ref-filter: move get_head_description() from branch.c
  ref-filter: modify "%(objectname:short)" to take length
  ref-filter: implement %(if:equals=<string>) and %(if:notequals=<string>)
  ref-filter: include reference to 'used_atom' within 'atom_value'
  ...
2017-02-27 13:57:13 -08:00
Junio C Hamano
a411726930 Merge branch 'ps/urlmatch-wildcard'
The <url> part in "http.<url>.<variable>" configuration variable
can now be spelled with '*' that serves as wildcard.
E.g. "http.https://*.example.com.proxy" can be used to specify the
proxy used for https://a.example.com, https://b.example.com, etc.,
i.e. any host in the example.com domain.

* ps/urlmatch-wildcard:
  urlmatch: allow globbing for the URL host part
  urlmatch: include host in urlmatch ranking
  urlmatch: split host and port fields in `struct url_info`
  urlmatch: enable normalization of URLs with globs
  mailmap: add Patrick Steinhardt's work address
2017-02-27 13:57:12 -08:00
Junio C Hamano
74aabf41ce Merge branch 'mm/merge-rename-delete-message'
When "git merge" detects a path that is renamed in one history
while the other history deleted (or modified) it, it now reports
both paths to help the user understand what is going on in the two
histories being merged.

* mm/merge-rename-delete-message:
  merge-recursive: make "CONFLICT (rename/delete)" message show both paths
2017-02-27 13:57:12 -08:00
Junio C Hamano
3ad8b5bf26 Merge branch 'mh/ref-remove-empty-directory'
Deletion of a branch "foo/bar" could remove .git/refs/heads/foo
once there no longer is any other branch whose name begins with
"foo/", but we didn't do so so far.  Now we do.

* mh/ref-remove-empty-directory: (23 commits)
  files_transaction_commit(): clean up empty directories
  try_remove_empty_parents(): teach to remove parents of reflogs, too
  try_remove_empty_parents(): don't trash argument contents
  try_remove_empty_parents(): rename parameter "name" -> "refname"
  delete_ref_loose(): inline function
  delete_ref_loose(): derive loose reference path from lock
  log_ref_write_1(): inline function
  log_ref_setup(): manage the name of the reflog file internally
  log_ref_write_1(): don't depend on logfile argument
  log_ref_setup(): pass the open file descriptor back to the caller
  log_ref_setup(): improve robustness against races
  log_ref_setup(): separate code for create vs non-create
  log_ref_write(): inline function
  rename_tmp_log(): improve error reporting
  rename_tmp_log(): use raceproof_create_file()
  lock_ref_sha1_basic(): use raceproof_create_file()
  lock_ref_sha1_basic(): inline constant
  raceproof_create_file(): new function
  safe_create_leading_directories(): set errno on SCLD_EXISTS
  safe_create_leading_directories_const(): preserve errno
  ...
2017-02-27 13:57:12 -08:00
Junio C Hamano
538569bc8a Merge branch 'jk/delta-chain-limit'
"git repack --depth=<n>" for a long time busted the specified depth
when reusing delta from existing packs.  This has been corrected.

* jk/delta-chain-limit:
  pack-objects: convert recursion to iteration in break_delta_chain()
  pack-objects: enforce --depth limit in reused deltas
2017-02-27 13:57:12 -08:00
Junio C Hamano
1b324988ac Merge branch 'jk/describe-omit-some-refs'
"git describe" and "git name-rev" have been taught to take more
than one refname patterns to restrict the set of refs to base their
naming output on, and also learned to take negative patterns to
name refs not to be used for naming via their "--exclude" option.

* jk/describe-omit-some-refs:
  describe: teach describe negative pattern matches
  describe: teach --match to accept multiple patterns
  name-rev: add support to exclude refs by pattern match
  name-rev: extend --refs to accept multiple patterns
  doc: add documentation for OPT_STRING_LIST
2017-02-27 13:57:11 -08:00
Ævar Arnfjörð Bjarmason
a78d9258dc cvs tests: skip tests that call "cvs commit" when running as root
Change the tests that fail to when we run the test suite as root, due
to calling "cvs commit".

The GNU cvs package has an optional compile-time CVS_BADROOT
flag. When compiled with this flag "cvs commit" will refuse to commit
anything as root. On my Debian box this isn't compiled in[1] in, but
on CentOS it is.

I've run all the t/t*cvs*.sh tests, and these are the only two that
fail. For some reason e.g. t9402-git-cvsserver-refs.sh still works as
root despite doing "cvs commit", I haven't dug into why.

This commit is technically being overzealous, we could do better by
making a mock cvs commit as root and run the tests if that works, but
I don't see any compelling reason to bend over backwards to run these
tests in all cases, just skipping them as root seems good enough.

1. Per: strings /usr/bin/cvs|grep 'is not allowed to commit'
   Using cvs 1.11.23 on CentOS, 1.12.13-MirDebian-18 on Debian.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-27 11:34:53 -08:00
Jeff King
f0252ca23c t6300: avoid creating refs/heads/HEAD
In one test, we use "git checkout --orphan HEAD" to create
an unborn branch. Confusingly, the resulting branch is named
"refs/heads/HEAD". The original probably meant something
like:

  git checkout --orphan orphaned-branch HEAD

Let's just use "orphaned-branch" here to make this less
confusing. Putting HEAD in the second argument is already
implied.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-27 11:33:44 -08:00
Johan Hovold
9d3343961b send-email: only allow one address per body tag
Adding comments after a tag in the body is a common practise (e.g. in
the Linux kernel) and git-send-email has been supporting this for years
by removing any trailing cruft after the address.

After some recent changes, any trailing comment is now instead appended
to the recipient name (with some random white space inserted) resulting
in undesirable noise in the headers, for example:

CC: "# 3 . 3 . x : 1b9508f : sched : Rate-limit newidle" <stable@vger.kernel.org>

Revert to the earlier behaviour of discarding anything after the (first)
address in a tag while parsing the body.

Note that multiple addresses after are still allowed after a command
line switch (and in a CC header field).

Also note that --suppress-cc=self was never honoured when using multiple
addresses in a tag.

Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-27 10:02:55 -08:00
Junio C Hamano
1274a155af config: use git_config_parse_key() in git_config_parse_parameter()
The parsing of one-shot assignments of configuration variables that
come from the command line historically was quite loose and allowed
anything to pass.  It also downcased everything in the variable name,
even a three-level <section>.<subsection>.<variable> name in which
the <subsection> part must be treated in a case sensitive manner.

Existing git_config_parse_key() helper is used to parse the variable
name that comes from the command line, i.e. "git config VAR VAL",
and handles these details correctly.  Replace the strbuf_tolower()
call in git_config_parse_parameter() with a call to it to correct
both issues.  git_config_parse_key() does a bit more things that are
not necessary for the purpose of this codepath (e.g. it allocates a
separate buffer to return the canonicalized variable name because it
takes a "const char *" input), but we are not in a performance-critical
codepath here.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-23 22:03:03 -08:00
Jeff King
94425552f3 ident: do not ignore empty config name/email
When we read user.name and user.email from a config file,
they go into strbufs. When a caller asks ident_default_name()
for the value, we fallback to auto-detecting if the strbuf
is empty.

That means that explicitly setting an empty string in the
config is identical to not setting it at all. This is
potentially confusing, as we usually accept a configured
value as the final value.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-23 12:58:47 -08:00
Jeff King
13b9a24e58 ident: reject all-crud ident name
An ident name consisting of only "crud" characters (like
whitespace or punctuation) is effectively the same as an
empty one, because our strbuf_addstr_without_crud() will
remove those characters.

We reject an empty name when formatting a strict ident, but
don't notice an all-crud one because our check happens
before the crud-removal step.

We could skip past the crud before checking for an empty
name, but let's make it a separate code path, for two
reasons. One is that we can give a more specific error
message. And two is that unlike a blank name, we probably
don't want to kick in the fallback-to-username behavior.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-23 12:47:02 -08:00
Jeff King
862e80a413 ident: handle NULL email when complaining of empty name
If we see an empty name, we complain about and mention the
matching email in the error message (to give it some
context). However, the "email" pointer may be NULL here if
we were planning to fill it in later from ident_default_email().

This was broken by 59f929596 (fmt_ident: refactor strictness
checks, 2016-02-04). Prior to that commit, we would look up
the default name and email before doing any other actions.
So one solution would be to go back to that.

However, we can't just do so blindly. The logic for handling
the "!email" condition has grown since then. In particular,
looking up the default email can die if getpwuid() fails,
but there are other errors that should take precedence.
Commit 734c7789a (ident: check for useConfigOnly before
auto-detection of name/email, 2016-03-30) reordered the
checks so that we prefer the error message for
useConfigOnly.

Instead, we can observe that while the name-handling depends
on "email" being set, the reverse is not true. So we can
simply set up the email variable first.

This does mean that if both are bogus, we'll complain about
the email before the name. But between the two, there is no
reason to prefer one over the other.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-23 12:46:00 -08:00
Ross Lagerwall
20690b2139 remote: ignore failure to remove missing branch.<name>.merge
It is not all too unusual for a branch to use "branch.<name>.remote"
without "branch.<name>.merge".  You may be using the 'push.default'
configuration set to 'current', for example, and do

    $ git checkout -b side colleague/side
    $ git config branch.side.remote colleague

However, "git remote rm" to remove the remote used in such a manner
fails with

    "fatal: could not unset 'branch.<name>.merge'"

because it assumes that a branch that has .remote defined must also
have .merge defined.  Detect the "cannot unset because it is not set
to begin with" case and ignore it.

Signed-off-by: Ross Lagerwall <rosslagerwall@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-21 13:57:41 -08:00
Kyle Meyer
39ee4c6c2f branch: record creation of renamed branch in HEAD's log
Renaming the current branch adds an event to the current branch's log
and to HEAD's log.  However, the logged entries differ.  The entry in
the branch's log represents the entire renaming operation (the old and
new hash are identical), whereas the entry in HEAD's log represents
the deletion only (the new sha1 is null).

Extend replace_each_worktree_head_symref(), whose only caller is
branch_rename(), to take a reflog message argument.  This allows the
creation of the new ref to be recorded in HEAD's log.  As a result,
the renaming event is represented by two entries (a deletion and a
creation entry) in HEAD's log.

It's a bit unfortunate that the branch's log and HEAD's log now
represent the renaming event in different ways.  Given that the
renaming operation is not atomic, the two-entry form is a more
accurate representation of the operation and is more useful for
debugging purposes if a failure occurs between the deletion and
creation events.  It would make sense to move the branch's log to the
two-entry form, but this would involve changes to how the rename is
carried out and to how the update flags and reflogs are processed for
deletions, so it may not be worth the effort.

Based-on-patch-by: Jeff King <peff@peff.net>
Signed-off-by: Kyle Meyer <kyle@kyleam.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-20 22:04:47 -08:00
Kyle Meyer
893dbf5ba1 rename_ref: replace empty message in HEAD's log
When the current branch is renamed, the deletion of the old ref is
recorded in HEAD's log with an empty message.  Now that delete_ref()
accepts a reflog message, provide a more descriptive message by
passing along the log message that is given to rename_ref().

The next step will be to extend HEAD's log to also include the second
part of the rename, the creation of the new branch.

Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Kyle Meyer <kyle@kyleam.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-20 22:04:47 -08:00
Kyle Meyer
de922669ab update-ref: pass reflog message to delete_ref()
Now that delete_ref() accepts a reflog message, pass the user-provided
message to delete_ref() rather than silently dropping it.

Signed-off-by: Kyle Meyer <kyle@kyleam.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-20 22:04:47 -08:00
Thomas Gummerer
6f5ccd4df5 stash: add test for the create command line arguments
Currently there is no test showing the expected behaviour of git stash
create's command line arguments.  Add a test for that to show the
current expected behaviour and to make sure future refactorings don't
break those expectations.

Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-19 23:47:41 -08:00
Thomas Gummerer
f5727e26e4 stash: introduce push verb
Introduce a new git stash push verb in addition to git stash save.  The
push verb is used to transition from the current command line arguments
to a more conventional way, in which the message is given as an argument
to the -m option.

This allows us to have pathspecs at the end of the command line
arguments like other Git commands do, so that the user can say which
subset of paths to stash (and leave others behind).

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-19 23:47:41 -08:00
Johannes Schindelin
098aa86762 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 10:21:54 -08:00
Michael Rappazzo
5de8a549b4 rev-parse tests: add tests executed from a subdirectory
t2027-worktree-list has an incorrect expectation for --git-common-dir
which has been adjusted and marked to expect failure.

Some of the tests added have been marked to expect failure.  These
demonstrate a problem with the way that some options to git rev-parse
behave when executed from a subdirectory of the main worktree.

[jes: fixed incorrect assumption that objects/ lives in the
worktree-specific git-dir (it lives in the common dir instead). Also
adjusted t1700 so that the test case does not *need* to be the last
one in that script.]

Signed-off-by: Michael Rappazzo <rappazzo@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-17 10:21:36 -08:00
Junio C Hamano
5a98255dec Merge branch 'ls/p4-path-encoding'
When "git p4" imports changelist that removes paths, it failed to
convert pathnames when the p4 used encoding different from the one
used on the Git side.  This has been corrected.

* ls/p4-path-encoding:
  git-p4: fix git-p4.pathEncoding for removed files
2017-02-16 14:45:12 -08:00
Junio C Hamano
ca3c2b85d1 Merge branch 'sb/push-options-via-transport'
The push-options given via the "--push-options" option were not
passed through to external remote helpers such as "smart HTTP" that
are invoked via the transport helper.

* sb/push-options-via-transport:
  push options: pass push options to the transport helper
2017-02-15 12:54:19 -08:00
Jeff King
131f3c96d2 grep: treat revs the same for --untracked as for --no-index
git-grep has always disallowed grepping in a tree (as
opposed to the working directory) with both --untracked
and --no-index. But we traditionally did so by first
collecting the revs, and then complaining when any were
provided.

The --no-index option recently learned to detect revs
much earlier. This has two user-visible effects:

  - we don't bother to resolve revision names at all. So
    when there's a rev/path ambiguity, we always choose to
    treat it as a path.

  - likewise, when you do specify a revision without "--",
    the error you get is "no such path" and not "--untracked
    cannot be used with revs".

The rationale for doing this with --no-index is that it is
meant to be used outside a repository, and so parsing revs
at all does not make sense.

This patch gives --untracked the same treatment. While it
_is_ meant to be used in a repository, it is explicitly
about grepping the non-repository contents. Telling the user
"we found a rev, but you are not allowed to use revs" is
not really helpful compared to "we treated your argument as
a path, and could not find it".

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-14 13:59:25 -08:00
Jonathan Nieder
4b0c3c7735 remote helpers: avoid blind fall-back to ".git" when setting GIT_DIR
To push from or fetch to the current repository, remote helpers need
to know what repository that is.  Accordingly, Git sets the GIT_DIR
environment variable to the path to the current repository when
invoking remote helpers.

There is a special case it does not handle: "git ls-remote" and "git
archive --remote" can be run to inspect a remote repository without
being run from any local repository.  GIT_DIR is not useful in this
scenario:

- if we are not in a repository, we don't need to set GIT_DIR to
  override an existing GIT_DIR value from the environment.  If GIT_DIR
  is present then we would be in a repository if it were valid and
  would have called die() if it weren't.

- not setting GIT_DIR may cause a helper to do the usual discovery
  walk to find the repository.  But we know we're not in one, or we
  would have found it ourselves.  So in the worst case it may expend
  a little extra effort to try to find a repository and fail (for
  example, remote-curl would do this to try to find repository-level
  configuration).

So leave GIT_DIR unset in this case.  This makes GIT_DIR easier to
understand for remote helper authors and makes transport code less of
a special case for repository discovery.

Noticed using b1ef400e (setup_git_env: avoid blind fall-back to
".git", 2016-10-20) from 'next':

 $ cd /tmp
 $ git ls-remote https://kernel.googlesource.com/pub/scm/git/git
 fatal: BUG: setup_git_env called without repository

Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-14 13:14:00 -08:00
Jeff King
4539c218c3 remote: avoid reading $GIT_DIR config in non-repo
The "git ls-remote" command can be run outside of a
repository, but needs to look up configured remotes. The
config code is smart enough to handle this case itself, but
we also check the historical "branches" and "remotes" paths
in $GIT_DIR. The git_path() function causes us to blindly
look at ".git/remotes", even if we know we aren't in a git
repository.

For now, this is just an unlikely bug (you probably don't
have such a file if you're not in a repository), but it will
become more obvious once we merge b1ef400ee (setup_git_env:
avoid blind fall-back to ".git", 2016-10-20):

  [now]
  $ git ls-remote
  fatal: No remote configured to list refs from.

  [with b1ef400ee]
  $ git ls-remote
  fatal: BUG: setup_git_env called without repository

We can fix this by skipping these sources entirely when
we're outside of a repository.

The test is a little more complex than the demonstration
above. Rather than detect the correct behavior by parsing
the error message, we can actually set up a case where the
remote name we give is a valid repository, but b1ef400ee
would cause us to die in the configuration step.

This test doesn't fail now, but it future-proofs us for the
b1ef400ee change.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-14 13:13:59 -08:00
Jeff King
73fc7b6b9b grep: do not diagnose misspelt revs with --no-index
If we are using --no-index, then our arguments cannot be
revs in the first place. Not only is it pointless to
diagnose them, but if we are not in a repository, we should
not be trying to resolve any names.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-14 11:26:37 -08:00
Jeff King
d0ffc06933 grep: avoid resolving revision names in --no-index case
We disallow the use of revisions with --no-index, but we
don't actually check and complain until well after we've
parsed the revisions.

This is the cause of a few problems:

 1. We shouldn't be calling get_sha1() at all when we aren't
    in a repository, as it might access the ref or object
    databases. For now, this should generally just return
    failure, but eventually it will become a BUG().

 2. When there's a "--" disambiguator and you're outside a
    repository, we'll complain early with "unable to resolve
    revision". But we can give a much more specific error.

 3. When there isn't a "--" disambiguator, we still do the
    normal rev/path checks. This is silly, as we know we
    cannot have any revs with --no-index. Everything we see
    must be a path.

    Outside of a repository this doesn't matter (since we
    know it won't resolve), but inside one, we may complain
    unnecessarily if a filename happens to also match a
    refname.

This patch skips the get_sha1() call entirely in the
no-index case, and behaves as if it failed (with the
exception of giving a better error message).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-14 11:26:37 -08:00
Jeff King
b5b81136da grep: fix "--" rev/pathspec disambiguation
If we see "git grep pattern rev -- file" then we apply the
usual rev/pathspec disambiguation rules: any "rev" before
the "--" must be a revision, and we do not need to apply the
verify_non_filename() check.

But there are two bugs here:

  1. We keep a seen_dashdash flag to handle this case, but
     we set it in the same left-to-right pass over the
     arguments in which we parse "rev".

     So when we see "rev", we do not yet know that there is
     a "--", and we mistakenly complain if there is a
     matching file.

     We can fix this by making a preliminary pass over the
     arguments to find the "--", and only then checking the rev
     arguments.

  2. If we can't resolve "rev" but there isn't a dashdash,
     that's OK. We treat it like a path, and complain later
     if it doesn't exist.

     But if there _is_ a dashdash, then we know it must be a
     rev, and should treat it as such, complaining if it
     does not resolve. The current code instead ignores it
     and tries to treat it like a path.

This patch fixes both bugs, and tries to comment the parsing
flow a bit better.

It adds tests that cover the two bugs, but also some related
situations (which already worked, but this confirms that our
fixes did not break anything).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-14 11:26:37 -08:00
Jonathan Tan
dca3b5f5ce grep: do not unnecessarily query repo for "--"
When running a command of the form

  git grep --no-index pattern -- path

in the absence of a Git repository, an error message will be printed:

  fatal: BUG: setup_git_env called without repository

This is because "git grep" tries to interpret "--" as a rev. "git grep"
has always tried to first interpret "--" as a rev for at least a few
years, but this issue was upgraded from a pessimization to a bug in
commit 59332d1 ("Resurrect "git grep --no-index"", 2010-02-06), which
calls get_sha1 regardless of whether --no-index was specified. This bug
appeared to be benign until commit b1ef400 ("setup_git_env: avoid blind
fall-back to ".git"", 2016-10-20) when Git was taught to die in this
situation.  (This "git grep" bug appears to be one of the bugs that
commit b1ef400 is meant to flush out.)

Therefore, always interpret "--" as signaling the end of options,
instead of trying to interpret it as a rev first.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-14 11:26:37 -08:00
David Turner
a831c06a2b gc: ignore old gc.log files
A server can end up in a state where there are lots of unreferenced
loose objects (say, because many users are doing a bunch of rebasing
and pushing their rebased branches).  Running "git gc --auto" in
this state would cause a gc.log file to be created, preventing
future auto gcs, causing pack files to pile up.  Since many git
operations are O(n) in the number of pack files, this would lead to
poor performance.

Git should never get itself into a state where it refuses to do any
maintenance, just because at some point some piece of the maintenance
didn't make progress.

Teach Git to ignore gc.log files which are older than (by default)
one day old, which can be tweaked via the gc.logExpiry configuration
variable.  That way, these pack files will get cleaned up, if
necessary, at least once per day.  And operators who find a need for
more-frequent gcs can adjust gc.logExpiry to meet their needs.

There is also some cleanup: a successful manual gc, or a
warning-free auto gc with an old log file, will remove any old
gc.log files.

It might still happen that manual intervention is required
(e.g. because the repo is corrupt), but at the very least it won't
be because Git is too dumb to try again.

Signed-off-by: David Turner <dturner@twosigma.com>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-13 15:19:11 -08:00
Lars Schneider
a8b05162e8 git-p4: fix git-p4.pathEncoding for removed files
In a9e38359e3 we taught git-p4 a way to re-encode path names from what
was used in Perforce to UTF-8. This path re-encoding worked properly for
"added" paths. "Removed" paths were not re-encoded and therefore
different from the "added" paths. Consequently, these files were not
removed in a git-p4 cloned Git repository because the path names did not
match.

Fix this by moving the re-encoding to a place that affects "added" and
"removed" paths. Add a test to demonstrate the issue.

Signed-off-by: Lars Schneider <larsxschneider@gmail.com>
Reviewed-by: Luke Diamand <luke@diamand.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-10 14:33:13 -08:00
Linus Torvalds
859b7f1d0e pathspec: don't error out on all-exclusionary pathspec patterns
Instead of erroring out and telling the user that they should add a
positive pattern that covers everything else, just _do_ that.

For commands where we honor the current cwd by default (ie grep, ls-files
etc), we make that default positive pathspec be the current working
directory.  And for commands that default to the whole project (ie diff,
log, etc), the default positive pathspec is the whole project.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-10 13:19:40 -08:00
Junio C Hamano
e53c7f8731 Merge branch 'jk/log-graph-name-only'
"git log --graph" did not work well with "--name-only", even though
other forms of "diff" output were handled correctly.

* jk/log-graph-name-only:
  diff: print line prefix for --name-only output
2017-02-10 12:52:27 -08:00
Junio C Hamano
dd19bca827 Merge branch 'da/t7800-cleanup'
Test updates.

* da/t7800-cleanup:
  t7800: replace "wc -l" with test_line_count
2017-02-10 12:52:26 -08:00
Junio C Hamano
163d24dc4d Merge branch 'js/difftool-builtin'
A few hot-fixes to C-rewrite of "git difftool".

* js/difftool-builtin:
  t7800: simplify basic usage test
  difftool: fix bug when printing usage
2017-02-10 12:52:25 -08:00
Junio C Hamano
cf36a4dc35 Merge branch 'rs/p5302-create-repositories-before-tests'
Adjust a perf test to new world order where commands that do
require a repository are really strict about having a repository.

* rs/p5302-create-repositories-before-tests:
  p5302: create repositories for index-pack results explicitly
2017-02-10 12:52:25 -08:00
Johannes Schindelin
18633e1a22 rebase -i: use the rebase--helper builtin
Now that the sequencer learned to process a "normal" interactive rebase,
we use it. The original shell script is still used for "non-normal"
interactive rebases, i.e. when --root or --preserve-merges was passed.

Please note that the --root option (via the $squash_onto variable) needs
special handling only for the very first command, hence it is still okay
to use the helper upon continue/skip.

Also please note that the --no-ff setting is volatile, i.e. when the
interactive rebase is interrupted at any stage, there is no record of
it. Therefore, we have to pass it from the shell script to the
rebase--helper.

Note: the test t3404 had to be adjusted because the the error messages
produced by the sequencer comply with our current convention to start with
a lower-case letter.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-09 14:55:40 -08:00
Stefan Beller
438fc68462 push options: pass push options to the transport helper
When using non-builtin protocols relying on a transport helper
(such as http), push options are not propagated to the helper.

The user could ask for push options and a push would seemingly succeed,
but the push options would never be transported to the server,
misleading the users expectation.

Fix this by propagating the push options to the transport helper.

This is only addressing the first issue of
   (1) the helper protocol does not propagate push-option
   (2) the http helper is not prepared to handle push-option

Once we fix (2), the http transport helper can make use of push options
as well, but that happens as a follow up. (1) is a bug fix, whereas (2)
is a feature, which is why we only do (1) here.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-08 15:45:01 -08:00
Cornelius Weig
df8512ede8 tag: generate useful reflog message
When tags are created with `--create-reflog` or with the option
`core.logAllRefUpdates` set to 'always', a reflog is created for them.
So far, the description of reflog entries for tags was empty, making the
reflog hard to understand. For example:
6e3a7b3 refs/tags/test@{0}:

Now, a reflog message is generated when creating a tag, following the
pattern "tag: tagging <short-sha1> (<description>)". If
GIT_REFLOG_ACTION is set, the message becomes "$GIT_REFLOG_ACTION
(<description>)" instead. If the tag references a commit object, the
description is set to the subject line of the commit, followed by its
commit date. For example:
6e3a7b3 refs/tags/test@{0}: tag: tagging 6e3a7b3398 (Git 2.12-rc0, 2017-02-03)

If the tag points to a tree/blob/tag objects, the following static
strings are taken as description:

 - "tree object"
 - "blob object"
 - "other tag object"

Signed-off-by: Cornelius Weig <cornelius.weig@tngtech.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-08 15:43:27 -08:00
Jeff King
63d428e656 receive-pack: avoid duplicates between our refs and alternates
We de-duplicate ".have" refs among themselves, but never
check if they are duplicates of our local refs. It's not
unreasonable that they would be if we are a "--shared" or
"--reference" clone of a similar repository; we'd have all
the same tags.

We can handle this by inserting our local refs into the
oidset, but obviously not suppressing duplicates (since the
refnames are important).

Note that this also switches the order in which we advertise
refs, processing ours first and then any alternates. The
order shouldn't matter (and arguably showing our refs first
makes more sense).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-08 15:39:55 -08:00
Jeff King
f5022b5fed diff: print line prefix for --name-only output
If you run "git log --graph --name-only", the pathnames are
not indented to go along with their matching commits (unlike
all of the other diff formats). We need to output the line
prefix for each item before writing it.

The tests cover both --name-status and --name-only. The
former actually gets this right already, because it builds
on the --raw format functions. It's only --name-only which
uses its own code (and this fix mirrors the code in
diff_flush_raw()).

Note that the tests don't follow our usual style of setting
up the "expect" output inside the test block. This matches
the surrounding style, but more importantly it is easier to
read: we don't have to worry about embedded single-quotes,
and the leading indentation is more obvious.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-08 13:39:57 -08:00
David Aguilar
1ce515f09d t7800: replace "wc -l" with test_line_count
Make t7800 easier to debug by capturing output into temporary files and
using test_line_count to make assertions on those files.

Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-08 13:36:07 -08:00
Junio C Hamano
a83c2d2972 Merge branch 'da/difftool-dir-diff-fix' into da/t7800-cleanup
* da/difftool-dir-diff-fix:
  difftool: fix dir-diff index creation when in a subdirectory
2017-02-08 13:36:03 -08:00
David Aguilar
e66adcadfe t7800: simplify basic usage test
Use "test_line_count" instead of "wc -l", use "git -C" instead of a
subshell, and use test_expect_code when calling difftool.  Ease
debugging by capturing output into temporary files.

Suggested-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-08 13:31:20 -08:00
Junio C Hamano
44a6b6ce17 ref-filter: resurrect "strip" as a synonym to "lstrip"
We forgot that "strip" was introduced at 0571979bd6 ("tag: do not
show ambiguous tag names as "tags/foo"", 2016-01-25) as part of Git
2.8 (and 2.7.1) when we started calling this "lstrip" to make it
easier to explain the new "rstrip" operation.

We shouldn't have renamed the existing one; "lstrip" should have
been a new synonym that means the same thing as "strip".  Scripts
in the wild are surely using the original form already.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-07 11:50:34 -08:00
René Scharfe
c86000c1a7 p5302: create repositories for index-pack results explicitly
Before 7176a314 (index-pack: complain when --stdin is used outside of a
repo) index-pack silently created a non-existing target directory; now
the command refuses to work unless it's used against a valid repository.
That causes p5302 to fail, which relies on the former behavior.  Fix it
by setting up the destinations for its performance tests using git init.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-06 10:55:25 -08:00
David Aguilar
d81345ce09 difftool: fix bug when printing usage
"git difftool -h" reports an error:

	fatal: BUG: setup_git_env called without repository

Defer repository setup so that the help option processing happens before
the repository is initialized.

Add tests to ensure that the basic usage works inside and outside of a
repository.

Signed-off-by: David Aguilar <davvid@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-06 10:13:48 -08:00
SZEDER Gábor
fad9484f0a completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:

  1. The command substitution involves the forking of a subshell,
     which has considerable overhead on some platforms.

  2. There are a few cases, where this command substitution is
     executed more than once during a single completion, which means
     multiple subshells and possibly multiple 'git rev-parse'
     executions.  __gitdir() is invoked twice while completing refs
     for e.g. 'git log', 'git rebase', 'gitk', or while completing
     remote refs for 'git fetch' or 'git push'.

Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:

  1. __git_find_repo_path() stores the path to the repository in a
     variable instead of printing it, so the command substitution
     around the function can be avoided.  Or rather: the command
     substitution should be avoided to make the new value of the
     variable set inside the function visible to the callers.
     (Yes, there is now a command substitution inside
     __git_find_repo_path() around each 'git rev-parse', but that's
     executed only if necessary, and only once per completion, see
     point 2. below.)

  2. $__git_repo_path, the variable holding the path to the
     repository, is declared local in the toplevel completion
     functions __git_main() and __gitk_main().  Thus, once set, the
     path is visible in all completion functions, including all
     subsequent calls to __git_find_repo_path(), meaning that they
     wouldn't have to re-discover the path to the repository.

So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory.  Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.

As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path.  Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:41 -08:00
SZEDER Gábor
beb6ee7163 completion: extract repository discovery from __gitdir()
To prepare for caching the path to the repository in the following
commit, extract the repository discovering part of __gitdir() into the
__git_find_repo_path() helper function, which stores the found path in
the $__git_repo_path variable instead of printing it.  Make __gitdir()
a wrapper around this new function.  Declare $__git_repo_path local in
the toplevel completion functions __git_main() and __gitk_main() to
ensure that it never leaks into the environment and influences
subsequent completions (though this isn't necessary right now, as
__gitdir() is still only executed in subshells, but will matter for
the following commit).

Adjust tests checking __gitdir() or any other completion function
calling __gitdir() to perform those checks in a subshell to prevent
$__git_repo_path from leaking into the test environment.  Otherwise
leave the tests unchanged to demonstrate that this change doesn't
alter __gitdir()'s behavior.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:41 -08:00
SZEDER Gábor
80ac0744b1 completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because

  - like '--git-dir=<path>', it can lead us to a different repository,

  - a few git commands executed in the completion script do care about
    in which directory they are executed, and

  - the command for which we are providing completion might care about
    in which directory it will be executed.

However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable.  Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.

Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.

Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from.  There are only three such
cases:

  - 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
    used for git-aware filename completion, and

  - the 'git ls-tree' used for completing the 'ref:path' notation.

The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account.  It would not hurt them, either, but let's not
induce unnecessary code churn.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:41 -08:00
SZEDER Gábor
a2f5a87626 rev-parse: add '--absolute-git-dir' option
The output of 'git rev-parse --git-dir' can be either a relative or an
absolute path, depending on whether the current working directory is
at the top of the worktree or the .git directory or not, or how the
path to the repository is specified via the '--git-dir=<path>' option
or the $GIT_DIR environment variable.  And if that output is a
relative path, then it is relative to the directory where any 'git
-C <path>' options might have led us.

This doesn't matter at all for regular scripts, because the git
wrapper automatically takes care of changing directories according to
the '-C <path>' options, and the scripts can then simply follow any
path returned by 'git rev-parse --git-dir', even if it's a relative
path.

Our Bash completion script, however, is unique in that it must run
directly in the user's interactive shell environment.  This means that
it's not executed through the git wrapper and would have to take care
of any '-C <path> options on its own, and it can't just change
directories as it pleases.  Consequently, adding support for taking
any '-C <path>' options on the command line into account during
completion turned out to be considerably more difficult, error prone
and required more subshells and git processes when it had to cope with
a relative path to the .git directory.

Help this rather special use case and teach 'git rev-parse' a new
'--absolute-git-dir' option which always outputs a canonicalized
absolute path to the .git directory, regardless of whether the path is
discovered automatically or is specified via $GIT_DIR or 'git
--git-dir=<path>'.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:41 -08:00
SZEDER Gábor
336d694ce4 completion: fix completion after 'git -C <path>'
The main completion function finds the name of the git command by
iterating through all the words on the command line in search for the
first non-option-looking word.  As it is not aware of 'git -C's
mandatory path argument, if the '-C <path>' option is present, 'path'
will be the first such word and it will be mistaken for a git command.
This breaks completion in various ways:

 - If 'path' happens to match one of the commands supported by the
   completion script, then options of that command will be offered.

 - If 'path' doesn't match a supported command and doesn't contain any
   characters not allowed in Bash identifier names, then the
   completion script does basically nothing and Bash in turn falls
   back to filename completion for all subsequent words.

 - Otherwise, if 'path' does contain such an unallowed character, then
   it leads to a more or less ugly error message in the middle of the
   command line.  The standard '/' directory separator is such a
   character, and it happens to trigger one of the uglier errors:

     $ git -C some/path <TAB>sh.exe": declare: `_git_some/path': not a valid identifier
     error: invalid key: alias.some/path

Fix this by skipping 'git -C's mandatory path argument while iterating
over the words on the command line.  Extend the relevant test with
this case and, while at it, with cases that needed similar treatment
in the past ('--git-dir', '-c', '--work-tree' and '--namespace').

Additionally, silence the standard error of the 'declare' builtins
looking for the completion function associated with the git command
and of the 'git config' query for the aliased command.  So if git ever
learns a new option with a mandatory argument in the future, then,
though the completion script will again misbehave, at least the
command line will not be utterly disrupted by those error messages.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:41 -08:00
SZEDER Gábor
91b7ea81e8 completion: list short refs from a remote given as a URL
e832f5c096 (completion: avoid ls-remote in certain scenarios,
2013-05-28) turned a 'git ls-remote <remote>' query into a 'git
for-each-ref refs/remotes/<remote>/' to improve responsiveness of
remote refs completion by avoiding potential network communication.
However, it inadvertently made impossible to complete short refs from
a remote given as a URL, e.g. 'git fetch git://server.com/repo.git
<TAB>', because there is, of course, no such thing as
'refs/remotes/git://server.com/repo.git'.

Since the previous commit we tell apart configured remotes, i.e. those
that can have a hierarchy under 'refs/remotes/', from others that
don't, including remotes given as URL, so we know when we can't use
the faster 'git for-each-ref'-based approach.

Resurrect the old, pre-e832f5c09680 'git ls-remote'-based code for the
latter case to support listing short refs from remotes given as a URL.
The code is slightly updated from the original to

  - take into account the path to the repository given on the command
    line (if any), and
  - omit 'ORIG_HEAD' from the query, as 'git ls-remote' will never
    list it anyway.

When the remote given to __git_refs() doesn't exist, then it will be
handled by this resurrected 'git ls-remote' query.  This code path
doesn't list 'HEAD' unconditionally, which has the nice side effect of
fixing two more expected test failures.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:40 -08:00
SZEDER Gábor
62a1b73216 completion: don't list 'HEAD' when trying refs completion outside of a repo
When refs completion is attempted while not in a git repository, the
completion script offers 'HEAD' erroneously.

Check early in __git_refs() that there is either a repository or a
remote to work on, and return early if neither is given.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:40 -08:00
SZEDER Gábor
69a775963b completion: list refs from remote when remote's name matches a directory
If the remote given to __git_refs() happens to match both the name of
a configured remote and the name of a directory in the current working
directory, then that directory is assumed to be a git repository, and
listing refs from that directory will be attempted.  This is wrong,
because in such a situation git commands (e.g. 'git fetch|pull|push
<remote>' whom these refs will eventually be passed to) give
precedence to the configured remote.  Therefore, __git_refs() should
list refs from the configured remote as well.

Add the helper function __git_is_configured_remote() that checks
whether its argument matches the name of a configured remote.  Use
this helper to decide how to handle the remote passed to __git_refs().

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:40 -08:00
SZEDER Gábor
5c12f642df completion: respect 'git --git-dir=<path>' when listing remote refs
In __git_refs() the git commands listing refs, both short and full,
from a given remote repository are run without giving them the path to
the git repository which might have been specified on the command line
via 'git --git-dir=<path>'.  This is bad, those git commands should
access the 'refs/remotes/<remote>/' hierarchy or the remote and
credentials configuration in that specified repository.

Use the __gitdir() helper only to find the path to the .git directory
and pass the resulting path to the 'git ls-remote' and 'for-each-ref'
executions that list remote refs.  While modifying that 'for-each-ref'
line, remove the superfluous disambiguating doubledash.

Don't use __gitdir() to check that the given remote is on the file
system: basically it performs only a single if statement for us at the
considerable cost of fork()ing a subshell for a command substitution.
We are better off to perform all the necessary checks of the remote in
__git_refs().

Though __git_refs() was the last remaining callsite that passed a
remote to __gitdir(), don't delete __gitdir()'s remote-handling part
yet, just in case some users' custom completion scriptlets depend on
it.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:40 -08:00
SZEDER Gábor
a2f03b0ec8 completion: ensure that the repository path given on the command line exists
The __gitdir() helper function prints the path to the git repository
to its stdout or stays silent and returns with error when it can't
find a repository or when the repository given via $GIT_DIR doesn't
exist.

This is not the case, however, when the path in $__git_dir, i.e. the
path to the repository specified on the command line via 'git
--git-dir=<path>', doesn't exist: __gitdir() still outputs it as if it
were a real existing repository, making some completion functions
believe that they operate on an existing repository.

Check that the path in $__git_dir exists and return with error without
printing anything to stdout if it doesn't.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:40 -08:00
SZEDER Gábor
fb9cd42042 completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.

  - short and full refs,
  - from a local or from a remote repository,
  - remote specified via path, name or URL,
  - with or without a repository specified on the command line,
  - non-existing remote,
  - unique remote branches for 'git checkout's tracking DWIMery,
  - not in a git repository, and
  - interesting combinations of the above.

Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:

  - ignoring the repository specified on the command line (2 tests),
  - listing refs from the wrong place when the name of a configured
    remote happens to match a directory,
  - listing only 'HEAD' but no short refs from a remote given as URL,
  - listing 'HEAD' even from non-existing remotes (2 tests), and
  - listing 'HEAD' when not in a repository.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:40 -08:00
SZEDER Gábor
8f0fa85d4d completion tests: check __gitdir()'s output in the error cases
The __gitdir() helper function shouldn't output anything if not in a
git repository.  The relevant tests only checked its error code, so
extend them to ensure that there's no output.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:40 -08:00
SZEDER Gábor
f611440811 completion tests: consolidate getting path of current working directory
Some tests of the __gitdir() helper function use the $TRASH_DIRECTORY
variable in direct path comparisons.  In general this should be
avoided, because it might contain symbolic links.  There happens to be
no issues with this here, however, because those tests use
$TRASH_DIRECTORY both for specifying the expected result and for
specifying input which in turn is just 'echo'ed verbatim.

Other __gitdir() tests ask for the path of the trash directory by
running $(pwd -P) in each test, sometimes even twice in a single test.

Run $(pwd) only once at the beginning of the test script to store the
path of the trash directory in a variable, and use that variable in
all __gitdir() tests.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:40 -08:00
SZEDER Gábor
eac90623bd completion tests: make the $cur variable local to the test helper functions
The test helper functions test_gitcomp() and test_gitcomp_nl() leak
the $cur variable into the test environment.  Since this variable has
a special role in the Bash completion script (it holds the word
currently being completed) it influences the behavior of most
completion functions and thus this leakage could interfere with
subsequent tests.  Although there are no such issues in the current
tests, early versions of the new tests that will be added later in
this series suffered because of this.

It's better to play safe and declare $cur local in those test helper
functions.  'local' is bashism, of course, but the tests of the Bash
completion script are run under Bash anyway, and there are already
other variables declared local in this test script.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:39 -08:00
SZEDER Gábor
e5edbef48d completion tests: don't add test cruft to the test repository
While preparing commits, three tests added newly created files to the
index using 'git add .', which added not only the files in question
but leftover test cruft from previous tests like the files 'expected'
and 'actual' as well.  Luckily, this had no effect on the tests'
correctness.

Add only the files we are actually interested in.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 22:18:39 -08:00
Junio C Hamano
fafca0f72a Merge branch 'cw/log-updates-for-all-refs-really'
The "core.logAllRefUpdates" that used to be boolean has been
enhanced to take 'always' as well, to record ref updates to refs
other than the ones that are expected to be updated (i.e. branches,
remote-tracking branches and notes).

* cw/log-updates-for-all-refs-really:
  doc: add note about ignoring '--no-create-reflog'
  update-ref: add test cases for bare repository
  refs: add option core.logAllRefUpdates = always
  config: add markup to core.logAllRefUpdates doc
2017-02-03 11:25:19 -08:00
Junio C Hamano
ecc486b1f8 Merge branch 'js/re-running-failed-tests'
"make -C t failed" will now run only the tests that failed in the
previous run.  This is usable only when prove is not use, and gives
a useless error message when run after "make clean", but otherwise
is serviceable.

* js/re-running-failed-tests:
  t/Makefile: add a rule to re-run previously-failed tests
2017-02-03 11:25:19 -08:00
Junio C Hamano
4ba6bb2d17 Merge branch 'sb/submodule-update-initial-runs-custom-script'
The user can specify a custom update method that is run when
"submodule update" updates an already checked out submodule.  This
was ignored when checking the submodule out for the first time and
we instead always just checked out the commit that is bound to the
path in the superproject's index.

* sb/submodule-update-initial-runs-custom-script:
  submodule update: run custom update script for initial populating as well
2017-02-03 11:25:19 -08:00
Junio C Hamano
5348021c67 Merge branch 'sb/submodule-recursive-absorb'
When a submodule "A", which has another submodule "B" nested within
it, is "absorbed" into the top-level superproject, the inner
submodule "B" used to be left in a strange state.  The logic to
adjust the .git pointers in these submodules has been corrected.

* sb/submodule-recursive-absorb:
  submodule absorbing: fix worktree/gitdir pointers recursively for non-moves
  cache.h: expose the dying procedure for reading gitlinks
  setup: add gentle version of resolve_git_dir
2017-02-03 11:25:18 -08:00
Junio C Hamano
2243d229f7 Merge branch 'sb/unpack-trees-super-prefix'
"git read-tree" and its underlying unpack_trees() machinery learned
to report problematic paths prefixed with the --super-prefix option.

* sb/unpack-trees-super-prefix:
  unpack-trees: support super-prefix option
  t1001: modernize style
  t1000: modernize style
  read-tree: use OPT_BOOL instead of OPT_SET_INT
2017-02-03 11:25:18 -08:00
Junio C Hamano
85279e8649 Merge branch 'nd/log-graph-configurable-colors'
Some people feel the default set of colors used by "git log --graph"
rather limiting.  A mechanism to customize the set of colors has
been introduced.

* nd/log-graph-configurable-colors:
  document behavior of empty color name
  color_parse_mem: allow empty color spec
  log --graph: customize the graph lines with config log.graphColors
  color.c: trim leading spaces in color_parse_mem()
  color.c: fix color_parse_mem() with value_len == 0
2017-02-02 13:36:58 -08:00
Junio C Hamano
f1fac407f5 Merge branch 'mm/reset-facl-before-umask-test'
Test tweaks for those who have default ACL in their git source tree
that interfere with the umask test.

* mm/reset-facl-before-umask-test:
  t0001: don't let a default ACL interfere with the umask test
2017-02-02 13:36:56 -08:00
Junio C Hamano
d008809bb5 Merge branch 'js/unzip-in-usr-bin-workaround'
Test tweak for FreeBSD where /usr/bin/unzip is unsuitable to run
our tests but /usr/local/bin/unzip is usable.

* js/unzip-in-usr-bin-workaround:
  test-lib: on FreeBSD, look for unzip(1) in /usr/local/bin/
2017-02-02 13:36:55 -08:00
Junio C Hamano
93d2387718 Merge branch 'js/status-pre-rebase-i'
After starting "git rebase -i", which first opens the user's editor
to edit the series of patches to apply, but before saving the
contents of that file, "git status" failed to show the current
state (i.e. you are in an interactive rebase session, but you have
applied no steps yet) correctly.

* js/status-pre-rebase-i:
  status: be prepared for not-yet-started interactive rebase
2017-02-02 13:36:54 -08:00
Junio C Hamano
1e6a89323b Merge branch 'sb/submodule-add-force'
"git submodule add" used to be confused and refused to add a
locally created repository; users can now use "--force" option
to add them.

* sb/submodule-add-force:
  submodule add: extend force flag to add existing repos
2017-02-02 13:36:54 -08:00
Nguyễn Thái Ngọc Duy
860a74d9d9 attr: support quoting pathname patterns in C style
Full pattern must be quoted. So 'pat"t"ern attr' will give exactly
'pat"t"ern', not 'pattern'. Also clarify that leading whitespaces are
not part of the pattern and document comment syntax.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-01 13:46:52 -08:00
Patrick Steinhardt
a272b9e70a urlmatch: allow globbing for the URL host part
The URL matching function computes for two URLs whether they match not.
The match is performed by splitting up the URL into different parts and
then doing an exact comparison with the to-be-matched URL.

The main user of `urlmatch` is the configuration subsystem. It allows to
set certain configurations based on the URL which is being connected to
via keys like `http.<url>.*`. A common use case for this is to set
proxies for only some remotes which match the given URL. Unfortunately,
having exact matches for all parts of the URL can become quite tedious
in some setups. Imagine for example a corporate network where there are
dozens or even hundreds of subdomains, which would have to be configured
individually.

Allow users to write an asterisk '*' in place of any 'host' or
'subdomain' label as part of the host name.  For example,
"http.https://*.example.com.proxy" sets "http.proxy" for all direct
subdomains of "https://example.com", e.g. "https://foo.example.com", but
not "https://foo.bar.example.com".

Signed-off-by: Patrick Steinhardt <patrick.steinhardt@elego.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-01 13:22:50 -08:00
Patrick Steinhardt
af99049ca9 urlmatch: include host in urlmatch ranking
In order to be able to rank positive matches by `urlmatch`, we inspect
the path length and user part to decide whether a match is better than
another match. As all other parts are matched exactly between both URLs,
this is the correct thing to do right now.

In the future, though, we want to introduce wild cards for the domain
part. When doing this, it does not make sense anymore to only compare
the path lengths. Instead, we also want to compare the domain lengths to
determine which of both URLs matches the host part more closely.

Signed-off-by: Patrick Steinhardt <patrick.steinhardt@elego.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-01 13:22:46 -08:00
Segev Finer
dd33e07766 connect: Add the envvar GIT_SSH_VARIANT and ssh.variant config
This environment variable and configuration value allow to
override the autodetection of plink/tortoiseplink in case that
Git gets it wrong.

[jes: wrapped overly-long lines, factored out and changed
get_ssh_variant() to handle_ssh_variant() to accomodate the
change from the putty/tortoiseplink variables to
port_option/needs_batch, adjusted the documentation, free()d
value obtained from the config.]

Signed-off-by: Segev Finer <segev208@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-01 10:57:53 -08:00
Jeff King
55cccf4bb3 color_parse_mem: allow empty color spec
Prior to c2f41bf52 (color.c: fix color_parse_mem() with
value_len == 0, 2017-01-19), the empty string was
interpreted as a color "reset". This was an accidental
outcome, and that commit turned it into an error.

However, scripts may pass the empty string as a default
value to "git config --get-color" to disable color when the
value is not defined. The git-add--interactive script does
this. As a result, the script is unusable since c2f41bf52
unless you have color.diff.plain defined (if it is defined,
then we don't parse the empty default at all).

Our test scripts didn't notice the recent breakage because
they run without a terminal, and thus without color. They
never hit this code path at all. And nobody noticed the
original buggy "reset" behavior, because it was effectively
a noop.

Let's fix the code to have an empty color name produce an
empty sequence of color codes. The tests need a few fixups:

  - we'll add a new test in t4026 to cover this case. But
    note that we need to tweak the color() helper. While
    we're there, let's factor out the literal ANSI ESC
    character. Otherwise it makes the diff quite hard to
    read.

  - we'll add a basic sanity-check in t4026 that "git add
    -p" works at all when color is enabled. That would have
    caught this bug, as well as any others that are specific
    to the color code paths.

  - 73c727d69 (log --graph: customize the graph lines with
    config log.graphColors, 2017-01-19) added a test to
    t4202 that checks some "invalid" graph color config.
    Since ",, blue" before yielded only "blue" as valid, and
    now yields "empty, empty, blue", we don't match the
    expected output.

    One way to fix this would be to change the expectation
    to the empty color strings. But that makes the test much
    less interesting, since we show only two graph lines,
    both of which would be colorless.

    Since the empty-string case is now covered by t4026,
    let's remove them entirely here. They're just in the way
    of the primary thing the test is supposed to be
    checking.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-31 21:02:04 -08:00
Junio C Hamano
14beee0d0d Merge branch 'jk/grep-e-could-be-extended-beyond-posix' into maint
Tighten a test to avoid mistaking an extended ERE regexp engine as
a PRE regexp engine.

* jk/grep-e-could-be-extended-beyond-posix:
  t7810: avoid assumption about invalid regex syntax
2017-01-31 13:32:09 -08:00
Junio C Hamano
f5f55a1046 Merge branch 'km/branch-get-push-while-detached' into maint
"git <cmd> @{push}" on a detached HEAD used to segfault; it has
been corrected to error out with a message.

* km/branch-get-push-while-detached:
  branch_get_push: do not segfault when HEAD is detached
2017-01-31 13:32:08 -08:00
Junio C Hamano
5fbb42a21e Merge branch 'jk/blame-fixes' into maint
"git blame --porcelain" misidentified the "previous" <commit, path>
pair (aka "source") when contents came from two or more files.

* jk/blame-fixes:
  blame: output porcelain "previous" header for each file
  blame: handle --no-abbrev
  blame: fix alignment with --abbrev=40
2017-01-31 13:32:07 -08:00
Junio C Hamano
b1e4e1782f Merge branch 'jk/archive-zip-userdiff-config' into maint
"git archive" did not read the standard configuration files, and
failed to notice a file that is marked as binary via the userdiff
driver configuration.

* jk/archive-zip-userdiff-config:
  archive-zip: load userdiff config
2017-01-31 13:32:07 -08:00
Junio C Hamano
81037171a5 Merge branch 'dt/disable-bitmap-in-auto-gc' into maint
It is natural that "git gc --auto" may not attempt to pack
everything into a single pack, and there is no point in warning
when the user has configured the system to use the pack bitmap,
leading to disabling further "gc".

* dt/disable-bitmap-in-auto-gc:
  repack: die on incremental + write-bitmap-index
  auto gc: don't write bitmaps for incremental repacks
2017-01-31 13:32:06 -08:00
Junio C Hamano
867ce0416c Merge branch 'mh/fast-import-notes-fix-new' into maint
"git fast-import" sometimes mishandled while rebalancing notes
tree, which has been fixed.

* mh/fast-import-notes-fix-new:
  fast-import: properly fanout notes when tree is imported
2017-01-31 13:32:05 -08:00
Junio C Hamano
bdc370a5c1 Merge branch 'jc/compression-config' into maint
Compression setting for producing packfiles were spread across
three codepaths, one of which did not honor any configuration.
Unify these so that all of them honor core.compression and
pack.compression variables the same way.

* jc/compression-config:
  compression: unify pack.compression configuration parsing
2017-01-31 13:32:05 -08:00
Junio C Hamano
4ba6197887 Merge branch 'jk/fsck-connectivity-check-fix'
"git fsck --connectivity-check" was not working at all.

* jk/fsck-connectivity-check-fix:
  fsck: lazily load types under --connectivity-only
  fsck: move typename() printing to its own function
  t1450: use "mv -f" within loose object directory
  fsck: check HAS_OBJ more consistently
  fsck: do not fallback "git fsck <bogus>" to "git fsck"
  fsck: tighten error-checks of "git fsck <head>"
  fsck: prepare dummy objects for --connectivity-check
  fsck: report trees as dangling
  t1450: clean up sub-objects in duplicate-entry test
2017-01-31 13:15:01 -08:00
Junio C Hamano
b7786bb4b0 Merge branch 'js/difftool-builtin'
Rewrite a scripted porcelain "git difftool" in C.

* js/difftool-builtin:
  difftool: hack around -Wzero-length-format warning
  difftool: retire the scripted version
  difftool: implement the functionality in the builtin
  difftool: add a skeleton for the upcoming builtin
2017-01-31 13:15:00 -08:00
Junio C Hamano
6ad8b8e98f Merge branch 'rs/qsort-s'
A few codepaths had to rely on a global variable when sorting
elements of an array because sort(3) API does not allow extra data
to be passed to the comparison function.  Use qsort_s() when
natively available, and a fallback implementation of it when not,
to eliminate the need, which is a prerequisite for making the
codepath reentrant.

* rs/qsort-s:
  ref-filter: use QSORT_S in ref_array_sort()
  string-list: use QSORT_S in string_list_sort()
  perf: add basic sort performance test
  add QSORT_S
  compat: add qsort_s()
2017-01-31 13:15:00 -08:00
Junio C Hamano
a49260b17d Merge branch 'vp/show-ref-verify-head'
"git show-ref HEAD" used with "--verify" because the user is not
interested in seeing refs/remotes/origin/HEAD, and used with
"--head" because the user does not want HEAD to be filtered out,
i.e. "git show-ref --head --verify HEAD", did not work as expected.

* vp/show-ref-verify-head:
  show-ref: remove a stale comment
  show-ref: remove dead `if (verify)' check
  show-ref: detect dangling refs under --verify as well
  show-ref: move --quiet handling into show_one()
  show-ref: allow -d to work with --verify
  show-ref: accept HEAD with --verify
2017-01-31 13:14:59 -08:00
Junio C Hamano
fe575f0653 Merge branch 'js/remote-rename-with-half-configured-remote'
With anticipatory tweaking for remotes defined in ~/.gitconfig
(e.g. "remote.origin.prune" set to true, even though there may or
may not actually be "origin" remote defined in a particular Git
repository), "git remote rename" and other commands misinterpreted
and behaved as if such a non-existing remote actually existed.

* js/remote-rename-with-half-configured-remote:
  remote rename: more carefully determine whether a remote is configured
  remote rename: demonstrate a bogus "remote exists" bug
2017-01-31 13:14:59 -08:00
Junio C Hamano
237bdd9ddb Merge branch 'st/verify-tag'
"git tag" and "git verify-tag" learned to put GPG verification
status in their "--format=<placeholders>" output format.

* st/verify-tag:
  t/t7004-tag: Add --format specifier tests
  t/t7030-verify-tag: Add --format specifier tests
  builtin/tag: add --format argument for tag -v
  builtin/verify-tag: add --format to verify-tag
  ref-filter: add function to print single ref_array_item
  gpg-interface, tag: add GPG_VERIFY_OMIT_STATUS flag
2017-01-31 13:14:58 -08:00
Junio C Hamano
307de75c48 Merge branch 'js/sequencer-i-countdown-3'
The sequencer machinery has been further enhanced so that a later
set of patches can start using it to reimplement "rebase -i".

* js/sequencer-i-countdown-3: (38 commits)
  sequencer (rebase -i): write out the final message
  sequencer (rebase -i): write the progress into files
  sequencer (rebase -i): show the progress
  sequencer (rebase -i): suggest --edit-todo upon unknown command
  sequencer (rebase -i): show only failed cherry-picks' output
  sequencer (rebase -i): show only failed `git commit`'s output
  sequencer: use run_command() directly
  sequencer: update reading author-script
  sequencer (rebase -i): differentiate between comments and 'noop'
  sequencer (rebase -i): implement the 'drop' command
  sequencer (rebase -i): allow rescheduling commands
  sequencer (rebase -i): respect strategy/strategy_opts settings
  sequencer (rebase -i): respect the rebase.autostash setting
  sequencer (rebase -i): run the post-rewrite hook, if needed
  sequencer (rebase -i): record interrupted commits in rewritten, too
  sequencer (rebase -i): copy commit notes at end
  sequencer (rebase -i): set the reflog message consistently
  sequencer (rebase -i): refactor setting the reflog message
  sequencer (rebase -i): allow fast-forwarding for edit/reword
  sequencer (rebase -i): implement the 'reword' command
  ...
2017-01-31 13:14:58 -08:00
Junio C Hamano
42ace93e41 Merge branch 'jk/loose-object-fsck'
"git fsck" inspects loose objects more carefully now.

* jk/loose-object-fsck:
  fsck: detect trailing garbage in all object types
  fsck: parse loose object paths directly
  sha1_file: add read_loose_object() function
  t1450: test fsck of packed objects
  sha1_file: fix error message for alternate objects
  t1450: refactor loose-object removal
2017-01-31 13:14:57 -08:00
Junio C Hamano
792e22e3fd Merge branch 'bw/push-submodule-only'
"git submodule push" learned "--recurse-submodules=only option to
push submodules out without pushing the top-level superproject.

* bw/push-submodule-only:
  push: add option to push only submodules
  submodules: add RECURSE_SUBMODULES_ONLY value
  transport: reformat flag #defines to be more readable
2017-01-31 13:14:56 -08:00
Karthik Nayak
3d9e4ce3eb branch: implement '--format' option
Implement the '--format' option provided by 'ref-filter'. This lets the
user list branches as per desired format similar to the implementation
in 'git for-each-ref'.

Add tests and documentation for the same.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-31 12:43:04 -08:00
Karthik Nayak
949af0684c branch: use ref-filter printing APIs
Port branch.c to use ref-filter APIs for printing. This clears out
most of the code used in branch.c for printing and replaces them with
calls made to the ref-filter library.

Introduce build_format() which gets the format required for printing
of refs. Make amendments to print_ref_list() to reflect these changes.

The strings included in build_format() may not be safely quoted for
inclusion (i.e. it might contain '%' which needs to be escaped with an
additional '%'). Introduce quote_literal_for_format() as a helper
function which takes a string and returns a version of the string that
is safely quoted to be used in the for-each-ref format which is built
in build_format().

Change calc_maxwidth() to also account for the length of HEAD ref, by
calling ref-filter:get_head_discription().

Also change the test in t6040 to reflect the changes.

Before this patch, all cross-prefix symrefs weren't shortened. Since
we're using ref-filter APIs, we shorten all symrefs by default. We also
allow the user to change the format if needed with the introduction of
the '--format' option in the next patch.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Jeff King <peff@peff.net>
Helped-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-31 12:43:04 -08:00
Karthik Nayak
1a34728e6b ref-filter: add an 'rstrip=<N>' option to atoms which deal with refnames
Complimenting the existing 'lstrip=<N>' option, add an 'rstrip=<N>'
option which strips `<N>` slash-separated path components from the end
of the refname (e.g., `%(refname:rstrip=2)` turns `refs/tags/foo` into
`refs`).

Signed-off-by: Karthik Nayak <Karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-31 12:42:33 -08:00
Karthik Nayak
1a0ca5e358 ref-filter: modify the 'lstrip=<N>' option to work with negative '<N>'
Currently the 'lstrip=<N>' option only takes a positive value '<N>'
and strips '<N>' slash-separated path components from the left. Modify
the 'lstrip' option to also take a negative number '<N>' which would
strip from the left as necessary and _leave_ behind only 'N'
slash-separated path components from the right-most end.

For e.g. %(refname:lstrip=-1) would make 'foo/goo/abc' into 'abc'.

Add documentation and tests for the same.

Signed-off-by: Karthik Nayak <Karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-31 12:38:59 -08:00
Cornelius Weig
b1421a43d5 update-ref: add test cases for bare repository
The default behavior of update-ref to create reflogs differs in
repositories with worktree and bare ones. The existing tests cover only
the behavior of repositories with worktree.

This commit adds tests that assert the correct behavior in bare
repositories for update-ref. Two cases are covered:

 - If core.logAllRefUpdates is not set, no reflogs should be created
 - If core.logAllRefUpdates is true, reflogs should be created

Signed-off-by: Cornelius Weig <cornelius.weig@tngtech.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-31 10:01:24 -08:00
Cornelius Weig
341fb28621 refs: add option core.logAllRefUpdates = always
When core.logallrefupdates is true, we only create a new reflog for refs
that are under certain well-known hierarchies. The reason is that we
know that some hierarchies (like refs/tags) are not meant to change, and
that unknown hierarchies might not want reflogs at all (e.g., a
hypothetical refs/foo might be meant to change often and drop old
history immediately).

However, sometimes it is useful to override this decision and simply log
for all refs, because the safety and audit trail is more important than
the performance implications of keeping the log around.

This patch introduces a new "always" mode for the core.logallrefupdates
option which will log updates to everything under refs/, regardless
where in the hierarchy it is (we still will not log things like
ORIG_HEAD and FETCH_HEAD, which are known to be transient).

Based-on-patch-by: Jeff King <peff@peff.net>
Signed-off-by: Cornelius Weig <cornelius.weig@tngtech.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-31 10:01:24 -08:00
Matt McCutchen
b26d87f2da merge-recursive: make "CONFLICT (rename/delete)" message show both paths
The current message printed by "git merge-recursive" for a rename/delete
conflict is like this:

CONFLICT (rename/delete): new-path deleted in HEAD and renamed in
other-branch. Version other-branch of new-path left in tree.

To be more helpful, the message should show both paths of the rename and
state that the deletion occurred at the old path, not the new path.  So
change the message to the following format:

CONFLICT (rename/delete): old-path deleted in HEAD and renamed to
new-path in other-branch. Version other-branch of new-path left in tree.

Since this doubles the number of cases in handle_change_delete (modify vs.
rename), refactor the code to halve the number of cases again by merging the
cases where o->branch1 has the change and o->branch2 has the delete with the
cases that are the other way around.

Also add a simple test of the new conflict message.

Signed-off-by: Matt McCutchen <matt@mattmccutchen.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-30 14:07:08 -08:00
Matt McCutchen
d549d21307 t0001: don't let a default ACL interfere with the umask test
The "init creates a new deep directory (umask vs. shared)" test expects
the permissions of newly created files to be based on the umask, which
fails if a default ACL is inherited from the working tree for git.  So
attempt to remove a default ACL if there is one.  Same idea as
8ed0a740dd.  (I guess I'm the only one who
ever runs the test suite with a default ACL set.)

Signed-off-by: Matt McCutchen <matt@mattmccutchen.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-30 14:03:21 -08:00
Jeff King
7dbabbbebe pack-objects: enforce --depth limit in reused deltas
Since 898b14c (pack-objects: rework check_delta_limit usage,
2007-04-16), we check the delta depth limit only when
figuring out whether we should make a new delta. We don't
consider it at all when reusing deltas, which means that
packing once with --depth=250, and then again with
--depth=50, the second pack may still contain chains larger
than 50.

This is generally considered a feature, as the results of
earlier high-depth repacks are carried forward, used for
serving fetches, etc. However, since we started using
cross-pack deltas in c9af708b1 (pack-objects: use mru list
when iterating over packs, 2016-08-11), we are no longer
bounded by the length of an existing delta chain in a single
pack.

Here's one particular pathological case: a sequence of N
packs, each with 2 objects, the base of which is stored as a
delta in a previous pack. If we chain all the deltas
together, we have a cycle of length N. We break the cycle,
but the tip delta is still at depth N-1.

This is less unlikely than it might sound. See the included
test for a reconstruction based on real-world actions.  I
ran into such a case in the wild, where a client was rapidly
sending packs, and we had accumulated 10,000 before doing a
server-side repack.  The pack that "git repack" tried to
generate had a very deep chain, which caused pack-objects to
run out of stack space in the recursive write_one().

This patch bounds the length of delta chains in the output
pack based on --depth, regardless of whether they are caused
by cross-pack deltas or existed in the input packs. This
fixes the problem, but does have two possible downsides:

  1. High-depth aggressive repacks followed by "normal"
     repacks will throw away the high-depth chains.

     In the long run this is probably OK; investigation
     showed that high-depth repacks aren't actually
     beneficial, and we dropped the aggressive depth default
     to match the normal case in 07e7dbf0d (gc: default
     aggressive depth to 50, 2016-08-11).

  2. If you really do want to store high-depth deltas on
     disk, they may be discarded and new delta computed when
     serving a fetch, unless you set pack.depth to match
     your high-depth size.

The implementation uses the existing search for delta
cycles.  That lets us compute the depth of any node based on
the depth of its base, because we know the base is DFS_DONE
by the time we look at it (modulo any cycles in the graph,
but we know there cannot be any because we break them as we
see them).

There is some subtlety worth mentioning, though. We record
the depth of each object as we compute it. It might seem
like we could save the per-object storage space by just
keeping track of the depth of our traversal (i.e., have
break_delta_chains() report how deep it went). But we may
visit an object through multiple delta paths, and on
subsequent paths we want to know its depth immediately,
without having to walk back down to its final base (doing so
would make our graph walk quadratic rather than linear).

Likewise, one could try to record the depth not from the
base, but from our starting point (i.e., start
recursion_depth at 0, and pass "recursion_depth + 1" to each
invocation of break_delta_chains()). And then when
recursion_depth gets too big, we know that we must cut the
delta chain.  But that technique is wrong if we do not visit
the nodes in topological order. In a chain A->B->C, it
if we visit "C", then "B", then "A", we will never recurse
deeper than 1 link (because we see at each node that we have
already visited it).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-27 16:24:44 -08:00
Johannes Schindelin
d98b2c5fce test-lib: on FreeBSD, look for unzip(1) in /usr/local/bin/
Eric Wong reported that while FreeBSD has a /usr/bin/unzip, it uses
different semantics from those that are needed by Git's tests: When
passing the -a option to Info-Zip, it heeds the text attribute of the
.zip file's central directory, while FreeBSD's unzip ignores that
attribute.

The common work-around is to install Info-Zip on FreeBSD, into
/usr/local/bin/.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Tested-by: Eric Wong <e@80x24.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-27 10:55:26 -08:00
Johannes Schindelin
93a04bb105 t/Makefile: add a rule to re-run previously-failed tests
This patch automates the process of determining which tests failed
previously and re-running them.

While developing patch series, it is a good practice to run the test
suite from time to time, just to make sure that obvious bugs are caught
early.  With complex patch series, it is common to run `make -j15 -k
test`, i.e.  run the tests in parallel and *not* stop at the first
failing test but continue. This has the advantage of identifying
possibly multiple problems in one big test run.

It is particularly important to reduce the turn-around time thusly on
Windows, where the test suite spends 45 minutes on the computer on which
this patch was developed.

It is the most convenient way to determine which tests failed after
running the entire test suite, in parallel, to look for left-over "trash
directory.t*" subdirectories in the t/ subdirectory. However, those
directories might live outside t/ when overridden using the
--root=<directory> option, to which the Makefile has no access. The next
best method is to grep explicitly for failed tests in the test-results/
directory, which the Makefile *can* access.

Please note that the often-recommended `prove` tool requires Perl, and
that opens a whole new can of worms on Windows. As no native Windows Perl
comes with Subversion bindings, we have to use a Perl in Git for Windows
that uses the POSIX emulation layer named MSYS2 (which is a portable
version of Cygwin). When using this emulation layer under stress, e.g.
when running massively-parallel tests, unexplicable crashes occur quite
frequently, and instead of having a solution to the original problem, the
developer now has an additional, quite huge problem. For that reason, this
developer rejected `prove` as a solution and went with this patch instead.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-27 10:53:40 -08:00
Johannes Schindelin
df9ded4984 status: be prepared for not-yet-started interactive rebase
Some developers might want to call `git status` in a working
directory where they just started an interactive rebase, but the
edit script is still opened in the editor.

Let's show a meaningful message in such cases.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-26 11:43:18 -08:00
Stefan Beller
e7b37caf4f submodule update: run custom update script for initial populating as well
In 1b4735d9f3 (submodule: no [--merge|--rebase] when newly cloned,
2011-02-17), all actions were defaulted to checkout for populating
a submodule initially, because merging or rebasing makes no sense
in that situation.

Other commands however do make sense, such as the custom command
that was added later (6cb5728c43, submodule update: allow custom
command to update submodule working tree, 2013-07-03).

I am unsure about the "none" command, as I can see an initial
checkout there as a useful thing. On the other hand going strictly
by our own documentation, we should do nothing in case of "none"
as well, because the user asked for it.

Reported-by: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-26 11:06:07 -08:00
Stefan Beller
ec9629b3b9 submodule absorbing: fix worktree/gitdir pointers recursively for non-moves
Consider having a submodule 'sub' and a nested submodule at 'sub/nested'.
When nested is already absorbed into sub, but sub is not absorbed into
its superproject, then we need to fixup the gitfile and core.worktree
setting for 'nested' when absorbing 'sub', but we do not need to move
its git dir around.

Previously 'nested's gitfile contained "gitdir: ../.git/modules/nested";
it has to be corrected to "gitdir: ../../.git/modules/sub1/modules/nested".

An alternative I considered to do this work lazily, i.e. when resolving
"../.git/modules/nested", we would notice the ".git" being a gitfile
linking to another path.  That seemed to be robuster by design, but harder
to get the implementation right.  Maybe we have to do that anyway once we
try to have submodules and worktrees working nicely together, but for now
just produce 'correct' (i.e. direct) pointers.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-26 11:01:04 -08:00
Segev Finer
e9d9a8a4d2 connect: handle putty/plink also in GIT_SSH_COMMAND
Git for Windows has special support for the popular SSH client PuTTY:
when using PuTTY's non-interactive version ("plink.exe"), we use the -P
option to specify the port rather than OpenSSH's -p option. TortoiseGit
ships with its own, forked version of plink.exe, that adds support for
the -batch option, and for good measure we special-case that, too.

However, this special-casing of PuTTY only covers the case where the
user overrides the SSH command via the environment variable GIT_SSH
(which allows specifying the name of the executable), not
GIT_SSH_COMMAND (which allows specifying a full command, including
additional command-line options).

When users want to pass any additional arguments to (Tortoise-)Plink,
such as setting a private key, they are required to either use a shell
script named plink or tortoiseplink or duplicate the logic that is
already in Git for passing the correct style of command line arguments,
which can be difficult, error prone and annoying to get right.

This patch simply reuses the existing logic and expands it to cover
GIT_SSH_COMMAND, too.

Note: it may look a little heavy-handed to duplicate the entire
command-line and then split it, only to extract the name of the
executable. However, this is not a performance-critical code path, and
the code is much more readable this way.

Signed-off-by: Segev Finer <segev208@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-25 13:47:22 -08:00
Stefan Beller
3d415425c7 unpack-trees: support super-prefix option
In the future we want to support working tree operations within submodules,
e.g. "git checkout --recurse-submodules", which will update the submodule
to the commit as recorded in its superproject. In the submodule the
unpack-tree operation is carried out as usual, but the reporting to the
user needs to prefix any path with the superproject. The mechanism for
this is the super-prefix. (see 74866d757, git: make super-prefix option)

Add support for the super-prefix option for commands that unpack trees
by wrapping any path output in unpacking trees in the newly introduced
super_prefixed function. This new function prefixes any path with the
super-prefix if there is one.  Assuming the submodule case doesn't happen
in the majority of the cases, we'd want to have a fast behavior for no
super prefix, i.e. no reallocation/copying, but just returning path.

Another aspect of introducing the `super_prefixed` function is to consider
who owns the memory and if this is the right place where the path gets
modified. As the super prefix ought to change the output behavior only and
not the actual unpack tree part, it is fine to be that late in the line.
As we get passed in 'const char *path', we cannot change the path itself,
which means in case of a super prefix we have to copy over the path.
We need two static buffers in that function as the error messages
contain at most two paths.

For testing purposes enable it in read-tree, which has no output
of paths other than an unpack-trees.c. These are all converted in
this patch.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-25 12:33:33 -08:00
Jeff King
c20d4d702f t1450: use "mv -f" within loose object directory
The loose objects are created with mode 0444. That doesn't
prevent them being overwritten by rename(), but some
versions of "mv" will be extra careful and prompt the user,
even without "-i".

Reportedly macOS does this, at least in the Travis builds.
The prompt reads from /dev/null, defaulting to "no", and the
object isn't moved. Then to make matters even more
interesting, it still returns "0" and the rest of the test
proceeds, but with a broken setup.

We can work around it by using "mv -f" to override the
prompt. This should work as it's already used in t5504 for
the same purpose.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-25 12:32:32 -08:00
Jacob Keller
77d21f29ea describe: teach describe negative pattern matches
Teach git-describe the `--exclude` option which will allow specifying
a glob pattern of tags to ignore. This can be combined with the
`--match` patterns to enable more flexibility in determining which tags
to consider.

For example, suppose you wish to find the first official release tag
that contains a certain commit. If we assume that official release tags
are of the form "v*" and pre-release candidates include "*rc*" in their
name, we can now find the first release tag that introduces the commit
abcdef:

  git describe --contains --match="v*" --exclude="*rc*" abcdef

Add documentation, tests, and completion for this change.

Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-23 18:33:17 -08:00
Jacob Keller
43f8080eaf describe: teach --match to accept multiple patterns
Teach `--match` to be accepted multiple times, accumulating a list of
patterns to match into a string list. Each pattern is inclusive, such
that a tag need only match one of the provided patterns to be
considered for matching.

This extension is useful as it enables more flexibility in what tags
match, and may avoid the need to run the describe command multiple
times to get the same result.

Add tests and update the documentation for this change.

Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-23 18:33:17 -08:00