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

190

Каковы различия между следующими командами ?:

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

Руководство по разным говорит об этом:

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

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

но не совсем понятно для меня

chrisjlee
источник
Хотя вопрос не является дубликатом, этот ответ графически показывает значение ..и ...в git diffи их различные значения в git log.
Марк Лонгэйр

Ответы:

335

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

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

Иллюстрация различных способов указания коммитов для 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может быть показано графически, как показано ниже:

Иллюстрация различных способов указания диапазонов коммитов для git log

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

Ну, я нахожу, что все это немного сбивает с толку, и я думаю, что диаграммы коммитов помогают :)

¹ Я говорю только «как правило», поскольку, например, при разрешении конфликтов слияния git diffвы увидите трехстороннее слияние.

Марк Лонгэйр
источник
1
Мне нравятся твои диаграммы. Я тоже придумал свою собственную . У меня есть некоторые идеи для моих собственных git diffдиаграмм, которые я сделаю позже.
34
Кто-то заметил? Эффекты ..и ...чувства вспять в git diff( по сравнению с git rev-list)!
Роберт Симер
2
Вы меня на "Это все, что вам нужно знать [...]. Однако ...". :-) Git полон таких вещей, где похожие обозначения и термины означают разные вещи в разных контекстах; спасибо за разъяснение этого так хорошо.
ShreevatsaR
Спасибо за упоминание rev-list. Я столкнулся с этим вопросом, когда искал способ сделать то, что делает rev-list через rev-parse.
Безумный физик
«Другими словами, git diff foo..barточно так же, как git diff foo bar; оба покажут вам разницу между кончиками двух ветвей foo и bar». Что именно вы подразумеваете под «разницей между кончиками двух ветвей»?
Асад Моосви
60

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

Diff vs Log & .. vs ..

DolphinDream
источник
3
это было бы очень хорошо, если бы в нем не было так много разных цветов и операций над множествами, смешанных с ../ ...stuff. Например log A...B, не ясно, возвращает ли команда пересечение (белая часть диаграммы) или остальную часть объединения AB (зеленая). Это было бы ближе к делу без каких-либо установленных операндов и только с одним цветом.
xealits
1
Если это действительно diff A..B<-> log A...B, то есть ли на самом деле разница с 2 точками, соответствуют войти с 3 - мя точками (!)? Или есть опечатка на изображении. Глядя на то, как точки имеют цветовую кодировку, мне кажется, что на изображении есть опечатка. Нижний левый угол: log A...Bдолжен быть log A..B, правый (?). И войти просто вправо быть ...не должно ...
КаджМагнус
1
Привет DolphinDream, спасибо за вашу фигуру. Я использую его как ссылку здесь: gitlab.com/tortoisegit/tortoisegit/issues/3427#note_227200695
Юэ Лин Хо,
1
@KajMagnus на самом деле красный / синий цвета используются только для различения 2-х точек и 3-х точек (независимо от того, используются ли они с diff или log). Диаграмма правильная. В первом столбце результат сравнения с 2 точками аналогичен логу с 3 точками (отсюда и начальная схема цели). Разница с 2 точками дает изменения кода в обоих оборотах вплоть до точки расхождения (проиллюстрированы зелеными пузырями вокруг коммитов и зелеными частями диаграмм фургона), в то время как журнал с 3 точками дает журналы изменений (сообщения коммита) в обоих оборотах вниз до точки расхождения.
DolphinDream
28

git diff foo master Различаются между верхними (головными) коммитами foo и master.

git diff foo..master Еще один способ сделать то же самое.

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

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

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

$ git diff master dev

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

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

$ git diff master...dev
manojlds
источник
2
git diff foo ... master изменения, которые внесла ветвь master, так как она является общим предком foo
0fnt
@manojlds хорошо, такой другой вопрос, если вы находитесь в ветке dev и фиксируете свои изменения (функцию) и помещаете изменения в удаленную ветку dev, значит ли это, что видимое изменение - это только функция или функция и readme?
Дэвид
Если я не ошибаюсь, diff запроса GitHub использует тройную точку. Это правильно?
Шон Луттин
Неработающая ссылка на пример страницы GitHub.
К.-Майкл Ай
6
git diff foo master

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

git diff foo..master

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

git diff foo...master

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

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

italiano40
источник
1

git log tree

Верхняя картинка эквивалентна нижней диаграмме дерева

A0 <- A1 <- A2 <- A3 (master)
   \
    C0 <- C1 (test)

Картинка стоит тысячи слов, разница между ними .. ... ^показана ниже.

$ git log master..test
# output C0 C1

$ git log ^master test
# output C0 C1

$ git log master…test
# output A1 A2 A3 C0 C1
yanhaijing
источник