Як я можу отримати бічний бік різниці, коли роблю "git diff"?


163

Коли я набираю "git diff", я хотів би бачити бічну сторону diff, як, наприклад, "diff -y", або хотів би відобразити diff в інтерактивному інструменті diff, наприклад "kdiff3". Як це можна зробити?



Примітка: у GitHub у вас є бічний бік .
VonC

Відповіді:


89

Хоча Git має внутрішню реалізацію diff, замість цього ви можете встановити зовнішній інструмент.

Існує два різні способи визначення зовнішнього інструменту "diff":

  1. встановлення змінних середовища GIT_EXTERNAL_DIFFта GIT_DIFF_OPTSсередовища.
  2. конфігурація зовнішнього інструменту різниці через git config

Дивитися також:

Виконуючи a git diff, Git перевіряє як налаштування вищезгаданих змінних середовища, так і його .gitconfigфайл.

За замовчуванням Git передає наступні сім аргументів програмі diff:

path  old-file  old-hex old-mode  new-file  new-hex new-mode

Зазвичай потрібні лише параметри старого та нового файлу. Звичайно, більшість інструментів різного роду приймають лише два імена файлів як аргумент. Це означає, що вам потрібно написати невеликий обгортковий скрипт, який бере аргументи, які Git надає сценарію, і передає їх зовнішній програмі git на ваш вибір.

Скажімо, ви помістили свій скрипт для обгортки під ~/scripts/my_diff.sh:

#!/bin/bash
# un-comment one diff tool you'd like to use

# side-by-side diff with custom options:
# /usr/bin/sdiff -w200 -l "$2" "$5" 

# using kdiff3 as the side-by-side diff:
# /usr/bin/kdiff3 "$2" "$5"

# using Meld 
/usr/bin/meld "$2" "$5"

# using VIM
# /usr/bin/vim -d "$2" "$5"

то вам потрібно зробити цей сценарій виконуваним:

chmod a+x ~/scripts/my_diff.sh

Тоді вам потрібно сказати Git, як і де знайти свій власний сценарій різної обгортки. У вас є три варіанти, як це зробити: (я вважаю за краще редагувати .gitconfig файл)

  1. Використовуючи GIT_EXTERNAL_DIFF,GIT_DIFF_OPTS

    наприклад, у файлі .bashrc або .bash_profile можна встановити:

    GIT_EXTERNAL_DIFF=$HOME/scripts/my_diff.sh
    export GIT_EXTERNAL_DIFF
    
  2. Використання git config

    використовуйте "git config", щоб визначити, де можна знайти ваш скрипт обгортки:

    git config --global diff.external ~/scripts/my_diff.sh
    
  3. Редагування ~/.gitconfigфайлу

    ви можете відредагувати ~/.gitconfigфайл, щоб додати ці рядки:

    [diff]
      external = ~/scripts/my_diff.sh
    

Примітка:

Аналогічно встановленню спеціального інструменту "diff", ви також можете встановити спеціальний інструмент злиття, який може бути візуальним інструментом злиття, щоб краще допомогти візуалізувати злиття. (див. сторінку progit.org)

Дивіться: http://fredpalma.com/518/visual-diff-and-merge-tool/ та https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration


1
Чи зберігає це забарвлення терміналу git?
Шрідхар Сарнобат

3
Це чудово, але запускає новий переглядач для кожного файлу. Будь-який спосіб створити консолідовану різницю, скажімо meld,?
HRJ

2
@Tilo Я отримую помилку для vim як IM: Попередження: Вихід не до терміналу
мертвий програміст

Чи може meldбути налаштована версія для створення каталогу diff, де я можу вибрати, для якого файла (файлів) я хочу бачити diff? В даний час він виконує окрему meldкоманду для кожного файлу, і мені доведеться вийти meld, щоб побачити наступний файл. Я вважаю за краще meldпоказати мені каталог зі зміненими файлами, як він поводиться при meldвикористанні з Mercurial.
kasperd

163

Спробуйте git difftool

Використовуйте git difftoolзамість git diff. Ви ніколи не повернетесь.

ОНОВЛЕННЯ, щоб додати приклад використання:

Ось посилання на інший stackoverflow, в якому йдеться про git difftool: Як я переглядаю вихід "git diff" за допомогою мого вподобаного інструменту / переглядача diff?

Для новіших версій git, difftoolкоманда підтримує безліч зовнішніх інструментів різного класу. Наприклад, vimdiffце автоматично підтримується, і його можна відкрити з командного рядка:

cd /path/to/git/repo
git difftool --tool=vimdiff

