* Fetching SHA id's instead of named references?
From: Klas Lindberg @ 2009-04-06 12:13 UTC (permalink / raw)
To: Git Users List
Hello
Is there a way to fetch based on SHA id's instead of named references?
My usage scenario is this: A change management tool based on version
controlled manifest files (somewhat similar to Google's Repo) must be
able to check out exact versions of all 200 trees in the project view.
To support this, tags are used since they specify an exact revision.
But there are two problems with tagging:
* Tags are not immutable.
* External components that already have a tagging style get polluted
by our excessive use of tags.
I would really prefer to just list SHA keys in the manifests, but
fetch apparently doesn't support that? Could I use a combination of
lower level commands instead?
BR / Klas
^ permalink raw reply
* Re: Running 'git pull' from an unnamed branch
From: Reece Dunn @ 2009-04-06 12:04 UTC (permalink / raw)
To: Björn Steinbrink; +Cc: Junio C Hamano, Git List
In-Reply-To: <20090406100305.GD20356@atjola.homenet>
2009/4/6 Björn Steinbrink <B.Steinbrink@gmx.de>:
> On 2009.04.06 08:42:16 +0100, Reece Dunn wrote:
>> 2009/4/6 Junio C Hamano <gitster@pobox.com>:
>> > Reece Dunn <msclrhd@googlemail.com> writes:
>> >
>> >> diff --git a/git-pull.sh b/git-pull.sh
>> >> index 8a26763..00a72dd 100755
>> >> --- a/git-pull.sh
>> >> +++ b/git-pull.sh
>> >> @@ -97,6 +97,10 @@ error_on_no_merge_candidates () {
>> >> echo "try again (e.g. 'git pull <repository> <refspec>')."
>> >> echo "See git-pull(1) for details on the refspec."
>> >> echo
>> >> + echo "You may not be on a branch. In this case, you need to move"
>> >> + echo "onto the branch you want to pull to (usually master):"
>> >> + echo " git checkout <branch>"
>> >> + echo
>> >
>> > I do not think that is necessarily what the user wanted to hear. Often I
>> > create trial merges on a detached HEAD when I hear a pull-request from
>> > others (I have a few work trees that share the repository with my primary
>> > working area, made with contrib/workdir/git-new-workdir script, and their
>> > HEAD are typically detached at the tip of the master), and in such a use
>> > case, the first line of the instruction in the context in your patch is
>> > the right thing to give. I do not want to have the resulting trial merge
>> > anywhere on my real branches, and do not want to be told to switch to any
>> > of them.
>> >
>> > We really should teach people, especially the new ones early on, that "git
>> > push" and "git pull" are meant to be told where-to/from and what, and how
>> > to drive these commands with explicit arguments, before letting them rely
>> > on the default configuration blindly without understanding the underlying
>> > concepts.
>>
>> Ok, so how about something like:
>>
>> "You may not be on a branch. Because of this, you need to specify
>
> This should not say "may", either you are or you are not on a detached
> HEAD, and git can tell that, so it should not let the user have to
> guess.
>
>> where you are pulling from and to. See git-pull(1) for how to do this.
>> Alternatively, you can move to a named branch using:
>> git checkout <branch>"
>
> Checking out a named branch won't solve the "problem" on its own.
> Consider this:
>
> git checkout origin/foo
> *do stuff*
>
> git pull
> *Oh! I need a named branch*
>
> git checkout -b foo
> git pull
> *Still fails*
>
> Maybe:
> You asked me to pull without telling me which branch you want to merge
> with and as you have no branch checked out, I cannot look for any
> defaults to use. Please name which branch you want to merge on the
> command line and try again (e.g. 'git pull <repository> <refspec>'). See
> git-pull(1) for details on the refspec.
Sounds reasonable. I'll update the patch and resubmit later on today.
> That just adjusts the "you can set some defaults" part, replacing it
> with a message telling that a detached HEAD cannot have any defaults.
> Without implying anything about how the user might want to work, but
> giving a hint that a branch can have defaults for "git pull".
>
> Björn
- Reece
^ permalink raw reply
* Re: [question] how can i verify whether a local branch is tracking a remote branch?
From: Michael J Gruber @ 2009-04-06 12:00 UTC (permalink / raw)
To: Jeff King; +Cc: Paolo Ciarrocchi, git, Junio C Hamano
In-Reply-To: <20090406043426.GC12341@coredump.intra.peff.net>
Jeff King venit, vidit, dixit 06.04.2009 06:34:
> On Sun, Apr 05, 2009 at 11:25:29PM +0200, Paolo Ciarrocchi wrote:
>
>> An example:
>> $ git clone -n URL temp
>> $ cd temp
>> $ git branch -r
>> origin/master
>> origin/foo
>> Origin/bar
>> $ git checkout --track -b foo origin/foo
>>
>> Now, how can I know that foo is tracking origin/foo ?
>
> Doing it right is hard. You have to:
>
> 1. check branch.foo.merge and branch.foo.rebase; if no value, it is not
> tracking anything; if it is, remember that value as $m
>
> 2. check branch.foo.remote for the remote name, $r
>
> 3. check the fetch refspecs for remote $r; these can come from
> the config, or from .git/remotes/* files. Maybe even .git/branches
> files; I don't even remember how those work.
>
> 4. find the refspec that fetches from $m; then find the matching
> destination for that refspec. That is the tracking branch.
>
> E.g., in your example (and using a modern git):
>
> 1. $m is refs/heads/foo
> 2. $r is origin
> 3. The fetch refspec is in remote.origin.fetch, and is generally
> "refs/heads/*:refs/remotes/origin/*"
> 4. So refs/heads/foo becomes refs/remotes/origin/foo.
> refs/remotes/origin/foo is your tracking branch.
>
> Steps 1 and 2 are easy, but 3 and 4 are a bit nasty. You can fake it by
> assuming that "refs/heads/$m" on "$r" is always "refs/remotes/$r/$m",
> which is true for very vanilla setups.
>
> There is C code that does this, but there is not a good way of accessing
> it from the command-line. The best you can do is "git remote show
> origin", which on recent git versions should show something like:
>
> ...
> Local branches configured for 'git pull':
> foo merges with remote foo
> ...
>
> But of course that implies that you already guessed the remote "origin".
> And it's not using plumbing, so it's not very suitable for scripts.
>
> I don't think it would be unreasonable to expose this functionality via
> "for-each-ref". Something like this (which would need cleanup,
> documentation, and perhaps a :short variant):
>
> ---
> diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c
> index 5cbb4b0..3f418e4 100644
> --- a/builtin-for-each-ref.c
> +++ b/builtin-for-each-ref.c
> @@ -8,6 +8,7 @@
> #include "blob.h"
> #include "quote.h"
> #include "parse-options.h"
> +#include "remote.h"
>
> /* Quoting styles */
> #define QUOTE_NONE 0
> @@ -66,6 +67,7 @@ static struct {
> { "subject" },
> { "body" },
> { "contents" },
> + { "tracking" },
> };
>
> /*
> @@ -699,6 +701,18 @@ static void populate_value(struct refinfo *ref)
> v->s = s;
> }
> }
> + if (!strcmp(name, "tracking")) {
> + struct branch *branch;
> + if (prefixcmp(ref->refname, "refs/heads/"))
> + continue;
> + branch = branch_get(ref->refname + 11);
> + if (branch && branch->merge && branch->merge[0] &&
> + branch->merge[0]->dst)
> + v->s = branch->merge[0]->dst;
Isn't that missing out on those cases where you --track (i.e. follow) a
local (upstream) branch? See
5e6e2b4 (Make local branches behave like remote branches when --tracked,
2009-04-01)
> + else
> + v->s = NULL;
> + free(branch); /* XXX should also free other parts? */
> + }
> }
>
> grab_values(ref->value, 0, obj, buf, size);
>
>
>
>
>
If we hook it up into git-branch there would be to useful directions:
- "git branch --follows foo" could list all branches which follow foo,
analogous to --contains. It gives you all your feature work on top of
foo, all branches affected by rebasing foo etc.
- "git branch --whatever foo" could list the branch whoch foo follows.
I just notices that "git branch -v foo" does not give me the "-v" output
for foo... Improving that would open up the possibility to go for -vv foo.
Michael
^ permalink raw reply
* Broken umlaut in my name, again
From: Björn Steinbrink @ 2009-04-06 11:46 UTC (permalink / raw)
To: Marius Storm-Olsen; +Cc: Junio C Hamano, git
In-Reply-To: <20090331153039.GA1520@atjola.homenet>
On 2009.03.31 17:30:39 +0200, Björn Steinbrink wrote:
> While it makes no sense to map some email address to an empty one, doing
> things the other way around can be useful. For example when using
> filter-branch with an env-filter that employs a mailmap to fix up an
> import that created such broken commits with empty email addresses.
>
> Signed-off-by: Björn Steinbrink <B.Steinbrink@gmx.de>
The umlaut (ö) in my name is broken in the commit that made it into
git.git --> 5288dd58356e53d61e2b3804fc7d8d23c3a46ab3
Last time this happened when I used format-patch -s instead of commit -s
IIRC. But since then, I pay attention to do the sign-off via commit -s,
yet my name is broken again. What did I do wrong this time?
Björn
^ permalink raw reply
* Re: [PATCH v2] Add configuration variable for sign-off to format-patch
From: Matthieu Moy @ 2009-04-06 11:36 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: Junio C Hamano, Heiko Voigt, Jeff King, git
In-Reply-To: <49D9E040.40007@op5.se>
Andreas Ericsson <exon@op5.com> writes:
> How about:
> "Some projects (notably the Linux kernel and git itself) put special
> meaning in a 'Signed-off-by' line while other's dont. Please refer
> to your project's documentation for appropriate behaviour."
>
> Optionally with the following amendment:
>
> "In general, you should refrain from signing off on a patch containing
> material that you're not sure can be legally spread under the project's
> license."
To me, this is at least an improvement over refering to
SubmittingPatches (which is targeted to Git contributors) in the
documentation (targeted to Git users), yes.
Not sure whether these two sentences should come in the documentation
for the config option or the command-line switch.
--
Matthieu
^ permalink raw reply
* Re: Performance issue: initial git clone causes massive repack
From: Matthieu Moy @ 2009-04-06 11:22 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: david, Nicolas Sebrecht, Robin H. Johnson, Git Mailing List
In-Reply-To: <alpine.LFD.2.00.0904052326090.6741@xanadu.home>
Nicolas Pitre <nico@cam.org> writes:
> If for example you have a single pack because your repo is already fully
> packed, then the "packing operation" involved during a clone should
> merely copy the existing pack over with no further attempt at delta
> compression.
There's still the question if your repository has too many objects
(for example, a branch that you deleted without garbage-collecting
it). Then, sending the whole pack sends data that one may have
considered as "secret".
To me, this is a non-issue (if the content of these objects are
secret, then why are they here at all on a public server?), but I
think there were discussions here about it (can't find the right
keywords to dig the archives though), and other people may think
differently.
Jeff King's answer in <20090405195714.GA4716@coredump.intra.peff.net>
tackles this problem too.
--
Matthieu
^ permalink raw reply
* Re: [PATCH v2] Add configuration variable for sign-off to format-patch
From: Andreas Ericsson @ 2009-04-06 10:58 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Heiko Voigt, Jeff King, git
In-Reply-To: <7veiw69p26.fsf@gitster.siamese.dyndns.org>
Junio C Hamano wrote:
> Heiko Voigt <hvoigt@hvoigt.net> writes:
>
>> diff --git a/Documentation/config.txt b/Documentation/config.txt
>> index ad22cb8..27cb7f1 100644
>> --- a/Documentation/config.txt
>> +++ b/Documentation/config.txt
>> @@ -715,6 +715,13 @@ format.thread::
>> A true boolean value is the same as `shallow`, and a false
>> value disables threading.
>>
>> +format.signoff::
>> + A boolean value which lets you enable the `-s/--signoff` option of
>> + format-patch by default. *Note:* Adding the Signed-off-by: line to a
>> + patch should be a conscious act and means that you certify you have
>> + the rights to submit this work under the same open source license.
>> + Please see the 'SubmittingPatches' document for further discussion.
>
> I have a mixed feeling about this description. The existing description
> on the --signoff option merely talks about what it does, leaving what it
> means, and it is quite deliberate. If your project uses S-o-b, it may be
> useful. If yours doesn't, you simply just don't use it. It does not
> matter to _us_ as the document writer what that line means to your
> project.
>
> We do want to make the reader think twice iff S-o-b is used in the
> reader's project with the same meaning as it means in git and the Linux
> kernel project, which is what the description you added is about. But
> should we just assume if anybody uses S-o-b convention in their project
> they must give it the same meaning as we give it?
>
> The patch looks straightforward enough, and the wording we can update if
> somebody can come up with a better one, so I'll apply the patch to
> 'master' and we will go from there.
>
How about:
"Some projects (notably the Linux kernel and git itself) put special
meaning in a 'Signed-off-by' line while other's dont. Please refer
to your project's documentation for appropriate behaviour."
Optionally with the following amendment:
"In general, you should refrain from signing off on a patch containing
material that you're not sure can be legally spread under the project's
license."
I'll whip up a patch if someone cares enough about it to say "+1" to
either proposal, or make a better one.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.
^ permalink raw reply
* Re: Running 'git pull' from an unnamed branch
From: Björn Steinbrink @ 2009-04-06 10:03 UTC (permalink / raw)
To: Reece Dunn; +Cc: Junio C Hamano, Git List
In-Reply-To: <3f4fd2640904060042m438a3a8en2d2746a6216b2b95@mail.gmail.com>
On 2009.04.06 08:42:16 +0100, Reece Dunn wrote:
> 2009/4/6 Junio C Hamano <gitster@pobox.com>:
> > Reece Dunn <msclrhd@googlemail.com> writes:
> >
> >> diff --git a/git-pull.sh b/git-pull.sh
> >> index 8a26763..00a72dd 100755
> >> --- a/git-pull.sh
> >> +++ b/git-pull.sh
> >> @@ -97,6 +97,10 @@ error_on_no_merge_candidates () {
> >> echo "try again (e.g. 'git pull <repository> <refspec>')."
> >> echo "See git-pull(1) for details on the refspec."
> >> echo
> >> + echo "You may not be on a branch. In this case, you need to move"
> >> + echo "onto the branch you want to pull to (usually master):"
> >> + echo " git checkout <branch>"
> >> + echo
> >
> > I do not think that is necessarily what the user wanted to hear. Often I
> > create trial merges on a detached HEAD when I hear a pull-request from
> > others (I have a few work trees that share the repository with my primary
> > working area, made with contrib/workdir/git-new-workdir script, and their
> > HEAD are typically detached at the tip of the master), and in such a use
> > case, the first line of the instruction in the context in your patch is
> > the right thing to give. I do not want to have the resulting trial merge
> > anywhere on my real branches, and do not want to be told to switch to any
> > of them.
> >
> > We really should teach people, especially the new ones early on, that "git
> > push" and "git pull" are meant to be told where-to/from and what, and how
> > to drive these commands with explicit arguments, before letting them rely
> > on the default configuration blindly without understanding the underlying
> > concepts.
>
> Ok, so how about something like:
>
> "You may not be on a branch. Because of this, you need to specify
This should not say "may", either you are or you are not on a detached
HEAD, and git can tell that, so it should not let the user have to
guess.
> where you are pulling from and to. See git-pull(1) for how to do this.
> Alternatively, you can move to a named branch using:
> git checkout <branch>"
Checking out a named branch won't solve the "problem" on its own.
Consider this:
git checkout origin/foo
*do stuff*
git pull
*Oh! I need a named branch*
git checkout -b foo
git pull
*Still fails*
Maybe:
You asked me to pull without telling me which branch you want to merge
with and as you have no branch checked out, I cannot look for any
defaults to use. Please name which branch you want to merge on the
command line and try again (e.g. 'git pull <repository> <refspec>'). See
git-pull(1) for details on the refspec.
That just adjusts the "you can set some defaults" part, replacing it
with a message telling that a detached HEAD cannot have any defaults.
Without implying anything about how the user might want to work, but
giving a hint that a branch can have defaults for "git pull".
Björn
^ permalink raw reply
* Re: [PATCH] perl: add new module Git::Config for cached 'git config' access
From: Frank Lichtenheld @ 2009-04-06 9:29 UTC (permalink / raw)
To: Sam Vilain; +Cc: git, Petr Baudis
In-Reply-To: <1238975176-14354-1-git-send-email-sam.vilain@catalyst.net.nz>
On Mon, Apr 06, 2009 at 11:46:15AM +1200, Sam Vilain wrote:
> + my ($fh, $c) = $git->command_output_pipe(
> + 'config', ( $which ? ("--$which") : () ),
> + '--list',
> + );
> + my $read_state = {};
> +
> + while (<$fh>) {
> + my ($item, $value) = m{(.*?)=(.*)};
> + my $sl = \( $read_state->{$item} );
> + if (!defined $$sl) {
> + $$sl = $value;
> + }
> + elsif (!ref $$sl) {
> + $$sl = [ $$sl, $value ];
> + }
> + else {
> + push @{ $$sl }, $value;
> + }
> + }
Any reason why you don't use --null here? The output of --list without --null
is not reliably parsable, since people can put newlines in values.
Gruesse,
--
Frank Lichtenheld <frank@lichtenheld.de>
www: http://www.djpig.de/
^ permalink raw reply
* Re: [RFC/PATCH 0/2] New 'stage' command
From: Björn Steinbrink @ 2009-04-06 9:48 UTC (permalink / raw)
To: Markus Heidelberg; +Cc: Felipe Contreras, git, Junio C Hamano
In-Reply-To: <200904060123.58602.markus.heidelberg@web.de>
On 2009.04.06 01:23:58 +0200, Markus Heidelberg wrote:
> Björn Steinbrink, 06.04.2009:
> > On 2009.04.06 01:35:24 +0300, Felipe Contreras wrote:
> > > Well, it's a matter of preference, and you would not loose the option
> > > to do it the way you like. But actually, "git diff --cached" is a
> > > different action; you can't do "git diff --cached HEAD^.." for
> > > example.
> >
> > Sure you can. It diffs the index against HEAD^
>
> No, note the ".."
Oh, d'oh... Sorry, and thanks!
Björn
^ permalink raw reply
* Re: [RFC/PATCH 0/2] New 'stage' command
From: Felipe Contreras @ 2009-04-06 9:37 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Sverre Rabbelier, markus.heidelberg, git, Junio C Hamano
In-Reply-To: <alpine.DEB.1.00.0904060141190.10279@pacific.mpi-cbg.de>
On Mon, Apr 6, 2009 at 2:45 AM, Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
> Hi,
>
> On Mon, 6 Apr 2009, Sverre Rabbelier wrote:
>
>> On Mon, Apr 6, 2009 at 01:17, Markus Heidelberg
>> <markus.heidelberg@web.de> wrote:
>> > Felipe Contreras, 06.04.2009:
>> >> But actually, "git diff --cached" is a different action; you can't do
>> >> "git diff --cached HEAD^.." for example.
>> >
>> > And I neither could I do "git stage diff HEAD^.."
>>
>> I rest my case ;). That's the whole point Felipe is trying to make here.
>> $ git diff --cached
>> $ git diff HEAD^..
>>
>> [...]
>
> Could you post at some stage what the current state of this discussion is,
> so that people who do not have time to read all those mails, let alone
> fire off 10+ mails per hour, can comment about their view of things?
>
> So far, it seems that the view of only a handful is represented in that
> thread.
So far it seems nobody likes the idea. Junio has explained why things
are the way they are, but he hasn't answered my arguments, including
the fact that this doesn't change anything, it merely adds options to
an already existing command.
This is the mail that hasn't been answered yet:
http://article.gmane.org/gmane.comp.version-control.git/115705
--
Felipe Contreras
^ permalink raw reply
* [PATCH v2 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib
From: David Aguilar @ 2009-04-06 9:30 UTC (permalink / raw)
To: gitster; +Cc: git, benji, markus.heidelberg, charles, David Aguilar
This consolidates the common functionality from git-mergetool and
git-difftool--helper into a single git-mergetool--lib scriptlet.
Signed-off-by: David Aguilar <davvid@gmail.com>
---
I changed valid_tool() to address Brian Gernhardt's note.
.gitignore | 1 +
Documentation/git-mergetool--lib.txt | 56 ++++++
Makefile | 1 +
git-difftool--helper.sh | 186 +-----------------
git-mergetool--lib.sh | 353 ++++++++++++++++++++++++++++++++++
git-mergetool.sh | 224 ++--------------------
6 files changed, 433 insertions(+), 388 deletions(-)
create mode 100644 Documentation/git-mergetool--lib.txt
create mode 100644 git-mergetool--lib.sh
diff --git a/.gitignore b/.gitignore
index a36da9d..757c7f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -80,6 +80,7 @@ git-merge-recursive
git-merge-resolve
git-merge-subtree
git-mergetool
+git-mergetool--lib
git-mktag
git-mktree
git-name-rev
diff --git a/Documentation/git-mergetool--lib.txt b/Documentation/git-mergetool--lib.txt
new file mode 100644
index 0000000..3d57031
--- /dev/null
+++ b/Documentation/git-mergetool--lib.txt
@@ -0,0 +1,56 @@
+git-mergetool--lib(1)
+=====================
+
+NAME
+----
+git-mergetool--lib - Common git merge tool shell scriptlets
+
+SYNOPSIS
+--------
+'. "$(git --exec-path)/git-mergetool--lib"'
+
+DESCRIPTION
+-----------
+
+This is not a command the end user would want to run. Ever.
+This documentation is meant for people who are studying the
+Porcelain-ish scripts and/or are writing new ones.
+
+The 'git-mergetool--lib' scriptlet is designed to be sourced (using
+`.`) by other shell scripts to set up functions for working
+with git merge tools.
+
+Before sourcing it, your script should set up a few variables;
+`TOOL_MODE` is used to define the operation mode for various
+functions. 'diff' and 'merge' are valid values.
+
+FUNCTIONS
+---------
+get_merge_tool::
+ returns a merge tool
+
+get_merge_tool_cmd::
+ returns the custom command for a merge tool.
+
+get_merge_tool_path::
+ returns the custom path for a merge tool.
+
+run_merge_tool::
+ launches a merge tool given the tool name and a true/false
+ flag to indicate whether a merge base is present.
+ '$merge_tool', '$merge_tool_path', and for custom commands,
+ '$merge_tool_cmd', must be defined prior to calling
+ run_merge_tool. Additionally, '$MERGED', '$LOCAL', '$REMOTE',
+ and '$BASE' must be defined for use by the merge tool.
+
+Author
+------
+Written by David Aguilar <davvid@gmail.com>
+
+Documentation
+--------------
+Documentation by David Aguilar and the git-list <git@vger.kernel.org>.
+
+GIT
+---
+Part of the linkgit:git[1] suite
diff --git a/Makefile b/Makefile
index a80055f..3e56274 100644
--- a/Makefile
+++ b/Makefile
@@ -284,6 +284,7 @@ SCRIPT_SH += git-merge-octopus.sh
SCRIPT_SH += git-merge-one-file.sh
SCRIPT_SH += git-merge-resolve.sh
SCRIPT_SH += git-mergetool.sh
+SCRIPT_SH += git-mergetool--lib.sh
SCRIPT_SH += git-parse-remote.sh
SCRIPT_SH += git-pull.sh
SCRIPT_SH += git-quiltimport.sh
diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
index f3c27d8..b450036 100755
--- a/git-difftool--helper.sh
+++ b/git-difftool--helper.sh
@@ -5,6 +5,10 @@
#
# Copyright (c) 2009 David Aguilar
+# Load common functions from git-mergetool--lib
+TOOL_MODE=diff
+. git-mergetool--lib
+
# difftool.prompt controls the default prompt/no-prompt behavior
# and is overridden with $GIT_DIFFTOOL*_PROMPT.
should_prompt () {
@@ -16,8 +20,7 @@ should_prompt () {
fi
}
-# This function prepares temporary files and launches the appropriate
-# merge tool.
+# Sets up shell variables and runs a merge tool
launch_merge_tool () {
# Merged is the filename as it appears in the work tree
# Local is the contents of a/filename
@@ -37,187 +40,16 @@ launch_merge_tool () {
fi
# Run the appropriate merge tool command
- case "$merge_tool" in
- kdiff3)
- basename=$(basename "$MERGED")
- "$merge_tool_path" --auto \
- --L1 "$basename (A)" \
- --L2 "$basename (B)" \
- "$LOCAL" "$REMOTE" \
- > /dev/null 2>&1
- ;;
-
- kompare)
- "$merge_tool_path" "$LOCAL" "$REMOTE"
- ;;
-
- tkdiff)
- "$merge_tool_path" "$LOCAL" "$REMOTE"
- ;;
-
- meld)
- "$merge_tool_path" "$LOCAL" "$REMOTE"
- ;;
-
- diffuse)
- "$merge_tool_path" "$LOCAL" "$REMOTE" | cat
- ;;
-
- vimdiff)
- "$merge_tool_path" -d -c "wincmd l" "$LOCAL" "$REMOTE"
- ;;
-
- gvimdiff)
- "$merge_tool_path" -d -c "wincmd l" -f "$LOCAL" "$REMOTE"
- ;;
-
- xxdiff)
- "$merge_tool_path" \
- -R 'Accel.Search: "Ctrl+F"' \
- -R 'Accel.SearchForward: "Ctrl-G"' \
- "$LOCAL" "$REMOTE"
- ;;
-
- opendiff)
- "$merge_tool_path" "$LOCAL" "$REMOTE" | cat
- ;;
-
- ecmerge)
- "$merge_tool_path" "$LOCAL" "$REMOTE" \
- --default --mode=merge2 --to="$MERGED"
- ;;
-
- emerge)
- "$merge_tool_path" -f emerge-files-command \
- "$LOCAL" "$REMOTE" "$(basename "$MERGED")"
- ;;
-
- *)
- if test -n "$merge_tool_cmd"; then
- ( eval $merge_tool_cmd )
- fi
- ;;
- esac
-}
-
-# Verifies that (difftool|mergetool).<tool>.cmd exists
-valid_custom_tool() {
- merge_tool_cmd="$(git config difftool.$1.cmd)"
- test -z "$merge_tool_cmd" &&
- merge_tool_cmd="$(git config mergetool.$1.cmd)"
- test -n "$merge_tool_cmd"
-}
-
-# Verifies that the chosen merge tool is properly setup.
-# Built-in merge tools are always valid.
-valid_tool() {
- case "$1" in
- kdiff3 | kompare | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge)
- ;; # happy
- *)
- if ! valid_custom_tool "$1"
- then
- return 1
- fi
- ;;
- esac
-}
-
-# Sets up the merge_tool_path variable.
-# This handles the difftool.<tool>.path configuration.
-# This also falls back to mergetool defaults.
-init_merge_tool_path() {
- merge_tool_path=$(git config difftool."$1".path)
- test -z "$merge_tool_path" &&
- merge_tool_path=$(git config mergetool."$1".path)
- if test -z "$merge_tool_path"; then
- case "$1" in
- vimdiff)
- merge_tool_path=vim
- ;;
- gvimdiff)
- merge_tool_path=gvim
- ;;
- emerge)
- merge_tool_path=emacs
- ;;
- *)
- merge_tool_path="$1"
- ;;
- esac
- fi
+ run_merge_tool "$merge_tool"
}
# Allow GIT_DIFF_TOOL and GIT_MERGE_TOOL to provide default values
test -n "$GIT_MERGE_TOOL" && merge_tool="$GIT_MERGE_TOOL"
test -n "$GIT_DIFF_TOOL" && merge_tool="$GIT_DIFF_TOOL"
-# If merge tool was not specified then use the diff.tool
-# configuration variable. If that's invalid then reset merge_tool.
-# Fallback to merge.tool.
-if test -z "$merge_tool"; then
- merge_tool=$(git config diff.tool)
- test -z "$merge_tool" &&
- merge_tool=$(git config merge.tool)
- if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then
- echo >&2 "git config option diff.tool set to unknown tool: $merge_tool"
- echo >&2 "Resetting to default..."
- unset merge_tool
- fi
-fi
-
-# Try to guess an appropriate merge tool if no tool has been set.
-if test -z "$merge_tool"; then
- # We have a $DISPLAY so try some common UNIX merge tools
- if test -n "$DISPLAY"; then
- # If gnome then prefer meld, otherwise, prefer kdiff3 or kompare
- if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
- merge_tool_candidates="meld kdiff3 kompare tkdiff xxdiff gvimdiff diffuse"
- else
- merge_tool_candidates="kdiff3 kompare tkdiff xxdiff meld gvimdiff diffuse"
- fi
- fi
- if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then
- # $EDITOR is emacs so add emerge as a candidate
- merge_tool_candidates="$merge_tool_candidates emerge opendiff vimdiff"
- elif echo "${VISUAL:-$EDITOR}" | grep 'vim' > /dev/null 2>&1; then
- # $EDITOR is vim so add vimdiff as a candidate
- merge_tool_candidates="$merge_tool_candidates vimdiff opendiff emerge"
- else
- merge_tool_candidates="$merge_tool_candidates opendiff emerge vimdiff"
- fi
- echo "merge tool candidates: $merge_tool_candidates"
-
- # Loop over each candidate and stop when a valid merge tool is found.
- for i in $merge_tool_candidates
- do
- init_merge_tool_path $i
- if type "$merge_tool_path" > /dev/null 2>&1; then
- merge_tool=$i
- break
- fi
- done
-
- if test -z "$merge_tool" ; then
- echo "No known merge resolution program available."
- exit 1
- fi
-
-else
- # A merge tool has been set, so verify that it's valid.
- if ! valid_tool "$merge_tool"; then
- echo >&2 "Unknown merge tool $merge_tool"
- exit 1
- fi
-
- init_merge_tool_path "$merge_tool"
-
- if test -z "$merge_tool_cmd" && ! type "$merge_tool_path" > /dev/null 2>&1; then
- echo "The merge tool $merge_tool is not available as '$merge_tool_path'"
- exit 1
- fi
-fi
-
+merge_tool=$(get_merge_tool "$merge_tool") || exit
+merge_tool_cmd="$(get_merge_tool_cmd "$merge_tool")"
+merge_tool_path="$(get_merge_tool_path "$merge_tool")" || exit
# Launch the merge tool on each path provided by 'git diff'
while test $# -gt 6
diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh
new file mode 100644
index 0000000..b837abf
--- /dev/null
+++ b/git-mergetool--lib.sh
@@ -0,0 +1,353 @@
+# git-mergetool--lib is a library for common merge tool functions
+diff_mode() {
+ test $TOOL_MODE = "diff"
+}
+
+merge_mode() {
+ test $TOOL_MODE = "merge"
+}
+
+translate_merge_tool_path () {
+ if test -n "$2"; then
+ echo "$2"
+ else
+ case "$1" in
+ vimdiff)
+ path=vim
+ ;;
+ gvimdiff)
+ path=gvim
+ ;;
+ emerge)
+ path=emacs
+ ;;
+ *)
+ path="$1"
+ ;;
+ esac
+ echo "$path"
+ fi
+}
+
+check_unchanged () {
+ if merge_mode; then
+ if test "$MERGED" -nt "$BACKUP"; then
+ status=0
+ else
+ while true; do
+ echo "$MERGED seems unchanged."
+ printf "Was the merge successful? [y/n] "
+ read answer < /dev/tty
+ case "$answer" in
+ y*|Y*) status=0; break ;;
+ n*|N*) status=1; break ;;
+ esac
+ done
+ fi
+ else
+ status=0
+ fi
+ return $status
+}
+
+valid_tool () {
+ case "$1" in
+ kdiff3 | tkdiff | xxdiff | meld | opendiff | \
+ emerge | vimdiff | gvimdiff | ecmerge | diffuse)
+ ;; # happy
+ tortoisemerge)
+ if ! merge_mode; then
+ return 1
+ fi
+ ;;
+ kompare)
+ if ! diff_mode; then
+ return 1
+ fi
+ ;;
+ *)
+ if test -z "$(get_merge_tool_cmd "$1")"; then
+ return 1
+ fi
+ ;;
+ esac
+}
+
+get_merge_tool_cmd () {
+ diff_mode &&
+ custom_cmd="$(git config difftool.$1.cmd)"
+ test -z "$custom_cmd" &&
+ custom_cmd="$(git config mergetool.$1.cmd)"
+ test -n "$custom_cmd" &&
+ echo "$custom_cmd"
+}
+
+run_merge_tool () {
+ base_present="$2"
+ if diff_mode; then
+ base_present="false"
+ fi
+ if test -z "$base_present"; then
+ base_present="true"
+ fi
+
+ case "$1" in
+ kdiff3)
+ if $base_present; then
+ ("$merge_tool_path" --auto \
+ --L1 "$MERGED (Base)" --L2 "$MERGED (Local)" --L3 "$MERGED (Remote)" \
+ -o "$MERGED" "$BASE" "$LOCAL" "$REMOTE" > /dev/null 2>&1)
+ else
+ if merge_mode; then
+ ("$merge_tool_path" --auto \
+ --L1 "$MERGED (Local)" \
+ --L2 "$MERGED (Remote)" \
+ -o "$MERGED" "$LOCAL" "$REMOTE" \
+ > /dev/null 2>&1)
+ else
+ ("$merge_tool_path" --auto \
+ --L1 "$MERGED (A)" \
+ --L2 "$MERGED (B)" \
+ "$LOCAL" "$REMOTE" \
+ > /dev/null 2>&1)
+ fi
+ fi
+ status=$?
+ ;;
+ kompare)
+ "$merge_tool_path" "$LOCAL" "$REMOTE"
+ status=$?
+ ;;
+ tkdiff)
+ if $base_present; then
+ "$merge_tool_path" -a "$BASE" -o "$MERGED" "$LOCAL" "$REMOTE"
+ else
+ if merge_mode; then
+ "$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE"
+ else
+ "$merge_tool_path" "$LOCAL" "$REMOTE"
+ fi
+ fi
+ status=$?
+ ;;
+ meld)
+ if merge_mode; then
+ touch "$BACKUP"
+ "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+ else
+ "$merge_tool_path" "$LOCAL" "$REMOTE"
+ fi
+ check_unchanged
+ ;;
+ diffuse)
+ if merge_mode; then
+ touch "$BACKUP"
+ fi
+ if $base_present; then
+ "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE" "$BASE" | cat
+ else
+ if merge_mode; then
+ "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE" | cat
+ else
+ "$merge_tool_path" "$LOCAL" "$REMOTE" | cat
+ fi
+ fi
+ check_unchanged
+ ;;
+ vimdiff)
+ if merge_mode; then
+ touch "$BACKUP"
+ "$merge_tool_path" -d -c "wincmd l" "$LOCAL" "$MERGED" "$REMOTE"
+ check_unchanged
+ else
+ "$merge_tool_path" -d -c "wincmd l" "$LOCAL" "$REMOTE"
+ fi
+ ;;
+ gvimdiff)
+ if merge_mode; then
+ touch "$BACKUP"
+ "$merge_tool_path" -d -c "wincmd l" -f "$LOCAL" "$MERGED" "$REMOTE"
+ check_unchanged
+ else
+ "$merge_tool_path" -d -c "wincmd l" -f "$LOCAL" "$REMOTE"
+ fi
+ ;;
+ xxdiff)
+ if merge_mode; then
+ touch "$BACKUP"
+ fi
+ if $base_present; then
+ "$merge_tool_path" -X --show-merged-pane \
+ -R 'Accel.SaveAsMerged: "Ctrl-S"' \
+ -R 'Accel.Search: "Ctrl+F"' \
+ -R 'Accel.SearchForward: "Ctrl-G"' \
+ --merged-file "$MERGED" "$LOCAL" "$BASE" "$REMOTE"
+ else
+ if merge_mode; then
+ "$merge_tool_path" -X $extra \
+ -R 'Accel.SaveAsMerged: "Ctrl-S"' \
+ -R 'Accel.Search: "Ctrl+F"' \
+ -R 'Accel.SearchForward: "Ctrl-G"' \
+ --merged-file "$MERGED" "$LOCAL" "$REMOTE"
+ else
+ "$merge_tool_path" \
+ -R 'Accel.Search: "Ctrl+F"' \
+ -R 'Accel.SearchForward: "Ctrl-G"' \
+ "$LOCAL" "$REMOTE"
+ fi
+ fi
+ check_unchanged
+ ;;
+ opendiff)
+ merge_mode && touch "$BACKUP"
+ if $base_present; then
+ "$merge_tool_path" "$LOCAL" "$REMOTE" \
+ -ancestor "$BASE" -merge "$MERGED" | cat
+ else
+ if merge_mode; then
+ "$merge_tool_path" "$LOCAL" "$REMOTE" \
+ -merge "$MERGED" | cat
+ else
+ "$merge_tool_path" "$LOCAL" "$REMOTE" | cat
+ fi
+ fi
+ check_unchanged
+ ;;
+ ecmerge)
+ merge_mode && touch "$BACKUP"
+ if $base_present; then
+ "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" \
+ --default --mode=merge3 --to="$MERGED"
+ else
+ "$merge_tool_path" "$LOCAL" "$REMOTE" \
+ --default --mode=merge2 --to="$MERGED"
+ fi
+ check_unchanged
+ ;;
+ emerge)
+ if $base_present; then
+ "$merge_tool_path" -f emerge-files-with-ancestor-command \
+ "$LOCAL" "$REMOTE" "$BASE" "$(basename "$MERGED")"
+ else
+ "$merge_tool_path" -f emerge-files-command \
+ "$LOCAL" "$REMOTE" "$(basename "$MERGED")"
+ fi
+ status=$?
+ ;;
+ tortoisemerge)
+ if $base_present; then
+ touch "$BACKUP"
+ "$merge_tool_path" -base:"$BASE" -mine:"$LOCAL" -theirs:"$REMOTE" -merged:"$MERGED"
+ check_unchanged
+ else
+ echo "TortoiseMerge cannot be used without a base" 1>&2
+ status=1
+ fi
+ ;;
+ *)
+ if test -n "$merge_tool_cmd"; then
+ if merge_mode &&
+ test "$merge_tool_trust_exit_code" = "false"; then
+ touch "$BACKUP"
+ ( eval $merge_tool_cmd )
+ check_unchanged
+ else
+ ( eval $merge_tool_cmd )
+ status=$?
+ fi
+ fi
+ ;;
+ esac
+ return $status
+}
+
+guess_merge_tool () {
+ if diff_mode; then
+ kompare="kompare"
+ fi
+ if test -n "$DISPLAY"; then
+ if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
+ tools="meld kdiff3 $kompare tkdiff"
+ tools="$tools xxdiff gvimdiff diffuse"
+ else
+ tools="kdiff3 $kompare tkdiff xxdiff"
+ tools="$tools meld gvimdiff diffuse"
+ fi
+ fi
+ if echo "${VISUAL:-$EDITOR}" | grep emacs > /dev/null 2>&1; then
+ # $EDITOR is emacs so add emerge as a candidate
+ tools="$tools emerge opendiff vimdiff"
+ elif echo "${VISUAL:-$EDITOR}" | grep vim > /dev/null 2>&1; then
+ # $EDITOR is vim so add vimdiff as a candidate
+ tools="$tools vimdiff opendiff emerge"
+ else
+ tools="$tools opendiff emerge vimdiff"
+ fi
+ echo >&2 "merge tool candidates: $tools"
+
+ # Loop over each candidate and stop when a valid merge tool is found.
+ for i in $tools
+ do
+ merge_tool_path="$(translate_merge_tool_path "$i")"
+ if type "$merge_tool_path" > /dev/null 2>&1; then
+ merge_tool="$i"
+ break
+ fi
+ done
+
+ if test -z "$merge_tool" ; then
+ echo >&2 "No known merge resolution program available."
+ return 1
+ fi
+ echo "$merge_tool"
+}
+
+get_configured_merge_tool () {
+ # Diff mode first tries diff.tool and falls back to merge.tool.
+ # Merge mode only checks merge.tool
+ if diff_mode; then
+ tool=$(git config diff.tool)
+ fi
+ if test -z "$tool"; then
+ tool=$(git config merge.tool)
+ fi
+ if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then
+ echo >&2 "git config option $TOOL_MODE.tool set to unknown tool: $merge_tool"
+ echo >&2 "Resetting to default..."
+ return 1
+ fi
+ echo "$tool"
+}
+
+get_merge_tool_path () {
+ # A merge tool has been set, so verify that it's valid.
+ if ! valid_tool "$merge_tool"; then
+ echo >&2 "Unknown merge tool $merge_tool"
+ exit 1
+ fi
+ if diff_mode; then
+ merge_tool_path=$(git config difftool."$merge_tool".path)
+ fi
+ if test -z "$merge_tool_path"; then
+ merge_tool_path=$(git config mergetool."$merge_tool".path)
+ fi
+ merge_tool_path="$(translate_merge_tool_path "$merge_tool" "$merge_tool_path")"
+ if test -z "$merge_tool_cmd" && ! type "$merge_tool_path" > /dev/null 2>&1; then
+ echo >&2 "The $TOOL_MODE tool $merge_tool is not available as '$merge_tool_path'"
+ exit 1
+ fi
+ echo "$merge_tool_path"
+}
+
+get_merge_tool () {
+ merge_tool="$1"
+ # Check if a merge tool has been configured
+ if test -z "$merge_tool"; then
+ merge_tool=$(get_configured_merge_tool)
+ fi
+ # Try to guess an appropriate merge tool if no tool has been set.
+ if test -z "$merge_tool"; then
+ merge_tool=$(guess_merge_tool) || exit
+ fi
+ echo "$merge_tool"
+}
diff --git a/git-mergetool.sh b/git-mergetool.sh
index cceebb7..efa31a2 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -11,7 +11,9 @@
USAGE='[--tool=tool] [-y|--no-prompt|--prompt] [file to merge] ...'
SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
+TOOL_MODE=merge
. git-sh-setup
+. git-mergetool--lib
require_work_tree
# Returns true if the mode reflects a symlink
@@ -110,22 +112,6 @@ resolve_deleted_merge () {
done
}
-check_unchanged () {
- if test "$MERGED" -nt "$BACKUP" ; then
- status=0;
- else
- while true; do
- echo "$MERGED seems unchanged."
- printf "Was the merge successful? [y/n] "
- read answer < /dev/tty
- case "$answer" in
- y*|Y*) status=0; break ;;
- n*|N*) status=1; break ;;
- esac
- done
- fi
-}
-
checkout_staged_file () {
tmpfile=$(expr "$(git checkout-index --temp --stage="$1" "$2")" : '\([^ ]*\) ')
@@ -188,107 +174,11 @@ merge_file () {
read ans
fi
- case "$merge_tool" in
- kdiff3)
- if base_present ; then
- ("$merge_tool_path" --auto --L1 "$MERGED (Base)" --L2 "$MERGED (Local)" --L3 "$MERGED (Remote)" \
- -o "$MERGED" "$BASE" "$LOCAL" "$REMOTE" > /dev/null 2>&1)
- else
- ("$merge_tool_path" --auto --L1 "$MERGED (Local)" --L2 "$MERGED (Remote)" \
- -o "$MERGED" "$LOCAL" "$REMOTE" > /dev/null 2>&1)
- fi
- status=$?
- ;;
- tkdiff)
- if base_present ; then
- "$merge_tool_path" -a "$BASE" -o "$MERGED" "$LOCAL" "$REMOTE"
- else
- "$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE"
- fi
- status=$?
- ;;
- meld)
- touch "$BACKUP"
- "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
- check_unchanged
- ;;
- vimdiff)
- touch "$BACKUP"
- "$merge_tool_path" -d -c "wincmd l" "$LOCAL" "$MERGED" "$REMOTE"
- check_unchanged
- ;;
- gvimdiff)
- touch "$BACKUP"
- "$merge_tool_path" -d -c "wincmd l" -f "$LOCAL" "$MERGED" "$REMOTE"
- check_unchanged
- ;;
- xxdiff)
- touch "$BACKUP"
- if base_present ; then
- "$merge_tool_path" -X --show-merged-pane \
- -R 'Accel.SaveAsMerged: "Ctrl-S"' \
- -R 'Accel.Search: "Ctrl+F"' \
- -R 'Accel.SearchForward: "Ctrl-G"' \
- --merged-file "$MERGED" "$LOCAL" "$BASE" "$REMOTE"
- else
- "$merge_tool_path" -X --show-merged-pane \
- -R 'Accel.SaveAsMerged: "Ctrl-S"' \
- -R 'Accel.Search: "Ctrl+F"' \
- -R 'Accel.SearchForward: "Ctrl-G"' \
- --merged-file "$MERGED" "$LOCAL" "$REMOTE"
- fi
- check_unchanged
- ;;
- opendiff)
- touch "$BACKUP"
- if base_present; then
- "$merge_tool_path" "$LOCAL" "$REMOTE" -ancestor "$BASE" -merge "$MERGED" | cat
- else
- "$merge_tool_path" "$LOCAL" "$REMOTE" -merge "$MERGED" | cat
- fi
- check_unchanged
- ;;
- ecmerge)
- touch "$BACKUP"
- if base_present; then
- "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" --default --mode=merge3 --to="$MERGED"
- else
- "$merge_tool_path" "$LOCAL" "$REMOTE" --default --mode=merge2 --to="$MERGED"
- fi
- check_unchanged
- ;;
- emerge)
- if base_present ; then
- "$merge_tool_path" -f emerge-files-with-ancestor-command "$LOCAL" "$REMOTE" "$BASE" "$(basename "$MERGED")"
- else
- "$merge_tool_path" -f emerge-files-command "$LOCAL" "$REMOTE" "$(basename "$MERGED")"
- fi
- status=$?
- ;;
- tortoisemerge)
- if base_present ; then
- touch "$BACKUP"
- "$merge_tool_path" -base:"$BASE" -mine:"$LOCAL" -theirs:"$REMOTE" -merged:"$MERGED"
- check_unchanged
- else
- echo "TortoiseMerge cannot be used without a base" 1>&2
- status=1
- fi
- ;;
- *)
- if test -n "$merge_tool_cmd"; then
- if test "$merge_tool_trust_exit_code" = "false"; then
- touch "$BACKUP"
- ( eval $merge_tool_cmd )
- check_unchanged
- else
- ( eval $merge_tool_cmd )
- status=$?
- fi
- fi
- ;;
- esac
- if test "$status" -ne 0; then
+ present=false
+ base_present &&
+ present=true
+
+ if ! run_merge_tool "$merge_tool" "$present"; then
echo "merge of $MERGED failed" 1>&2
mv -- "$BACKUP" "$MERGED"
@@ -347,44 +237,6 @@ do
shift
done
-valid_custom_tool()
-{
- merge_tool_cmd="$(git config mergetool.$1.cmd)"
- test -n "$merge_tool_cmd"
-}
-
-valid_tool() {
- case "$1" in
- kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge | tortoisemerge)
- ;; # happy
- *)
- if ! valid_custom_tool "$1"; then
- return 1
- fi
- ;;
- esac
-}
-
-init_merge_tool_path() {
- merge_tool_path=$(git config mergetool.$1.path)
- if test -z "$merge_tool_path" ; then
- case "$1" in
- vimdiff)
- merge_tool_path=vim
- ;;
- gvimdiff)
- merge_tool_path=gvim
- ;;
- emerge)
- merge_tool_path=emacs
- ;;
- *)
- merge_tool_path=$1
- ;;
- esac
- fi
-}
-
prompt_after_failed_merge() {
while true; do
printf "Continue merging other unresolved paths (y/n) ? "
@@ -402,62 +254,12 @@ prompt_after_failed_merge() {
done
}
-if test -z "$merge_tool"; then
- merge_tool=$(git config merge.tool)
- if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then
- echo >&2 "git config option merge.tool set to unknown tool: $merge_tool"
- echo >&2 "Resetting to default..."
- unset merge_tool
- fi
-fi
-
-if test -z "$merge_tool" ; then
- if test -n "$DISPLAY"; then
- if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
- merge_tool_candidates="meld kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse"
- else
- merge_tool_candidates="kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse"
- fi
- fi
- if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then
- merge_tool_candidates="$merge_tool_candidates emerge opendiff vimdiff"
- elif echo "${VISUAL:-$EDITOR}" | grep 'vim' > /dev/null 2>&1; then
- merge_tool_candidates="$merge_tool_candidates vimdiff opendiff emerge"
- else
- merge_tool_candidates="$merge_tool_candidates opendiff emerge vimdiff"
- fi
- echo "merge tool candidates: $merge_tool_candidates"
- for i in $merge_tool_candidates; do
- init_merge_tool_path $i
- if type "$merge_tool_path" > /dev/null 2>&1; then
- merge_tool=$i
- break
- fi
- done
- if test -z "$merge_tool" ; then
- echo "No known merge resolution program available."
- exit 1
- fi
-else
- if ! valid_tool "$merge_tool"; then
- echo >&2 "Unknown merge_tool $merge_tool"
- exit 1
- fi
-
- init_merge_tool_path "$merge_tool"
-
- merge_keep_backup="$(git config --bool merge.keepBackup || echo true)"
- merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)"
-
- if test -z "$merge_tool_cmd" && ! type "$merge_tool_path" > /dev/null 2>&1; then
- echo "The merge tool $merge_tool is not available as '$merge_tool_path'"
- exit 1
- fi
-
- if ! test -z "$merge_tool_cmd"; then
- merge_tool_trust_exit_code="$(git config --bool mergetool.$merge_tool.trustExitCode || echo false)"
- fi
-fi
+merge_tool=$(get_merge_tool "$merge_tool") || exit
+merge_tool_cmd="$(get_merge_tool_cmd "$merge_tool")"
+merge_tool_path="$(get_merge_tool_path "$merge_tool")" || exit
+merge_keep_backup="$(git config --bool merge.keepBackup || echo true)"
+merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)"
+merge_tool_trust_exit_code="$(git config --bool mergetool."$merge_tool".trustExitCode || echo false)"
last_status=0
rollup_status=0
--
1.6.2.2.414.g81aa9
^ permalink raw reply related
* Re: [PATCH v2] mergetool--lib: add new merge tool TortoiseMerge
From: David Aguilar @ 2009-04-06 9:27 UTC (permalink / raw)
To: Brian Gernhardt; +Cc: gitster, markus.heidelberg, charles, git
In-Reply-To: <DB42161D-8B55-4739-B418-D286B280EFF8@silverinsanity.com>
On 0, Brian Gernhardt <benji@silverinsanity.com> wrote:
>
> On Apr 5, 2009, at 12:00 AM, David Aguilar wrote:
>
>> valid_tool () {
>> case "$1" in
>> <lots-of-stuff>)
>> if test "$1" = "kompare" && ! diff_mode; then
>> return 1
>> fi
>> + if test "$1" = "tortoisemerge" && ! merge_mode; then
>> + return 1
>> + fi
>> ;; # happy
>> *)
>> if test -z "$(get_merge_tool_cmd "$1")"; then
>
> Why is `case "$1"` being followed by two `if test "$1" =`s?
> Wouldn't it be simpler to have separate case arms for them?
> Especially with how long that list is getting...
>
> ~~ Brian
It would. It wasn't until after the rewrite that I remembered
this email... oh well [PATCH v2 14/14] it is
--
David
^ permalink raw reply
* Re: git diff bug?
From: David Abrahams @ 2009-04-06 9:09 UTC (permalink / raw)
To: Jeff King; +Cc: git
In-Reply-To: <20090404014527.GA13350@coredump.intra.peff.net>
On Apr 3, 2009, at 9:45 PM, Jeff King wrote:
> On Fri, Apr 03, 2009 at 09:10:42PM -0400, David Abrahams wrote:
>
>> Please see
>> http://github.com/techarcana/elisp/commit/63d672c296316c85690085930b05c642b88a9978#diff-2
>>
>> Note how the @@ ... @@ clauses are followed by text from the previous
>> line's comment. Not sure, but this strikes me as a line-ending
>> issue.
>> custom.el was originally built on a linux machine; now I'm using a
>> Mac.
>
> This is as designed. The original file ("git show e7dd7db") contains
> (my
> numbering seems different than what git produces; it is produced by
> "nl"
> which is maybe treating some line endings differently earlier in the
> file):
>
> 102 '(mm-attachment-override-types (quote ("text/x-vcard"
> "application/pkcs7-mime" "application/x-pkcs7-mime" "application/
> pkcs7-signature" "application/x-pkcs7-signature" "image/*")) nil nil "
> 103 Added image/* to display attached images inline")
> 104 '(mm-discouraged-alternatives (quote ("text/html" "text/
> richtext" "image/.*")) nil nil "
> 105 The documentation for this variable says it all")
> 106 '(mm-inline-text-html-with-images t)
> 107 '(muse-project-alist (quote (("WikiPlanner" ("~/
> plans" :default "index" :major-mode planner-mode :visit-link planner-
> visit-link)))))
> 108 '(org-agenda-files (quote ("~/organizer.org")))
>
> The changed text in your diff starts on 108. So we show 105-107 as
> context lines. The text after the @@ clause is the "function header";
> this is equivalent to "-p" in GNU diff. It's basically a guess about
> the
> most interesting context to show, and looks alphabetic characters that
> are left-aligned. In the case of lisp, it really isn't all that
> interesting (and what looks so weird is that your file contains
> a lot of
>
> "\nSome text"
>
> so the text strings are all left-aligned. You can customize the regex
> used to guess at the function header. See "defining a custom
> hunk-header" in "git help attributes".
Hmm, so I tried sticking this .gitattributes in my repo
*.el diff=el
[diff "el"]
xfuncname = "^(\\(def[a-z]+ .+)$"
and git diff barfed with
"el"] is not a valid attribute name: .gitattributes:2
"^(\\(def[a-z]+ is not a valid attribute name: .gitattributes:3
What am I missing? I tried googling, but from what turns up for me,
it doesn't look like anyone else has ever tried to use this feature!
TIA,
--
David Abrahams
BoostPro Computing
http://boostpro.com
^ permalink raw reply
* Re: [PATCH] mailmap: resurrect lower-casing of email addresses
From: Johannes Schindelin @ 2009-04-06 9:16 UTC (permalink / raw)
To: A Large Angry SCM; +Cc: Junio C Hamano, git
In-Reply-To: <49D6B8C8.8090304@gmail.com>
Hi,
On Fri, 3 Apr 2009, A Large Angry SCM wrote:
> Sorry, this is not a flame war (and as Peff already sent a response that
> superior to my own) so I'll let Junio decide.
Thanks for keeping a cool head where I failed. My sincere apologies.
> However, to keep the peace (and as a thank you for all the hard work to
> date, I'll say that I'm scheduled to be be Germany and Munich the first
> 10 days in October and I'll buy the first $100 dollars in drinks at any
> meet that participate in (as a thank you to all the hard work for git
> that has been performed) that may happen that I participate in).
I'll take you up on that!
Ciao,
Dscho
^ permalink raw reply
* Re: non-ascii filenames issue
From: Johannes Schindelin @ 2009-04-06 9:12 UTC (permalink / raw)
To: Peter Krefting; +Cc: Teemu Likonen, git
In-Reply-To: <alpine.DEB.2.00.0904060823400.21376@ds9.cixit.se>
Hi,
On Mon, 6 Apr 2009, Peter Krefting wrote:
> It comes from the Unix tradition, unfortunately, that file names are
> just a stream of bytes, instead of a stream of characters mapped to a
> byte sequence.
How is that different from .txt not having a defined locale?
Really, please, do not add to the non-information.
> Since most people on Linux nowadays probably are running in a
> UTF-8-based locale, I tried introducing some (very incomplete) patches
> for the Windows port to make this assumption, to allow Windows users to
> make use of non-ASCII file names (Windows uses Unicode strings for file
> names). Mac OS uses (semi-decomposed) UTF-8 strings, so it should also
> be able to make use of this.
Most Russian programmers I know do not run in a UTF-8 locale.
> Unfortunately, there seems to be quite some resistance towards deciding
> on a platform- and language-independent way of storing file names in
> Git, but rather just going the "Unix" way and making it someone elses
> problem. I find this a bit sad.
I find it a bit unfair that you say that, after many people participated
in that very informative thread, and after I tried to work with you
personally on getting the stuff into 4msysgit.git.
Actually, not just only a bit.
Ciao,
Dscho
^ permalink raw reply
* [PATCH 10/14] difftool: add various git-difftool tests
From: David Aguilar @ 2009-04-06 8:31 UTC (permalink / raw)
To: gitster; +Cc: git, charles, markus.heidelberg, David Aguilar
In-Reply-To: <1239006689-14695-10-git-send-email-davvid@gmail.com>
t7800-difftool.sh tests the various command-line flags,
git-config variables, and environment settings supported by
git-difftool.
Signed-off-by: David Aguilar <davvid@gmail.com>
---
t/t7800-difftool.sh | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 147 insertions(+), 0 deletions(-)
create mode 100755 t/t7800-difftool.sh
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
new file mode 100755
index 0000000..85946d9
--- /dev/null
+++ b/t/t7800-difftool.sh
@@ -0,0 +1,147 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 David Aguilar
+#
+
+test_description='git-difftool
+
+Testing basic diff tool invocation
+'
+
+. ./test-lib.sh
+
+remove_config_vars()
+{
+ # Unset all config variables used by git-difftool
+ git config --unset diff.tool
+ git config --unset difftool.test-tool.cmd
+ git config --unset merge.tool
+ git config --unset mergetool.test-tool.cmd
+ return 0
+}
+
+restore_test_defaults()
+{
+ # Restores the test defaults used by several tests
+ remove_config_vars
+ unset GIT_DIFF_TOOL
+ unset GIT_MERGE_TOOL
+ unset GIT_DIFFTOOL_NO_PROMPT
+ git config diff.tool test-tool &&
+ git config difftool.test-tool.cmd 'cat $LOCAL'
+}
+
+# Create a file on master and change it on branch
+test_expect_success 'setup' '
+ echo master >file &&
+ git add file &&
+ git commit -m "added file" &&
+
+ git checkout -b branch master &&
+ echo branch >file &&
+ git commit -a -m "branch changed file" &&
+ git checkout master
+'
+
+# Configure a custom difftool.<tool>.cmd and use it
+test_expect_success 'custom commands' '
+ restore_test_defaults &&
+ git config difftool.test-tool.cmd "cat \$REMOTE" &&
+
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "master" &&
+
+ restore_test_defaults &&
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "branch"
+'
+
+# Ensures that git-difftool ignores bogus --tool values
+test_expect_success 'difftool ignores bad --tool values' '
+ diff=$(git difftool --no-prompt --tool=bogus-tool branch)
+ test "$?" = 1 &&
+ test "$diff" = ""
+'
+
+# Specify the diff tool using $GIT_DIFF_TOOL
+test_expect_success 'GIT_DIFF_TOOL variable' '
+ git config --unset diff.tool
+ GIT_DIFF_TOOL=test-tool &&
+ export GIT_DIFF_TOOL &&
+
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
+# Test the $GIT_*_TOOL variables and ensure
+# that $GIT_DIFF_TOOL always wins unless --tool is specified
+test_expect_success 'GIT_DIFF_TOOL overrides' '
+ git config diff.tool bogus-tool &&
+ git config merge.tool bogus-tool &&
+
+ GIT_MERGE_TOOL=test-tool &&
+ export GIT_MERGE_TOOL &&
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "branch" &&
+ unset GIT_MERGE_TOOL &&
+
+ GIT_MERGE_TOOL=bogus-tool &&
+ GIT_DIFF_TOOL=test-tool &&
+ export GIT_MERGE_TOOL &&
+ export GIT_DIFF_TOOL &&
+
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "branch" &&
+
+ GIT_DIFF_TOOL=bogus-tool &&
+ export GIT_DIFF_TOOL &&
+
+ diff=$(git difftool --no-prompt --tool=test-tool branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
+# Test that we don't have to pass --no-prompt to difftool
+# when $GIT_DIFFTOOL_NO_PROMPT is true
+test_expect_success 'GIT_DIFFTOOL_NO_PROMPT variable' '
+ GIT_DIFFTOOL_NO_PROMPT=true &&
+ export GIT_DIFFTOOL_NO_PROMPT &&
+
+ diff=$(git difftool branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
+# git-difftool falls back to git-mergetool config variables
+# so test that behavior here
+test_expect_success 'difftool + mergetool config variables' '
+ remove_config_vars
+ git config merge.tool test-tool &&
+ git config mergetool.test-tool.cmd "cat \$LOCAL" &&
+
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "branch" &&
+
+ # set merge.tool to something bogus, diff.tool to test-tool
+ git config merge.tool bogus-tool &&
+ git config diff.tool test-tool &&
+
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
+test_expect_success 'difftool.<tool>.path' '
+ git config difftool.tkdiff.path echo &&
+ diff=$(git difftool --no-prompt -t tkdiff branch) &&
+ git config --unset difftool.tkdiff.path &&
+ lines=$(echo "$diff" | grep file | wc -l) &&
+ test "$lines" = 1
+'
+
+test_done
--
1.6.2.2.414.g81aa9
^ permalink raw reply related
* [PATCH 11/14] difftool: add support for a difftool.prompt config variable
From: David Aguilar @ 2009-04-06 8:31 UTC (permalink / raw)
To: gitster; +Cc: git, charles, markus.heidelberg, David Aguilar
In-Reply-To: <1239006689-14695-11-git-send-email-davvid@gmail.com>
difftool now supports difftool.prompt so that users do not have to
pass --no-prompt or hit enter each time a diff tool is launched.
The --prompt flag overrides the configuration variable.
Signed-off-by: David Aguilar <davvid@gmail.com>
---
Documentation/config.txt | 3 ++
Documentation/git-difftool.txt | 10 +++++-
git-difftool--helper.sh | 10 +++++-
git-difftool.perl | 15 +++++++--
t/t7800-difftool.sh | 64 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 96 insertions(+), 6 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 185a9ef..79c8b66 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -684,6 +684,9 @@ difftool.<tool>.cmd::
is set to the name of the temporary file containing the contents
of the diff post-image.
+difftool.prompt::
+ Prompt before each invocation of the diff tool.
+
diff.wordRegex::
A POSIX Extended Regular Expression used to determine what is a "word"
when performing word-by-word difference calculations. Character
diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt
index a2fa474..d2d762c 100644
--- a/Documentation/git-difftool.txt
+++ b/Documentation/git-difftool.txt
@@ -7,7 +7,7 @@ git-difftool - Show changes using common diff tools
SYNOPSIS
--------
-'git difftool' [-t|--tool=<tool>] [-y|--no-prompt] [<'git diff' options>]
+'git difftool' [-t|--tool=<tool>] [-y|--no-prompt|--prompt] [<'git diff' options>]
DESCRIPTION
-----------
@@ -21,6 +21,11 @@ OPTIONS
--no-prompt::
Do not prompt before launching a diff tool.
+--prompt::
+ Prompt before each invocation of the diff tool.
+ This is the default behaviour; the option is provided to
+ override any configuration settings.
+
-t <tool>::
--tool=<tool>::
Use the diff tool specified by <tool>.
@@ -72,6 +77,9 @@ difftool.<tool>.cmd::
+
See the `--tool=<tool>` option above for more details.
+difftool.prompt::
+ Prompt before each invocation of the diff tool.
+
SEE ALSO
--------
linkgit:git-diff[1]::
diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
index fc61416..f3c27d8 100755
--- a/git-difftool--helper.sh
+++ b/git-difftool--helper.sh
@@ -5,9 +5,15 @@
#
# Copyright (c) 2009 David Aguilar
-# Set GIT_DIFFTOOL_NO_PROMPT to bypass the per-file prompt.
+# difftool.prompt controls the default prompt/no-prompt behavior
+# and is overridden with $GIT_DIFFTOOL*_PROMPT.
should_prompt () {
- test -z "$GIT_DIFFTOOL_NO_PROMPT"
+ prompt=$(git config --bool difftool.prompt || echo true)
+ if test "$prompt" = true; then
+ test -z "$GIT_DIFFTOOL_NO_PROMPT"
+ else
+ test -n "$GIT_DIFFTOOL_PROMPT"
+ fi
}
# This function prepares temporary files and launches the appropriate
diff --git a/git-difftool.perl b/git-difftool.perl
index 8857ac8..948ff7f 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -2,9 +2,12 @@
# Copyright (c) 2009 David Aguilar
#
# This is a wrapper around the GIT_EXTERNAL_DIFF-compatible
-# git-difftool--helper script. This script exports
-# GIT_EXTERNAL_DIFF and GIT_PAGER for use by git, and
-# GIT_DIFFTOOL_NO_PROMPT and GIT_DIFF_TOOL for use by git-difftool--helper.
+# git-difftool--helper script.
+#
+# This script exports GIT_EXTERNAL_DIFF and GIT_PAGER for use by git.
+# GIT_DIFFTOOL_NO_PROMPT, GIT_DIFFTOOL_PROMPT, and GIT_DIFF_TOOL
+# are exported for use by git-difftool--helper.
+#
# Any arguments that are unknown to this script are forwarded to 'git diff'.
use strict;
@@ -62,6 +65,12 @@ sub generate_command
}
if ($arg eq '-y' || $arg eq '--no-prompt') {
$ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';
+ delete $ENV{GIT_DIFFTOOL_PROMPT};
+ next;
+ }
+ if ($arg eq '--prompt') {
+ $ENV{GIT_DIFFTOOL_PROMPT} = 'true';
+ delete $ENV{GIT_DIFFTOOL_NO_PROMPT};
next;
}
if ($arg eq '-h' || $arg eq '--help') {
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 85946d9..0b263ea 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -15,6 +15,7 @@ remove_config_vars()
# Unset all config variables used by git-difftool
git config --unset diff.tool
git config --unset difftool.test-tool.cmd
+ git config --unset difftool.prompt
git config --unset merge.tool
git config --unset mergetool.test-tool.cmd
return 0
@@ -26,11 +27,18 @@ restore_test_defaults()
remove_config_vars
unset GIT_DIFF_TOOL
unset GIT_MERGE_TOOL
+ unset GIT_DIFFTOOL_PROMPT
unset GIT_DIFFTOOL_NO_PROMPT
git config diff.tool test-tool &&
git config difftool.test-tool.cmd 'cat $LOCAL'
}
+prompt_given()
+{
+ prompt="$1"
+ test "$prompt" = "Hit return to launch 'test-tool': branch"
+}
+
# Create a file on master and change it on branch
test_expect_success 'setup' '
echo master >file &&
@@ -116,6 +124,62 @@ test_expect_success 'GIT_DIFFTOOL_NO_PROMPT variable' '
restore_test_defaults
'
+# git-difftool supports the difftool.prompt variable.
+# Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false
+test_expect_success 'GIT_DIFFTOOL_PROMPT variable' '
+ git config difftool.prompt false &&
+ GIT_DIFFTOOL_PROMPT=true &&
+ export GIT_DIFFTOOL_PROMPT &&
+
+ prompt=$(echo | git difftool --prompt branch | tail -1) &&
+ prompt_given "$prompt" &&
+
+ restore_test_defaults
+'
+
+# Test that we don't have to pass --no-prompt when difftool.prompt is false
+test_expect_success 'difftool.prompt config variable is false' '
+ git config difftool.prompt false &&
+
+ diff=$(git difftool branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
+# Test that the -y flag can override difftool.prompt = true
+test_expect_success 'difftool.prompt can overridden with -y' '
+ git config difftool.prompt true &&
+
+ diff=$(git difftool -y branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
+# Test that the --prompt flag can override difftool.prompt = false
+test_expect_success 'difftool.prompt can overridden with --prompt' '
+ git config difftool.prompt false &&
+
+ prompt=$(echo | git difftool --prompt branch | tail -1) &&
+ prompt_given "$prompt" &&
+
+ restore_test_defaults
+'
+
+# Test that the last flag passed on the command-line wins
+test_expect_success 'difftool last flag wins' '
+ diff=$(git difftool --prompt --no-prompt branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults &&
+
+ prompt=$(echo | git difftool --no-prompt --prompt branch | tail -1) &&
+ prompt_given "$prompt" &&
+
+ restore_test_defaults
+'
+
# git-difftool falls back to git-mergetool config variables
# so test that behavior here
test_expect_success 'difftool + mergetool config variables' '
--
1.6.2.2.414.g81aa9
^ permalink raw reply related
* [PATCH 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib
From: David Aguilar @ 2009-04-06 8:31 UTC (permalink / raw)
To: gitster; +Cc: git, charles, markus.heidelberg, David Aguilar
In-Reply-To: <1239006689-14695-14-git-send-email-davvid@gmail.com>
This consolidates the common functionality from git-mergetool and
git-difftool--helper into a single git-mergetool--lib scriptlet.
Signed-off-by: David Aguilar <davvid@gmail.com>
---
.gitignore | 1 +
Documentation/git-mergetool--lib.txt | 56 ++++++
Makefile | 1 +
git-difftool--helper.sh | 186 +-----------------
git-mergetool--lib.sh | 346 ++++++++++++++++++++++++++++++++++
git-mergetool.sh | 224 ++---------------------
6 files changed, 426 insertions(+), 388 deletions(-)
create mode 100644 Documentation/git-mergetool--lib.txt
create mode 100644 git-mergetool--lib.sh
diff --git a/.gitignore b/.gitignore
index a36da9d..757c7f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -80,6 +80,7 @@ git-merge-recursive
git-merge-resolve
git-merge-subtree
git-mergetool
+git-mergetool--lib
git-mktag
git-mktree
git-name-rev
diff --git a/Documentation/git-mergetool--lib.txt b/Documentation/git-mergetool--lib.txt
new file mode 100644
index 0000000..3d57031
--- /dev/null
+++ b/Documentation/git-mergetool--lib.txt
@@ -0,0 +1,56 @@
+git-mergetool--lib(1)
+=====================
+
+NAME
+----
+git-mergetool--lib - Common git merge tool shell scriptlets
+
+SYNOPSIS
+--------
+'. "$(git --exec-path)/git-mergetool--lib"'
+
+DESCRIPTION
+-----------
+
+This is not a command the end user would want to run. Ever.
+This documentation is meant for people who are studying the
+Porcelain-ish scripts and/or are writing new ones.
+
+The 'git-mergetool--lib' scriptlet is designed to be sourced (using
+`.`) by other shell scripts to set up functions for working
+with git merge tools.
+
+Before sourcing it, your script should set up a few variables;
+`TOOL_MODE` is used to define the operation mode for various
+functions. 'diff' and 'merge' are valid values.
+
+FUNCTIONS
+---------
+get_merge_tool::
+ returns a merge tool
+
+get_merge_tool_cmd::
+ returns the custom command for a merge tool.
+
+get_merge_tool_path::
+ returns the custom path for a merge tool.
+
+run_merge_tool::
+ launches a merge tool given the tool name and a true/false
+ flag to indicate whether a merge base is present.
+ '$merge_tool', '$merge_tool_path', and for custom commands,
+ '$merge_tool_cmd', must be defined prior to calling
+ run_merge_tool. Additionally, '$MERGED', '$LOCAL', '$REMOTE',
+ and '$BASE' must be defined for use by the merge tool.
+
+Author
+------
+Written by David Aguilar <davvid@gmail.com>
+
+Documentation
+--------------
+Documentation by David Aguilar and the git-list <git@vger.kernel.org>.
+
+GIT
+---
+Part of the linkgit:git[1] suite
diff --git a/Makefile b/Makefile
index a80055f..3e56274 100644
--- a/Makefile
+++ b/Makefile
@@ -284,6 +284,7 @@ SCRIPT_SH += git-merge-octopus.sh
SCRIPT_SH += git-merge-one-file.sh
SCRIPT_SH += git-merge-resolve.sh
SCRIPT_SH += git-mergetool.sh
+SCRIPT_SH += git-mergetool--lib.sh
SCRIPT_SH += git-parse-remote.sh
SCRIPT_SH += git-pull.sh
SCRIPT_SH += git-quiltimport.sh
diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
index f3c27d8..b450036 100755
--- a/git-difftool--helper.sh
+++ b/git-difftool--helper.sh
@@ -5,6 +5,10 @@
#
# Copyright (c) 2009 David Aguilar
+# Load common functions from git-mergetool--lib
+TOOL_MODE=diff
+. git-mergetool--lib
+
# difftool.prompt controls the default prompt/no-prompt behavior
# and is overridden with $GIT_DIFFTOOL*_PROMPT.
should_prompt () {
@@ -16,8 +20,7 @@ should_prompt () {
fi
}
-# This function prepares temporary files and launches the appropriate
-# merge tool.
+# Sets up shell variables and runs a merge tool
launch_merge_tool () {
# Merged is the filename as it appears in the work tree
# Local is the contents of a/filename
@@ -37,187 +40,16 @@ launch_merge_tool () {
fi
# Run the appropriate merge tool command
- case "$merge_tool" in
- kdiff3)
- basename=$(basename "$MERGED")
- "$merge_tool_path" --auto \
- --L1 "$basename (A)" \
- --L2 "$basename (B)" \
- "$LOCAL" "$REMOTE" \
- > /dev/null 2>&1
- ;;
-
- kompare)
- "$merge_tool_path" "$LOCAL" "$REMOTE"
- ;;
-
- tkdiff)
- "$merge_tool_path" "$LOCAL" "$REMOTE"
- ;;
-
- meld)
- "$merge_tool_path" "$LOCAL" "$REMOTE"
- ;;
-
- diffuse)
- "$merge_tool_path" "$LOCAL" "$REMOTE" | cat
- ;;
-
- vimdiff)
- "$merge_tool_path" -d -c "wincmd l" "$LOCAL" "$REMOTE"
- ;;
-
- gvimdiff)
- "$merge_tool_path" -d -c "wincmd l" -f "$LOCAL" "$REMOTE"
- ;;
-
- xxdiff)
- "$merge_tool_path" \
- -R 'Accel.Search: "Ctrl+F"' \
- -R 'Accel.SearchForward: "Ctrl-G"' \
- "$LOCAL" "$REMOTE"
- ;;
-
- opendiff)
- "$merge_tool_path" "$LOCAL" "$REMOTE" | cat
- ;;
-
- ecmerge)
- "$merge_tool_path" "$LOCAL" "$REMOTE" \
- --default --mode=merge2 --to="$MERGED"
- ;;
-
- emerge)
- "$merge_tool_path" -f emerge-files-command \
- "$LOCAL" "$REMOTE" "$(basename "$MERGED")"
- ;;
-
- *)
- if test -n "$merge_tool_cmd"; then
- ( eval $merge_tool_cmd )
- fi
- ;;
- esac
-}
-
-# Verifies that (difftool|mergetool).<tool>.cmd exists
-valid_custom_tool() {
- merge_tool_cmd="$(git config difftool.$1.cmd)"
- test -z "$merge_tool_cmd" &&
- merge_tool_cmd="$(git config mergetool.$1.cmd)"
- test -n "$merge_tool_cmd"
-}
-
-# Verifies that the chosen merge tool is properly setup.
-# Built-in merge tools are always valid.
-valid_tool() {
- case "$1" in
- kdiff3 | kompare | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge)
- ;; # happy
- *)
- if ! valid_custom_tool "$1"
- then
- return 1
- fi
- ;;
- esac
-}
-
-# Sets up the merge_tool_path variable.
-# This handles the difftool.<tool>.path configuration.
-# This also falls back to mergetool defaults.
-init_merge_tool_path() {
- merge_tool_path=$(git config difftool."$1".path)
- test -z "$merge_tool_path" &&
- merge_tool_path=$(git config mergetool."$1".path)
- if test -z "$merge_tool_path"; then
- case "$1" in
- vimdiff)
- merge_tool_path=vim
- ;;
- gvimdiff)
- merge_tool_path=gvim
- ;;
- emerge)
- merge_tool_path=emacs
- ;;
- *)
- merge_tool_path="$1"
- ;;
- esac
- fi
+ run_merge_tool "$merge_tool"
}
# Allow GIT_DIFF_TOOL and GIT_MERGE_TOOL to provide default values
test -n "$GIT_MERGE_TOOL" && merge_tool="$GIT_MERGE_TOOL"
test -n "$GIT_DIFF_TOOL" && merge_tool="$GIT_DIFF_TOOL"
-# If merge tool was not specified then use the diff.tool
-# configuration variable. If that's invalid then reset merge_tool.
-# Fallback to merge.tool.
-if test -z "$merge_tool"; then
- merge_tool=$(git config diff.tool)
- test -z "$merge_tool" &&
- merge_tool=$(git config merge.tool)
- if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then
- echo >&2 "git config option diff.tool set to unknown tool: $merge_tool"
- echo >&2 "Resetting to default..."
- unset merge_tool
- fi
-fi
-
-# Try to guess an appropriate merge tool if no tool has been set.
-if test -z "$merge_tool"; then
- # We have a $DISPLAY so try some common UNIX merge tools
- if test -n "$DISPLAY"; then
- # If gnome then prefer meld, otherwise, prefer kdiff3 or kompare
- if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
- merge_tool_candidates="meld kdiff3 kompare tkdiff xxdiff gvimdiff diffuse"
- else
- merge_tool_candidates="kdiff3 kompare tkdiff xxdiff meld gvimdiff diffuse"
- fi
- fi
- if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then
- # $EDITOR is emacs so add emerge as a candidate
- merge_tool_candidates="$merge_tool_candidates emerge opendiff vimdiff"
- elif echo "${VISUAL:-$EDITOR}" | grep 'vim' > /dev/null 2>&1; then
- # $EDITOR is vim so add vimdiff as a candidate
- merge_tool_candidates="$merge_tool_candidates vimdiff opendiff emerge"
- else
- merge_tool_candidates="$merge_tool_candidates opendiff emerge vimdiff"
- fi
- echo "merge tool candidates: $merge_tool_candidates"
-
- # Loop over each candidate and stop when a valid merge tool is found.
- for i in $merge_tool_candidates
- do
- init_merge_tool_path $i
- if type "$merge_tool_path" > /dev/null 2>&1; then
- merge_tool=$i
- break
- fi
- done
-
- if test -z "$merge_tool" ; then
- echo "No known merge resolution program available."
- exit 1
- fi
-
-else
- # A merge tool has been set, so verify that it's valid.
- if ! valid_tool "$merge_tool"; then
- echo >&2 "Unknown merge tool $merge_tool"
- exit 1
- fi
-
- init_merge_tool_path "$merge_tool"
-
- if test -z "$merge_tool_cmd" && ! type "$merge_tool_path" > /dev/null 2>&1; then
- echo "The merge tool $merge_tool is not available as '$merge_tool_path'"
- exit 1
- fi
-fi
-
+merge_tool=$(get_merge_tool "$merge_tool") || exit
+merge_tool_cmd="$(get_merge_tool_cmd "$merge_tool")"
+merge_tool_path="$(get_merge_tool_path "$merge_tool")" || exit
# Launch the merge tool on each path provided by 'git diff'
while test $# -gt 6
diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh
new file mode 100644
index 0000000..fa1d0ff
--- /dev/null
+++ b/git-mergetool--lib.sh
@@ -0,0 +1,346 @@
+# git-mergetool--lib is a library for common merge tool functions
+diff_mode() {
+ test $TOOL_MODE = "diff"
+}
+
+merge_mode() {
+ test $TOOL_MODE = "merge"
+}
+
+translate_merge_tool_path () {
+ if test -n "$2"; then
+ echo "$2"
+ else
+ case "$1" in
+ vimdiff)
+ path=vim
+ ;;
+ gvimdiff)
+ path=gvim
+ ;;
+ emerge)
+ path=emacs
+ ;;
+ *)
+ path="$1"
+ ;;
+ esac
+ echo "$path"
+ fi
+}
+
+check_unchanged () {
+ if merge_mode; then
+ if test "$MERGED" -nt "$BACKUP"; then
+ status=0
+ else
+ while true; do
+ echo "$MERGED seems unchanged."
+ printf "Was the merge successful? [y/n] "
+ read answer < /dev/tty
+ case "$answer" in
+ y*|Y*) status=0; break ;;
+ n*|N*) status=1; break ;;
+ esac
+ done
+ fi
+ else
+ status=0
+ fi
+ return $status
+}
+
+valid_tool () {
+ case "$1" in
+ kdiff3 | tkdiff | xxdiff | meld | opendiff | \
+ emerge | vimdiff | gvimdiff | ecmerge | diffuse)
+ return 0
+ ;; # happy
+ esac
+ if merge_mode && test "$1" = tortoisemerge; then
+ return 0
+ fi
+ if diff_mode && test "$1" = kompare; then
+ return 0
+ fi
+ test -n "$(get_merge_tool_cmd "$1")"
+}
+
+get_merge_tool_cmd () {
+ diff_mode &&
+ custom_cmd="$(git config difftool.$1.cmd)"
+ test -z "$custom_cmd" &&
+ custom_cmd="$(git config mergetool.$1.cmd)"
+ test -n "$custom_cmd" &&
+ echo "$custom_cmd"
+}
+
+run_merge_tool () {
+ base_present="$2"
+ if diff_mode; then
+ base_present="false"
+ fi
+ if test -z "$base_present"; then
+ base_present="true"
+ fi
+
+ case "$1" in
+ kdiff3)
+ if $base_present; then
+ ("$merge_tool_path" --auto \
+ --L1 "$MERGED (Base)" --L2 "$MERGED (Local)" --L3 "$MERGED (Remote)" \
+ -o "$MERGED" "$BASE" "$LOCAL" "$REMOTE" > /dev/null 2>&1)
+ else
+ if merge_mode; then
+ ("$merge_tool_path" --auto \
+ --L1 "$MERGED (Local)" \
+ --L2 "$MERGED (Remote)" \
+ -o "$MERGED" "$LOCAL" "$REMOTE" \
+ > /dev/null 2>&1)
+ else
+ ("$merge_tool_path" --auto \
+ --L1 "$MERGED (A)" \
+ --L2 "$MERGED (B)" \
+ "$LOCAL" "$REMOTE" \
+ > /dev/null 2>&1)
+ fi
+ fi
+ status=$?
+ ;;
+ kompare)
+ "$merge_tool_path" "$LOCAL" "$REMOTE"
+ status=$?
+ ;;
+ tkdiff)
+ if $base_present; then
+ "$merge_tool_path" -a "$BASE" -o "$MERGED" "$LOCAL" "$REMOTE"
+ else
+ if merge_mode; then
+ "$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE"
+ else
+ "$merge_tool_path" "$LOCAL" "$REMOTE"
+ fi
+ fi
+ status=$?
+ ;;
+ meld)
+ if merge_mode; then
+ touch "$BACKUP"
+ "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+ else
+ "$merge_tool_path" "$LOCAL" "$REMOTE"
+ fi
+ check_unchanged
+ ;;
+ diffuse)
+ if merge_mode; then
+ touch "$BACKUP"
+ fi
+ if $base_present; then
+ "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE" "$BASE" | cat
+ else
+ if merge_mode; then
+ "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE" | cat
+ else
+ "$merge_tool_path" "$LOCAL" "$REMOTE" | cat
+ fi
+ fi
+ check_unchanged
+ ;;
+ vimdiff)
+ if merge_mode; then
+ touch "$BACKUP"
+ "$merge_tool_path" -d -c "wincmd l" "$LOCAL" "$MERGED" "$REMOTE"
+ check_unchanged
+ else
+ "$merge_tool_path" -d -c "wincmd l" "$LOCAL" "$REMOTE"
+ fi
+ ;;
+ gvimdiff)
+ if merge_mode; then
+ touch "$BACKUP"
+ "$merge_tool_path" -d -c "wincmd l" -f "$LOCAL" "$MERGED" "$REMOTE"
+ check_unchanged
+ else
+ "$merge_tool_path" -d -c "wincmd l" -f "$LOCAL" "$REMOTE"
+ fi
+ ;;
+ xxdiff)
+ if merge_mode; then
+ touch "$BACKUP"
+ fi
+ if $base_present; then
+ "$merge_tool_path" -X --show-merged-pane \
+ -R 'Accel.SaveAsMerged: "Ctrl-S"' \
+ -R 'Accel.Search: "Ctrl+F"' \
+ -R 'Accel.SearchForward: "Ctrl-G"' \
+ --merged-file "$MERGED" "$LOCAL" "$BASE" "$REMOTE"
+ else
+ if merge_mode; then
+ "$merge_tool_path" -X $extra \
+ -R 'Accel.SaveAsMerged: "Ctrl-S"' \
+ -R 'Accel.Search: "Ctrl+F"' \
+ -R 'Accel.SearchForward: "Ctrl-G"' \
+ --merged-file "$MERGED" "$LOCAL" "$REMOTE"
+ else
+ "$merge_tool_path" \
+ -R 'Accel.Search: "Ctrl+F"' \
+ -R 'Accel.SearchForward: "Ctrl-G"' \
+ "$LOCAL" "$REMOTE"
+ fi
+ fi
+ check_unchanged
+ ;;
+ opendiff)
+ merge_mode && touch "$BACKUP"
+ if $base_present; then
+ "$merge_tool_path" "$LOCAL" "$REMOTE" \
+ -ancestor "$BASE" -merge "$MERGED" | cat
+ else
+ if merge_mode; then
+ "$merge_tool_path" "$LOCAL" "$REMOTE" \
+ -merge "$MERGED" | cat
+ else
+ "$merge_tool_path" "$LOCAL" "$REMOTE" | cat
+ fi
+ fi
+ check_unchanged
+ ;;
+ ecmerge)
+ merge_mode && touch "$BACKUP"
+ if $base_present; then
+ "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" \
+ --default --mode=merge3 --to="$MERGED"
+ else
+ "$merge_tool_path" "$LOCAL" "$REMOTE" \
+ --default --mode=merge2 --to="$MERGED"
+ fi
+ check_unchanged
+ ;;
+ emerge)
+ if $base_present; then
+ "$merge_tool_path" -f emerge-files-with-ancestor-command \
+ "$LOCAL" "$REMOTE" "$BASE" "$(basename "$MERGED")"
+ else
+ "$merge_tool_path" -f emerge-files-command \
+ "$LOCAL" "$REMOTE" "$(basename "$MERGED")"
+ fi
+ status=$?
+ ;;
+ tortoisemerge)
+ if $base_present; then
+ touch "$BACKUP"
+ "$merge_tool_path" -base:"$BASE" -mine:"$LOCAL" -theirs:"$REMOTE" -merged:"$MERGED"
+ check_unchanged
+ else
+ echo "TortoiseMerge cannot be used without a base" 1>&2
+ status=1
+ fi
+ ;;
+ *)
+ if test -n "$merge_tool_cmd"; then
+ if merge_mode &&
+ test "$merge_tool_trust_exit_code" = "false"; then
+ touch "$BACKUP"
+ ( eval $merge_tool_cmd )
+ check_unchanged
+ else
+ ( eval $merge_tool_cmd )
+ status=$?
+ fi
+ fi
+ ;;
+ esac
+ return $status
+}
+
+guess_merge_tool () {
+ if diff_mode; then
+ kompare="kompare"
+ fi
+ if test -n "$DISPLAY"; then
+ if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
+ tools="meld kdiff3 $kompare tkdiff"
+ tools="$tools xxdiff gvimdiff diffuse"
+ else
+ tools="kdiff3 $kompare tkdiff xxdiff"
+ tools="$tools meld gvimdiff diffuse"
+ fi
+ fi
+ if echo "${VISUAL:-$EDITOR}" | grep emacs > /dev/null 2>&1; then
+ # $EDITOR is emacs so add emerge as a candidate
+ tools="$tools emerge opendiff vimdiff"
+ elif echo "${VISUAL:-$EDITOR}" | grep vim > /dev/null 2>&1; then
+ # $EDITOR is vim so add vimdiff as a candidate
+ tools="$tools vimdiff opendiff emerge"
+ else
+ tools="$tools opendiff emerge vimdiff"
+ fi
+ echo >&2 "merge tool candidates: $tools"
+
+ # Loop over each candidate and stop when a valid merge tool is found.
+ for i in $tools
+ do
+ merge_tool_path="$(translate_merge_tool_path "$i")"
+ if type "$merge_tool_path" > /dev/null 2>&1; then
+ merge_tool="$i"
+ break
+ fi
+ done
+
+ if test -z "$merge_tool" ; then
+ echo >&2 "No known merge resolution program available."
+ return 1
+ fi
+ echo "$merge_tool"
+}
+
+get_configured_merge_tool () {
+ # Diff mode first tries diff.tool and falls back to merge.tool.
+ # Merge mode only checks merge.tool
+ if diff_mode; then
+ tool=$(git config diff.tool)
+ fi
+ if test -z "$tool"; then
+ tool=$(git config merge.tool)
+ fi
+ if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then
+ echo >&2 "git config option $TOOL_MODE.tool set to unknown tool: $merge_tool"
+ echo >&2 "Resetting to default..."
+ return 1
+ fi
+ echo "$tool"
+}
+
+get_merge_tool_path () {
+ # A merge tool has been set, so verify that it's valid.
+ if ! valid_tool "$merge_tool"; then
+ echo >&2 "Unknown merge tool $merge_tool"
+ exit 1
+ fi
+ if diff_mode; then
+ merge_tool_path=$(git config difftool."$merge_tool".path)
+ fi
+ if test -z "$merge_tool_path"; then
+ merge_tool_path=$(git config mergetool."$merge_tool".path)
+ fi
+ merge_tool_path="$(translate_merge_tool_path "$merge_tool" "$merge_tool_path")"
+ if test -z "$merge_tool_cmd" && ! type "$merge_tool_path" > /dev/null 2>&1; then
+ echo >&2 "The $TOOL_MODE tool $merge_tool is not available as '$merge_tool_path'"
+ exit 1
+ fi
+ echo "$merge_tool_path"
+}
+
+get_merge_tool () {
+ merge_tool="$1"
+ # Check if a merge tool has been configured
+ if test -z "$merge_tool"; then
+ merge_tool=$(get_configured_merge_tool)
+ fi
+ # Try to guess an appropriate merge tool if no tool has been set.
+ if test -z "$merge_tool"; then
+ merge_tool=$(guess_merge_tool) || exit
+ fi
+ echo "$merge_tool"
+}
diff --git a/git-mergetool.sh b/git-mergetool.sh
index cceebb7..efa31a2 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -11,7 +11,9 @@
USAGE='[--tool=tool] [-y|--no-prompt|--prompt] [file to merge] ...'
SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
+TOOL_MODE=merge
. git-sh-setup
+. git-mergetool--lib
require_work_tree
# Returns true if the mode reflects a symlink
@@ -110,22 +112,6 @@ resolve_deleted_merge () {
done
}
-check_unchanged () {
- if test "$MERGED" -nt "$BACKUP" ; then
- status=0;
- else
- while true; do
- echo "$MERGED seems unchanged."
- printf "Was the merge successful? [y/n] "
- read answer < /dev/tty
- case "$answer" in
- y*|Y*) status=0; break ;;
- n*|N*) status=1; break ;;
- esac
- done
- fi
-}
-
checkout_staged_file () {
tmpfile=$(expr "$(git checkout-index --temp --stage="$1" "$2")" : '\([^ ]*\) ')
@@ -188,107 +174,11 @@ merge_file () {
read ans
fi
- case "$merge_tool" in
- kdiff3)
- if base_present ; then
- ("$merge_tool_path" --auto --L1 "$MERGED (Base)" --L2 "$MERGED (Local)" --L3 "$MERGED (Remote)" \
- -o "$MERGED" "$BASE" "$LOCAL" "$REMOTE" > /dev/null 2>&1)
- else
- ("$merge_tool_path" --auto --L1 "$MERGED (Local)" --L2 "$MERGED (Remote)" \
- -o "$MERGED" "$LOCAL" "$REMOTE" > /dev/null 2>&1)
- fi
- status=$?
- ;;
- tkdiff)
- if base_present ; then
- "$merge_tool_path" -a "$BASE" -o "$MERGED" "$LOCAL" "$REMOTE"
- else
- "$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE"
- fi
- status=$?
- ;;
- meld)
- touch "$BACKUP"
- "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
- check_unchanged
- ;;
- vimdiff)
- touch "$BACKUP"
- "$merge_tool_path" -d -c "wincmd l" "$LOCAL" "$MERGED" "$REMOTE"
- check_unchanged
- ;;
- gvimdiff)
- touch "$BACKUP"
- "$merge_tool_path" -d -c "wincmd l" -f "$LOCAL" "$MERGED" "$REMOTE"
- check_unchanged
- ;;
- xxdiff)
- touch "$BACKUP"
- if base_present ; then
- "$merge_tool_path" -X --show-merged-pane \
- -R 'Accel.SaveAsMerged: "Ctrl-S"' \
- -R 'Accel.Search: "Ctrl+F"' \
- -R 'Accel.SearchForward: "Ctrl-G"' \
- --merged-file "$MERGED" "$LOCAL" "$BASE" "$REMOTE"
- else
- "$merge_tool_path" -X --show-merged-pane \
- -R 'Accel.SaveAsMerged: "Ctrl-S"' \
- -R 'Accel.Search: "Ctrl+F"' \
- -R 'Accel.SearchForward: "Ctrl-G"' \
- --merged-file "$MERGED" "$LOCAL" "$REMOTE"
- fi
- check_unchanged
- ;;
- opendiff)
- touch "$BACKUP"
- if base_present; then
- "$merge_tool_path" "$LOCAL" "$REMOTE" -ancestor "$BASE" -merge "$MERGED" | cat
- else
- "$merge_tool_path" "$LOCAL" "$REMOTE" -merge "$MERGED" | cat
- fi
- check_unchanged
- ;;
- ecmerge)
- touch "$BACKUP"
- if base_present; then
- "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" --default --mode=merge3 --to="$MERGED"
- else
- "$merge_tool_path" "$LOCAL" "$REMOTE" --default --mode=merge2 --to="$MERGED"
- fi
- check_unchanged
- ;;
- emerge)
- if base_present ; then
- "$merge_tool_path" -f emerge-files-with-ancestor-command "$LOCAL" "$REMOTE" "$BASE" "$(basename "$MERGED")"
- else
- "$merge_tool_path" -f emerge-files-command "$LOCAL" "$REMOTE" "$(basename "$MERGED")"
- fi
- status=$?
- ;;
- tortoisemerge)
- if base_present ; then
- touch "$BACKUP"
- "$merge_tool_path" -base:"$BASE" -mine:"$LOCAL" -theirs:"$REMOTE" -merged:"$MERGED"
- check_unchanged
- else
- echo "TortoiseMerge cannot be used without a base" 1>&2
- status=1
- fi
- ;;
- *)
- if test -n "$merge_tool_cmd"; then
- if test "$merge_tool_trust_exit_code" = "false"; then
- touch "$BACKUP"
- ( eval $merge_tool_cmd )
- check_unchanged
- else
- ( eval $merge_tool_cmd )
- status=$?
- fi
- fi
- ;;
- esac
- if test "$status" -ne 0; then
+ present=false
+ base_present &&
+ present=true
+
+ if ! run_merge_tool "$merge_tool" "$present"; then
echo "merge of $MERGED failed" 1>&2
mv -- "$BACKUP" "$MERGED"
@@ -347,44 +237,6 @@ do
shift
done
-valid_custom_tool()
-{
- merge_tool_cmd="$(git config mergetool.$1.cmd)"
- test -n "$merge_tool_cmd"
-}
-
-valid_tool() {
- case "$1" in
- kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge | tortoisemerge)
- ;; # happy
- *)
- if ! valid_custom_tool "$1"; then
- return 1
- fi
- ;;
- esac
-}
-
-init_merge_tool_path() {
- merge_tool_path=$(git config mergetool.$1.path)
- if test -z "$merge_tool_path" ; then
- case "$1" in
- vimdiff)
- merge_tool_path=vim
- ;;
- gvimdiff)
- merge_tool_path=gvim
- ;;
- emerge)
- merge_tool_path=emacs
- ;;
- *)
- merge_tool_path=$1
- ;;
- esac
- fi
-}
-
prompt_after_failed_merge() {
while true; do
printf "Continue merging other unresolved paths (y/n) ? "
@@ -402,62 +254,12 @@ prompt_after_failed_merge() {
done
}
-if test -z "$merge_tool"; then
- merge_tool=$(git config merge.tool)
- if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then
- echo >&2 "git config option merge.tool set to unknown tool: $merge_tool"
- echo >&2 "Resetting to default..."
- unset merge_tool
- fi
-fi
-
-if test -z "$merge_tool" ; then
- if test -n "$DISPLAY"; then
- if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
- merge_tool_candidates="meld kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse"
- else
- merge_tool_candidates="kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse"
- fi
- fi
- if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then
- merge_tool_candidates="$merge_tool_candidates emerge opendiff vimdiff"
- elif echo "${VISUAL:-$EDITOR}" | grep 'vim' > /dev/null 2>&1; then
- merge_tool_candidates="$merge_tool_candidates vimdiff opendiff emerge"
- else
- merge_tool_candidates="$merge_tool_candidates opendiff emerge vimdiff"
- fi
- echo "merge tool candidates: $merge_tool_candidates"
- for i in $merge_tool_candidates; do
- init_merge_tool_path $i
- if type "$merge_tool_path" > /dev/null 2>&1; then
- merge_tool=$i
- break
- fi
- done
- if test -z "$merge_tool" ; then
- echo "No known merge resolution program available."
- exit 1
- fi
-else
- if ! valid_tool "$merge_tool"; then
- echo >&2 "Unknown merge_tool $merge_tool"
- exit 1
- fi
-
- init_merge_tool_path "$merge_tool"
-
- merge_keep_backup="$(git config --bool merge.keepBackup || echo true)"
- merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)"
-
- if test -z "$merge_tool_cmd" && ! type "$merge_tool_path" > /dev/null 2>&1; then
- echo "The merge tool $merge_tool is not available as '$merge_tool_path'"
- exit 1
- fi
-
- if ! test -z "$merge_tool_cmd"; then
- merge_tool_trust_exit_code="$(git config --bool mergetool.$merge_tool.trustExitCode || echo false)"
- fi
-fi
+merge_tool=$(get_merge_tool "$merge_tool") || exit
+merge_tool_cmd="$(get_merge_tool_cmd "$merge_tool")"
+merge_tool_path="$(get_merge_tool_path "$merge_tool")" || exit
+merge_keep_backup="$(git config --bool merge.keepBackup || echo true)"
+merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)"
+merge_tool_trust_exit_code="$(git config --bool mergetool."$merge_tool".trustExitCode || echo false)"
last_status=0
rollup_status=0
--
1.6.2.2.414.g81aa9
^ permalink raw reply related
* [PATCH 13/14] mergetool: use $( ... ) instead of `backticks`
From: David Aguilar @ 2009-04-06 8:31 UTC (permalink / raw)
To: gitster; +Cc: git, charles, markus.heidelberg, David Aguilar
In-Reply-To: <1239006689-14695-13-git-send-email-davvid@gmail.com>
This makes mergetool consistent with Documentation/CodingGuidelines.
Signed-off-by: David Aguilar <davvid@gmail.com>
---
git-mergetool.sh | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/git-mergetool.sh b/git-mergetool.sh
index b4d2432..cceebb7 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -137,7 +137,7 @@ checkout_staged_file () {
merge_file () {
MERGED="$1"
- f=`git ls-files -u -- "$MERGED"`
+ f=$(git ls-files -u -- "$MERGED")
if test -z "$f" ; then
if test ! -f "$MERGED" ; then
echo "$MERGED: file not found"
@@ -156,9 +156,9 @@ merge_file () {
mv -- "$MERGED" "$BACKUP"
cp -- "$BACKUP" "$MERGED"
- base_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}'`
- local_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}'`
- remote_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}'`
+ base_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}')
+ local_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}')
+ remote_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}')
base_present && checkout_staged_file 1 "$MERGED" "$BASE"
local_present && checkout_staged_file 2 "$MERGED" "$LOCAL"
@@ -318,7 +318,7 @@ do
-t|--tool*)
case "$#,$1" in
*,*=*)
- merge_tool=`expr "z$1" : 'z-[^=]*=\(.*\)'`
+ merge_tool=$(expr "z$1" : 'z-[^=]*=\(.*\)')
;;
1,*)
usage ;;
@@ -366,7 +366,7 @@ valid_tool() {
}
init_merge_tool_path() {
- merge_tool_path=`git config mergetool.$1.path`
+ merge_tool_path=$(git config mergetool.$1.path)
if test -z "$merge_tool_path" ; then
case "$1" in
vimdiff)
@@ -403,7 +403,7 @@ prompt_after_failed_merge() {
}
if test -z "$merge_tool"; then
- merge_tool=`git config merge.tool`
+ merge_tool=$(git config merge.tool)
if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then
echo >&2 "git config option merge.tool set to unknown tool: $merge_tool"
echo >&2 "Resetting to default..."
@@ -463,7 +463,7 @@ last_status=0
rollup_status=0
if test $# -eq 0 ; then
- files=`git ls-files -u | sed -e 's/^[^ ]* //' | sort -u`
+ files=$(git ls-files -u | sed -e 's/^[^ ]* //' | sort -u)
if test -z "$files" ; then
echo "No files need merging"
exit 0
--
1.6.2.2.414.g81aa9
^ permalink raw reply related
* [PATCH 12/14] bash completion: add git-difftool
From: David Aguilar @ 2009-04-06 8:31 UTC (permalink / raw)
To: gitster; +Cc: git, charles, markus.heidelberg, David Aguilar
In-Reply-To: <1239006689-14695-12-git-send-email-davvid@gmail.com>
This adds completion for difftool's --tool flag.
The known diff tool names were also consolidated into
a single variable.
Signed-off-by: David Aguilar <davvid@gmail.com>
---
contrib/completion/git-completion.bash | 27 ++++++++++++++++++++++-----
1 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 4fcd77a..551e33e 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -909,6 +909,26 @@ _git_diff ()
__git_complete_file
}
+__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
+ tkdiff vimdiff gvimdiff xxdiff
+"
+
+_git_difftool ()
+{
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --tool=*)
+ __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
+ return
+ ;;
+ --*)
+ __gitcomp "--tool="
+ return
+ ;;
+ esac
+ COMPREPLY=()
+}
+
__git_fetch_options="
--quiet --verbose --append --upload-pack --force --keep --depth=
--tags --no-tags
@@ -1171,11 +1191,7 @@ _git_mergetool ()
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--tool=*)
- __gitcomp "
- kdiff3 tkdiff meld xxdiff emerge
- vimdiff gvimdiff ecmerge diffuse
- opendiff
- " "" "${cur##--tool=}"
+ __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
return
;;
--*)
@@ -1900,6 +1916,7 @@ _git ()
config) _git_config ;;
describe) _git_describe ;;
diff) _git_diff ;;
+ difftool) _git_difftool ;;
fetch) _git_fetch ;;
format-patch) _git_format_patch ;;
fsck) _git_fsck ;;
--
1.6.2.2.414.g81aa9
^ permalink raw reply related
* [PATCH 07/14] difftool: add a -y shortcut for --no-prompt
From: David Aguilar @ 2009-04-06 8:31 UTC (permalink / raw)
To: gitster; +Cc: git, charles, markus.heidelberg, David Aguilar
In-Reply-To: <1239006689-14695-7-git-send-email-davvid@gmail.com>
This is another consistency cleanup to make git-difftool's options
match git-mergetool.
Signed-off-by: David Aguilar <davvid@gmail.com>
---
contrib/difftool/git-difftool | 6 +++---
contrib/difftool/git-difftool.txt | 36 ++++++++++++++----------------------
2 files changed, 17 insertions(+), 25 deletions(-)
diff --git a/contrib/difftool/git-difftool b/contrib/difftool/git-difftool
index 207dd50..8c160e5 100755
--- a/contrib/difftool/git-difftool
+++ b/contrib/difftool/git-difftool
@@ -18,7 +18,7 @@ my $DIR = abs_path(dirname($0));
sub usage
{
print << 'USAGE';
-usage: git difftool [--tool=<tool>] [--no-prompt] ["git diff" options]
+usage: git difftool [--tool=<tool>] [-y|--no-prompt] ["git diff" options]
USAGE
exit 1;
}
@@ -60,11 +60,11 @@ sub generate_command
$ENV{GIT_DIFF_TOOL} = substr($arg, 7);
next;
}
- if ($arg eq '--no-prompt') {
+ if ($arg eq '-y' || $arg eq '--no-prompt') {
$ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';
next;
}
- if ($arg eq '-h' or $arg eq '--help') {
+ if ($arg eq '-h' || $arg eq '--help') {
usage();
}
push @command, $arg;
diff --git a/contrib/difftool/git-difftool.txt b/contrib/difftool/git-difftool.txt
index 2b7bc03..4dff529 100644
--- a/contrib/difftool/git-difftool.txt
+++ b/contrib/difftool/git-difftool.txt
@@ -3,35 +3,32 @@ git-difftool(1)
NAME
----
-git-difftool - compare changes using common merge tools
+git-difftool - Show changes using common diff tools
SYNOPSIS
--------
-'git difftool' [--tool=<tool>] [--no-prompt] ['git diff' options]
+'git difftool' [-t|--tool=<tool>] [-y|--no-prompt] [<'git diff' options>]
DESCRIPTION
-----------
'git-difftool' is a git command that allows you to compare and edit files
-between revisions using common merge tools. At its most basic level,
-'git-difftool' does what 'git-mergetool' does but its use is for non-merge
-situations such as when preparing commits or comparing changes against
-the index.
-
-'git difftool' is a frontend to 'git diff' and accepts the same
-arguments and options.
-
-See linkgit:git-diff[1] for the full list of supported options.
+between revisions using common diff tools. 'git difftool' is a frontend
+to 'git-diff' and accepts the same options and arguments.
OPTIONS
-------
+-y::
+--no-prompt::
+ Do not prompt before launching a diff tool.
+
-t <tool>::
--tool=<tool>::
- Use the merge resolution program specified by <tool>.
+ Use the diff tool specified by <tool>.
Valid merge tools are:
kdiff3, kompare, tkdiff, meld, xxdiff, emerge,
vimdiff, gvimdiff, ecmerge, and opendiff
+
-If a merge resolution program is not specified, 'git-difftool'
+If a diff tool is not specified, 'git-difftool'
will use the configuration variable `diff.tool`. If the
configuration variable `diff.tool` is not set, 'git-difftool'
will pick a suitable default.
@@ -42,7 +39,7 @@ can configure the absolute path to kdiff3 by setting
`difftool.kdiff3.path`. Otherwise, 'git-difftool' assumes the
tool is available in PATH.
+
-Instead of running one of the known merge tool programs,
+Instead of running one of the known diff tools,
'git-difftool' can be customized to run an alternative program
by specifying the command line to invoke in a configuration
variable `difftool.<tool>.cmd`.
@@ -56,8 +53,7 @@ is set to the name of the temporary file containing the contents
of the diff post-image. `$BASE` is provided for compatibility
with custom merge tool commands and has the same value as `$LOCAL`.
---no-prompt::
- Do not prompt before launching a diff tool.
+See linkgit:git-diff[1] for the full list of supported options.
CONFIG VARIABLES
----------------
@@ -65,21 +61,17 @@ CONFIG VARIABLES
difftool equivalents have not been defined.
diff.tool::
- The default merge tool to use.
+ The default diff tool to use.
difftool.<tool>.path::
Override the path for the given tool. This is useful in case
your tool is not in the PATH.
difftool.<tool>.cmd::
- Specify the command to invoke the specified merge tool.
+ Specify the command to invoke the specified diff tool.
+
See the `--tool=<tool>` option above for more details.
-merge.keepBackup::
- The original, unedited file content can be saved to a file with
- a `.orig` extension. Defaults to `true` (i.e. keep the backup files).
-
SEE ALSO
--------
linkgit:git-diff[1]::
--
1.6.2.2.414.g81aa9
^ permalink raw reply related
* [PATCH 09/14] difftool: move 'git-difftool' out of contrib
From: David Aguilar @ 2009-04-06 8:31 UTC (permalink / raw)
To: gitster; +Cc: git, charles, markus.heidelberg, David Aguilar
In-Reply-To: <1239006689-14695-9-git-send-email-davvid@gmail.com>
This prepares 'git-difftool' and its documentation for
mainstream use.
'git-difftool-helper' became 'git-difftool--helper'
since users should not use it directly.
'git-difftool' was added to the list of commands as
an ancillaryinterrogator.
Signed-off-by: David Aguilar <davvid@gmail.com>
---
.gitignore | 2 ++
Documentation/config.txt | 17 +++++++++++++++++
.../difftool => Documentation}/git-difftool.txt | 0
Makefile | 2 ++
command-list.txt | 1 +
.../git-difftool-helper => git-difftool--helper.sh | 2 +-
contrib/difftool/git-difftool => git-difftool.perl | 6 +++---
7 files changed, 26 insertions(+), 4 deletions(-)
rename {contrib/difftool => Documentation}/git-difftool.txt (100%)
rename contrib/difftool/git-difftool-helper => git-difftool--helper.sh (98%)
rename contrib/difftool/git-difftool => git-difftool.perl (92%)
diff --git a/.gitignore b/.gitignore
index 1c57d4c..a36da9d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,8 @@ git-diff
git-diff-files
git-diff-index
git-diff-tree
+git-difftool
+git-difftool--helper
git-describe
git-fast-export
git-fast-import
diff --git a/Documentation/config.txt b/Documentation/config.txt
index ad22cb8..185a9ef 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -667,6 +667,23 @@ diff.suppressBlankEmpty::
A boolean to inhibit the standard behavior of printing a space
before each empty output line. Defaults to false.
+diff.tool::
+ Controls which diff tool is used. `diff.tool` overrides
+ `merge.tool` when used by linkgit:git-difftool[1] and has
+ the same valid values as `merge.tool`.
+
+difftool.<tool>.path::
+ Override the path for the given tool. This is useful in case
+ your tool is not in the PATH.
+
+difftool.<tool>.cmd::
+ Specify the command to invoke the specified diff tool.
+ The specified command is evaluated in shell with the following
+ variables available: 'LOCAL' is set to the name of the temporary
+ file containing the contents of the diff pre-image and 'REMOTE'
+ is set to the name of the temporary file containing the contents
+ of the diff post-image.
+
diff.wordRegex::
A POSIX Extended Regular Expression used to determine what is a "word"
when performing word-by-word difference calculations. Character
diff --git a/contrib/difftool/git-difftool.txt b/Documentation/git-difftool.txt
similarity index 100%
rename from contrib/difftool/git-difftool.txt
rename to Documentation/git-difftool.txt
diff --git a/Makefile b/Makefile
index 7867eac..a80055f 100644
--- a/Makefile
+++ b/Makefile
@@ -277,6 +277,7 @@ TEST_PROGRAMS =
SCRIPT_SH += git-am.sh
SCRIPT_SH += git-bisect.sh
+SCRIPT_SH += git-difftool--helper.sh
SCRIPT_SH += git-filter-branch.sh
SCRIPT_SH += git-lost-found.sh
SCRIPT_SH += git-merge-octopus.sh
@@ -296,6 +297,7 @@ SCRIPT_SH += git-submodule.sh
SCRIPT_SH += git-web--browse.sh
SCRIPT_PERL += git-add--interactive.perl
+SCRIPT_PERL += git-difftool.perl
SCRIPT_PERL += git-archimport.perl
SCRIPT_PERL += git-cvsexportcommit.perl
SCRIPT_PERL += git-cvsimport.perl
diff --git a/command-list.txt b/command-list.txt
index 3583a33..fb03a2e 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -33,6 +33,7 @@ git-diff mainporcelain common
git-diff-files plumbinginterrogators
git-diff-index plumbinginterrogators
git-diff-tree plumbinginterrogators
+git-difftool ancillaryinterrogators
git-fast-export ancillarymanipulators
git-fast-import ancillarymanipulators
git-fetch mainporcelain common
diff --git a/contrib/difftool/git-difftool-helper b/git-difftool--helper.sh
similarity index 98%
rename from contrib/difftool/git-difftool-helper
rename to git-difftool--helper.sh
index 4b0daec..fc61416 100755
--- a/contrib/difftool/git-difftool-helper
+++ b/git-difftool--helper.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# git-difftool-helper is a GIT_EXTERNAL_DIFF-compatible diff tool launcher.
+# git-difftool--helper is a GIT_EXTERNAL_DIFF-compatible diff tool launcher.
# This script is typically launched by using the 'git difftool'
# convenience command.
#
diff --git a/contrib/difftool/git-difftool b/git-difftool.perl
similarity index 92%
rename from contrib/difftool/git-difftool
rename to git-difftool.perl
index 8c160e5..8857ac8 100755
--- a/contrib/difftool/git-difftool
+++ b/git-difftool.perl
@@ -2,9 +2,9 @@
# Copyright (c) 2009 David Aguilar
#
# This is a wrapper around the GIT_EXTERNAL_DIFF-compatible
-# git-difftool-helper script. This script exports
+# git-difftool--helper script. This script exports
# GIT_EXTERNAL_DIFF and GIT_PAGER for use by git, and
-# GIT_DIFFTOOL_NO_PROMPT and GIT_DIFF_TOOL for use by git-difftool-helper.
+# GIT_DIFFTOOL_NO_PROMPT and GIT_DIFF_TOOL for use by git-difftool--helper.
# Any arguments that are unknown to this script are forwarded to 'git diff'.
use strict;
@@ -27,7 +27,7 @@ sub setup_environment
{
$ENV{PATH} = "$DIR:$ENV{PATH}";
$ENV{GIT_PAGER} = '';
- $ENV{GIT_EXTERNAL_DIFF} = 'git-difftool-helper';
+ $ENV{GIT_EXTERNAL_DIFF} = 'git-difftool--helper';
}
sub exe
--
1.6.2.2.414.g81aa9
^ permalink raw reply related
* [PATCH 08/14] difftool/mergetool: add diffuse as merge and diff tool
From: David Aguilar @ 2009-04-06 8:31 UTC (permalink / raw)
To: gitster; +Cc: git, charles, markus.heidelberg, Sebastian Pipping, David Aguilar
In-Reply-To: <1239006689-14695-8-git-send-email-davvid@gmail.com>
From: Sebastian Pipping <sebastian@pipping.org>
This adds diffuse as a built-in merge tool.
Signed-off-by: Sebastian Pipping <sebastian@pipping.org>
Signed-off-by: David Aguilar <davvid@gmail.com>
---
Documentation/git-mergetool.txt | 2 +-
Documentation/merge-config.txt | 2 +-
contrib/completion/git-completion.bash | 3 ++-
contrib/difftool/git-difftool-helper | 10 ++++++----
contrib/difftool/git-difftool.txt | 4 ++--
git-mergetool.sh | 4 ++--
6 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt
index 5edac4d..ff9700d 100644
--- a/Documentation/git-mergetool.txt
+++ b/Documentation/git-mergetool.txt
@@ -27,7 +27,7 @@ OPTIONS
Use the merge resolution program specified by <tool>.
Valid merge tools are:
kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge,
- tortoisemerge and opendiff
+ diffuse, tortoisemerge and opendiff
+
If a merge resolution program is not specified, 'git-mergetool'
will use the configuration variable `merge.tool`. If the
diff --git a/Documentation/merge-config.txt b/Documentation/merge-config.txt
index 8c10f66..4832bc7 100644
--- a/Documentation/merge-config.txt
+++ b/Documentation/merge-config.txt
@@ -23,7 +23,7 @@ merge.tool::
Controls which merge resolution program is used by
linkgit:git-mergetool[1]. Valid built-in values are: "kdiff3",
"tkdiff", "meld", "xxdiff", "emerge", "vimdiff", "gvimdiff",
- "ecmerge", tortoisemerge and
+ "diffuse", "ecmerge", "tortoisemerge", and
"opendiff". Any other value is treated is custom merge tool
and there must be a corresponding mergetool.<tool>.cmd option.
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index e72ce24..4fcd77a 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1173,7 +1173,8 @@ _git_mergetool ()
--tool=*)
__gitcomp "
kdiff3 tkdiff meld xxdiff emerge
- vimdiff gvimdiff ecmerge opendiff
+ vimdiff gvimdiff ecmerge diffuse
+ opendiff
" "" "${cur##--tool=}"
return
;;
diff --git a/contrib/difftool/git-difftool-helper b/contrib/difftool/git-difftool-helper
index e74a274..4b0daec 100755
--- a/contrib/difftool/git-difftool-helper
+++ b/contrib/difftool/git-difftool-helper
@@ -1,7 +1,5 @@
#!/bin/sh
# git-difftool-helper is a GIT_EXTERNAL_DIFF-compatible diff tool launcher.
-# It supports kdiff3, kompare, tkdiff, xxdiff, meld, opendiff,
-# emerge, ecmerge, vimdiff, gvimdiff, and custom user-configurable tools.
# This script is typically launched by using the 'git difftool'
# convenience command.
#
@@ -55,6 +53,10 @@ launch_merge_tool () {
"$merge_tool_path" "$LOCAL" "$REMOTE"
;;
+ diffuse)
+ "$merge_tool_path" "$LOCAL" "$REMOTE" | cat
+ ;;
+
vimdiff)
"$merge_tool_path" -d -c "wincmd l" "$LOCAL" "$REMOTE"
;;
@@ -164,9 +166,9 @@ if test -z "$merge_tool"; then
if test -n "$DISPLAY"; then
# If gnome then prefer meld, otherwise, prefer kdiff3 or kompare
if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
- merge_tool_candidates="meld kdiff3 kompare tkdiff xxdiff gvimdiff"
+ merge_tool_candidates="meld kdiff3 kompare tkdiff xxdiff gvimdiff diffuse"
else
- merge_tool_candidates="kdiff3 kompare tkdiff xxdiff meld gvimdiff"
+ merge_tool_candidates="kdiff3 kompare tkdiff xxdiff meld gvimdiff diffuse"
fi
fi
if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then
diff --git a/contrib/difftool/git-difftool.txt b/contrib/difftool/git-difftool.txt
index 4dff529..a2fa474 100644
--- a/contrib/difftool/git-difftool.txt
+++ b/contrib/difftool/git-difftool.txt
@@ -25,8 +25,8 @@ OPTIONS
--tool=<tool>::
Use the diff tool specified by <tool>.
Valid merge tools are:
- kdiff3, kompare, tkdiff, meld, xxdiff, emerge,
- vimdiff, gvimdiff, ecmerge, and opendiff
+ kdiff3, kompare, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff,
+ ecmerge, diffuse and opendiff
+
If a diff tool is not specified, 'git-difftool'
will use the configuration variable `diff.tool`. If the
diff --git a/git-mergetool.sh b/git-mergetool.sh
index be9717a..b4d2432 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -414,9 +414,9 @@ fi
if test -z "$merge_tool" ; then
if test -n "$DISPLAY"; then
if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
- merge_tool_candidates="meld kdiff3 tkdiff xxdiff tortoisemerge gvimdiff"
+ merge_tool_candidates="meld kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse"
else
- merge_tool_candidates="kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff"
+ merge_tool_candidates="kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse"
fi
fi
if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then
--
1.6.2.2.414.g81aa9
^ permalink raw reply related
* [PATCH 06/14] difftool: use perl built-ins when testing for msys
From: David Aguilar @ 2009-04-06 8:31 UTC (permalink / raw)
To: gitster; +Cc: git, charles, markus.heidelberg, David Aguilar
In-Reply-To: <1239006689-14695-6-git-send-email-davvid@gmail.com>
I don't even know what $COMSPEC means so let's be safe and use the
same perly $^O test add--interactive uses. While we're at it, make
git-difftool match the prevalent git-perl style.
Signed-off-by: David Aguilar <davvid@gmail.com>
---
contrib/difftool/git-difftool | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/contrib/difftool/git-difftool b/contrib/difftool/git-difftool
index 0deda3a..207dd50 100755
--- a/contrib/difftool/git-difftool
+++ b/contrib/difftool/git-difftool
@@ -33,7 +33,10 @@ sub setup_environment
sub exe
{
my $exe = shift;
- return defined $ENV{COMSPEC} ? "$exe.exe" : $exe;
+ if ($^O eq 'MSWin32' || $^O eq 'msys') {
+ return "$exe.exe";
+ }
+ return $exe;
}
sub generate_command
@@ -47,7 +50,7 @@ sub generate_command
$skip_next = 0;
next;
}
- if ($arg eq '-t' or $arg eq '--tool') {
+ if ($arg eq '-t' || $arg eq '--tool') {
usage() if $#ARGV <= $idx;
$ENV{GIT_DIFF_TOOL} = $ARGV[$idx + 1];
$skip_next = 1;
--
1.6.2.2.414.g81aa9
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox