Мастер-ветвь и "происхождение/мастер" расходятся, как "разделить ветки"?

Как-то мой хозяин и моя ветка происхождения/мастера расходились. На самом деле я не хочу, чтобы они расходились. Как я могу просмотреть эти различия и "объединить" их?

Ответ 1

Вы можете просмотреть различия с помощью:

git log HEAD..origin/master

перед тем, как потянуть его (выборка + слияние) (см. также "Как вы получаете git, чтобы всегда тянуть из определенной ветки?")


Когда у вас есть сообщение типа:

"Ваша ветка и" источник/хозяин "расходятся, # и имеют 1 и 1 разные фиксации соответственно".

проверьте, нужно ли обновлять origin. Если origin обновлен, то некоторые коммиты были перенесены в origin из другого репо, в то время как вы сделали свои локальные коммиты.

... o ---- o ---- A ---- B  origin/master (upstream work)
                   \
                    C  master (your work)

Вы основали фиксацию C на фиксации A, потому что это была последняя работа, которую вы вытащили из восходящего потока в то время.

Однако, прежде чем вы попытаетесь вернуться к происхождению, кто-то еще нажал commit B.
История развития распалась на отдельные пути.

Затем вы можете объединить или переустановить. Подробнее см. Pro Git: Git Branching - Rebasing.

сливаться

Используйте команду git merge:

$ git merge origin/master

Это говорит Git, чтобы интегрировать изменения из origin/master в вашу работу и создать фиксацию слияния.
График истории теперь выглядит следующим образом:

... o ---- o ---- A ---- B  origin/master (upstream work)
                   \      \
                    C ---- M  master (your work)

Новое слияние, commit M, имеет двух родителей, каждый из которых представляет один путь развития, который привел к содержимому, хранящемуся в этой фиксации.

Заметим, что история за M теперь нелинейна.

Rebase

Используйте команду git rebase:

$ git rebase origin/master

Это говорит Git переписать фиксацию C (ваша работа), как если бы вы основали ее на фиксации B вместо A.
Пользователи CVS и Subversion регулярно обновляют свои локальные изменения поверх восходящей работы при их обновлении до фиксации.
Git просто добавляет четкое разделение между шагами фиксации и переадресации.

График истории теперь выглядит следующим образом:

... o ---- o ---- A ---- B  origin/master (upstream work)
                          \
                           C'  master (your work)

Commit C '- это новый коммит, созданный командой git rebase.
Он отличается от C двумя способами:

  1. Он имеет другую историю: B вместо A.
  2. Его содержимое учитывает изменения как в B, так и в C; это то же самое, что и M из примера слияния.

Заметим, что история за C 'по-прежнему линейна.
Мы выбрали (пока), чтобы разрешить только линейную историю в cmake.org/cmake.git.
Этот подход сохраняет рабочий процесс на основе CVS, используемый ранее, и может облегчить переход.
Попытка нажать C 'в наш репозиторий будет работать (при условии, что у вас есть разрешения, и никто не нажал, пока вы пересобирали).

Команда git pull предоставляет сокращенный путь для извлечения из источника и реорганизации локальной работы:

$ git pull --rebase

Это объединяет приведенные выше шаги выборки и переадресации в одну команду.

Ответ 2

У меня было это и я был озадачен тем, что вызвало это, даже после прочтения вышеупомянутых ответов. Мое решение состояло в том, чтобы сделать

git reset --hard origin/master

Затем это просто сбрасывает мою (локальную) копию мастера (который, как я полагаю, прикручен) до правильной точки, представленной (удаленным) источником/мастером.

ПРЕДУПРЕЖДЕНИЕ: вы потеряете все изменения, которые еще не были перенесены в origin/master.

Ответ 3

git pull --rebase origin/master 

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

Изменить: Вытягивает фиксации из оригинала/мастера и применяет ваши изменения к недавно перенесенной истории ветвей.

Ответ 4

Я оказался в этой ситуации, когда попытался переустановить ветку, отслеживающую удаленную ветку, и я пытался ее переустановить на master. В этом случае, если вы попытаетесь переустановить, вы, скорее всего, обнаружите, что ваша ветка расходится, и это может создать беспорядок, который не для git nubees!

Скажем, вы находитесь на ветке my_remote_tracking_branch, которая была разветвлена от мастера

$ git status

# На ветке my_remote_tracking_branch

ничего не делать (рабочий каталог чист)

И теперь вы пытаетесь переустановить от мастера как:

