remote.c: add command line option parser for "--lockref"

Update "git push" and "git send-pack" to parse this commnd line
option.

The intended sematics is:

 * "--lockref" alone, without specifying the details, will protect
   _all_ remote refs that are going to be updated by requiring their
   current value to be the same as the remote-tracking branch we
   have for them, unless otherwise specified;

 * "--lockref=refname", without specifying the expected value, will
   protect that refname, if it is going to be updated, by requiring
   its current value to be the same as the remote-tracking branch we
   have for it;

 * "--lockref=refname:value" will protect that refname, if it is
   going to be updated, by requiring its current value to be the
   same as the specified value (which is allowed to be different
   from the remote-tracking branch we have for the refname, or we do
   not even have to have such a remote-tracking branch when this
   form is used); and

 * "--no-lockref" will cancel all the previous --lockref on the
   command line.

In any of the forms, when we try to use a remote-tracking branch for
the remote ref being updated, it is an error if there is no such
remote-tracking branch on our end.

Because the command line options are parsed _before_ we know which
remote we are pushing to, there needs further processing to the
parsed data after we instantiate the transport object to:

 * expand "refname" given by the user to a full refname to be
   matched with the list of "struct ref" used in match_push_refs()
   and set_ref_status_for_push(); and

 * learning the actual local ref that is the remote-tracking branch
   for the specified remote ref.

Further, some processing need to be deferred until we find the set
of remote refs and match_push_refs() returns in order to find the
ones that need to be checked after explicit ones have been processed
for "--lockref" (no specific details).

These post-processing will be the topic of the next patch.

Oh, of course, the option name is still not cast in stone.

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

 This round makes --lockref simply a weaker form of --force.

 The old version used to allow "--lockref=<refname>:" to say "I want
 this push to create <refname>, any existing old value should make
 it fail", but the normal fast-forward check already implements it,
 so there is no need for such an option.  This round removes it.

 The old version allowed you to express "I want the old value of
 'master' to be at X and also I want the update to fast-forward" by
 giving only "--lockref=master:X" without "--force".  Because you
 already know if the commit you are updating their 'master' with
 fast-forwards from X or not, such a combination is unnecessary to
 support.  This simplifies the UI greatly, as "--force" can again be
 the big red button that overrides all the safety.

 I think the option now should be renamed to "--force-with-???"; you
 are essentially taking a lease on the ref before you start your
 rebase, and making sure the ref hasn't been updated by other
 people, you are safely forcing your push of a rebased history.

 Perhaps "--force-with-lease"?  "--force-leased-ref"?
push --lockref: implement logic to populate old_sha1_expect[]

This plugs the push_cas_option data collected by the command line
option parser to the transport system with a new function
apply_push_cas(), which is called after match_push_refs() has
already been called.

At this point, we know which remote we are talking to, and what
remote refs we are going to update, so we can fill in the details
that may have been missing from the command line, such as

 (1) what abbreviated refname the user gave us matches the actual
     refname at the remote; and

 (2) which remote tracking branch in our local repository to read the
     value of the object to expect at the remote.

to populate the old_sha1_expect[] field of each of the remote ref.

Still nobody uses this information, which is the topic of the next
patch.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
push --lockref: tie it all together

This teaches the deepest part of the callchain for "git push" (and
"git send-pack") to enforce "the old value of the ref must be this,
otherwise fail this push" (aka "compare-and-swap" / "--lockref").

Signed-off-by: Junio C Hamano <gitster@pobox.com>
t5533: test "push --lockref"

Prepare two repositories, src and dst, the latter of which is a
clone of the former (with tracking branches), and push from the
latter into the former, using --lockref=name (using tracking ref for
"name" when updating "name"), --lockref=name:value, --lockref=name:
(i.e. check creation), and --lockref (using tracking ref for
anything that we update).

Signed-off-by: Junio C Hamano <gitster@pobox.com>
t6131 - skip tests if on case-insensitive file system

This test fails on Cygwin where the default system configuration does not
support case sensitivity (only case retention), so don't run the test on
such systems.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff: pass the whole diff_options to diffcore_apply_filter()

The --diff-filter=<arg> option given by the user is kept as a
string, and passed to the underlying diffcore_apply_filter()
function as a string for each resulting path we run number of
strchr() to see if each class of change among ACDMRTXUB is meant to
be given.

Change the function signature to pass the whole diff_options, so
that we can pre-parse this string in the next patch.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff: factor out match_filter()

diffcore_apply_filter() checks if a filepair matches the filter
given with the "--diff-filter" option for each input filepairs with
a fairly complex expression in two places.

Create a helper function and call it.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff: preparse --diff-filter string argument

Instead of running strchr() on the list of status characters over
and over again, parse the --diff-filter option into bitfields and
use the bits to see if the change to the filepair matches the status
requested.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff: reject unknown change class given to --diff-filter

We used to accept "git diff --diff-filter=Q" (note that there is no
such change class 'Q') silently and showed no output (because there
is no such change class 'Q').

Error out when such an input is given.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff: allow lowercase letter to specify what change class to exclude

In order to express "we do not care about deletions", we had to say
"--diff-filter=ACMRTXUB", giving all the possible change class
except for the one we do not want, "D".

This is cumbersome.  As all the change classes are in uppercase,
allow their lowercase counterpart to selectively exclude the class
from the output.  When such a negated change class is in the input,
start the filter option with the full bits set.

This would allow us to express the old "show-diff -q" with
"git diff-files --diff-filter=d".

Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff: deprecate -q option to diff-files

