Git Merge сообщает «Уже в актуальном состоянии», хотя есть разница


287

У меня есть git-репозиторий с 2 ​​ветками: master и test.

Существуют различия между основной и тестовой ветками.

Обе ветви имеют все зафиксированные изменения.

Если я сделаю:

мастер проверки
тест на git diff

Появится экран, полный изменений, показывающий различия. Я хочу объединить изменения в тестовой ветке и так:

Git Merge Test

Но получите сообщение "Уже в курсе"

Тем не менее, проверка файлов в каждой отдельной ветви четко показывает различия.

В чем здесь проблема и как мне ее решить?


У вас есть незафиксированный модифицированный код?
Озма

Ответы:


148

Сообщение «Уже обновлено» означает, что все изменения из ветви, которую вы пытаетесь объединить, уже объединены с веткой, в которой вы находитесь. Более конкретно, это означает, что ветвь, которую вы пытаетесь объединить, является родителем вашей текущей ветки . Поздравляю, это самое легкое слияние, которое ты когда-либо делал. :)

Используйте, gitkчтобы взглянуть на ваш репозиторий. Метка для «тестовой» ветви должна быть где-то ниже вашей «основной» ветки.

Ваш филиал обновлен по отношению к своему родителю. Согласно слиянию нет никаких новых изменений в родительском с момента последнего слияния. Это не означает, что ветки одинаковы, потому что вы можете иметь множество изменений в вашей рабочей ветке, и это звучит так же, как и вы.

Изменить 10/12/2019:

Согласно Чарльзу Дрейку в комментарии к этому ответу, одним из решений этой проблемы является:

git checkout master
git reset --hard test

Это возвращает его к уровню «теста».

Затем сделайте:

git push --force origin master

чтобы заставить изменения вернуться к центральному репо.


2
Святой кр * р! Ты прав! Я думаю, что произошло то, что другая ветвь (нестабильная разработка) была неправильно объединена с master, а тестовая ветвь была подмножеством unstable. Слияние, которое я пытался сделать, должно было вернуть мастера на уровень «испытаний».
Чарльз Дарк

2
Правильно. Эта операция не имеет никакого смысла, поэтому Git отказывается что-либо делать. :)
Бомба

24
Теперь я сделал следующее: git checkout master; git reset - жесткий тест; Это возвращает его к уровню «теста». Затем я выполнил «мастер происхождения git push --force», чтобы заставить изменения вернуться к центральному репо.
Чарльз Дарк

22
Было бы неплохо, если бы у git было предупреждение «попытаться слиться с родителем».
Чарльз Дарк

1
Нажатие на ветку, которая не является потомком ветви, уже существующей на удаленной стороне, считается плохой вещью: см. Обсуждения на страницах руководства для git-push и git-pull.
Бомба

131

Это часто случается со мной, когда я знаю, что на удаленном мастере есть изменения, поэтому я пытаюсь объединить их, используя git merge master. Однако это не сливается с удаленным мастером, а с вашим локальным мастером.

Поэтому, прежде чем делать слияние, проверьте мастер, а затем git pullтам. Тогда вы сможете объединить новые изменения в свою ветку.


7
Есть ли способ избежать переключения веток, что-то вроде вытягивания ветви, которая должна быть объединена, пока она еще находится в ветви, в которую нужно объединиться, а затем объединить?
Иафет Онгери - Инкалимеева

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

1
@Raik Вы можете сделать git fetch --all, но это только выбирает ветви, но не тянет их.
Инго Бюрк

6
@ JaphethOngeri-Inkalimeva Вы можете просто сделать git fetch --all && git merge origin/master. Нет необходимости обновлять ваш локальный, masterчтобы объединить удаленные изменения.
Инго Бюрк