Інші підтримувані зовнішні інструменти різного переліку, перелічені git difftool --tool-helpтут, є прикладом виводу:

'git difftool --tool=<tool>' may be set to one of the following:
        araxis
        kompare
        vimdiff
        vimdiff2

The following tools are valid, but not currently available:
        bc3
        codecompare
        deltawalker
        diffuse
        ecmerge
        emerge
        gvimdiff
        gvimdiff2
        kdiff3
        meld
        opendiff
        tkdiff
        xxdiff

34
А може, ви повернетесь, якщо отримаєте This message is displayed because 'diff.tool' is not configured.. Можливо, оновіть відповідь мінімальним способом, як налаштувати цю річ, щоб її відображення поруч відрізнялося терміналом, про що вимагає ОП? Інструменти графічного інтерфейсу досить марні на віддаленому сервері, де ви підключаєтесь за допомогою ssh.
Петро

1
Цікавий момент, хоча я не думаю, що мені особисто коли-небудь потрібно було використовувати git, поки SSH'd. Один із приємних речей про DVCS - це Розподілена частина: принаймні в моїх середовищах ніколи не виникає клопотів локально клонувати те, про що я хочу обминути.
Метт Бал

1
Принаймні, в моєму конфігурації, git difftoolз vimdiffне завжди правильно вибудовуються два файли / буфери.
Ромер

1
Це добре, і так нижче в списку відповідей: ОІ використовуйте git difftool -yдля запобігання підказок tkdiff
harshvchawla

Пов’язано: зробіть збиток git difftoolу Windows та Linux: stackoverflow.com/a/48979939/4561887
Габріель

55

Ви також можете спробувати git diff --word-diff. Це не зовсім поруч, але якось краще, тому ви можете віддати перевагу вашій реальній потребі.


12
Це найпростіший спосіб. Що ще кращеgit diff --word-diff=color
Рольф

@Rolf --word-diff=colorдає мені помилку помилки. У якій версії він був представлений?
Холлоуей

@Trengot Я запускаю git 1.7.9, який починається з 02/2012
Рольф

4
Тут встановлена ​​версія за замовчуванням @Rolf - 1.7.1. Можна пояснити різницю. git diff --color-wordsсправді працює.
Холлоуей

4
Так, git diff --color-wordsце шлях до сучасних версій git.
ВасильНовіков

41

ydiff

Раніше cdiffцей інструмент може відображатись поруч , поступово та кольорово .

Замість цього git diffробіть:

ydiff -s -w0

Це запуститься ydiffв режимі одночасного відображення для кожного з файлів з відмінностями.

Встановити за допомогою:

python3 -m pip install --user ydiff

або

brew install ydiff

Бо git logви можете використовувати:

ydiff -ls -w0

-w0автоматично визначає ширину вашого терміналу. Детальну інформацію та демонстрацію див. На ydiff сторінці сховища GitHub .

Перевірено в Git 2.18.0, ydiff 1.1.


@RyneEverett: Чи можете ви пояснити, як зробити еквівалент git diff | cdiff -sз icdiff?
einpoklum

Просто запустіть ydiff -sз робочої області git / svn / hg, вам не потрібно працювати.
ymattw

якщо ви хочете обмежити diff на певний файл через історію Git, cd <git repo>а потім запустітьydiff -ls <path/to/file>
slm

22

Ви можете зробити це поруч, diffвикористовуючи sdiffнаступне:

$ git difftool -y -x sdiff  HEAD^ | less

де HEAD^є приклад, який слід замінити тим, на що ви хочете відрізнятись.

Я знайшов це рішення тут, де також є кілька інших пропозицій. Однак ця відповідь відповідає на питання ОП коротко і чітко.

Для пояснення аргументів див. Людину git-difftool .


Взявши коментарі на борту, ви можете створити зручну git sdiffкоманду, написавши такий виконуваний сценарій:

#!/bin/sh
git difftool -y -x "sdiff -w $(tput cols)" "${@}" | less

Збережіть це як /usr/bin/git-sdiffі chmod -xце. Тоді ви зможете зробити це:

$ git sdiff HEAD^

Зазвичай я роблю "$ git difftool -x 'sdiff -s -w 240'" (або будь-яка ширина екрану), якщо / коли я хочу придушити ті самі рядки, і є лише один файл (ще я роблю vimdiff)
HidekiAI

1
@HidekiAI Я вважаю , це біль , щоб ввести термінал ширина кожен раз, тому я використовую tput colsзамість цього, наприклад: git difftool -x "sdiff -s -w $(tput cols)".
jaume

