Я зіткнувся з конфліктом злиття. Як я можу скасувати злиття?


2537

Я використовував git pullі мав конфлікт злиття:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

Я знаю, що інша версія файлу хороша і що моя погана, тому всі мої зміни слід відмовитися. Як я можу це зробити?


30
Я усвідомлюю, що це дуже старе питання, але чи хочете ви скасувати все злиття та залишити гілку, яку ви об’єднали, без розладу, або просто ігноруйте цей один файл як частину більшого злиття, дозволяючи всі інші файли зливатися як нормально? Як на мене, ваша назва має на увазі перше, ваше питання питання хоче останнє. Відповіді роблять і те, і інше.
rjmunro

У мене трапився аналогічний випадок, коли я сказав, що автоматичне злиття не вдалося; виправити конфлікти, а потім здійснити результат:[rejected] gh-pages -> gh-pages (non-fast-forward)
Четабахана

4
Гвіне, тут може бути корисно вибрати прийняту відповідь. Топ, що проголосував, є трохи менш безпечним, ніж деякі більш сучасні рішення, тому я думаю, що це допоможе виділити інші над цим :)
Привітне

Відповіді:


2219

Оскільки ваш файл pullне вдався, тоді HEAD(не HEAD^) є останньою "дійсною" комісією у вашій галузі:

git reset --hard HEAD

Інший твір, який ви хочете, - це дозволити їх змінам перевершити зміни.

Старіші версії git дозволяли вам використовувати "їхню" стратегію злиття:

git pull --strategy=theirs remote_branch

Але це було знято, як пояснив у цьому повідомленні Хуніо Хамано (супроводжувач Git). Як зазначено у посиланні , замість цього ви зробите це:

git fetch origin
git reset --hard origin

49
Замість того, щоб робити жорсткий скидання, ви можете вивести його на більш детальний рівень, зробивши: git fetch origin -> git reset origin (soft reset, your changes are still present) -> git checkout file_to_use_their_version_of another_file (steamroll your own changes back to match the origin) Я ніколи більше не використовую git pull. Оскільки в сутичці між моїм останнім кодом та походженням, походження завжди має перемагати, я завжди git fetchі завжди git rebase origin. Це насправді робить мої злиття та конфлікти малою і далеко між ними.
Kzqai

7
Я згоден. Я також хотів би спершу отримати, а потім вивчити зміни ( git log ..@{upstream}або git diff ..@{upstream}). Після цього, як і ви, я перегляну свою роботу.
Пат Нотц

162
Як зазначається в останній відповіді, з версії 1.6.1 можна використовувати "git reset --merge"
Matt Ball

5
Я використовував git merge -X theirs remote_branchзамість того, git pull --strategy=theirs remote_branchяк theirsвиглядає варіантrecursive
mlt

14
git merge --abortє набагато кращим.
Даніель Кассіді

1956

Якщо ваша версія git> = 1.6.1, ви можете використовувати git reset --merge.

Також, як згадує @Michael Johnson, якщо ваша версія git> = 1.7.4, ви також можете використовувати git merge --abort.

Як завжди, переконайтеся, що у вас немає неподілених змін, перш ніж розпочати злиття.

Зі сторінки git merge man

git merge --abortеквівалентно , git reset --mergeколи MERGE_HEADприсутній.

MERGE_HEAD присутній, коли відбувається злиття.

Також щодо невмілих змін при запуску об’єднання:

Якщо у вас є зміни, які ви не хочете здійснити перед початком злиття, просто git stashїх перед злиттям і git stash popпісля закінчення злиття або припинення його.


3
Цікаво - але керівництво мене лякає. Коли саме це доцільно використовувати? Коли вам доведеться вказати необов’язковий <commit>? #GitMoment: -o
conny

1
Зазвичай ви використовуєте це, коли ви хочете повторити злиття з самого початку. Мені ніколи не доводилося самостійно вказувати необов'язкове зобов’язання, тому за замовчуванням (не необов'язково <commit>) просто добре.
Карл

44
Я хочу, щоб ця відповідь мала більше голосів! На даний момент це здається найбільш актуальним рішенням у багатьох випадках.
Джей Тейлор

1
Навіть при невмілих змінах git зміг відновити стан до злиття. Приємно!
T3rm1

2
Це git merge --abortпросто синонім git reset --merge? Назва, безумовно, має більше сенсу, але чи має він однаковий функціонал?
Тихон Єлвіс

517
git merge --abort

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

Якщо в процесі злиття були присутні незаперечні зміни робочих дерев, git merge --abortв деяких випадках неможливо відновити ці зміни. Тому рекомендується завжди здійснювати або приховувати зміни перед запуском git merge.

