use a hashmap to make remotes faster

Remotes are stored as an array, so looking one up or adding one without
duplication is an O(n) operation.  Reading an entire config file full of
remotes is O(n^2) in the number of remotes.  For a repository with tens of
thousands of remotes, the running time can hit multiple minutes.

Hash tables are way faster.  So we add a hashmap from remote name to
struct remote and use it for all lookups.  The time to add a new remote to
a repo that already has 50,000 remotes drops from ~2 minutes to < 1
second.

We retain the old array of remotes so iterators proceed in config-file
order.

Signed-off-by: Patrick Reynolds <patrick.reynolds@github.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
commit --amend: test specifies authorship but forgets to check

The test case "--amend option copies authorship" specifies that the
git-commit option `--amend` uses the authorship of the replaced
commit for the new commit. Add the omitted check that this property
actually holds.

Signed-off-by: Fabian Ruch <bafain@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
add documentation for writing config files

Replace TODO introduced in commit 9c3c22 with documentation
explaining Git config API functions for writing configuration
files.

Signed-off-by: Tanay Abhra <tanayabh@gmail.com>
Reviewed-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
revision: drop useless string offset when parsing "--pretty"

Once upon a time, we parsed pretty options by looking for
"--pretty" at the start of the string, and then feeding the
rest (including an "=") to get_commit_format. Later, commit
48ded91 (log --pretty: do not accept bogus "--prettyshort",
2008-05-25) split this into a separate check for "--pretty"
versus "--pretty=".

However, when parsing "--pretty", we still passed "arg+8" to
get_commit_format. This is useless, since it will always
point to the NUL terminator at the end of the string. We can
simply pass NULL instead; both parameters are treated the
same by get_commit_format.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
pretty: treat "--format=" as an empty userformat

Until now, we treated "--pretty=" or "--format=" as "give me
the default format". This was not planned nor documented,
but only what happened to work due to our parsing of
"--pretty" (which should give the default format).

Let's instead let these be an actual empty userformat.
Otherwise one must write out the annoyingly long
"--pretty=tformat:" to get the same behavior.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
pretty: make empty userformats truly empty

If the user provides an empty format with "--format=", we
end up putting in extra whitespace that the user cannot
prevent. This comes from two places:

  1. If the format is missing a terminating newline, we add
     one automatically. This makes sense for --format=%h, but
     not for a truly empty format.

  2. We add an extra newline between the pretty-printed
     format and a diff or diffstat. If the format is empty,
     there's no point in doing so if there's nothing to
     separate.

With this patch, one can get a diff with no other cruft out
of "diff-tree --format= $commit".

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
add --simplify-combined-diff option

When showing a combined diff, we are comparing two (or more)
parents to a final state, and some of these states may be
the same.  Here's a table of the possible contents for a
given path (for two parents, but we will generalize to more
in a moment; we also omit isomorphic cases where the parents
are swapped):

  case | M | P1 | P2
  -------------------
  1    | A | A  | A
  2    | A | A  | B
  3    | A | B  | B
  4    | A | B  | C

In case 1, the path was not relevant to the merge at all,
and we omit it as uninteresting. In case 2, we did resolve
the path, but in favor of one side. We also consider this
uninteresting and do not show the diff.

In case 4, we had a real content-level merge, and the
combined diff is interesting. We show it.

That leaves case 3, in which both parents are the same, but
the merge picks a new content. This should be rare in
normal merges, though it could happen if you updated an
unrelated file due to a resolution elsewhere (i.e., an evil
merge that crosses a file boundary). But it happens
frequently in the fake merge commits we create for stashes,
in which one parent is the base of the stash and the other
is the index (in which case it simply means that the index
entry for the path was not touched).

Right now, we treat it the same as case 4, and show a normal
combined diff. However, the result is harder to read, and
the combined nature of the diff gives no extra information;
every marker in the combined diff will be identical for both
parents.

This patch adds a new option, "--simplify-combined-diff",
which converts this case into a normal, non-combined diff.
It would not be correct to simply omit it, because there
really is an interesting change going from B..A. It's just
that there are not two interesting changes, which the
combined diff would show.

