【问题标题】:How do I pipe in FileMerge as a diff tool with git on OS X?如何在 OS X 上使用 git 作为差异工具在 FileMerge 中进行管道传输?
【发布时间】:2011-01-28 20:06:35
【问题描述】:

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

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

我只需使用 TextMate 就可以做到这一点:

git diff | mate

但我不确定如何进行设置,以便我可以使用 FileMerge 代替?

【问题讨论】:

    标签: git macos command-line filemerge


    【解决方案1】:

    虽然它与将标准输入传送到脚本中并不完全相同,但您可以这样做:

    git difftool -t opendiff -y
    

    这将为每个文件启动一次 FileMerge。一次做整个项目树takes a little scripting.

    另见this question

    【讨论】:

    • 谢谢!!!!!!!!!!!!!!!所以“difftool”基本上就像一个常规的“diff”命令,但可以选择外部 diff 工具?并且“opendiff”专门调用FileMerge?而且我仍然可以将特定文件的路径传递给仅区分一个文件吗?抱歉,现在在家,无法在我的工作机器上进行测试;)
    • 实际上,我看到这对我没有任何帮助。我的命令行只返回一个提示。我试过启动 filemerge,什么都没有。
    • 这对我不起作用。 git difftool 总是将其输出转储到终端。
    • -d 选项将执行单个目录差异,而不是在每个更改的文件上调用该工具。 git difftool -d -t opendiff
    • opendiff 作为 difftool 有几个问题。我写了一个小 bash 脚本来解决这些问题:gist.github.com/miner/e73fc98a83a8fe05d9ef000d46d68a9f
    【解决方案2】:

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

    #!/bin/bash
    
    xattr -w com.apple.TextEncoding "UTF-8;134217984" "$2"
    xattr -w com.apple.TextEncoding "UTF-8;134217984" "$5"
    
    /usr/bin/opendiff "$2" "$5" -merge "$1"
    

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

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

    ...将&lt;path-to&gt; 替换为git-diff-cmd.sh 的路径。 现在git diff 将使用 FileMerge,并正确显示 UTF-8 Unicode 字符。

    【讨论】:

    • 这很好用,但是谁能解释我如何将这个脚本与difftool 一起使用?似乎在使用 cmd = &lt;path-to&gt;/git-diff-cmd.sh 时,脚本不会获得与使用 external 时相同的变量。
    • 一定要chmod 755 git-diff-cmd.sh,以免收到Permission denied
    • @Boblet Syzgies 发布的脚本将位置参数 2、5 和 1 传递给 opendiff 忽略其余部分。 difftool 可能只传入 2 个参数
    【解决方案3】:

    这是我编写的一个脚本(最初由 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 "$1" in
            -h)
                echo "usage: $0 [--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="$1"
                    else
                        NEW="$1"
                        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
    

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

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

    更新:diff 子目录与-- &lt;path&gt;。还有更好的参数解析。

    【讨论】:

    • 我添加了这个脚本但是得到了&gt;git opendiff README.mdgit: 'opendiff' is not a git command. See 'git --help'.
    • @HarryMoreno 听起来脚本可能不在您的路径中。此外,您的用法看起来有问题。此脚本用于比较整个树,而不是单个文件。
    【解决方案4】:

    自从我更新了 OS X 后,我不知道发生了什么事,现在 opendiff 不能像以前那样工作了。 所以我从here 复制了这个脚本,它成功了。

    #!/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/$1" -right "$2" -merge "$5"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-09-29
      • 2011-12-18
      • 2019-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多