如何在 OS X 上使用 git 将 FileMerge 作为差异工具进行管道传输?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2466821/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 04:10:11  来源:igfitidea点击:

How do I pipe in FileMerge as a diff tool with git on OS X?

gitmacoscommand-linefilemerge

提问by doug

I'm new to git on OS X, and I'm using it via the command line. I come from the world of Tortoise SVN and Beyond Compare on Windows.

我是 OS X 上的 git 新手,我通过命令行使用它。我来自 Windows 上的 Tortoise SVN 和 Beyond Compare 的世界。

I want to be able to send diffs to FileMerge.

我希望能够将差异发送到 FileMerge。

I was able to do this with TextMate simply by using:

我可以通过使用 TextMate 来做到这一点:

git diff | mate

But I'm not sure how to get that set up so I can use FileMerge instead?

但我不确定如何设置以便我可以改用 FileMerge?

回答by undees

Although it's not exactly the same as piping stdin into a script, you can do this:

尽管这与将 stdin 管道化到脚本中并不完全相同,但您可以这样做:

git difftool -t opendiff -y

That will launch FileMerge once for each file. Doing the whole project tree at once takes a little scripting.

这将为每个文件启动一次 FileMerge。一次完成整个项目树需要编写一些脚本

See also this question.

另请参阅此问题

回答by Syzygies

Create an executable script git-diff-cmd.sh

创建可执行脚本 git-diff-cmd.sh

#!/bin/bash

xattr -w com.apple.TextEncoding "UTF-8;134217984" ""
xattr -w com.apple.TextEncoding "UTF-8;134217984" ""

/usr/bin/opendiff "" "" -merge ""

Now edit your .gitconfigfile to include the lines

现在编辑您的.gitconfig文件以包含这些行

[diff]
    external = <path-to>/git-diff-cmd.sh

...replacing <path-to>by the path to git-diff-cmd.sh. Now git diffwill use FileMerge, and correctly display UTF-8 Unicode characters.

...替换<path-to>git-diff-cmd.sh. 现在git diff将使用 FileMerge,并正确显示 UTF-8 Unicode 字符。

回答by millerdev

Here's a script (originally by Toby White) that I hacked up to compare the entire directory structure in FileMerge rather than opening each file individually.

这是一个脚本(最初由 Toby White 编写),我使用它来比较 FileMerge 中的整个目录结构,而不是单独打开每个文件。

#!/bin/sh
#
# This script was written by Toby White under an unknown license, and published
# on the Git mailing list:
#
#   http://kerneltrap.org/mailarchive/git/2007/11/21/435536
#
# Superficial changes were made by Nathan de Vries to allow the script to be
# run under Leopard.
#
# Adapted by Daniel Miller : http://stackoverflow.com/a/12957945/10840
# - allow changes to be saved back to the working copy when diffing against HEAD
# - work when FileMerge is already open
# - always compare archived copies so ignored files are excluded from the diff
# - allow diff of unstaged changes (no arguments); creates a dangling commit
# - allow diff of subdirectory within the repo
#
# Known issues:
# - Always uses the same two directories (/tmp/git-opendiff-old and
#   /tmp/git-opendiff-new); THEY WILL BE DELETED IF THEY ALREADY EXIST.
#   Ugly, I know, but it makes the script work even if FileMerge is open.

OLD=
NEW=
FILEPATH=
HAS_ARGS=no
IGNORE_TO_PATH=no

# loosely based on https://stackoverflow.com/a/14787208/10840
while [ "$#" -ge 1 ]; do
    HAS_ARGS=yes
    case "" in
        -h)
            echo "usage: 
#!/bin/sh 
dir=$PWD
until [ -e "$dir/.git" ]; do
  if [ "$dir" == "/" ]; then
    echo "Not a git repository" >&2
    exit 1;
  fi
  dir=`dirname "$dir"`
done
open -a FileMerge -n -W --args -left "$dir/" -right "" -merge ""
[--cached | <ref> [<ref>]] [-- <path>]" exit 0 ;; --cached) # diff staged changes NEW=$(git write-tree) OLD=HEAD IGNORE_TO_PATH=yes shift ;; --) shift FILEPATH="$@" break ;; *) if [[ "$IGNORE_TO_PATH" == "no" ]]; then if [ -z "$OLD" ]; then OLD="" else NEW="" IGNORE_TO_PATH=yes fi fi shift ;; esac done if [ -z "$OLD" ]; then OLD=HEAD fi if [[ "$HAS_ARGS" == "no" ]]; then # diff unstaged changes # http://stackoverflow.com/a/12010656/10840 NEW=$(git stash create) echo "diff unstaged changes" fi TMP_OLD=/tmp/git-opendiff-old TMP_NEW=/tmp/git-opendiff-new test -d $TMP_OLD && rm -rf $TMP_OLD; mkdir $TMP_OLD test -d $TMP_NEW && rm -rf $TMP_NEW; mkdir $TMP_NEW TMP_OLD=$TMP_OLD/$OLD; mkdir -p $TMP_OLD git archive --format=tar $OLD $FILEPATH | (cd $TMP_OLD; tar xf -) if test -z "$NEW"; then SAVE_TO=$(git rev-parse --show-cdup) test -z "$cdup" && SAVE_TO=. git archive --format=tar HEAD $FILEPATH | (cd $TMP_NEW; tar xf -) opendiff $TMP_OLD/$FILEPATH $TMP_NEW/$FILEPATH -merge $SAVE_TO &> /dev/null & else TMP_NEW=$TMP_NEW/$NEW; mkdir -p $TMP_NEW git archive --format=tar $NEW $FILEPATH | (cd $TMP_NEW; tar xf -) opendiff $TMP_OLD/$FILEPATH $TMP_NEW/$FILEPATH &> /dev/null & fi

Put this somewhere on your path. I prefer ~/bin/git-opendiff, which means git opendiff ...works as expected.

把它放在你路径上的某个地方。我更喜欢~/bin/git-opendiff,这意味着git opendiff ...按预期工作。

Update: diff unstaged changes when called with no arguments, added -h(help) option.

更新:在不带参数的情况下调用时 diff 未暂存的更改,添加了-h(帮助)选项。

Update: diff subdirectory with -- <path>. Also better argument parsing.

更新: diff 子目录与-- <path>. 还有更好的参数解析。

回答by Hola Soy Edu Feliz Navidad

I don't know what's happening to me since I updated OS X and now opendiff is not working as it used to be. So I copied this script from hereand it worked.

我不知道自从我更新了 OS X 之后我发生了什么事,现在 opendiff 不像以前那样工作了。所以我从这里复制了这个脚本并且它起作用了。

##代码##