Як об'єднати всі файли вручну в Git?


78

Я хочу об'єднати всі файли вручну з meld або будь-яким іншим інструментом diff, як я можу це зробити за допомогою Git?
Коли я запускаю, git mergetool це говорить no files need merging. Тож, гадаю, я можу це зробити, лише якщо у мене конфлікти.


Будь ласка, надайте нам деякий контекст того, що ви хочете об’єднати, і чому ви не хочете, щоб це робилося автоматично.
Johnsyweb

3
Я хочу об'єднати текстові файли :) Раніше я проводив ручне злиття mercurial і хотів би бачити 3 файли одночасно, якщо щось піде не так, я завжди можу редагувати їх усі самостійно
gennad

8
Так, я хотів би об’єднати вручну в деяких випадках, тому що в таких ситуаціях я знаю, що все відбувається як я хочу, а не так, як вирішив додаток
gennad

1
А як щодо об’єднання автоматично та виправлення проблем, якщо це сталося?
Томаш Висоцький,

1
@TomaszWysocki, тому що я ніяк не можу дізнатись, чи виникла "проблема, яку людина вважає проблематичною". Мені існує лише спосіб дізнатися, чи виникла "проблема, яку git вважає проблематичною". Git автоматично зливає файли, і я не можу поставити галочку біля всіх результатів автоматичного прийняття рішень git. Він може прийняти певні зміни, які мені не подобаються. Я хочу схвалити всі зміни до їх внесення.
торт

Відповіді:


107

Існує набагато простіший спосіб:

git merge --no-commit merge_branch

Як каже людина:

За допомогою --no-commitвиконати злиття, але вдавати, що злиття не вдалося, і не виконувати автокомісію, щоб дати користувачеві можливість перевірити та додатково налаштувати результат злиття перед фіксацією.


7
Дякую. Чи є, можливо, спосіб використовувати mergetool / meld для перегляду та об’єднання змін по частинах із приємним триходовим інтерфейсом?
Джеймс,

18
Додаючи --no-ffфункцію швидкої переадресації, вимкнено, що трапиться, якщо не буде конфліктів.
Løiten

І звичайно, використовуйте, git mergetoolякщо є конфлікти.
Плутон

8
Це все ще автоматичне об’єднання, тому це не відповідає на запитання про походження.
ThomasMcLeod

61

У мене був сценарій, коли:

git merge --no-commit merge_branch 

щойно спричинило швидке перемотування вперед.

Якщо це трапиться, ви можете використовувати:

git merge --no-commit --no-ff merge_branch

і тоді ви зможете переглянути свої зміни


1
Чи можна потягнути його так само? Мені потрібно вручну перевірити ВСІ конфлікти, якщо перемотування вперед неможливо.
Максим

1
@Maxim ні, але оскільки pullце просто комбінація fetchі mergeзробити перший дзвінок, git fetch merge_branchа потім зробитиmerge
Top-Master

використання обох --no-commit --no-ff- це як мати .gitattributesфайл у кореневій директорії, що містить * -merge, але за mergeвибором використовувати його чи ні
Top-Master

Я отримую Automatic merge went well; stopped before committing as requestedпісля запуску цього. Коли я намагаюся запустити, git mergetoolце говорить No files need merging.
Unknow0059

23

Подібне питання - як запобігти появі автомерґу за допомогою git?

FractalSpace дав відповідь, яку я вважаю корисною:

$ git checkout master
$ git difftool -t kdiff3 local-branch HEAD

Ідея полягає у використанні інструментів difftools замість інструментів автоматичного об’єднання, щоб вручну вибрати те, що вам потрібно, і створити нові файли.


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

7

Зверніть увагу: якщо ви наполягаєте на об’єднанні вручну (можливо, для певного класу файлів), ви все одно можете визначити драйвер об’єднання .
У вас є конкретний приклад у " Git - як примусити конфлікт злиття та об'єднати вручну для вибраного файлу ".

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


7

Для тих, хто прийшов сюди і зараз задається питанням про різницю між відповіддю @ True git difftoolта іншими відповідями, які використовуються git merge, див. Git mergetool vs difftool .

