С git log
(и всеми другими командами Git, которые принимают аналогичный набор аргументов), это спецификация того, как найти диапазон ревизий, да. Помните, что в общем мире Git это означает некоторый подграф графа ревизий - для большинства людей это обычно означает просто диапазон ревизий в списке. (И если вы не делаете много, если есть ветвление, это упрощается и в Git).
Спецификация ревизии содержит набор положительных ссылок (начальных точек) и отрицательных ссылок (точек останова) и дополнительных фильтров (ограничение количества ревизий, текст фиксации grep и т. Д.). Git начинается с положительных ссылок и возвращается к истории изменений, останавливаясь, когда он сталкивается с ревизиями, которые достижимы из отрицательных ссылок (не обязательно только когда он достигает одной из самих отрицательных ссылок).
Возможно, довольно запутанно, что существуют различные сокращенные обозначения, которые призваны сделать все это более простым в использовании и, тем не менее, каким-то образом сбить его с толку. "," maint..master "и т. д. означают и когда использовать.
Когда вы просто говорите «происхождение / мастер», это означает, что «происхождение / мастер» является положительной ссылкой, и нет никаких отрицательных ссылок. Итак, Git начинается с origin / master и проходит через all доступные ревизии - вы получаете полную историю origin / master.
«origin / master ..» - это сокращение от «origin / master..HEAD», которое выглядит примерно так, как оно означает «от origin / master до HEAD». Что это делает, эффективно. Его можно переписать как «HEAD ^ origin / master» или «HEAD - not origin / master». В этом случае HEAD является положительной ссылкой, а «origin / master» - отрицательной ссылкой. Таким образом, Git начинается с HEAD и идет назад по графику, пока не встретит ревизию, доступную из origin / master. Вполне вероятно, что он действительно столкнется с источником / мастером. Обратите внимание, что все ссылки являются включающими - сами положительные ссылки выводятся, а отрицательные - нет (если вы не укажете --boundary, а затем они помечаются). Это означает, что «origin / master..HEAD» ничего не выводит, если HEAD и origin / master имеют одинаковую ревизию.
Так что, если вы сделали пару локальных коммитов поверх вышестоящей версии, у вас будет такая ситуация:
steve@monolith:~/src/git <master>$ git log --pretty=oneline --abbrev-commit --decorate -n 4
ea3107d (refs/heads/master) Add another dummy comment
869c260 Add dummy comment
6345d7a (refs/remotes/origin/master, refs/remotes/origin/HEAD) Merge branch 'maint'
be427d7 allow -t abbreviation for --track in git branch
А теперь "git log origin / master .." означает, что git будет начинаться с HEAD (ea3107d), который недоступен из origin / master, поэтому печатает это. Затем он возвращается к родителю HEAD (869c260), который до сих пор нет, поэтому печатает это. Тогда следующий родитель - 6345d7a, который равен origin / master, поэтому он останавливается.
Обратите внимание, что "git log ..origin / master" делает обратное - пытается вернуться от origin / master к HEAD. В этом случае он ничего не печатает. Но если бы я выбрал «origin / maint», он напечатал бы ревизии на origin / master, которые не были на origin / maint: так что в общем, попытайтесь представить «A..B» как «ревизии в B, которые не являются в A ", и помните, что пропуск A или B означает" ГОЛОВА ".
Просто для сверхчувствительной путаницы есть также обозначение "A ... B". Так что не забудьте посчитать количество точек! В случае, когда A и B находятся в строке пересмотра, нет никакой разницы. Но что означает «A ... B» - это ревизии в A или B, которые не находятся ни в одной из баз слияния для A и B. Поэтому, если A и B находятся на расходящихся ветвях, он показывает все коммиты, сделанные на так как они разошлись.
«Длинная форма» для диапазона ревизий («B - not A») позволяет вам указывать такие вещи, как «все ревизии в локальных ветвях, которые не находятся ни в одной ветке удаленного отслеживания» («--branches - не --remotes "). Этот список аргументов анализируется многими командами Git (основным является git rev-list), включая gitk. Таким образом, вы можете выполнить команду «gitk --branches --not --remotes», чтобы увидеть ваши локальные изменения в графическом виде.
И, наконец, для путаницы с мега-бонусами такие команды, как "git diff", принимают тот же самый сокращенный синтаксис, но это не означает (совсем) одно и то же. git diff
фактически берет две ревизии и сравнивает их, что не совпадает с диапазоном - помните, что диапазон ревизий в Git - это подграф, а не просто список. «git diff A..B» эквивалентно «git diff A B». «git diff A ... B» означает «показать изменения в B, так как он отличается от A». Смешение? Немного: например, «git log A ... B» и «git log B ... A» означают одно и то же, но «git diff A ... B» и «git diff B ... A» "нет.