Мастер-ветвь и "происхождение/мастер" расходятся, как "разделить ветки"?
Как-то мой хозяин и моя ветка происхождения/мастера расходились. На самом деле я не хочу, чтобы они расходились. Как я могу просмотреть эти различия и "объединить" их?
Ответы
Ответ 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 двумя способами:
- Он имеет другую историю: B вместо A.
- Его содержимое учитывает изменения как в 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
не было проблем.