Осторожно: 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 гласит:
- в противном случае, 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 | мерзавец?