Ответ 1
tl; dr Вы должны обновить master
и feature
с помощью git pull
и git pull --rebase
прежде чем перезапустить feature
поверх master
. Нет необходимости делать git pull
после git pull
как вы пересоздали свою ветку feature
поверх master
.
С вашим текущим рабочим процессом, причина, по которой git status
говорит вам об этом:
Ваша ветка и "происхождение/особенность" расходятся и имеют соответственно 27 и 2 разных коммита.
потому что в вашей ветке с измененной feature
теперь есть 25 новых коммитов, которые недоступны из origin/feature
(поскольку они произошли из rebase на master
) плюс 2 фиксации, которые достижимы с origin/feature
но имеют разные идентификаторы фиксации. Эти коммиты содержат те же самые изменения (т.е. Они эквивалентны патчу), но у них разные хэши SHA-1, поскольку они основаны на другой фиксации по origin/feature
чем тот, который вы их переустановили в своем локальном репозитории.
Вот пример. Предположим, что это ваша история, прежде чем делать git pull
on master
:
A - B - C (master)
\
D - E (feature)
После git pull
, master
получил фиксацию F
:
A - B - C - F (master, origin/master)
\
D - E (feature)
В этот момент вы переустанавливаете feature
поверх master
, которая применяет D
и E
:
A - B - C - F (master, origin/master)
\
D - E (feature)
Между тем, origin/feature
удаленного ветки по-прежнему основывается на фиксации C
:
A - B - C - F (master, origin/master)
\ \
\ D' - E' (feature)
\
D - E (origin/feature)
Если у вас git status
на feature
, Git покажет вам, что ваша feature
филиал расходились от origin/feature
с 3 (F
, D'
E'
) и 2 (D
, E
) совершающее соответственно.
Обратите внимание, что
D'
иE'
содержат те же изменения, что иD
иE
но имеют разные идентификаторы фиксации, поскольку они были перегруппированы поверхF
Решение состоит в том, чтобы сделать git pull
как на master
и feature
, прежде чем перебазирования feature
на master
. Однако, так как вы можете иметь фиксации на feature
, которые вы еще не сдвинуты к origin
, вы хотели бы сделать:
git checkout feature && git pull --rebase
чтобы избежать создания фиксации слияния между origin/feature
и вашей локальной feature
.
Обновление о последствиях перезагрузки:
В свете этого комментария я расширился на расходящихся ветвях. Причина, по которой git status
сообщает о том, что feature
и origin/feature
отклоняются после переучета, связана с тем, что rebasing привносит новые коммиты в feature
, а также перезаписывает коммиты, которые ранее были перенесены в origin/feature
.
Рассмотрим ситуацию после тяги, но до перезагрузки:
A - B - C - F (master)
\
D - E (feature, origin/feature)
На этом этапе feature
и origin/feature
указывают на одно и то же совершение E
-in другими словами, они находятся в "синхронизации". После восстановления feature
поверх master
история будет выглядеть так:
A - B - C - F (master)
\ \
\ D' - E' (feature)
\
D - E (origin/feature)
Как вы можете видеть, feature
и origin/feature
расходились, их общий предок - совершать C
Это связано с тем, что теперь feature
содержит новый фиксатор F
от master
плюс D'
и E'
(считанные как "D prime" и "E prime"), которые фиксируют D
и E
применяемые поверх F
Несмотря на то, что они содержат те же самые изменения, Git считает их разными, потому что они имеют разные идентификаторы фиксации. Между тем, origin/feature
все еще ссылаются на D
и E
На этом этапе вы переписали историю: вы изменили существующие коммиты в силу их перезагрузки, эффективно создавая "новые".
Теперь, если вы хотите запустить git pull
on feature
это то, что произойдет:
A - B - C - F (master)
\ \
\ D' - E'- M (feature)
\ /
D - E - (origin/feature)
Поскольку git pull
делает git fetch
+ git merge
, это приведет к созданию слияния M
, родителями которого являются E'
и E
Если вместо этого вы git pull --rebase
(то есть git fetch
+ git rebase
), тогда Git будет:
- Переместить
feature
для фиксацииC
(общий предокfeature
иorigin/feature
) - Примените
D
иE
отorigin/feature
- Примените
F
,D'
иE'
Однако, заметив, что D'
и E'
содержат те же изменения, что и D
и E
, Git просто отбросит их, в результате чего история будет выглядеть так:
A - B - C - F (master)
\
D - E - F' (feature)
^
(origin/feature)
Обратите внимание, как фиксация F
, ранее достижимая из feature
, была применена поверх origin/feature
привело к F'
. На данный момент git status
скажет вам следующее:
Ваш филиал опережает "происхождение/особенность" на 1 фиксацию.
Это совершение, конечно, F'
.