Вопрос
У меня есть репозиторий git на GitHub (демо), который имеет 3 ветки:
main
: ветка по умолчаниюbranch-modify
: разветвлен на main
, содержит модифицирующий коммит на main
branch-revert
: разветвлен на branch-modify
, содержит еще один коммит, возвращающий модифицирующий коммит.В этом репозитории я сделал PR с branch-modify
против main
и объединил его с объединенным коммитом (#1).
А еще я сделал еще один пиар с branch-revert
против main
(#2).
Я ожидал, что второй PR покажет, что разница возвращает изменения, внесенные модифицирующим коммитом.
Однако GitHub показывает пустой diff.
Почему дифф оказался пустым? Если это намеренное поведение, какова его причина?
Git-график репо после операций:
% git log --all --oneline --graph
* 97d2b9b (HEAD -> main, origin/main) Merge pull request #1 from nekomachi-touge/branch-modify
|\
| | * 6d23f11 (origin/branch-revert, branch-revert) Revert "modify test.txt"
| |/
| * eaec7f6 (origin/branch-modify, branch-modify) modify test.txt
|/
* c1f094b add test.txt
Предыдущие исследования
Я нашел похожие вопросы:
Оба предполагают разницу между двухточечными и трехточечными различиями, но в моем случае я не вижу никакой разницы.
% git diff main..branch-revert
diff --git a/test.txt b/test.txt
index 55b5f1f..323fae0 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-foofoo
+foobar
% git diff main...branch-revert
diff --git a/test.txt b/test.txt
index 55b5f1f..323fae0 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-foofoo
+foobar
Кроме того, я обнаружил, что функция «Сравнение изменений» создает различия, которые не обратятся, если я сравниваю main
с branch-revert
, а затем меняю местами ветки:
https://github.com/nekomachi-touge/github-revert-test-20240814/compare/main...branch-revert
https://github.com/nekomachi-touge/github-revert-test-20240814/compare/branch-revert...main
Фон
В моей работе у меня есть репозиторий IaC, управляющий двумя кластерами с избыточностью в активном/резервном стиле.
Чтобы переключить активный кластер, мне нужно внести изменения в репо.
Я хотел проверить избыточность, сделав PR, а затем отменив его другим PR.
Однако после слияния первого PR дифф второго PR стал пустым, что было совершенно неожиданно.
Попытка воспроизвести и понять проблему привела меня к публикации этого вопроса.
Обновлять
(24.08.2024) Базой слияния между main
и branch-revert
является коммит «modify test.txt»:
% git merge-base main branch-revert
eaec7f69baf9c990021537ad269cb4e6527a7b37
Проблема в том, что вы создали два одновременных запроса на включение, один из которых зависит от другого, и то, как вы это сделали, привело к такому поведению GitHub.
branch-revert
от branch-modify
.branch-modify
и один для branch-revert
.branch-revert
, попросив объединить его с main
. (Это простую конфигурацию, поскольку она используется по умолчанию.)Таким образом, даже после того, как вы объединили первый запрос на включение, второй (branch-revert
) запрос на включение включает в себя как фиксацию branch-modify
, так и фиксацию branch-revert
(поскольку база слияния между branch-revert
и main
является корневой фиксацией):
Вот как можно посмотреть, из чего «состоит» запрос на включение. Ну и конечно же, общая сумма изменений файлов за все время этих двух коммитов равна нулю; test.txt переходит от «foobar» к «foofoo» и обратно к «foobar».
Как еще вы могли бы поступить и каков был бы результат?
Поскольку branch-revert
был ответвлением от branch-modify
, вы могли бы создать второй запрос на включение, попросив объединиться с branch-modify
. Если бы вы это сделали, то, когда первый (branch-modify
) запрос на включение был бы объединен, GitHub переназначил бы цель слияния для второго запроса на включение как main
, и запрос на включение состоял бы только из одного коммита, коммита возврата и «файлы изменены» включали бы test.txt — «правильный» результат.
Альтернативно, вы могли бы подождать, пока первый запрос на включение не будет объединен, прежде чем создавать второй запрос на включение. Это также дало бы тот же «правильный» результат.
Если вы будете делать все так, как вы это сделали, в долгосрочной перспективе никакого серьезного вреда не будет, потому что объединение второго запроса на извлечение приведет к ожидаемому результату. Просто отображение GitHub того, из чего «состоит» второй запрос на включение, вышло таким образом, что вас удивило (отсюда и ваш вопрос).
Keep in mind, too, that this is entirely a matter of how GitHub displays things at its site. It has almost nothing to do with Git! Pull requests are not a Git feature. A pull request is effectively a trick performed by the hosting site, as a convenience for people doing collaborative development. (That is why looking at the Git log
locally didn't help you very much. Git knows nothing of what's going on here.) Every hosting site that adds this sort of feature can do it in its own way and can display the info in its own way. In this case, you simply stumbled across a quirk of the way GitHub does things.