@ IngoBürk У меня было 2 ветки, обновленные 1 с git merge masterи 1 с git merge origin/master. Я также проверил masterи git pullдо обновления 2 ветки. Несмотря на то, что они использовали один и тот же контент, создание пиара между двумя ветвями показало некоторые файлы различий. Я исправил git pullцелевую ветвь в ветке Feature, которая показала: Already up to date! Merge made by the 'recursive' strategy.это привело к коммиту слияния без изменений, но удалил неожиданные файлы diff из PR. Любая идея, почему существует разница между объединением "эквивалентных" локальных и удаленных филиалов?
Wrapperapps

45

Допустим, у вас есть ветка masterсо следующей историей коммитов:

A -- B -- C -- D

Теперь вы создаете тест ветки, работаете над ним и делаете 4 коммита:


                 E -- F -- G -- H
                /
A -- B -- C -- D

masterголова указывает на D, а testголова указывает на H.

Сообщение «Уже обновлено» появляется, когда HEAD ветви, с которой вы объединяетесь, является родителем цепочки коммитов ветви, которую вы хотите объединить. Это тот случай, здесь: Dявляется родителем E.

Там нет ничего слияния с testк master, так как ничего не изменилось по masterс тех пор. То, что вы хотите сделать здесь, это буквально сказать Git, чтобы masterголова указывала на H, поэтому ветвь master имеет следующую историю коммитов:

A -- B -- C -- D -- E -- F -- G -- H

Это работа для команды Git reset. Вы также хотите, чтобы рабочий каталог отражал это изменение, поэтому вы сделаете полный сброс:

git reset --hard H

3
В прошлом мне говорили, что использование git reset --hardдовольно радикально, может ли оно потерять коммиты? Есть ли более безопасный способ внесения этих изменений или опасность git reset --hardзавышена?
Грэм Р. Армстронг

1
Эта команда в здравом уме, не беспокойтесь. Я бы сказал, что единственная вещь, на которую следует обратить внимание при использовании этой --hardопции, - это то, что она фактически изменяет ваш рабочий каталог, и, как следствие, вы теряете незафиксированные изменения. Лично я делаю git statusдо и после каждой запускаемой вручную команды git, чтобы убедиться, что мое репо чистое или находится в ожидаемом состоянии.
Марек Стэнли,

это приведет к сообщению о статусе «Ваша ветка и« источник / мастер »разошлись», как я могу его разрешить?
Eido95

1
Я хотел бы дать вам больше, чем один голос. Спасибо!
KMC

Есть ли необходимость в --hardвыборе? Я был в этой ситуации пару раз сейчас и всегда сбрасывал без --hard. Это работало просто отлично без риска потерять любые незафиксированные изменения.
Казимир

16

Что работает для меня, скажем, у вас есть branch1, и вы хотите объединить его в branch2.

Вы открываете командную строку git, идете в корневую папку branch2 и набираете:

git checkout branch1
git pull branch1
git checkout branch2
git merge branch1
git push

Если у вас есть конфликты, вам не нужно делать git push, но сначала решите конфликты, а затем нажмите.


6

Слияние всегда происходит между текущим HEAD и одним или несколькими коммитами (обычно это заголовок ветви или тег),
и файл индекса должен соответствовать дереву коммитов HEAD (т. Е. Содержимому последнего коммита), когда он начинается.
Другими словами, git diff --cached HEADдолжен сообщить об отсутствии изменений.

Объединенный коммит уже содержится в HEAD. Это самый простой случай, который называется «Уже в курсе».

Это должно означать, что коммиты в тесте уже объединены с мастером, но, поскольку другие коммиты выполняются на мастере, git diff testвсе равно будут иметь некоторые различия.


6

Это происходит потому, что ваша локальная копия ветви, которую вы хотите объединить, устарела. Я получил свою ветку, позвонил MyBranchи хочу слить ее ProjectMaster.

_>git status
On branch MyBranch-Issue2
Your branch is up-to-date with 'origin/MyBranch-Issue2'.

nothing to commit, working tree clean