git rebase master

ОСТАНОВИТЕ СЕЙЧАС и избавь себя от неприятностей! Вместо этого используйте merge как:

git merge master

Да, вы получите дополнительные коммиты в своем филиале. Но если вы не готовы к "разрозненным" ветвям, это будет гораздо более гладкий рабочий процесс, чем перезагрузка. См. Этот блог для более подробного объяснения.

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

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

git reset --hard origin/my_remote_tracking_branch

Ответ 5

В моем случае вот что я сделал, чтобы вызвать расходящееся сообщение: я сделал git push, но затем сделал git commit --amend, чтобы добавить что-то в сообщение фиксации. Затем я также сделал еще одну фиксацию.

Итак, в моем случае это просто означало, что источник/мастер устарел. Поскольку я знал, что никто не трогал оригинал/мастер, исправление было тривиальным: git push -f (где -f означает силу)

Ответ 6

В моем случае я нажал изменения на origin/master, а затем понял, что не должен был этого делать:-( Это осложнялось тем фактом, что локальные изменения были в поддереве. Поэтому я вернулся к последнему хорошему фиксации перед "плохими" локальными изменениями (используя SourceTree), а затем я получил "сообщение о расхождении".

После того, как я установил свой беспорядок локально (подробности здесь не важны), я хотел "вернуться назад" к удаленной ветке origin/master, чтобы она снова синхронизировалась с локальным master. Решение в моем случае было:

git push origin master -f

Обратите внимание на переключатель -f (force). Это удалило "плохие изменения", которые были ошибочно нажаты на origin/master, и теперь локальная и удаленная ветки находятся в синхронизации.

Пожалуйста, имейте в виду, что это потенциально разрушительная операция, поэтому выполняйте ее только в том случае, если вы на 100% уверены, что "вернувшийся" удаленный мастер вовремя в порядке.

Ответ 7

В моем случае это было вызвано не разрешением моего разрешения конфликта.

Проблема была вызвана запуском команды git pull. Изменения в происхождении привели к конфликтам с моим местным репо, которые я разрешил. Однако я не совершал их. Решением в этой точке является фиксация изменений (git commit разрешенный файл)

Если вы также изменили некоторые файлы после разрешения конфликта, команда git status покажет локальные модификации как нестационарные локальные модификации и разрешение слияния в виде локальных локальных изменений. Это можно устранить, выполнив сначала изменения слияния git commit, затем добавив и выполнив нестационарные изменения, как обычно (например, git commit -a).

Ответ 8

Чтобы просмотреть различия:

git difftool --dir-diff master origin/master

Это отобразит изменения или различия между двумя ветвями. В araxis (Мой любимый) он отображает его в стиле diff. Отображение каждого из измененных файлов. Затем я могу щелкнуть файл, чтобы просмотреть сведения об изменениях в файле.

Ответ 9

Я знаю, что здесь есть много ответов, но я думаю, что git reset --soft HEAD~1 заслуживает некоторого внимания, потому что это позволяет вам сохранять изменения в последнем локальном (не нажатом) фиксации при решении расходящегося состояния. Я думаю, что это более универсальное решение, чем pull с rebase, потому что локальная фиксация может быть пересмотрена и даже перемещена в другую ветвь.

Ключ использует --soft вместо жесткого --hard. Если есть более 1 фиксации, то должна быть изменена вариация HEAD~x. Итак, вот все шаги, которые решили мою ситуацию (у меня было 1 локальная фиксация и 8 коммитов на пульте дистанционного управления):

1) git reset --soft HEAD~1, чтобы отменить локальную фиксацию. Для следующих шагов я использовал интерфейс в SourceTree, но я думаю, что следующие команды также должны работать:

2) git stash, чтобы скрыть изменения от 1). Теперь все изменения безопасны и больше нет расхождений.

3) git pull, чтобы получить удаленные изменения.

4) git stash pop или git stash apply, чтобы применить последние спрятанные изменения, а затем новый фиксатор, если это требуется. Этот шаг является необязательным, а также 2), когда вы хотите сбросить изменения локального коммита. Кроме того, если вы хотите передать другую ветвь, этот шаг должен быть выполнен после переключения на желаемый.

Ответ 10

У меня было такое же сообщение, когда я пытался отредактировать последнее сообщение коммита, уже запушил коммит, используя: git commit --amend -m "New message" Когда я нажал изменения, используя git push --force-with-lease repo_name branch_name не было проблем.