Каковы различия между двуточечными ".." и тройными точками "..." в диапазонах значений Git diff?

В чем разница между следующими командами?:

git diff foo master   # a 
git diff foo..master  # b
git diff foo...master # c

Пособие по diff говорит об этом:

Сравнение ветвей

$ git diff topic master    <1>
$ git diff topic..master   <2>
$ git diff topic...master  <3>
  • Изменения между концами темы и главными ветвями.
  • То же, что и выше.
  • Изменения, произошедшие на главной ветке с тех пор, как ветка темы была отключена.

но мне это не совсем понятно.

Ответ 1

Поскольку я уже создал эти изображения, я подумал, что стоит использовать их в другом ответе, хотя описание разницы между .. (точка-точка) и ... (точка-точка-точка) по существу такая же, как в manojlds answer.

Команда git diff обычно¹ показывает только разницу между состояниями дерева между ровно двумя точками графа фиксации. Обозначения .. и ... в git diff имеют следующие значения:

An illustration of the different ways of specifying commits for git diff

Другими словами, git diff foo..bar точно совпадает с git diff foo bar; оба будут показывать разницу между концами двух ветвей foo и bar. С другой стороны, git diff foo...bar покажет вам разницу между "базой слияния" двух ветвей и концом bar. "База слияния" обычно является последней фиксацией, общей между этими двумя ветвями, поэтому эта команда покажет вам изменения, внесенные вашей работой в bar, игнорируя все, что было сделано на foo в среднем.

Это все, что вам нужно знать о обозначениях .. и ... в git diff. Однако...


... общий источник путаницы здесь состоит в том, что .. и ... означают тонко разные вещи при использовании в команде, такой как git log, которая ожидает, что набор коммиттов будет одним или несколькими аргументами. (Эти команды в конечном итоге используют git rev-list для анализа списка коммитов из своих аргументов.)

Значение .. и ... для git log может быть показано графически, как показано ниже:

An illustration of the different ways of specifying ranges of commits for git log

Итак, git rev-list foo..bar показывает вам все на ветке bar, которая также не находится на ветке foo. С другой стороны, git rev-list foo...bar показывает вам все коммиты, которые находятся в foo или bar, но не оба. Третья диаграмма показывает, что если вы перечислите две ветки, вы получите коммиты, которые находятся либо в одном, либо в обоих из них.

Ну, я считаю, что все немного запутанно, во всяком случае, и я думаю, что диаграммы диаграммы фиксации помогают:)

¹ Я ​​говорю только "обычно", так как при разрешении конфликтов слияния, например, git diff покажет вам трехстороннее слияние.

Ответ 2

git diff foo master Разница между верхней (головной) фиксацией foo и master.

git diff foo..master Другой способ сделать то же самое.

git diff foo...master Отклоните от общего предка (git merge-base foo master) от foo и master до кончика мастера. Другими словами, отображаются только те изменения, которые ввел мастер-ветвь с момента своего общего предка с мастером.

Этот пример из GitHub объясняет, когда использовать два:

Например, если вы создаете ветвь dev и добавляете функцию к файл, затем вернитесь к своей "главной ветке" и удалите строку из README, а затем запустите что-то вроде этого:

$ git diff master dev

Он скажет вам, что функция была добавлена ​​из первого файла и строка была добавлена ​​в README. Зачем? Потому что на ветке README все еще имеет оригинальную строку, но на "master youve удален" - так прямое сравнение снимков выглядит так: 'dev добавил его.

То, что вы действительно хотите сравнить, - это то, что "dev" изменилось с момента вашего ветки расходятся. Для этого Git имеет небольшое сокращение:

$ git diff master...dev

Ответ 3

Моя консолидированная версия .. vs ... с diff vs log

Diff vs Log and.. vs..

Ответ 4

git diff foo master

покажет различия между темой и главной ветвью в этот момент времени

git diff foo..master

это также покажет различия между темой и главной ветвью в этот момент времени

git diff foo...master

это покажет все различия между тем, когда тема была сделана из ветки и после

поэтому первые две команды одинаковы, а последний показывает более широкий вид в истории различий