Git Interactive Merge?


78

У мене є дві гілки з однаковим файлом (якщо вам цікаво, що це файл .sql), і я хочу інтерактивно об'єднати його.

Практично я хочу відкрити програму diff, як це роблю, коли виникає конфлікт (або командний рядок), і вибрати, які саме рядки куди йти.

Чи можна це зробити?

Відповіді:


84

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

git merge --no-commit --no-ff branch-to-merge

Потім ви запитаєте git для файлу, як він з’явився у двох гілках:

git show HEAD:filename >filename.HEAD
git show branch-to-merge:filename >filename.branch

та їх база злиття,

git show `git merge-base HEAD branch-to-merge`:filename  >filename.base

Ви об’єднаєте їх, використовуючи будь-який потрібний вам інструмент (наприклад)

meld filename.{HEAD,branch,base}

ви git add filenameвстановите етап ( ), а потім здійсните злиття ( git commit).


2
Замислюючись про те саме, Грехем ... Я спробував це зробити, git merge --no-commit branchі в підсумку це злилося ... Я б хотів, щоб у підсумку вийшло 3 файли або 2 файли. Що я міг би використовувати диф і переносити все, що хочу, у цей файл.
Стівен

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

@Steven; Я думаю, ідея полягає в тому, що ви ігноруєте об’єднаний файл і використовуєте файли HEAD та гілки, тобто "два файли", за якими ви шукаєте, це HEAD: ім’я файлу та галузь для об’єднання: ім’я файлу.
Адріан Муат,

7
Git Gotcha: git merge --no-commit --no-ffне буде взагалі нічого робити, див. Відповідь @ Brad-O нижче. Ви повинні включити--no-ff
Рона Вертлена

1
@Kootoopas: так
Філ Міллер

41

Найпростіший спосіб зробити git merge <other_branchте git mergetoolграфічно вирішити конфлікти. Дивіться # 10935226 про те, як налаштувати mergetool.

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

Novelocrat дає чудовий спосіб копати трохи глибше, але вам часто доведеться змінити початкову команду на, git merge --no-commit --no-ff <other_branch>оскільки --no-commit насправді означає "Не виконувати об'єднання ... якщо це не швидке об'єднання вперед". Це трохи важко для багатьох людей, які намагаються робити саме те, що ти хочеш.

Іноді найменш заплутаний спосіб - не дуже стильний: перевірте іншу гілку в іншій робочій копії, використовуйте улюблений інструмент злиття, щоб отримати потрібну версію в потрібному каталозі, а потім зафіксуйте її.


13
10935226 - номер цього запитання. Що ви мали на увазі там писати?
Матьє К.

32

Відповідно до цього суті, де temp може бути існуючою гілкою.

https://gist.github.com/katylava/564416


На майстрі:

git checkout -b temp

На темп:

git merge --no-commit --no-ff refactor

... що все стадіює, отже:

git reset HEAD

Потім почніть додавати потрібні фрагменти:

git add --interactive

1
Це спрацювало, але мені довелося залишити `` head '' у `` git reset head '', але git reset працював нормально.
Micah

Фінал git commitне робить злиття! - Як врешті закінчити злиття?
Роберт Сімер,

@RobertSiemer Можливо, я думаю, ви можете зробити звичайне злиття на наступних кроках: git co master; git merge temp
Віктор Чой,

Приємною частиною є patchваріант від git add --interactive, який дозволяє вам інсценувати частини різниці, як описано в git book .
djvg

30

З гілки, яку ви хочете об'єднати:

git checkout -p branch_to_merge --

Це не дозволить перевірити галузь_до_злиття, але дозволить інтерактивно додавати шматки з патча (різниця).

http://git-scm.com/docs/git-checkout


1
Це було дуже просто у використанні для інтерактивного об’єднання - дякую!
cbcoutinho

Це робить саме те, що я шукав. Чому це не прийнята відповідь?
iliis

Ця команда представляє кожен "кусок" (відмінності у файлах, які згруповані впритул) і варіант "так" чи "ні", використовувати його чи ні. Дуже корисний.
Марк Лаката

1
Для всього, що ви робили на гілці, а що не на master, це передбачає його видалення. Це не найрозумніша стратегія об’єднання.
Енн ван Россум,

0

Ви можете просто використовувати WinMerge , DiffMerge або будь-який доступний інструмент різниці / злиття інтерфейсу, щоб виконати роботу вручну. Якщо ви хочете підключити його до "git difftool", ви можете шукати в Інтернеті, щоб знайти способи змусити ці інструменти працювати з git.


0

Найкращий спосіб, який я знайшов, це:

  1. Оформіть філію зі своїми змінами
  2. Створіть нову гілку з цієї точки
  3. Скиньте нову гілку до коміту, з яким ви хочете порівняти та на якому будувати. За замовчуванням скидання буде "змішаним" скиданням, що означає, що воно не змінить "робоче дерево", тобто фактичні файли коду
  4. На даний момент мій текстовий редактор (VSCode) показує мені, чим відрізняються мої поточні файли та коміт, до якого я скинув. Я можу редагувати код, щоб вибрати, які рядки я хочу зробити. Що це робить, це дозволяє мені побачити все, що змінилося в моїй гілці, і підтвердити кожен рядок коду, який я вкладу. Це корисно, наприклад, перед тим, як мої зміни змінити назад у виробництво.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.