Git rebase проверяет родительский коммит - PullRequest
0 голосов
/ 07 апреля 2020

Git ведет себя странно в конкретном случае, и я могу воспроизвести проблему. У меня есть две ветви, скажем, master и feature, указывающие на один и тот же коммит. Когда я сбрасываю мастер на родительский коммит и пытаюсь перебазировать функцию поверх мастер, ветвь функции также указывает на родительский коммит, хотя я ожидаю, что rebase ничего не сделает. Я не уверен, почему это происходит.

Шаги для воспроизведения:

Выполните следующие команды, чтобы воспроизвести исходное состояние:

deepakgupta @ git init
Initialized empty Git repository in /tmp/hello/.git/

deepakgupta (master)@ touch hello

deepakgupta (master)@ git add hello

deepakgupta (master)@ git commit -m "First commit"
[master (root-commit) 1750f9c] First commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 hello

deepakgupta (master)@ touch world

deepakgupta (master)@ git add world

deepakgupta (master)@ git commit -m "Second commit"
[master 7411ad0] Second commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 world

deepakgupta (master)@ git branch feature

В этот момент времени это как git log выглядит:

commit 7411ad0984841b28dca630d54c3b079ebd01c7e9 (HEAD -> master, feature)
Author: Deepak Gupta <deepakguptacse@gmail.com>
Date:   Tue Apr 7 13:58:09 2020 +0530

    Second commit

commit 1750f9c5ba95f53742005657e9cee41390165dc7
Author: Deepak Gupta <deepakguptacse@gmail.com>
Date:   Tue Apr 7 13:57:54 2020 +0530

    First commit

Теперь попробуйте:

git reset --hard HEAD^
git checkout feature
git branch --set-upstream-to master

Это теперь git Журнал выглядит сейчас:

commit 7411ad0984841b28dca630d54c3b079ebd01c7e9 (HEAD -> feature)
Author: Deepak Gupta <deepakguptacse@gmail.com>
Date:   Tue Apr 7 13:58:09 2020 +0530

    Second commit

commit 1750f9c5ba95f53742005657e9cee41390165dc7 (master)
Author: Deepak Gupta <deepakguptacse@gmail.com>
Date:   Tue Apr 7 13:57:54 2020 +0530

    First commit

Что должно произойдет, когда я попробую git rebase? Я чувствую, что государство должно оставаться таким же. но он меняется на:

commit 1750f9c5ba95f53742005657e9cee41390165dc7 (HEAD -> feature, master)
Author: Deepak Gupta <deepak.gupta@rubrik.com>
Date:   Tue Apr 7 13:57:54 2020 +0530

    First commit
(END)

Может кто-нибудь объяснить поведение?

1 Ответ

2 голосов
/ 07 апреля 2020

Эта проблема - или функция , как предпочитают к ней обращаться люди Git, - связана с Git режимом точки разветвления . Документация git rebase описывает это следующим образом:

Если upstream не указан, восходящий поток сконфигурирован в branch.<em>name</em>.remote и branch.<em>name</em>.merge будут использоваться опции (см. git -config [1] ) , а опция --fork-point предполагается . Если вы в настоящее время не находитесь ни в одной ветви, или если текущая ветвь не имеет настроенного восходящего потока, перебазировка будет прервана.

(форматирование, особенно полужирная часть, здесь мое). Следующий абзац предлагает эту крипти c сводку:

Все изменения, сделанные коммитами в текущей ветке, но не в upstream, сохраняются во временную область. Это тот же набор коммитов, который будет показан git log <upstream>..HEAD; или git log 'fork_point'..HEAD, если --fork-point активен (см. описание на --fork-point ниже); или git log HEAD, если указан параметр --root.

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

Описание точки разветвления находится частично внизу страницы. В нем упоминается, что:

fork_point является результатом команды git merge-base --fork-point <upstream> <branch> (см. git -merge-base [1] ). Если fork_point окажется пустым, в качестве запасного варианта будет использоваться upstream.

upstream равно master, а branch - текущая ветвь, feature. В моем репозитории я теперь запускаю:

$ git merge-base --fork-point master feature
af07c3c48ff0d499400ac539aa9c665a8dddcd6f

(используя идентификаторы ha sh в репозитории, который я сделал при воспроизведении вашего примера). Давайте используем git log в моем репозитории, чтобы увидеть два коммита:

$ git log --decorate --oneline
af07c3c (HEAD -> feature) Second commit
dbf1741 (master) First commit

Итак, учитывая, что этот вывод из git merge-base --fork-point, rebase обещает, что коммиты, которые он скопирует, будут теми, которые будут показаны по git log af07c3c48ff0d499400ac539aa9c665a8dddcd6f..HEAD:

$ git log af07c3c48ff0d499400ac539aa9c665a8dddcd6f..HEAD
$

Нет коммитов в списке, поэтому коммиты не копируются.

Как решить проблему

В отключить режим точки разветвления, запустите:

git rebase --no-fork-point

или:

git rebase master

Даже если восходящий поток текущей ветви feature равен master, явный git rebase master по умолчанию отключает режим точки разворота. Заставить Git использовать режим точки разветвления при использовании явного имени ветви - если вы сделаете это sh; в этом случае вы, вероятно, не хотите этого - вы также можете запустить:

git rebase --fork-point master

Без аргументов вы получите эффект git rebase --fork-point master.

...