git merge --abortеквівалентно , git reset --mergeколи MERGE_HEADприсутній.

http://www.git-scm.com/docs/git-merge


16
Це доступно з git v1.7.4. Це псевдонім для скидання git --merge.
Майкл Джонсон

162

Це так просто.

git merge --abort

Сам Git показує вам рішення, коли ви стикаєтеся з таким типом проблем і виконуєте команду git status.

git status

Сподіваюся, що це допоможе людям.


97

Я думаю, це git resetвам потрібно.

Будьте уважні git revert, скажімо, svn revertу Subversion повернення відкине ваші (невідомі) зміни, повернувши файл у поточну версію зі сховища, тоді як git revert"скасовує" фіксацію.

git resetповинні зробити еквівалент svn revert, тобто відкинути свої небажані зміни.


76

У цьому конкретному випадку ви не хочете переривати злиття, просто вирішуйте конфлікт певним чином.

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

Для непоєднаного файлу в конфліктному git надає загальну базу, локальну та віддалену версії файлу в індексі. (Тут вони читаються для використання у тривимірному інструменті різниці git mergetool.) Ви можете використовувати їх git showдля перегляду.

# common base:
git show :1:_widget.html.erb

# 'ours'
git show :2:_widget.html.erb

# 'theirs'
git show :3:_widget.html.erb

Найпростіший спосіб вирішити конфлікт для використання дослідної версії віддаленої версії:

git show :3:_widget.html.erb >_widget.html.erb
git add _widget.html.erb

Або з git> = 1.6.1:

git checkout --theirs _widget.html.erb

5
дякую за підказку. хіба це не присмак поганого користувальницького інтерфейсу git?
Петро

@ Петер: Я не переконаний. Бажаний результат досягається за допомогою декількох основних команд з простими параметрами. Які вдосконалення ви б запропонували?
CB Bailey

10
Я думаю, що git 1.6.1команда має багато сенсу, і це добре. Саме цього я б хотів. Я думаю, що рішення до 1.6.1 не є елегантним і вимагає знань про інші частини git, які слід відокремити від процесу вирішення злиття. Але нова версія чудова!
Пітер

67

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

git reset --merge 

Це повернуто назад, не скидаючи мої локальні зміни.


45

Коментарі говорять, що git reset --mergeце псевдонім для git merge --abort. Варто зазначити, що git merge --abortце рівнозначно тому, git reset --mergeщо MERGE_HEADприсутній a . Про це можна прочитати в довідці git для злиття команди.

git merge --abort еквівалентно скиданню git --merge, коли присутній MERGE_HEAD.

Після невдалого злиття, коли його немає MERGE_HEAD, невдале злиття можна відмінити git reset --merge, але не обов'язково з git merge --abort. Вони не лише старий і новий синтаксис для одного і того ж .

Особисто я знаходжу git reset --mergeнабагато більш потужним сценарії, подібні до описаного, і невдалі злиття в цілому.


2
що тут насправді означає "невдале злиття"? Злитися з конфліктами чи чимось іншим? Або перефразовувати: коли MERGE_HEAD немає? Моє наступне питання - це зрозуміти, як краще використовувати "git reset --merge".
Евокс

@Ewoks git stash applyспричинив конфлікт для злиття для мене, але git merge --abortне допоміг git reset --merge.
ніцель

27

Якщо у вас закінчився конфлікт злиття і не має нічого робити, але все-таки відображається помилка злиття. Після застосування всіх наведених нижче команд,

git reset --hard HEAD
git pull --strategy=theirs remote_branch
git fetch origin
git reset --hard origin

Видаліть, будь ласка

.git \ index.lock

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

git reset --hard HEAD
git reset --hard origin

Сподіваюся, що допомагає !!!


19

Альтернативою, яка зберігає стан робочої копії, є:

git stash
git merge --abort
git stash pop

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


Цей підхід я вважав корисним, коли випадково з’єднався з гіткою gn-svn, яка не справляється з цим чудово. Злиття сквош або вишневого вибору краще при роботі з гілками відстеження git-svn. Насправді моє рішення перетворює злиття в злиття сквош після факту.
Ален О'Дея

Найкраща відповідь на питання
Fouad Boukredine

18

Оскільки Git 1.6.1.3 git checkoutотримав можливість оформлення замовлення з будь-якої сторони злиття:

git checkout --theirs _widget.html.erb

3

Я виявив, що працює для мене (повернення одного файлу до стану попереднього об'єднання):

git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*

-5

Джерело дерева

Оскільки ви не здійснюєте злиття, просто двічі клацніть на іншій гілці (що означає оформити замовлення), і коли sourcetree запитає вас про відмінення всіх змін, тоді погоджуйтесь :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.