Звіти про злиття Git "Вже оновлені", хоча є різниця


286

У мене є сховище git з 2 гілками: майстер і тест.

Існують відмінності між ведучими та тестовими галузями.

В обох відділеннях відбулися всі зміни.

Якщо я:

git checkout master
git diff test

З'явиться екран, повний змін, що показує відмінності. Я хочу об'єднати зміни в тестовій галузі і так зробити:

тест на злиття git

Але отримайте повідомлення "Вже оновлено"

Однак, вивчення файлів під кожною різною гілкою чітко показує відмінності.

У чому тут проблема і як її вирішити?


Чи є у вас некомітований модифікований код?
озма

Відповіді:


146

Повідомлення "Вже оновлено" означає, що всі зміни з гілки, яку ви намагаєтеся об'єднати, вже були об'єднані з гілкою, в якій ви зараз перебуваєте. Більш конкретно, це означає, що гілка, яку ви намагаєтеся об'єднати, є батьківською стороною вашої поточної гілки . Вітаємо, це найпростіше злиття, яке ви коли-небудь зробите. :)

Використовуйте gitkдля перегляду вашого сховища. Мітка для "тестової" гілки повинна бути десь нижче вашої "головної" мітки гілки.

Ваше відділення є сучасним стосовно батьків. Відповідно до злиття, у батьківській системі з моменту останнього злиття немає нових змін. Це не означає, що гілки є однаковими, тому що ви можете мати багато змін у своїй робочій гілці, і це звучить так, як ви.

Редагувати 12.10.2019:

Перший Чарльз Дрейк у коментарі до цієї відповіді одним із варіантів вирішення проблеми є:

git checkout master
git reset --hard test

Це повертає його до рівня "тестування".

Потім зробіть:

git push --force origin master

щоб примусити зміни повернутися до центрального репо.


2
Святий кр * р! Ти маєш рацію! Я думаю, що сталося те, що інша гілка (нестабільна розробка) була неправильно об'єднана з головним, а тестова гілка була підмножиною нестабільної. Злиття, яке я намагався зробити, було повернути майстра до рівня "тесту".
Чарльз Дарк

2
Правильно. Ця операція не мала б сенсу, тому Git відмовляється робити що-небудь. :)
Бомбе

24
Що я зараз зробив, це: майстер виписки з git; git reset - твердий тест; Це повертає його до рівня "тестування". Тоді я зробив "git push - force origin master", щоб примусити зміни повернутися до центрального репо.
Чарльз Дарк

22
Було б добре, якби git мав попередження сказати "намагання злитися з батьком".
Чарльз Дарк

1
Натискання гілки, яка не є нащадком гілки, яка вже існує на віддаленій стороні, вважається поганою справою: див. Дискусії на сторінках man для git-push та git-pull.
Бомбе

131

Це часто трапляється зі мною, коли я знаю, що на віддаленому майстрі є зміни, тому я намагаюся їх об'єднати за допомогою git merge master. Однак це не зливається з віддаленим майстром, а з вашим місцевим господарем.

Тому перед тим, як здійснити злиття, майстер оформлення замовлення, а потім git pullтам. Тоді ви зможете об'єднати нові зміни у свою філію.


7
Чи є спосіб уникнути перемикання гілок, щось на зразок того, як витягнути гілку, яку слід об'єднати, поки вона ще в гілці, щоб її об'єднати, а потім злити?
Japheth Ongeri - inkalimeva

Ах, приємний. Я думав 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 відділень. незважаючи на те, що вони ділилися однаковим вмістом, створюючи PR між двома гілками, було показано кілька різних файлів. Я зафіксував git pullцільову гілку в гілку функцій, яка показала: Already up to date! Merge made by the 'recursive' strategy.це призвело до об'єднання об'єднань без змін, але вилучило з PR несподівані файли різниці. будь-яка ідея, чому існує різниця між об'єднанням "еквівалентних" локальних та віддалених гілок?
обгортки

45

Скажімо, у вас є відділення masterіз такою історією фіксування:

A -- B -- C -- D

Тепер ви створюєте тест гілки, працюєте над ним і робіть 4 коміти:


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

masterголова вказує на D, а testголова вказує на H.

Повідомлення "Вже оновлене" з'являється, коли ВИГОТ гілки, до якої ви зливаєтесь, є батьківським ланцюжком комітетів гілки, яку потрібно об'єднати. Ось так, тут: Dє батьком E.

Там немає нічого злиття з testдо master, так як нічого не змінилося по masterвідтоді. Що ви хочете зробити тут, це буквально сказати Git мати masterголову, щоб вказувати на H, тож гілка магістра має наступні історії:

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

Що для мене працює, скажімо, у вас є філія1, і ви хочете об'єднати її у гілку2.

Ви відкриваєте командний рядок git, переходите до кореневої папки гілки2 і вводите:

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

Якщо у вас є конфлікти, вам не потрібно робити git push, але спочатку вирішіть конфлікти, а потім натисніть.


6