When generalizing this to more than two parents, we have two
options:

  1. Either simply to a single parent content, or not at all.

  2. Omit parents whose contents are duplicates of other
     parents.

For a case like "A B B C", option (2) would still result in
a combined diff, but one with fewer sources. However, it
would also be ambiguous. The parents in a combined diff are
marked only by their position, so omitting a position means
that a reader can no longer tell which line goes with which
parent.

Instead, we choose option (1). Either you get the full
combined diff, or you get a normal non-combined diff.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
stash: default listing to "--cc --simplify-combined-diff"

When you list stashes, you can provide arbitrary git-log
options to change the display. However, adding just "-p"
does nothing, because each stash is actually a merge commit.

This implementation detail is easy to forget, leading to
confused users who think "-p" is not working. We can make
this easier by specifying "--cc" as a default ourselves
(which does nothing if no diff format is requested by the
user).

The resulting diff would then be a combined diff between the
base commit and the stashed index state. In many cases,
though, the user did not stash anything in the index. We can
further simplify this to a normal pairwise diff by using
"--simplify-combined-diff".

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
stash: show combined diff with "stash show"

A stash may store not only working tree changes, but also
changes to the index. However, "git stash show" will only
ever show the working tree changes. We can instead show both
as a combined diff, but use "--simplify-combined-diff" so
that we show a normal pairwise diff in the common case that
there were no index changes.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
SQUASH??? future-proof, log --cc should imply -p without being told
Git 2.0.4

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Merge branch 'ep/avoid-test-a-o'

* ep/avoid-test-a-o:
  t9814: fix misconversion from test $a -o $b to test $a || test $b
Merge branch 'sk/mingw-uni-fix-more'

Most of these are battle-tested in msysgit and are needed to
complete what has been merged to 'master' already.

* sk/mingw-uni-fix-more:
  Win32: enable color output in Windows cmd.exe
  Win32: patch Windows environment on startup
  Win32: keep the environment sorted
  Win32: use low-level memory allocation during initialization
  Win32: reduce environment array reallocations
  Win32: don't copy the environment twice when spawning child processes
  Win32: factor out environment block creation
  Win32: unify environment function names
  Win32: unify environment case-sensitivity
  Win32: fix environment memory leaks
  Win32: Unicode environment (incoming)
  Win32: Unicode environment (outgoing)
  Revert "Windows: teach getenv to do a case-sensitive search"
  tests: do not pass iso8859-1 encoded parameter
Merge branch 'sk/mingw-tests-workaround'

Make tests pass on msysgit by mostly disabling ones that are
infeasible on that platform.

* sk/mingw-tests-workaround:
  t800[12]: work around MSys limitation
  t9902: mingw-specific fix for gitfile link files
  t4210: skip command-line encoding tests on mingw
  MinGW: disable legacy encoding tests
  t0110/MinGW: skip tests that pass arbitrary bytes on the command line
  MinGW: Skip test redirecting to fd 4
Merge branch 'jk/more-push-completion'

* jk/more-push-completion:
  completion: complete `git push --force-with-lease=`
  completion: add some missing options to `git push`
  completion: complete "unstuck" `git push --recurse-submodules`
Update draft release notes to 2.1

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Sync with 2.0.4

* maint:
  Git 2.0.4
  commit --amend: test specifies authorship but forgets to check
Merge branch 'hv/submodule-config' into jch

* hv/submodule-config:
  do not die on error of parsing fetchrecursesubmodules option
  use new config API for worktree configurations of submodules
  extract functions for submodule config set and lookup
  implement submodule config cache for lookup of submodule names
Merge branch 'jc/reopen-lock-file' into jch

Needed in the "commit -p" code path to update the cache tree in the
index.

* jc/reopen-lock-file:
  lockfile: allow reopening a closed but still locked file
Merge branch 'dt/cache-tree-repair' into jch

Add a few more places in "commit" and "checkout" that make sure
that the cache-tree is fully populated in the index.

* dt/cache-tree-repair:
  cache-tree: Write updated cache-tree after commit
  cache-tree: subdirectory tests
  test-dump-cache-tree: invalid trees are not errors
  cache-tree: create/update cache-tree on checkout

# Conflicts:
# 	builtin/checkout.c
# 	builtin/commit.c