t7800: Test difftool passing arguments to diff

git-difftool relies on the ability to forward unknown arguments
to the git-diff command.  Add a test to ensure that this works
as advertised.

Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
push: Provide situational hints for non-fast-forward errors

Pushing a non-fast-forward update to a remote repository will result in
an error, but the hint text doesn't provide the correct resolution in
every case. Give better resolution advice in three push scenarios:

1) If you push a non-fast-forward update to your current branch, you
should merge remote changes with 'git pull' before pushing again.

2) If you push to a shared repository others push to, and your local
tracking branches are not kept up to date, the 'matching refs' default
will generate non-fast-forward errors on outdated branches. If this is
your workflow, the 'matching refs' default is not for you. Consider
setting the 'push.default' configuration variable to 'current' or
'upstream' to ensure only your current branch is pushed.

3) If you explicitly specify a ref that is not your current branch or
push matching branches with ':', you will generate a non-fast-forward
error if any pushed branch tip is out of date. You should checkout the
offending branch and merge remote changes before pushing again.

Teach transport.c to recognize these scenarios and push.c to hint for
them. Do it with a switch statement so if 'git push's default behavior
changes or we discover more scenarios, modification is easy. Standardize
on the advice API and replace 'advice.pushNonFastForward' with two new
config variables, 'advice.pushNonFFCurrent' and 'advice.pushNonFFOther'.
Resolving a non-fast-forward error on your current branch requires
different operations than resolving one on a non-current branch. It
shouldn't be possible to disable both types of advice with one config
option.

Based-on-patch-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Christopher Tiwald <christiwald@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
difftool: parse options using Getopt::Long

Replace custom option/argument parser with standard Getopt::Long
module.  This shortens the code and makes it easier to understand.

Signed-off-by: Tim Henigan <tim.henigan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
difftool: exit(0) when usage is printed

Prior to this commit, the script exited with an error whenever the
usage string was printed, regardless of the reason it was done. In
cases where usage was printed due to a user request (e.g. '-h'
option), the script should exit without error (exit 0).

This commit adds an argument to the usage function that allows the
exit code to be specified when the function is called.

Signed-off-by: Tim Henigan <tim.henigan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
difftool: remove explicit change of PATH

Adding the script directory to PATH is not needed. The script is
located at '$(git --exec-path)', which is already on the PATH.

Signed-off-by: Tim Henigan <tim.henigan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
difftool: stop appending '.exe' to git

The system call to Git works the same whether or not ".exe" is
appended to "git". The extra code is not necessary.

Signed-off-by: Tim Henigan <tim.henigan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
difftool: eliminate setup_environment function

Removing this function shortens the code and makes it easier to read.
Now all environment variables are set as part of procedural operation.

Signed-off-by: Tim Henigan <tim.henigan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
difftool: replace system call with Git::command_noisy

The Git.pm module includes functions intended to standardize working
with Git repositories in Perl scripts. This commit teaches difftool
to use Git::command_noisy rather than a system call to run the diff
command.

Signed-off-by: Tim Henigan <tim.henigan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
difftool: teach difftool to handle directory diffs

Prior to this commit, the difftool utility could only open files one
at a time.  The new '--dir-diff' option copies all the modified files
to a temporary location and runs a directory diff on them.

Signed-off-by: Tim Henigan <tim.henigan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
difftool: teach dir-diff to copy modified files back to working tree

If the user runs a diff when there are modified files in the working copy,
they expect to be able to be edit the files in the diff viewer and save
the changes. When using difftool in file mode (i.e. diffing one file at
a time), this works as expected.  However, when using difftool in directory
diff mode, the changes are not saved.

This commit teaches the directory diff mode to copy changes from the diff
viewer back to the working copy.

Signed-off-by: Tim Henigan <tim.henigan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
difftool: print list of valid tools with '--tool-help'

Since bc7a96a (mergetool--lib: Refactor tools into separate files,
2011-08-18), it is possible to add a new diff tool by creating a simple
script in the '$(git --exec-path)/mergetools' directory.  Updating the
difftool help text is still a manual process, and the documentation can
easily go out of sync.

Teach the command to read the list of valid tools from the 'mergetools'
directory and print them for the user when the '--tool-help' option is
given.

Signed-off-by: Tim Henigan <tim.henigan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Merge branch 'ct/advise-push-default' into pu

Breaks down the cases in which "git push" fails due to non-ff into three
categories, and gives separate advise messages.

Replaces the long stalled jc/advise-push-default topic.

* ct/advise-push-default:
  push: Provide situational hints for non-fast-forward errors

Conflicts:
	builtin/push.c
Merge branch 'nl/rebase-i-cheat-sheet' into pu

* nl/rebase-i-cheat-sheet:
  [Do not merge] rebase -i: remind that the lines are top-to-bottom
Merge branch 'da/difftool-test' into pu

* da/difftool-test:
  t7800: Test difftool passing arguments to diff
Merge branch 'th/difftool-diffall' into pu

* th/difftool-diffall:
  difftool: print list of valid tools with '--tool-help'
  difftool: teach dir-diff to copy modified files back to working tree
  difftool: teach difftool to handle directory diffs
  difftool: replace system call with Git::command_noisy
  difftool: eliminate setup_environment function
  difftool: stop appending '.exe' to git
  difftool: remove explicit change of PATH
  difftool: exit(0) when usage is printed
  difftool: parse options using Getopt::Long