_>git merge ProjectMaster
Already up-to-date.

Но я знаю, что есть изменения, которые необходимо объединить!

Вот что, когда я git merge ProjectMasterпечатаю, git просматривает мою локальную копию этой ветви, которая может быть не текущей . Чтобы увидеть, так ли это, я сначала говорю Git проверить и проверить, не устарели ли мои ветки, и извлечь какие-либо изменения, если это так, используя fetch. Затем я прыгаю в ветку, которую хочу объединить, чтобы посмотреть, что там происходит ...

_>git fetch origin

_>git checkout ProjectMaster
Switched to branch ProjectMaster
**Your branch is behind 'origin/ProjectMaster' by 85 commits, and can be fast-forwarded.**
  (use "git pull" to update your local branch)

Ах-ха! Моя локальная копия устарела на 85 коммитов, это все объясняет! Теперь я Pullвнесу изменения, которые мне не хватает, затем перепрыгиваю MyBranchи пытаюсь снова объединиться.

_>git pull
Updating 669f825..5b49912
Fast-forward

_>git checkout MyBranch-Issue2
Switched to branch MyBranch-Issue2
Your branch is up-to-date with 'origin/MyBranch-Issue2'.

_>git merge ProjectMaster
Auto-merging Runbooks/File1.ps1
CONFLICT (content): Merge conflict in Runbooks/Runbooks/File1.ps1

Automatic merge failed; fix conflicts and then commit the result.

И теперь у меня есть еще одна проблема, чтобы исправить ...


5

Это случилось со мной, потому что странно GIT думал, что локальный филиал отличается от удаленного филиала. Это было видно на графике ветвей: он отображал две разные ветви: remotes / origin / branch_name и branch_name.

Решение состояло в том, чтобы просто удалить локальное хранилище и повторно клонировать его из удаленного. Таким образом, GIT поймет, что remotes / origin / branch_name> и branch_name действительно одинаковы, и я могу выдать git merge branch_name.

rm <my_repo>
git clone <my_repo>
cd <my_repo>
git checkout <branch_name>
git pull
git checkout master
git merge <branch_name>

Разве это не тот же ответ, что и у Акартера?
Андрей C

Я думаю, что Акартер на самом деле упустил момент - на пульте не было никаких изменений - это не было проблемой вообще. Мне нужно было «git checkout master», а затем «git merge <имя_ответа>», чтобы вызвать ускоренное слияние. Наоборот, ничего не сделал, так как ветка была впереди хозяина. Ответ Бомбе - хорошее объяснение, но он никогда не отвечал на вопрос «как мне это решить».
MrMas,

5

git merge origin/masterвместо этого git merge masterработал для меня. Таким образом, чтобы объединить мастер в ветку функций, вы можете использовать:

git checkout feature_branch
git merge origin/master

5

Обязательно сначала извлеките ветку, которую хотите объединить, а затем извлеките ее (чтобы ваша локальная версия соответствовала удаленной версии).

Затем вернитесь в свою ветку, на которой вы хотите выполнить слияние, и ваш git merge должен работать.


1
Это было для меня - я сделал тягу в то время как в мастере; узнал, что я получил новые коммиты в "ветке". Пытался объединить «ветку» в мастер - «Уже в курсе». Ли мерзавец оформить заказ «филиал» - получил, что означает , что я должен был обновить «ветку», запустив «Ваша отрасль находится позади ... и может быть быстро пересылаются.» , git pullА в «ветви»
sdbbs

3

случилось со мной и был отправлен на эту страницу, не уверенный, был ли у меня такой же сценарий, но мой я пытался «объединить» эту «тестовую» ветку.

Поэтому я ранее слил его, но я намеренно исключил некоторые конкретные изменения во время этого слияния, поэтому он явно имеет некоторые различия между ветвями. Затем я пытался повторно объединить его, потому что я осознал / забыл, что должен был и хотел добавить конкретное изменение / файл, который я ранее исключил, и я надеялся, что при повторном слиянии все изменения, которые я исключил ранее, будут показаны. , но я ошибся и вместо этого получаю сообщение «Уже обновлено».