This reimplements the ancient "-q" option to "git diff-files" that
was inherited from "show-diff -q" in terms of "--diff-filter=d".  We
will be deprecating the "-q" option, so let's issue a warning when
we do so.

Incidentally this also tentatively fixes "git diff --no-index" to
honor "-q" and hide deletions; the use will get the same warning.

We should remove the support for "-q" in Git 2.0.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
do_one_ref(): save and restore value of current_ref

If do_one_ref() is called recursively, then the inner call should not
permanently overwrite the value stored in current_ref by the outer
call.  Aside from the tiny optimization loss, peel_ref() expects the
value of current_ref not to change across a call to peel_entry().  But
in the presence of replace references that assumption could be
violated by a recursive call to do_one_ref:

do_for_each_entry()
  do_one_ref()
    builtin/describe.c:get_name()
      peel_ref()
        peel_entry()
          peel_object ()
            deref_tag_noverify()
              parse_object()
                lookup_replace_object()
                  do_lookup_replace_object()
                    prepare_replace_object()
                      do_for_each_ref()
                        do_for_each_entry()
                          do_for_each_entry_in_dir()
                            do_one_ref()

The inner call to do_one_ref() was unconditionally setting current_ref
to NULL when it was done, causing peel_ref() to perform an invalid
memory access.

So change do_one_ref() to save the old value of current_ref before
overwriting it, and restore the old value afterward rather than
setting it to NULL.

Reported-by: Mantas Mikulėnas <grawity@gmail.com>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
cygwin: Remove the Win32 l/stat() implementation

Commit adbc0b6b ("cygwin: Use native Win32 API for stat", 30-09-2008)
added a Win32 specific implementation of the stat functions. In order
to handle absolute paths, cygwin mount points and symbolic links, this
implementation may fall back on the standard cygwin l/stat() functions.
Also, the choice of cygwin or Win32 functions is made lazily (by the
first call(s) to l/stat) based on the state of some config variables.

Unfortunately, this "schizophrenic stat" implementation has been the
source of many problems ever since. For example, see commits 7faee6b8,
79748439, 452993c2, 085479e7, b8a97333, 924aaf3e, 05bab3ea and 0117c2f0.

In order to avoid further problems, such as the issue raised by the new
reference handling API, remove the Win32 l/stat() implementation.

Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
pull: require choice between rebase/merge on non-fast-forward pull

Because it is so easy to let Git handle automatically a trivial
merge with "git pull", a person who is new to Git may not realize
that the project s/he is interacting with may prefer a "rebase"
workflow.

Add a safety valve to fail "git pull" that does not explicitly
specify what branch from which repository to integrate your history
with, when it is neither a fast-forward or "already up-to-date",
until/unless the user expressed her preference between the two ways
of integration.

This can be an irritating backward incompatible change for old
timers, but it can be a one time irritation by doing:

    git config --global pull.rebase false

once to say "I will always --merge", and they'd not even notice.

    http://thread.gmane.org/gmane.comp.version-control.git/225146/focus=225326

for a full discussion.

Helped-by: John Keeping <john@keeping.me.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Merge branch 'jc/name-rev-exact-ref' into jch

Corrects the longstanding sloppiness in the implementation of
name-rev that conflated "we take commit-ish" and "differences
between tags and commits do not matter".

* jc/name-rev-exact-ref:
  describe: fix --contains when a tag is given as input
  name-rev: differentiate between tags and commits they point at
  describe: use argv-array
  name-rev: allow converting the exact object name at the tip of a ref
  name-ref: factor out name shortening logic from name_ref()
Merge branch 'tr/fd-gotcha-fixes' into jch

Two places we did not check return value (expected to be a file
descriptor) correctly.

* tr/fd-gotcha-fixes:
  run-command: dup_devnull(): guard against syscalls failing
  git_mkstemps: correctly test return value of open()
Merge branch 'jc/mailmap-case-insensitivity' into jch

The mailmap mechanism unnecessarily downcased the e-mail addresses
in the output, and also ignored the human name when it is a single
character name.

This now has become Eric Sunshine's series, even though it still is
under jc/ hierarchy.

* jc/mailmap-case-insensitivity:
  mailmap: style fixes
  mailmap: debug: avoid passing NULL to fprintf() '%s' conversion specification
  mailmap: debug: eliminate -Wformat field precision type warning
  mailmap: debug: fix malformed fprintf() format conversion specification
  mailmap: debug: fix out-of-order fprintf() arguments
  mailmap: do not downcase mailmap entries
  t4203: demonstrate loss of uppercase characters in canonical email
  mailmap: do not lose single-letter names
  t4203: demonstrate loss of single-character name in mailmap entry
Merge branch 'dw/request-pull-diag' into jch

* dw/request-pull-diag:
  request-pull: improve error message for invalid revision args
Merge branch 'mm/diff-no-patch-synonym-to-s' into jch

"git show -s" was less discoverable than it should be.

* mm/diff-no-patch-synonym-to-s:
  Documentation/git-log.txt: capitalize section names
  Documentation: move description of -s, --no-patch to diff-options.txt
  Documentation/git-show.txt: include common diff options, like git-log.txt
  diff: allow --patch & cie to override -s/--no-patch
  diff: allow --no-patch as synonym for -s
  t4000-diff-format.sh: modernize style
Merge branch 'tr/do-not-call-submodules-subprojects' into jch

* tr/do-not-call-submodules-subprojects:
  show-branch: fix description of --date-order
  apply, entry: speak of submodules instead of subprojects

# Conflicts:
# 	builtin/show-branch.c