Когда 2 патча считаются равными в git? - PullRequest
1 голос
/ 04 ноября 2019

Мой вопрос возник, когда я прочитал в git rebase doc , что

Если вышестоящая ветвь уже содержит внесенные вами изменения (например, потому что вы отправили патч,был применен вверх по течению), то этот коммит будет пропущен. Например, запустив git rebase master в следующей истории (в которой A 'и A вводят один и тот же набор изменений, но имеют разную информацию о коммитере):

      A---B---C topic
     /
D---E---A'---F master will result in:

               B'---C' topic
              /
D---E---A'---F master

Одним из способов является просмотрID патча, используя git patch-id , но это не то, что я хочу.

Позвольте мне иметь 2 ветки. Тема и мастер, и я изменяю в ней только один файл.

Inserted 2  ->  T2     M2 <--  Inserted 2 in new line
                |      |       
Inserted 1  ->  T1     M3 <-- Inserted 3 in new line
                  \   /
                   \ /
                    * <--  Contents similar here 

Теперь на T2 и M2 патч не считается тем же, хотя мы добавляем 2 в одной и той же новой строке в обеих версияхфайл (нашел это был git patch-id). Это открытие было удивительным для меня. Я думал, что патч будет таким же, если одинаковое содержимое в одной строке будет применено в 2 разных версиях файла.

Это заставило меня подумать, что патч, следовательно, зависит и от предыдущего коммита,где я применяю патч. Итак, когда мы говорим (patch1 в некоторой ветке) = (patch2 в какой-то другой ветке), тогда их предки также должны быть одинаковыми? Если да, мы можем применить это рекурсивно, и 2 ветви окажутся идентичными, что нелогично.

Итак, мой вопрос, когда мы говорим, что 2 патча равны (не учитывая идентификатор патча)?

Используйте этот скрипт, чтобы воспроизвести вышесказанное на местном:

#!/bin/bash

git init .
echo "10" >> 1.txt && git add . && git commit -m "1"

# Add 2 commits to master
echo "3" >> 1.txt && git commit -am "m3"
echo "2" >> 1.txt && git commit -am "m2"


#checkout topic branch
git checkout -b topic HEAD~2
echo "1" >> 1.txt && git commit -am "t1"
echo "2" >> 1.txt && git commit -am "t2"

#Show graph
git log --oneline --all --decorate --graph

1 Ответ

2 голосов
/ 04 ноября 2019

Итак, когда мы говорим (patch1 в некоторой ветви) = (patch2 в другой ветви), тогда их предки также должны быть одинаковыми?

Не для git rebase,нет. Rebase использует те же вычисления, что и git patch-id, что является просто результатом хеширования разборного текста (удалены номера строк и пробелы).

Команда git rev-list также делает это. См. Параметры --left-right, --right-only, --cherry-mark и --cherry-pick, которые должны использоваться с селекторами фиксации симметричной разностной трехточечной нотации.

Фактически, git rebase использует git rev-list делать работу. В старые времена, когда git rebase были в основном сценариями оболочки, было легко увидеть, как это было сделано. Теперь все это построено как код C, поэтому вместо запуска git rev-list он содержит те же биты, что и git rev-list, скомпилированные в нем.

... думал, что патч будет таким же, если то же самоесодержимое в той же строке ...

Нет, номера строк удаляются. Это сделано специально: например, патч может быть таким же простым, как замена вызова, передающего false, на тот, который передает true, что для Git:

-    foo(false)
+    foo(true)

(с, вслучай git diff, некоторый окружающий контекст - не ясно, включает ли ID патча контекст, но я предположил бы, что это делает). Предположим, что это исправление принято в восходящем направлении, пока вы работаете над функцией, которая может или не может быть связана с исправлением ... но в восходящем направлении , которая вызывает foo,который был в строке 42, теперь в строке 47, потому что пять не связанных строк были добавлены намного выше этой точки?

Перебазировать следует и пропускает этот патч теперь, когда он существует в восходящем, к которому вы перебазируете,как определено путем выполнения --left-right передачи по симметричной разности вышестоящего аргумента для rebase, и HEAD. Все левые коммиты имеют свои идентификаторы патчей. Для всех правых коммитов рассчитано их идентификаторов патчей. Если идентификаторы патчей совпадают, фиксация считается дубликатом и исключается из набора коммитов для копирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...