Прочитав комментарий / ответ @ Bombe, он прав, и я думаю, что git ведет себя так, поэтому я сделал резервное копирование файлов в тестовой ветви, затем извлек мастер-ветку, вручную вставил в нее файлы и зафиксировал это как если бы это были новые изменения.

Я не уверен, что это правильный путь или может помочь другим людям, имеющим такую ​​же проблему, но это дало решение моего конкретного случая.


Та же ситуация здесь. Сценарий заключается в том, что я хочу разделить ветку «интеграция» обратно на несколько веток «функция».
Ядли

2
Вместо ручной пасты, вы можете проверку файлов непосредственно из одной ветви в текущую ветвь: git checkout srcBranch -- path/to/file. Можно использовать файловые глобусы тоже.
Тодд

Спасибо, я использовал ваш метод оформления заказа, но я поставил, checkout srcBranch -- *а затем посмотрел на свои различия
portforwardpodcast

2

Если при слиянии ветви A с веткой B появляется сообщение «Уже в курсе», обратное не всегда верно. Это верно только в том случае, если ветвь B является потомком ветви A, в противном случае ветвь B просто может иметь изменения, которых нет в A.

Пример:

  1. Вы создаете ветви A и B от мастера
  2. Вы вносите некоторые изменения в master и объединяете эти изменения только в ветку B (не обновляя или не забывая обновить ветку A).
  3. Вы вносите некоторые изменения в ветку A и объединяете A в B.

На этом этапе слияние от А до Б сообщает «Уже в курсе», но ветви отличаются, потому что ветвь В имеет обновления от главного, а ветвь А - нет.


2

Столкнулся с этим сценарием, используя Git Bash.

Наш репозиторий имеет несколько ветвей, и у каждой ветви свой цикл фиксации, и слияние происходит время от времени. Old_Branch использовался как родитель для New_Branch

Old_Branch был обновлен с некоторыми изменениями, которые необходимо объединить с New_Branch

Использовал приведенную ниже команду pull без какой-либо ветви, чтобы получить все источники из всех ветвей.

мерзавец происхождения

Странно, но это не вытягивает все коммиты из всех веток. Думал так, как указано, показывает почти все ветки и метки.

Таким образом, чтобы исправить это проверил Old_Branch вытащил последние использования

git checkout Old_Branch

git pull origin Old_Branch

Сейчас проверил New_Branch

git checkout New_Branch

Вытащил это, чтобы быть уверенным

git pull origin New_Branch

git merge Old_Branch

И альт получил конфликты, чтобы исправить из Old_Branch в New_Branch :), что и ожидалось


0

То же самое случилось со мной. Но сценарий был немного другой, у меня была основная ветка, и я вырезал release_1 (скажем) из него. Сделал некоторые изменения в ветке release_1 и объединил ее в origin. затем я сделал ssh и на удаленном сервере я снова извлекаю release_1 с помощью команды git checkout -b release_1 - которая фактически создает новую ветку release_! от мастера, а не проверять уже существующую ветку release_1 из источника. Решил проблему, убрав переключатель "-b"


0

У меня такая же проблема. У меня были изменения в пульте, и он все еще показывал «Уже в курсе». Перемещение репозитория устранило проблему для меня.


0

Глупо, но это может случиться. Предположим, что перед именем вашей ветки стоит ссылка на проблему (например #91-fix-html-markup), если вы выполните это слияние:

$ git merge #91-fix-html-markup

он не будет работать так, как задумано, потому что все после #игнорируется, потому что #начинается встроенный комментарий.

В этом случае вы можете переименовать ветку Опуская #или использовать одиночные кавычки , чтобы окружить имя ветви: git merge '#91-fix-html-markup'.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.