Злиття завжди відбувається між поточним HEAD і одним або декількома комісіями (як правило, заголовком гілки або тегом),
а індексний файл повинен відповідати дереву фіксації HEAD (тобто вмісту останньої комісії), коли він починається.
Іншими словами, не git diff --cached HEADповинно повідомляти про зміни.

Об'єднана комісія вже міститься в HEAD. Це найпростіший випадок, який називається "Вже оновлений".

Це повинно означати, що зобов'язання в тесті вже об'єднані в master, але оскільки інші комісії виконуються на master, 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 думав, що місцева гілка відрізняється від віддаленої гілки. Це було видно на графіку гілки: він відображав дві різні гілки: видалення / походження / ім'я гілки та ім'я гілки.

Рішення полягало в тому, щоб просто видалити локальний репо і повторно клонувати його з віддаленого. Таким чином GIT зрозуміє, що віддалені / походження / ім'я_розділу> і ім’я гілки дійсно однакові, і я міг би видати цю 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>

Це не точно така ж відповідь, як і Acarter?
Андрій C

Я думаю, що Acarter насправді пропустив справу - на пульті дистанційних змін не було - це зовсім не було проблемою. Мені потрібно було "git checkout master", а потім "git merge <branch_name>", щоб примусити швидке злиття вперед. З іншого боку, нічого не зробили, оскільки гілка випереджала господаря. Відповідь Бомбе є приємним поясненням, але ніколи не відповідала на питання "як я це вирішу".
MrMas

5

git merge origin/masterнатомість git merge masterпрацював на мене. Отже, для об'єднання головного у галузь функції ви можете використовувати:

git checkout feature_branch
git merge origin/master

5

Не забудьте спочатку перевірити гілку, яку ви хочете об’єднати, а потім витягніть її (щоб ваша локальна версія відповідала віддаленій версії).

Потім поверніться до своєї філії, на якій ви хочете зробити злиття, і ваше об'єднання git має працювати.


1
Це було для мене - я робив тягу, будучи майстром; дізнався, що я отримав нові комісії у "філії". Намагався об'єднати "гілку" в головну - "Вже до цього часу". Чи мерзотник оформити замовлення «філія» - отримав, що означає , що я повинен був оновити «гілку», запустивши «Ваша галузь знаходиться позаду ... і може бути швидко пересилаються.» , git pullА в «гілки»
sdbbs

3

прийшов до мене і був відправлений на цю сторінку, не впевнений, чи був у мене той самий сценарій, але мій намагався "повторно об'єднати" цю "тестову" гілку.

Тому я попередньо об'єднав його, але навмисно виключаю деякі конкретні зміни під час цього злиття, тому він чітко має деякі відмінності між гілками. Тоді я намагався повторно об'єднати його, бо розумію / забуваю, що мав би і хотів додати певну зміну / файл, яку раніше виключав, і сподівався, що якщо я знову зробить об'єднання, покаже всі зміни, які я виключав раніше , але я помилявся, і натомість отримую повідомлення "Вже оновлене".

Прочитавши коментар / відповідь @ Bombe, він має рацію, і git я думаю, що так поводиться, тому я зробив жорстке резервне копіювання файлів на тестовій гілці, а потім перевірити головну гілку і вручну вставити файли в неї та зробити це ніби це були нові зміни.

Я не впевнений, чи це правильний шлях, чи може допомогти іншим, хто має цю ж проблему, але він вирішив мою конкретну справу.


Тут же ситуація. Сценарій полягає в тому, що я хочу розділити гілку "інтеграції" назад на декілька гілок "функції".
Ядлі

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

Дякую, я використав ваш метод оформлення замовлення, але я поставив, checkout srcBranch -- *а потім подивився на свої розбіжності
portforwardpodcast

2

Якщо об'єднання гілки А у відділення В повідомляє "Вже оновлено", зворотний зв'язок не завжди відповідає дійсності. Це вірно, лише якщо гілка B є нащадком гілки A, інакше гілка B просто може мати зміни, яких немає в А.

Приклад:

  1. Ви створюєте гілки A і B off master
  2. Ви вносите деякі зміни в master і об'єднуєте ці зміни лише у гілку B (не оновлюючи або не забувши оновити гілку A).
  3. Ви внесете деякі зміни у гілку А та злиття A до B.

У цей момент об'єднання A до B повідомляє "Вже оновлено", але гілки відрізняються, оскільки гілка B має оновлення від головного, тоді як гілка A не робить.


2

Зіткнувся з цим сценарієм за допомогою Git Bash.

У нашому сховищі є кілька відділень, і кожна гілка має різний цикл фіксування, і злиття відбувається раз у раз. Old_Branch використовувався в якості батьків для New_Branch

Old_Branch було оновлено з деякими змінами, які потрібно було об'єднати з New_Branch

Використовується команда pull нижче без жодної гілки, щоб отримати всі джерела з усіх гілок.

git 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 (скажімо). Внесла деякі зміни у випуск_1 та вилучила її в початковий код. тоді я зробив 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.