`git rebase -i`, несколько обычных коммитов отсутствуют в интерактивном списке - PullRequest
0 голосов
/ 17 декабря 2018

Среда: git версии 2.17.1 в macOS 10.14.2

Вы можете клонировать репозиторий для тестирования:

git clone https://gist.github.com/arzyu/9c4a50257bd2be18ed1e9774b7600070 rebase-demo

git log:

* 32b845d (origin/b2, b2) C7
| * be5dd19 (origin/b1, b1) C6
|/
| * 166caa4 (HEAD -> master, origin/master) C5
| * 27bb508 C4
| * 63aed5a C3
|/
* 1ed4bc4 C2
* 8ff08b7 C1

case 1:

# on master
git rebase -i b1


# list 1
pick 63aed5a C3

case 2:

# on master
git rebase -i b2

# list 2
pick 63aed5a C3
pick 27bb508 C4
pick 166caa4 C5

Почему C4 и C5 не отображаются в списке 1?

1 Ответ

0 голосов
/ 17 декабря 2018

Редактировать: клонирование хранилища подтверждает правильность теории;см. приложение ниже.

Проблема здесь в том, что rebase решил, что коммиты являются избыточными.В частности, git rebase (с или без -i) будет пропускать коммиты, которые имеют восходящий коммит, «эквивалентный патчу».

То есть предположим, что у нас есть:

...--F--G--H2--J2--K   <-- upstream
         \
          H--I--J   <-- branch

Здесь, если мы попросим Git перебазировать branch на upstream, Git обычно скопирует коммиты H, затем I, затем J, чтобы новые копии шли после коммита K:

                     H3--I2--J3   <-- branch
                    /
...--F--G--H2--J2--K   <-- upstream
         \
          H--I--J   [abandoned]

Однако, пока Git готовит список хеш-идентификаторов коммитов для копирования, он делает что-то немного хитрое: для каждого коммита H, I и J он проверяет, есть лииз коммитов только для восходящего потока - здесь H2, J2 и K - имеют те же git patch-id, что и коммиты H, I или J:

git show <hash> | git patch-id

более или менее (попробуйте это, чтобы увидеть, как это работает, хотя это не совсем удобно для пользователя).

Если, как я подразумеваю под именами H2 и J2, некоторые изУ коммитов есть апстрим, который «делает то же самое», процесс ребазирования будет отбрасывать этих коммитов.В этом случае, поскольку H уже реплицируется H2, а J уже реплицируется J2, фактическая перебазировка будет производить:

                     I2   <-- branch
                    /
...--F--G--H2--J2--K   <-- upstream
         \
          H--I--J   [abandoned]

Это, похоже, то, что вы наблюдаете,Это немного странно, так как это означает, что коммиты C4 и C5 должны иметь одинаковый идентификатор патча - на b1 есть только один восходящий коммит, а именно C6.Их можно удалить, только если они оба имеют одинаковые идентификаторы патчей и , которые совпадают с идентификаторами патчей C6.

(Очевидно, идентификатор патчей C7 отличается,Таким образом, ребаз сохраняет все коммиты.)

Приложение

$ git clone https://gist.github.com/arzyu/9c4a50257bd2be18ed1e9774b7600070 gri
$ git show master~3..master | git patch-id
c711e5dfe43107af9bcff6c00bed4211d3b60cf6 166caa401ede4f97841a2715a80b4d26c40c50b8
c711e5dfe43107af9bcff6c00bed4211d3b60cf6 27bb50839ee73bce4cbb97089306c5dfa04c4516
2ee54397f45e5f955fc7b5b6717544e526818ede 63aed5a10cf22e1dd1ba699dac9104f3605a3751

Хеш-идентификаторы слева - это идентификаторы патчей, а хэш-идентификаторы справа - это идентификаторы коммитов (для C3, C4 и C5 соответственно).Например:

$ git show master~2
commit 63aed5a10cf22e1dd1ba699dac9104f3605a3751
Author: arzyu <arzyu@live.cn>
Date:   Mon Dec 17 17:17:01 2018 +0800

    C3

diff --git a/test.txt b/test.txt
index 4b87763..a25c784 100644
--- a/test.txt
+++ b/test.txt
@@ -1,2 +1,4 @@
 //
 //
+
+//

Два совпадают с хэш-идентификатором кончика b1:

$ git show origin/b1 | git patch-id
c711e5dfe43107af9bcff6c00bed4211d3b60cf6 be5dd192f9bed20036491915766be61d66eec8aa
$ git show origin/b1
commit be5dd192f9bed20036491915766be61d66eec8aa (origin/b1)
Author: arzyu <arzyu@live.cn>
Date:   Mon Dec 17 17:19:09 2018 +0800

    C6

diff --git a/test.txt b/test.txt
index 4b87763..b8e0885 100644
--- a/test.txt
+++ b/test.txt
@@ -1,2 +1,3 @@
 //
 //
+//

Поскольку все три коммита имеют идентификатор патча c711e5dfe43107af9bcff6c00bed4211d3b60cf6, git rebase опускает два, которые иначе были бы скопированы.

Идентификатор патча коммита, как git patch-ID документация говорит:

ничего, кромесумма SHA-1 различий в файлах, связанных с патчем, с пропуском пробелов и номеров строк.

Поскольку все три патча просто , добавьте строку, состоящую из //все они имеют одинаковые идентификаторы патчей, и Git предполагает, что он делает правильные вещи, когда пропускает их для перебазирования.

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