Почему `git diff` не вызывает внешний инструмент сравнения?

В моем репозитории, если я наберу

$ git diff some-file

or

$ git difftool some-file

Я получаю отображение различий в терминале. Я думаю, что этого не должно происходить, потому что я установил внешний инструмент сравнения, как показано в выводе git config -l:

$ git config -l
user.name=blah blah
user.email=blah blah
http.sslverify=true
diff.external=/home/daniel/bin/git-diff  <--This is the important line
push.default=simple
core.filemode=false
core.editor=gedit
alias.tree=log --all --graph --decorate=short --color --format=format:'%C(bold blue)%h%C(reset) %C(auto)%d%C(reset)
         %C(black)[%cr]%C(reset)  %x09%C(black)%an: %s %C(reset)'
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
remote.origin.url=https://daniel@skynet/git/pyle.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
branch.daniel.remote=origin
branch.daniel.merge=refs/heads/daniel

Файл git-diff, указанный в строке diff.external, выглядит так

#!/bin/bash

meld $2 $5

Почему git diff не вызывает объединение?

Я получу такое же поведение, если настрою так, что git config -l будет иметь следующую строку:

diff.tool = meld

or

diff.external = usr/bin/meld

Примечание. В других репозиториях на моем компьютере этой проблемы нет.

Связанные, но не эквивалентные вопросы SO:

  1. В чем разница между git diff и _12 _?
  2. Не удается заставить git diff использовать diff.external для внешних инструмент сравнения

person DanielSank    schedule 26.07.2014    source источник
comment
Почему вы используете второй и пятый аргументы?   -  person merlin2011    schedule 26.07.2014
comment
@ merlin2011: Насколько я понимаю, git diff передает семь аргументов во внешний инструмент сравнения, и что meld требует только два из них.   -  person DanielSank    schedule 26.07.2014


Ответы (3)


Я получаю отображение различий в терминале. У меня этого не должно происходить, потому что я установил внешний инструмент сравнения

Да, должно: diff.external is для отображения различий в терминале.

(из git config справочной страницы)

diff.external

Если эта переменная конфигурации установлена, генерация различий выполняется не с использованием внутреннего механизма сравнения различий, а с использованием данной команды.
Может быть переопределено с помощью переменной среды GIT_EXTERNAL_DIFF.
Команда вызывается с параметрами, как описано в разделе git Diffs в git (1). Примечание: если вы хотите использовать внешнюю программу сравнения только для части ваших файлов, вы можете использовать gitattributes (5) вместо этого.

вопрос, на который вы ссылаетесь, объясняет, почему meld не сможет играть роль внешнего сравнения.

Визуальный просмотр различий с помощью другого инструмента выполняется с помощью:

git difftool --dir-diff shaOfHisCheckIn^!
git difftool --tool=meld --dir-diff shaOfHisCheckIn^!
git difftool -t meld -d shaOfHisCheckIn^!

meld можно настроить в Windows как инструмент сравнения: см. Git Diff and Meld в Windows.


Если вы хотите настроить meld для git diff, вы можете (в Ubuntu) используйте diff.external, но со сценарием-оболочкой:

создайте файл с именем git-diff.sh, используя следующее содержимое:

#!/bin/bash
meld "$2" "$5" > /dev/null 2>&1

Сохраните это в таком месте, как /usr/local/bin, предоставив ему права на исполнение:

$ sudo mv git-diff.sh /usr/local/bin/
$ sudo chmod +x /usr/local/bin/git-diff.sh

Последний шаг - открыть ваш $HOME/.gitconfig файл и добавить следующие несколько строк:

[diff]
        external = /usr/local/bin/git-diff.sh

В следующий раз, когда вы наберете git diff в проекте Git с изменениями, Meld будет запущен, показывая вам средство просмотра различий с разделенной панелью.
Обратите внимание, что вам необходимо закрыть открытый экземпляр meld перед тем, как откроется следующее средство просмотра различий.


будет примечания в комментарии:

Этот сценарий-оболочка отлично работает в моей системе Ubuntu.

Я обнаружил недоразумение: я отсоединил команду meld следующим образом:

meld "$2" "$5" > /dev/null 2>&1 &

Не удается открыть файл $2 (временный файл).
Что происходит? Что ж, git удаляет $2 после выхода из оболочки.
Мое предложение, если вы хотите отсоединить копию tmp файла, вызовите meld и удалите tmp файл самостоятельно.

person VonC    schedule 26.07.2014
comment
git difftool кажется решением. Я пробовал использовать сценарий-оболочку, но по какой-то причине это не сработало. - person DanielSank; 29.07.2014
comment
Этот сценарий-оболочка отлично работает в моей системе Ubuntu. Я обнаружил gottcha. Я отсоединил команду meld так: meld "$2" "$5" > /dev/null 2>&1 &. Не удается открыть файл $2 (временный файл). Что случается? Что ж, git удаляет $2 после выхода из оболочки. Мое предложение: если вы хотите отключить копию tmp-файла, вызовите meld и удалите tmp-файл самостоятельно. - person will; 19.07.2021
comment
@will Спасибо за отзыв. Я включил ваш комментарий в ответ для большей наглядности. - person VonC; 19.07.2021

Кажется, что git diff (по крайней мере, начиная с git версии 1.7.12.4) не будет запускать ничего, кроме внутреннего, консольного diff для файла, который находится в состоянии "оба измененных". Однако git mergetool работает с такими файлами.

person Trebor Rude    schedule 07.11.2014
comment
Это по-прежнему актуально для git версии 1.9.1. Какая досада! Я просто потратил час, пытаясь понять, почему мои настройки конфигурации git для difftool внезапно перестали работать. - person Die in Sente; 20.01.2016
comment
Еще дело на git version 2.5.4 (Apple Git-61). Консоль только с 3-сторонним рабочим процессом слияния - довольно большая проблема. На самом деле существует огромная нехватка способных встроенных в консоль инструментов различий. Я считаю, что путь, который я выберу, - это позволить git сбрасывать маркеры конфликтов в файлы, а затем использовать простой инструмент, который я напишу, для их обработки для создания удобочитаемых выходных данных diff. - person Steven Lu; 22.02.2016
comment
Ага! @ trebor-rude, ты только что спас мне рассудок, задавшись вопросом, почему ни один из моих выбранных инструментов difftool не работал - person jaygooby; 26.01.2017

Обычно я просто хочу проверить, верны ли изменения, которые я собираюсь зарегистрировать. Поэтому я выполнил предложенную процедуру здесь (аналогично отмеченному VonC). Однако запуск git difftool по-прежнему не открывал слияние. Затем я создал псевдоним:

alias git-diff='git difftool $(git rev-parse HEAD)'

Сохраните это в своем .bashrc или .zshrc или в соответствующей конфигурации для вашей оболочки. По сути, это сравнивает состояние ветки с предыдущей фиксацией ветки.

Выполните git-diff, чтобы увидеть изменения по каждому файлу, или git-diff --dir, чтобы увидеть все изменения в представлении каталога.

person Lodewyk    schedule 09.02.2016