Как сделать ребаз в мастер вместо git pull origin master? - PullRequest
0 голосов
/ 08 сентября 2018

У меня есть старая ветка foo, и я хочу сделать ее до последней master.

Если я выполню $ git rebase origin master в ветви foo, почему-то изменения, сделанные в ветке foo, исчезают и foo становится таким же, как HEAD из master.

Почему это происходит? И как перебазировать мою foo ветку на мастер?

Вот мой git reflog. foo равно komoto/crop_image.

fd8d9c1d (HEAD -> komoto/crop_image, origin/master, origin/HEAD, master) HEAD@{0}: rebase finished: returning to refs/heads/komoto/crop_image
fd8d9c1d (HEAD -> komoto/crop_image, origin/master, origin/HEAD, master) HEAD@{1}: rebase: checkout master
92284980 (tag: beta-test, origin/komoto/crop_image) HEAD@{2}: checkout: moving from master to komoto/crop_image

1 Ответ

0 голосов
/ 08 сентября 2018

Осторожно: git rebase origin master означает git checkout master; git rebase origin (а затем вернитесь к исходной ветви). Вот почему ваш рефлог показывает:

HEAD@{1}: rebase: checkout master

(а затем HEAD@{0}: rebase finished: returning to refs/heads/komoto/crop_image: очевидно, вы были на komoto/crop_image, когда начинали).

Что вы на самом деле запустили

Когда вы пишете origin самостоятельно в этом позиционном аргументе , ваш Git следует шестиэтапному процессу, описанному в документации gitrevisions . Шаг 6 гласит:

  1. в противном случае, refs / remotes / / HEAD , если он существует.

Таким образом, если git rev-parse origin/HEAD завершается успешно (а пять предыдущих шагов не выполняются), последовательность команд:

git checkout master
git rebase origin

эквивалентно последовательности:

git checkout master
git rebase origin/master

Если на вашем master нет коммитов, которые еще не были бы доступны с origin/master, это ничего не делает. Хорошее введение в достижимость см. В Think Like (a) Git .

Что вы должны были запустить

У меня есть старая ветка foo, и я хочу сделать ее до последней master.

В общем, я предпочитаю делать это так:

git checkout foo
git rebase master

но вы можете - из-за ярлыка, которого, как мне кажется, следует избегать (в старых версиях Git есть неудачные режимы сбоев) - запустить:

git rebase master foo

Помните, что rebase работает путем копирования коммитов, поэтому сначала будут перечислены все коммиты без слияния, достижимые из foo, которые недоступны из master, в топологически отсортированном порядке, 1 где-то сохраняют свои хэш-идентификаторы. 2 Затем будет использоваться эквивалент git cherry-pick 3 до копия каждого такого коммита с копией посадка после ранее скопированного коммита. Первый скопированный коммит приземляется сразу после кончика master:

...--A--B--C--...--N--O   <-- master
         \
          G--H--I   <-- foo

становится:

                        G'-H'-I'  <-- foo
                       /
...--A--B--C--...--N--O   <-- master
         \
          G--H--I   [abandoned, but still findable as foo@{1}]

где G'-H'-I' - последовательность выбранных вишен, то есть скопированных коммитов, соответствующих исходным коммитам G-H-I.


1 Для простой цепочки коммитов без разветвлений и слияний единственная правильная топологическая сортировка: в порядке от первого до последнего . Если в цепочке коммитов, которые вы перебазируете, есть последовательности ветвления и слияния, ребаз выбирает some допустимый топологический вид, линеаризуя коммиты в процессе и пропуская коммиты слияния. На самом деле это иногда хорошая идея и то, что вы хотите, но чаще это не так. Git разрабатывает новый тип ребаз, который сможет справиться с этим лучше; в настоящее время существует опция под названием --preserve-merges, которая пытается выполнить эту работу, но не совсем адекватна, и ее следует избегать, за исключением чрезвычайных ситуаций.

2 Это где-то буквально в файле, полном pick директив при использовании git rebase -i. Каждая директива pick <em>hash</em> говорит Git выполнить выборку именно этого коммита, указав его истинное имя: идентификатор хеша. для некоторых других типов перебазирования идентификаторы не так легко видны - но они все еще где-то сохраняются, с возможностью остановить процесс копирования при сбое шага копирования, затем возобновить с того места, где он остановился после того, как вы исправили вещи вручную.

3 Интерактивное перебазирование или запуск перебазирования с флагами -m или -s буквально использует git cherry-pick. Все перебазирования, вероятно, должны по умолчанию использовать это, но в настоящее время не -интерактивные перебазировки, которые не используют -m или -s, используют более старый метод, который комбинирует git format-patch с git am --3way. См. Также В чем разница между git cherry-pick и git format-patch | мерзавец?

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