За исключением некоторых особых случаев, связанных с объединением различий (когда вы можете использовать --combined
), изменения фиксации всегда парные. Это меняет способ интерпретации x..y
. Вместо этого означает «все обороты, достижимые из y
, которые недоступны из x
», это означает «сравнить обороты x
с оборотами y
».
(Здесь стоит отметить, что ответ на связанный вопрос замалчивает тот факт, что x..y
в git diff
интерпретируется иначе, чем в других командах git.)
Когда вы запрашиваете E..topic
, git преобразует topic
в конкретную фиксацию — в данном случае K
— и затем сравнивает дерево в E
с деревом в K
. Вот почему вы видите изменения из G
и I
, потому что эти изменения были внесены в J
посредством слияния.
Вы можете сравнить F
и K
, но это все равно покажет изменения в G
и I
, потому что опять же, эти изменения на самом деле в J
.
На самом деле есть только один способ игнорировать то, что произошло в J
, сохраняя при этом F
и H
нетронутыми, и это построить дерево, которое либо пропускает это, либо возвращает его. Например, начиная с H
, вы можете добавить патч, основанный на разнице между J
и K
:
K' <-- HEAD[detached]
/
B---D---F---H---J---K <-- topic
/ / /
A---C---E---G---I <-- master
(для этого git checkout topic~2
отсоединиться при фиксации H
, затем git cherry-pick topic
добавить к уже отсоединенному HEAD
сделанные изменения для перехода от J
к K
).
Теперь вы можете сравнить дерево в коммите E
с деревом в HEAD
(в коммите K'
):
git diff E HEAD # or git diff E..HEAD or git diff E..
Но в целом это не то, что люди хотят пересматривать. На самом деле, поскольку вы почти наверняка впоследствии полностью откажетесь от версии K'
(создав ее только для проверки), они будут проверять версию кода, которая никогда не используется!
Вот почему принятым ответом на связанный вопрос является просто git diff master..topic
, что означает то же самое, что и git diff master topic
, и в данном случае сравнивает дерево для I
с деревом для K
. Вы предлагаете разместить на ветке topic
дерево, похожее на K
. Это код, который будет в topic
. Он имеет некоторое отличие от кода, который находится в версии I
в версии master
. Разница, которую он имеет по сравнению с I
, представляет собой сумму изменений в F
, H
, K
и любой работы с прокладками, которая была проделана, чтобы J
соответствовала. Он действительно имеет изменения, сделанные в G
(и, конечно, в самом I
), но это не изменения в I
, это просто изменения, включенные в I
.
Более тщательный способ просмотреть код — представить на проверку четыре отличия:
E
vs F
F
vs H
H
против J
(возможно, комбинированный дифференциал, H
и I
против J
)
J
vs K
Первая разница сообщает вашим рецензентам, что, если они ее примут, можно будет проверить дерево, похожее на F
(что, безусловно, верно, просто git checkout F
). Вторая разница говорит вашим рецензентам, что, имея F
в своих репозиториях, можно будет проверить H
(если они примут это) и т. д. Очевидно, что четыре обзора сложнее, чем один, поэтому люди принимают такие сокращения, как сравнение I
против K
.
person
torek
schedule
28.10.2013