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

412

Некоторые команды Git принимают диапазоны фиксации, и один допустимый синтаксис - разделять два имени фиксации двумя точками .., а другой синтаксис использует три точки ....

Каковы различия между этими двумя?

Пэт Нотц
источник

Ответы:

251

Это зависит от того, используете ли вы logкоманду или diffкоманду. В logслучае, это в man git-rev-parseдокументации:

Чтобы исключить коммиты, достижимые из коммита, используется префикс ^. Например, ^ r1 r2 означает коммиты, достижимые из r2, но исключая коммиты, достижимые из r1.

Эта операция установки появляется так часто, что для нее есть сокращение. Если у вас есть два коммита r1 и r2 (названные в соответствии с синтаксисом, описанным в разделе «УКАЗАНИЯ ПЕРЕСМОТРА» выше), вы можете запросить коммиты, которые достижимы из r2, за исключением коммитов, которые достижимы из r1 «^ r1 r2», и это можно записать как "r1..r2".

Подобное обозначение «r1 ... r2» называется симметричной разностью r1 и r2 и определяется как «r1 r2 - not $ (git merge-base --all r1 r2)». Это набор коммитов, которые доступны с одного из r1 или r2, но не с обоих.

Что в основном означает, что вы получите все коммиты, которые находятся в любой из двух веток, но не в обеих.

В diffслучае, это в man git-diffдокументации:

  git diff [--options] <commit>...<commit> [--] [<path>...]

      This form is to view the changes on the branch containing and up to
      the second <commit>, starting at a common ancestor of both
      <commit>. "git diff A...B" is equivalent to "git diff
      $(git-merge-base A B) B". You can omit any one of <commit>, which
      has the same effect as using HEAD instead.

Что немного нечетко. По сути, это означает, что он показывает только различия в этой ветви по сравнению с другой веткой: он ищет последний общий коммит с первым коммитом, который вы ему дали, а затем переводит в него второй коммит. Это простой способ увидеть, какие изменения внесены в эту ветку, по сравнению с этой веткой, без учета изменений только в этой ветке.

..Несколько проще: В git-diffслучае, это то же самое , как git diff A Bи просто дифференциалы А против В. В logслучае, он показывает все коммиты , которые находятся в B , но не в А.

Pieter
источник
31
Это довольно смешно, как значение ..и ...точно log A..Bпоменяется местами для log и diff: это изменения от базы слияния к B, что и diff A...Bделает
phiresky
1
@phiresky Да, это действительно плохое удобство использования. Я рекомендую не использовать точечные обозначения для git diff.
Висбуки
2
Это значит A...B== A..B + B..A?
Данон
2
@ Данон для git logэтого абсолютно да
маоизм
659

Использование диапазонов коммитов с Git Log

Когда вы используете диапазоны фиксации, такие как ..и ...с git log, разница между ними заключается в том, что для ветвей A и B

git log A..B

покажет вам все коммиты, которые есть у B, которых нет у A , а

git log A...B

покажет вам как коммиты, которые есть у A, так и у которых нет B, так и коммиты, которые есть у B, которых нет у A, или другими словами, он отфильтрует все коммиты, которые есть у A и B, таким образом, показывая только коммиты, которые они оба не разделяют .

Визуализация с помощью диаграмм Венна и деревьев коммитов

Вот визуальное представление git log A..B. Коммиты, содержащиеся в ветви B, которые не существуют в A, - это то, что возвращается диапазоном коммитов, подсвечивается красным на диаграмме Венна и обводится синим цветом в дереве коммитов:

 диаграмма "git log A..B"Дерево 1

Это диаграммы для git log A...B. Обратите внимание, что коммиты, которые являются общими для обеих ветвей, не возвращаются командой:

 Диаграмма "git log A ... B"Дерево 2

Создание Triple-Dot Commit Range ...Больше полезного

Вы можете сделать диапазон фиксации тройной точки ...более полезным в команде журнала, используя --left-rightопцию, чтобы показать, какие коммиты принадлежат какой ветви:

$ git log --oneline --decorate --left-right --graph master...origin/master
< 1794bee (HEAD, master) Derp some more
> 6e6ce69 (origin/master, origin/HEAD) Add hello.txt

В приведенном выше выводе вы увидите, что коммиты, к которым они принадлежат, masterимеют префикс <, а коммиты, которым они принадлежат, origin/master- префикс >.

Использование диапазонов коммитов с Git Diff

Когда-нибудь я мог бы добавить свое собственное объяснение того, как работают диапазоны фиксации git diff, но сейчас вы можете проверить, каковы различия между двойной точкой ".." и тройной точкой "..." в коммите Git diff диапазоны? ,

Смотрите также

Сообщество
источник
35
Этот ответ на самом деле объясняет разницу с помощью краткого текста, примеров и рисунков. Мне он нравится намного лучше, чем ответ, получивший наибольшее количество голосов и цитирующий неясную документацию. (tl; dr благодаря этому ответу я действительно понимаю разницу.)
aerique
4
@Cupcake, не могли бы вы добавить значение ... в git diff?
Мариус
1
@Marius на самом деле, теперь, когда вы подняли этот вопрос, я отвечу на другой вопрос в моем ответе для будущих читателей, таких как вы.
2
Разве это не наоборот? dig diff a..b - это ALL diff, или в основном то же самое, что git diff a b. Принимая во внимание, что git dif a ... b - ТОЛЬКО изменения, сделанные b после ветвления из a.
Вейровский
2
По крайней мере, для git log. Для git diff, может быть, все наоборот: stackoverflow.com/questions/7251477/…
Бенджамин Аткин