Каким-то образом мой мастер и моя ветвь происхождения / мастера разошлись.
Я на самом деле не хочу, чтобы они расходились.
Как я могу просмотреть эти различия и «объединить» их?
Каким-то образом мой мастер и моя ветвь происхождения / мастера разошлись.
Я на самом деле не хочу, чтобы они расходились.
Как я могу просмотреть эти различия и «объединить» их?
Ответы:
Вы можете просмотреть различия с:
git log HEAD..origin/master
перед тем, потянув его (принести + слияние) (см «Как ты мерзавец всегда вытащить из конкретной отрасли?» )
Когда у вас есть сообщение вроде:
«Ваша ветка и« origin / master »разошлись, # и имеют 1 и 1 разных коммитов соответственно».
Проверьте, если вам нужно обновитьorigin
. Если origin
это актуально, то некоторые коммиты были перенесены origin
из другого репо, пока вы делали свои коммиты локально.
... o ---- o ---- A ---- B origin/master (upstream work)
\
C master (your work)
Вы основали коммит C на коммите A, потому что это была последняя работа, которую вы получили из апстрима в то время.
Однако, прежде чем вы попытались вернуться к исходной точке, кто-то еще подтолкнул коммит 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 просто добавляет явное разделение между шагами commit и rebase.
Граф истории теперь выглядит так:
... o ---- o ---- A ---- B origin/master (upstream work)
\
C' master (your work)
Commit C '- это новый коммит, созданный командой git rebase.
Он отличается от C двумя способами:
Обратите внимание, что история C 'все еще линейна.
Мы выбрали (на данный момент), чтобы разрешить только линейную историю в cmake.org/cmake.git
.
Этот подход сохраняет рабочий процесс на основе CVS, который использовался ранее, и может облегчить переход.
Попытка вставить C 'в наш репозиторий сработает (при условии, что у вас есть разрешения, и никто не выдвигал их во время перебазировки).
Команда git pull обеспечивает сокращенный способ извлечения из источника и перебазирования локальной работы над ним:
$ git pull --rebase
Это объединяет вышеупомянутые шаги извлечения и перебазирования в одну команду.
git reset --hard HEAD
удалит только локальные индексированные не зафиксированные изменения и ничего не сделает для приведения в соответствие различий между локальным и удаленным коммитами . Только слияние или перебазирование объединят два набора коммитов (локальный и удаленный).
master
указать B
на ваш пример.
git reset --hard origin/master
как указано в ответе чуть ниже: stackoverflow.com/a/8476004/6309
У меня было это, и я не уверен, что вызвало это, даже после прочтения вышеупомянутых ответов. Мое решение было сделать
git reset --hard origin/master
Затем это просто сбрасывает мою (локальную) копию мастера (которая, как я полагаю, облажалась) в правильную точку, представленную (удаленным) источником / мастером.
ВНИМАНИЕ : Вы потеряете все изменения, которые еще не были переданы
origin/master
.
git reflog
или увидеть их в gitk --all
. Но все же, конечно, хард ресет это совсем не то, что ребейс.
git pull --rebase origin/master
это одна команда, которая может помочь вам большую часть времени.
Редактировать: извлекает коммиты из источника / мастера и применяет ваши изменения к недавно извлеченной истории веток.
Я оказался в этой ситуации, когда попытался перебазировать ветку, которая отслеживала удаленную ветку, и пытался перебазировать ее на master. В этом сценарии, если вы попытаетесь перебазировать, вы, скорее всего, обнаружите, что ваша ветвь разошлась, и это может создать беспорядок, который не для git nubees!
Допустим, вы находитесь на ветке my_remote_tracking_branch, которая была разветвлена от master
$ git status
# На ветке my_remote_tracking_branch
нечего коммитить (рабочий каталог чистый)
И теперь вы пытаетесь сделать ребаз из мастера как:
мастер git rebase
Остановись сейчас и избавь себя от неприятностей! Вместо этого используйте слияние как:
Git Merge Master
Да, в вашей ветке вы получите дополнительные коммиты. Но если вы не хотите «не расходящихся» веток, это будет гораздо более плавный рабочий процесс, чем перебазирование. Смотрите этот блог для более подробного объяснения.
С другой стороны, если ваша ветвь является только локальной ветвью (т.е. еще не передана на какой-либо удаленный узел), вам определенно следует выполнить ребазинг (и ваша ветвь не будет расходиться в этом случае).
Теперь, если вы читаете это, потому что вы уже находитесь в «дивергированном» сценарии из-за такой перебазировки, вы можете вернуться к последнему коммиту из источника (то есть в нерасходившемся состоянии), используя:
git reset --hard origin / my_remote_tracking_branch
rebase
Практическое правило - использовать, если ветка, которую вы перебираете, не была опубликована (и использовалась другими людьми). В противном случае используйте merge
. Если вы перебазируете уже опубликованные (и использованные) ветки, вам нужно согласовать заговор, чтобы переписать историю всех разработчиков, которые использовали вашу ветку.
git rebase master
...
git reset --hard origin/my_remote_tracking_branch
это то, что действительно работало
В моем случае вот что я сделал, чтобы вызвать расхождение сообщения: я сделал, git push
но потом сделал, git commit --amend
чтобы добавить что-то к сообщению фиксации. Затем я также сделал еще один коммит.
Так что в моем случае это просто означало, что origin / master устарел. Поскольку я знал, что никто не трогал происхождение / мастера, исправление было тривиальным: git push -f
(где -f
означает силу)
git push -f
чтобы перезаписать изменения, ранее зафиксированные и отправленные на источник. Я также уверен, что никто больше не трогал хранилище.
В моем случае я отправил изменения в origin/master
и затем понял, что не должен был делать это :-( Это было осложнено тем, что локальные изменения были в поддереве. Поэтому я вернулся к последнему хорошему коммиту перед «плохим» локальным изменения (используя SourceTree), а затем я получил «сообщение расхождения».
После локального исправления беспорядка (подробности здесь не важны) я захотел «отодвинуть назад» удаленную origin/master
ветку, чтобы она снова синхронизировалась с локальной master
. Решение в моем случае было:
git push origin master -f
Обратите внимание на -f
переключатель (сила). Это удалило «плохие изменения», которые были выдвинуты origin/master
по ошибке, и теперь локальные и удаленные ветви синхронизированы.
Помните, что это потенциально разрушительная операция, поэтому выполняйте ее только в том случае, если вы на 100% уверены в том, что «возврат» удаленного мастера во времени в порядке.
You are not allowed to force push code to a protected branch on this project.
. Я пытаюсь подтолкнуть к своей вилке.
Я знаю, что здесь есть много ответов, но я думаю, что git reset --soft HEAD~1
заслуживает некоторого внимания, потому что это позволяет вам сохранять изменения в последнем локальном (не выдвинутом) коммите при решении расхожденного состояния. Я думаю, что это более универсальное решение, чем использование 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) , когда вы хотите отменить изменения в локальной фиксации. Также, когда вы хотите зафиксировать другую ветку, этот шаг следует выполнить после переключения на нужную.
pull --rebase
все равно будет автоматически прятаться. stackoverflow.com/a/30209750/6309
Чтобы увидеть различия:
git difftool --dir-diff master origin/master
Это покажет изменения или различия между двумя ветвями. В araxis (Мой любимый) он отображает его в стиле diff папки. Отображение каждого из измененных файлов. Затем я могу щелкнуть файл, чтобы просмотреть подробную информацию об изменениях в файле.
В моем случае это было вызвано невыполнением моего разрешения конфликта.
Проблема была вызвана запуском git pull
команды. Изменения в происхождении привели к конфликтам с моим локальным репо, которые я решил. Однако я их не совершал. Решение на этом этапе - зафиксировать изменения ( git commit
разрешенный файл).
Если вы также изменили некоторые файлы после разрешения конфликта, git status
команда покажет локальные изменения как локальные изменения без этапов, а разрешение слияния - как локальные этапные изменения. Эту git commit
проблему можно решить, зафиксировав сначала изменения из слияния , затем добавив и зафиксировав необработанные изменения, как обычно (например, с помощью git commit -a
).
У меня было то же самое сообщение, когда я пытался редактировать последнее сообщение о коммите, уже переданного коммита, используя: git commit --amend -m "New message"
Когда я выдвигал изменения, git push --force-with-lease repo_name branch_name
не было никаких проблем.
Я столкнулся с этой проблемой, когда создал ветку на основе
git checkout -b a
а затем я установил восходящий поток ветви А к исходной ветви В
git branch -u origin/B
Тогда я получил сообщение об ошибке выше.
Один из способов решить эту проблему для меня был,
git checkout -b b origin/B