после git rebase моя локальная ветка и удаленная ветка разошлись

У меня есть ветка my-feature, которая подталкивается к источнику для проверки кода. Он не передается. В конце концов он будет объединен с моей develop веткой, которая используется всей моей командой. Я бы хотел переставить свою ветку develop в my-feature, чтобы история оставалась более чистой, а затем объединить свою ветку функций в разработку. Вот чем я занимаюсь:

$ git checkout my-feature
// do some work. make commits.

$ git rebase develop
// fix some conflicts

$ git add .

$ git rebase --continue

После успешной перезагрузки я проверяю статус:

$ git status
On branch my-feature
Your branch and 'origin/my-feature' have diverged,
and have 155 and 1 different commit each, respectively.
  (use "git pull" to merge the remote branch into yours)

$ git what do I do here?

Я должен понять, что здесь делать. Если я git pull, то я заметил, что у меня будут конфликты, которые не имеют смысла. Некоторые люди говорят, что нужно давить, но я нервничаю по этому поводу. Нормально ли принудительно подталкивать мою тематическую ветку к источнику? Если никто другой не использует эту ветку?


person Jeff    schedule 19.11.2015    source источник


Ответы (3)


Во-первых, вы можете сделать git push --force на этом этапе, не беспокоясь: вы сказали, что ваша ветка не является общей.
Таким образом, изменение ее истории на стороне сервера не повлияет на других пользователей.

Во-вторых, когда вы переустанавливаете ветку, вы меняете ее общего предка с ее удаленной ветки отслеживания (origin/xxx)

До git rebase develop у вас есть

d--d--d (develop)
    \
     x--x--x--x--x--X--y--y--y (my-feature)
                    |
       (origin/my-feature)   

X является общим предком между origin / feature и feature, что просто означает, что вы добавили несколько коммитов в свою ветку my-feature).
Статус git вернет что-то вроде:

On branch my-feature
Your branch is ahead of 'origin/my-feature' by 3 commit.

Но когда вы переставляете эту ветку поверх develop, вы воспроизводите все коммиты my-feature поверх разработки HEAD

        X--X--X--X--X--X--Y--Y--Y  (my-feature)
       /
d--D--d (develop)
    \
     x--x--x--x--x--X
                    |
       (origin/my-feature)   

На этот раз общий предок между my-feature и origin/my-feature - это уже не несколько добавленных коммитов, а полная история my-feature плюс несколько коммитов develop! (D здесь)

Следовательно, статус

Your branch and 'origin/my-feature' have diverged,
and have 155 and 1 different commit each, respectively.

Поскольку ваша ветка не является общей, опять же, простой git push --force origin my-feature завершит операцию:

        X--X--X--X--X--X--Y--Y--Y  (my-feature, origin/my-feature)
       /
d--D--d (develop)

(Если у my-feature есть восходящая ветвь, git push --force будет достаточно при условии, что для политики push по умолчанию push.default установлено значение simple.
Проверьте это с помощью git rev-parse --abbrev-ref --symbolic-full-name @{u})

person VonC    schedule 01.12.2015
comment
отличное объяснение. И тогда я могу без последствий слить свой feature в develop? - person Jeff; 01.12.2015
comment
@Jeff да, тогда слияние будет тривиальным слиянием с перемоткой вперед. - person VonC; 01.12.2015
comment
@VonC В зависимости от версии git кто-то использует git push --force немного рискованно. До git 1.9.5 поведение git по умолчанию для push заключалось в том, чтобы выталкивать каждую ветку из вашего локального репозитория. Так что лучше явно указать ветку: git push --force origin ‹имя ветки› - person Eruvanos; 02.12.2015
comment
@Eruvanos Я согласен. Я отредактировал ответ, чтобы сделать его более заметным, со ссылкой на stackoverflow.com/a/21772695/6309 - person VonC; 02.12.2015
comment
И что произойдет, если моя ветка my-feature без общего доступа (которую я перебазировал для разработки и принудительного нажатия) внезапно станет общей (кто-то снимет ее и начнет делать коммиты)? Я облажался? Стоит ли выбросить ветку? - person Jeff; 08.12.2015
comment
@Jeff Не нужно ничего выбрасывать. После того, как ветка станет общедоступной, вы можете интегрировать develop evolution путем слияния develop с my-feature (вместо перебазирования my-feature поверх develop): это позволит вам нажать my-feature без --force. - person VonC; 08.12.2015
comment
Отличное объяснение с использованием git push --force, оно решает мою проблему. - person Sojimaxi; 21.10.2020

Вы видите, что my-feature действительно отличается от origin/my-feature (как выглядела моя-функция в исходной точке в последний раз, когда вы проверяли), потому что вы только что изменили my-feature (мою-функцию, с которой вы работаете), когда выполняли перебазирование.

Когда вы выполняете перебазирование, вы меняете историю ветки, поэтому вам почти всегда нужно --force нажимать после этого. Ничего страшного, если это ваша ветка и никто из соавторов не использует эту ветку.

Если у этой функциональной ветки есть соавторы, вам не следовало делать переустановку с самого начала. Общее практическое правило - не изменять историю общих ветвей. В этом случае вам необходимо отменить перебазирование, с чем вы можете обратиться за помощью в этом сообщении.

person jaredready    schedule 19.11.2015
comment
Спасибо. В этом есть смысл. Иногда я не знаю, будут ли у ветки соавторы или нет, поэтому мне было интересно, есть ли лучшая практика для обмена функциональной веткой, которая была перебазирована. Я полагаю, я мог бы начать новую ветку и выбрать те коммиты, которые я хочу в новую ветку. - person Jeff; 20.11.2015
comment
Если к нему уже поделились, не переустанавливайте его. Если вы перебазируете до того, как кто-то его возьмет, то все в порядке. Как правило, вы должны знать, безопасно ли перебазирование в вашей ситуации. - person jaredready; 20.11.2015

Предположим, у вас есть следующая структура git-commit-structure:

A--B--C--D--E(origin/my-feature)
 \
  F--G--H--I(someotherbranch)

если вы теперь перебазируете origin/my-feature на someotherbranch, то у вас будет следующая ситуация:

A--B--C--D--E(origin/my-feature)
 \
  F--G--H--I(someotherbranch)
            \
             B'--C'--D'--E'(my-feature)

это diverging ситуация. my-feature входит в ветку, отличную от origin/my-feature, и вы не можете fast-forward использовать обе ветки. Теперь, если origin/my-feature не тянет ни один человек, вы можете безопасно push -f. Но если кто-то его вытащил, у вас могут возникнуть проблемы, если этот человек продолжит работу над этой веткой. Убедитесь, что любой человек, который вытащил вашу неправильную origin/my-feature, не изменил ли он заголовок ветки на вашу недавно принудительную фиксацию.

Всегда следуйте правилу: не перебазируйте какие-либо нажатые фиксации.

Плохая ситуация:

              J--K--G(origin/otherperson)
             /
A--B--C--D--E(origin/my-feature)
 \
  F--G--H--I(someotherbranch)
            \
             B'--C'--D'--E'(my-feature)

Затем это следует изменить на:

A--B--C--D--E(origin/my-feature) (orphaned if push-f)
 \
  F--G--H--I(someotherbranch)
            \
             \               J'--K'--G'(origin/otherperson)
              \             /
               B'--C'--D'--E'(my-feature)
person Michael Mairegger    schedule 01.12.2015