чи можна виділити зміни кольору? Зараз здається, що ми повинні використати очі, щоб помітити, що насправді є змінами
неополярність

Замініть sdiff на icdiff, щоб отримати гарний кольоровий дисплей.
Грег

10
export GIT_EXTERNAL_DIFF='meld $2 $5; echo >/dev/null'

тоді просто:

git diff

1
`meld. ' працює теж! І він показує всі зміни у зведеному вікні.
HRJ

@HRJ, що прекрасно працює! Так просто і практично :)
waldyrious

9

Якщо ви хочете, щоб у веб-переглядачі без участі GitHub бачилися різниці , ви можете насолоджуватися git webdiff , заміною для спаду для git diff:

$ pip install webdiff
$ git webdiff

Це пропонує низку переваг перед традиційними диффузолями графічного інтерфейсу, наприклад, tkdiffв тому, що вони можуть надавати підсвічування синтаксису та показувати зображення.

Детальніше про це читайте тут .


7

Я використовую colordiff .

На Mac OS X встановіть його

$ sudo port install colordiff

В Linux можливо apt get install colordiffчи щось подібне, залежно від вашого дистрибутива.

Тоді:

$ git difftool --extcmd="colordiff -ydw" HEAD^ HEAD

Або створити псевдонім

$ git alias diffy "difftool --extcmd=\"colordiff -ydw\""

Тоді ви можете використовувати його

$ git diffy HEAD^ HEAD

Я назвав це "diffy", тому diff -yщо бічний бік відрізняється від unix. Colordiff також додає кольори, які приємніше. У варіанті -ydw, то yє на бік про бік, то wє ігнорувати пробільні, і dце справляє мінімальний диференціал ( як правило , ви отримаєте найкращий результат , як дифф)


додати, -yщоб пропустити Launch 'colordiff' [Y/n]:підказку.
Бені Чернявський-Паскін

ти впевнений, що це git alias diffy "difftool --extcmd=\"colordiff -ydw\""? Чи не повинно бути git config --global alias.diffy "difftool --extcmd=\"colordiff -ydw\""?
неополярність

6

Для Unix, що поєднує просто gitта вбудований diff:

git show HEAD:path/to/file | diff -y - path/to/file

Звичайно, ви можете замінити HEAD будь-яким іншим посиланням на git, і ви, ймовірно, хочете додати щось подібне -W 170до команди diff.

Це передбачає, що ви просто порівнюєте вміст свого каталогу з минулим комітом. Порівняння між двома комітами складніше. Якщо ваша оболонка є, bashви можете використовувати "процес заміни":

diff -y -W 170 <(git show REF1:path/to/file) <(git show REF2:path/to/file)

де REF1і REF2є посилання на git - теги, гілки чи хеші.


Спасибі - ваша команда "git show HEAD: шлях / файл / файл" - це те, що мені потрібно було придумати власне рішення, "vimdfiff <(git show HEAD: шлях / до / файл) шлях / до / файл". Біти все ще не викладені правильно, але це найкраще рішення, яке я маю зараз.
talexb

5

Мені особисто дуже подобається icdiff !

Якщо ви Mac OS Xз HomeBrew, просто зробіть brew install icdiff.

Щоб правильно встановити мітки файлів, а також інші цікаві функції, у мене є ~/.gitconfig:

[pager]
    difftool = true
[diff]
    tool = icdiff
[difftool "icdiff"]
    cmd = icdiff --head=5000 --highlight --line-numbers -L \"$BASE\" -L \"$REMOTE\" \"$LOCAL\" \"$REMOTE\"

І я використовую це так: git difftool


3

Це питання з'явилося, коли я шукав швидкий спосіб використовувати git вбудований спосіб знайти відмінності. Мої критерії рішення:

  • Швидкий запуск, потрібні вбудовані варіанти
  • Можна легко обробляти безліч форматів, XML, різні мови програмування
  • Швидко визначте невеликі зміни коду у великих текстових файлах

Я знайшов цю відповідь, щоб отримати колір в git.

Щоб встати на бік diff замість рядкового розбігу, я налаштував відмінну відповідь mb14 на це запитання з такими параметрами:

$ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]"

Якщо вам не подобається додатковий [- або {+ варіант, --word-diff=colorможна використовувати.

$ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]" --word-diff=color

Це допомогло отримати належне порівняння як з json, так і з XML текстом та кодом Java.

Підсумовуючи, --word-diff-regexпараметри мають корисну видимість разом із налаштуваннями кольору, щоб отримати кольоровий кольоровий досвід вихідного коду порівняно зі стандартним розрізненням рядків під час перегляду великих файлів із невеликими змінами рядків.


3

Кілька інших вже згадували cdiff для git бік-о-пліч, але ніхто не давав його повною мірою.

Налаштування cdiff:

git clone https://github.com/ymattw/cdiff.git
cd cdiff
ln -s `pwd`/cdiff ~/bin/cdiff
hash -r # refresh your PATH executable in bash (or 'rehash' if you use tcsh)
        # or just create a new terminal

Відредагуйте ~ / .gitconfig, вставляючи ці рядки:

[pager]
        diff = false
        show = false

[diff]
        tool = cdiff
        external = "cdiff -s $2 $5 #"

[difftool "cdiff"]
        cmd = cdiff -s \"$LOCAL\" \"$REMOTE\"

[alias]
        showw = show --ext-dif

Вимкнення пейджера потрібно, щоб cdiff працював з Diff, все одно це пейджер так чи інакше. Difftool працюватиме незалежно від цих параметрів.

Псевдонім show потрібен тому, що git show підтримує лише зовнішні інструменти різниці через аргумент.

Значення "#" в кінці зовнішньої команди diff є важливим. Команда diff Git додає до команди $ @ (усі доступні змінні diff), але ми хочемо лише двох імен файлів. Тому ми чітко виказуємо ці два $ 2 і $ 5, а потім ховаємо $ @ за коментарем, який інакше заплутає sdiff. У результаті виникла помилка, яка виглядає так:

fatal: <FILENAME>: no such path in the working tree
Use 'git <command> -- <path>...' to specify paths that do not exist locally.

Команди Git, які тепер створюють різницю:

git diff <SHA1> <SHA2> 
git difftool <SHA1> <SHA2>
git showw <SHA>

Використання Cdiff:

'SPACEBAR' - Advances the page of the current file.
'Q'        - Quits current file, thus advancing you to the next file.

Тепер у вас є бічний бік diff через git diff та difftool. І у вас є вихідний код cdiff python для налаштування користувачем живлення, якщо вам це потрібно.


2

Ось підхід. Якщо ви пропускаєте менше, ширина xterm встановлюється на 80, що не так вже й гаряче. Але якщо продовжити команду, наприклад, COLS = 210, ви можете використовувати розширений xterm.

gitdiff()
{
    local width=${COLS:-$(tput cols)}
    GIT_EXTERNAL_DIFF="diff -yW$width \$2 \$5; echo >/dev/null" git diff "$@"
}

1
Смішно. Я підписався на ім'я псевдонімом, але це було проігноровано ... Дякую за те, що виходили на мене, Stack Overflow. :(
Томас Мелман

2

Відкрийте Intellij IDEA , виберіть одну чи кілька комісій у вікні інструмента «Контроль версій», перегляньте змінені файли та двічі клацніть по них, щоб переглянути зміни поруч із кожним файлом.

За допомогою пакетного запуску командного рядка ви можете вивести IDEA будь-де просто idea some/path

перегляд версії різний вигляд


1

На цю тему є багато хороших відповідей. Моє рішення цього питання було написати сценарій.

Назвіть це "git-scriptname" (і зробіть його виконуваним і помістіть його у свій PATH, як і будь-який сценарій), і ви можете викликати його як звичайну команду git, запустивши

$ git scriptname

Фактична функціональність - це лише останній рядок. Ось джерело:

#!/usr/bin/env zsh
#
#   Show a side-by-side diff of a particular file how it currently exists between:
#       * the file system
#       * in HEAD (latest committed changes)

function usage() {
    cat <<-HERE
    USAGE

    $(basename $1) <file>

    Show a side-by-side diff of a particular file between the current versions:

        * on the file system (latest edited changes)
        * in HEAD (latest committed changes)

HERE
}

if [[ $# = 0 ]]; then
    usage $0
    exit
fi

file=$1
diff -y =(git show HEAD:$file) $file | pygmentize -g | less -R

1

Це може бути дещо обмеженим рішенням, але виконує завдання, використовуючи команду системи diffбез зовнішніх інструментів:

diff -y  <(git show from-rev:the/file/path) <(git show to-rev:the/file/path)
  • фільтруйте лише використання змінних ліній --suppress-common-lines(якщо ваш diffваріант підтримує).
  • в цьому випадку немає кольорів, просто звичайні diffмаркери
  • може налаштувати ширину стовпчика --width=term-width; в Bash може отримати ширину як $COLUMNSабо tput cols.

Це також можна перетворити на помічник git-скрипта для більшої зручності, наприклад, використання такого:

git diffy the/file/path --from rev1 --to rev2
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.