Обратите внимание, что ваш связанный репозиторий содержит 15 полностью пустых коммитов.Под «пустыми коммитами» я подразумеваю не просто тот тип коммитов без изменений, который git commit --allow-empty
позволяет, а скорее полностью пустой: каждый коммит вообще не имеет файлов, просто сообщение коммита.(Точнее, каждый коммит имеет пустое дерево 4b825dc642cb6eb9a060e54bf8d69288fbee4904
в качестве своего дерева.) Таким образом, каждый коммит в вашем хранилище имеет идентификатор патча, эквивалентный каждому другому commit в вашем репозитории.
Это (в основном) объясняет, почему ваш раздел update-2 показывает вывод, который он делает: commit 6dd3b5b
эквивалентен патчу для коммитов 6276bec
, 9d23e9c
и т. д.,Загадка заключается в том, почему коммит caa4e2f
не связан с другим коммитом, поскольку он также эквивалентен патчу для любого другого коммита.В любом случае, это почти пример ложного положительного результата, но здесь это действительно больше истинного положительного результата: эти коммиты равны и являются одинаковыми, и поэтому могут быть отброшены без эффекта.
Команды Git для обхода ревизий (git log
и git rev-list
) могут использовать git patch-id
для отметки эквивалента патча коммитов.Это не надежно, но если коммит был выбран без ручного вмешательства, идентификаторы патчей копии и оригинала будут совпадать.
Чтобы увидеть, как это использовать, посмотрите на git log
или git rev-list
документация (раздел об этом разделен между обоими наборами документации - как и базовая реализация - поэтому я связал только одну).Перейдите к разделу на --left-right
опции .Обратите внимание, что --left-right
имеет смысл только в сочетании с симметричной разностью , что в данном случае означает использование синтаксиса release1...release2
или release2...release1
.Обратите внимание, что между этими двумя именами есть три , а не две точки.
Используя три точки и --left-right
, Git будет перечислять коммиты 5 и 4, которые доступны из release1
, а также два разных коммита 5 и 4, которые доступны с release2
.(Конечно, Git сначала перечислит коммиты 9, 8, 7 и 6, доступные с release2
, прежде чем перечислять 5 и 4, достижимые с release2
, но не release1
. Как вы можете видеть, этовозможно, ошибочно называть эти четыре разных коммита одинаковыми именами. У них разные хэш-идентификаторы по причине: это разные коммиты. Назовите их 5A
и 5B
и 4A
и 4B
, если хотите,или, возможно, 5.1
и 5.2
, чтобы добавить номер релиза, но дать им разные имена!)
Пока что это не очень помогает: у вас есть Git, показывающий, что вы делаете коммиты 5.1 и 4.1 из release1
, помеченный <
или >
в зависимости от того, с какой стороны из трех точек указано имя release1
.И у вас есть Git, показывающий, что вы фиксируете 9, 8, 7, 6, 5.2 и 4.2 из release2
, помеченные другим маркером.Но это важнейшая отправная точка.Теперь вы можете переключиться с --left-right
на --left-only
или --right-only
, чтобы сказать Git не показывать мне один из двух наборов, даже если выпо-прежнему перечисляя все коммиты.
С или без опций влево или вправо, вы можете добавить --cherry-mark
, чтобы сказать Git: Run git patch-id
на каждом коммите в обоих наборах.Если коммит в левом наборе имеет тот же идентификатор патча, что и коммит в правом наборе, пометьте этот коммит знаком равенства =
.В противном случае пометьте коммит знаком плюс +
.
Итак, в этом случае, если вы запустите:
git rev-list --left-right --cherry-mark --abbrev-commit release2...release1
, вы увидите (при условии хеш-идентификаторакоммит 9 начинается с 999999
и т. д.):
<9999999
<8888888
<7777777
<6666666
=5200000
=4200000
=5100000
=4100000
Таким образом, вы хотите именно те коммиты, которые отмечены <
.Используя release1...release2
, вы хотите получить именно те коммиты, которые отмечены >
.
. Предполагая, что все вышеперечисленное имеет смысл, прочитайте раздел --cherry-pick
.
Обратите внимание, что если вам нужно было разрешить конфликт при выборе вишни, идентификаторы патча исходного коммита и его копии не будут совпадать . Такой коммит не будет пропущен этим процессом. Также возможно получить ложное совпадение. Это обычно происходит с исправлением, которое состоит, например, из перемещения некоторых открывающих и закрывающих фигурных скобок: идентификатор патча формируется путем удаления не только номеров строк, но и пробелов. Таким образом, уменьшение двух разных (по отступу и номеру строки) фиксаций с изменением скобок до идентификаторов патчей приводит к тому, что должен быть разными. Отсюда мое утверждение вверху о том, что оно не является надежным: вы можете получить оба ложных отрицания (выбор вишни с разрешением конфликта слияния) и ложных срабатываний (сопоставленные коммиты, которые на самом деле разные).