Коротше кажучи, якщо у вас git налаштовано на використання сучасних, diff.toolтаких як kdiff3, meld або vimdiff, ви зможете вручну об’єднатись за допомогою цього інструменту diff, а командний рядок може бути простим:

git difftool other_branch

... це дозволить вам здійснити двостороннє об’єднання вручну між поточною гілкою та other_branch (описується як $ LOCAL та $ REMOTE у man git-config).

"Правильним" способом обговорення інших відповідей буде натомість налаштування git для використання, наприклад, kdiff3 або vimdiff як вашого merge.tool, і використання:

git merge --no-commit --no-ff other_branch
git mergetool

... ця команда може здійснити N-шлях ручного злиття між $ BASE, $ LOCAL і $ REMOTE у $ MERGED. Див. Https://stackoverflow.com/a/2235841/1264797 для прикладу, як налаштувати git. Багато вам взагалі не потрібно налаштовувати mergetool.*.cmdзапис, якщо ви використовуєте один із інструментів, про який Git вже знає. (Meld може відображати лише три панелі, тому, якщо ви використовуєте meld із налаштуваннями за замовчуванням, ви не побачите $ BASE.)

Хтось може підскочити, щоб виправити мене, але окрім можливості злиття в N-спосіб, ці два методи дають однаковий результат. Ні, difftoolні mergetoolдодає other_branch як батьківський елемент у новому коміті, тому в обох випадках злиття не є очевидним, наприклад, у gitk, і його потрібно було б описати (і помітити пізніше) у повідомленні коміту.


5

Я знайшов інші відповіді незадовільними і розчарувався, шукаючи відповідь. Рішення цього питання я нарешті знайшов тут: https://stackoverflow.com/a/11593308/1351182

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

git checkout branchToMergeTo
git checkout --patch branchToMergeFrom [file]

Потім вам буде запропоновано (файл-за-файлом, якщо ви не вказали file), які саме "шматки" ви хочете об’єднати. Таким чином, він проводить вас через кожну частину того, що було б автоматичним процесом злиття, і замість цього просить про ручний арбітраж, які біти та фрагменти ви хочете прийняти від mergefromгілки. Ось приклад того, як це виглядало в моєму проекті:

@@ -249,7 +251,8 @@ def draw_everything():
  
     draw_bg()
     draw_balls(ax)
-    plt.show(block=False)
+    if show:
+        plt.show(block=False)
 
 def advance(ms, accel_fun, collision_matrix_fun):
     global balls
(3/6) Apply this hunk to index and worktree [y,n,q,a,d,K,j,J,g,/,e,?]?

Після набору тексту yі <Enter>, мені подарували наступний шматок (4/6)для цього файлу. Ця підказка внизу дозволяє вам просто прийняти злиття `` шматком '' y, відхилити його nабо навіть зайти та відредагувати його вручну. Ось варіанти:

y - apply this hunk to index and worktree
n - do not apply this hunk to index and worktree
q - quit; do not apply this hunk or any of the remaining ones
a - apply this hunk and all later hunks in the file
d - do not apply this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

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

Я б рекомендував цей процес, якщо те, що ви хочете, - це об’єднання вручну, де ви як і раніше використовуєте автоматичний процес, наскільки це можливо. Різниця полягає в тому, що ви можете спостерігати за кожним "об'єднанням" об'єднань і редагувати їх як завгодно. Сподіваюся, це допоможе майбутнім читачам.

Після цього процесу, ви , ймовірно , хочете працювати git checkout branchToMergeTo && git merge branchToMergeFromдля того , щоб формально злитися історії branchToMergeFromв branchToMergeTo.


1

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

З: https://git-scm.com/docs/merge-strategies

Механізм злиття (команди git merge та git pull) дозволяє обрати серверні «стратегії злиття» за допомогою опції -s. Деякі стратегії також можуть використовувати власні варіанти, які можна передавати, надаючи аргументи -X для git merge та / або git pull.

наші

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

Однак те, що Bitbucket побачить пізніше, для мене загадка, він визнає коміт як злиття, але не зможе насправді об’єднати гілку (не вирішує запит на витяг) - можливо, гуру Bitbucket може допомогти з цим питанням, я навіть не можу дати вам жодного журнали / повідомлення про помилки, оскільки у мене немає такої видимості - git / TortoiseGit взагалі не скаржиться.

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