git - пропуск конкретних комісій при злитті


200

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

У мене є дві гілки, які називаються, скажімо, master10 (для v1) і master20 (для v2). Я робив виправлення помилок у v1 на гілці master10 та розробляв нові речі master20. Щоразу, коли я роблю виправлення помилок, я зливаю його у v2, перевіряючи master20 і роблячи git merge master10. Все йде нормально.

Тепер я змінив v1, який не хочу в v2, але хочу продовжувати об'єднання інших виправлень помилок. Як я можу сказати Git пропустити цю конкретну комісію (або діапазон комітетів), але, рухаючись уперед, я все ж хочу об'єднати інші виправлення помилок.

Я думав, що це git rebaseможе бути те, що мені потрібно, але прочитав документ і моя голова майже вибухнула.

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

Будь-яка допомога вдячна.

Відповіді:


289

Якщо ви хочете об'єднати більшість, але не всі зобов'язання з гілки "maint", наприклад, "master", ви можете зробити це. Це вимагає певної роботи ----, як згадувалося вище, звичайним випадком використання є об'єднання всього з гілки --- але іноді трапляється зміна версії випуску, яка не повинна бути інтегрована назад (можливо, цей код вже витіснили майстра), так як ви це представляєте? Ось іде ...

Отже, припустимо, що в maint було застосовано 5 змін, і одна з цих (maint ~ 3) не повинна бути об'єднана назад у головний, хоча всі інші повинні бути. Ви робите це в три етапи: насправді з’єднайте все перед цим, скажіть git позначити maint ~ 3 як об'єднане навіть тоді, коли його немає, а потім об'єднайте решту. Магія:

bash <master>$ git merge maint~4
bash <master>$ git merge -s ours maint~3
bash <master>$ git merge maint

Перша команда об'єднує все, перш ніж ваш клопіткий maint здійснить майстер. Повідомлення журналу злиття за замовчуванням пояснить, що ви об'єднуєте "гілку" maint "(рання частина)".

Друга команда об'єднує клопітку команду maint ~ 3, але опція "-s ours" вказує git використовувати спеціальну "стратегію злиття", яка, власне, працює, просто зберігаючи дерево, в яке ви зливаєтесь, і ігноруючи коміти (s) ) ви повністю зливаєтесь. Але це все ще робить нове об'єднання об'єднання з HEAD та maint ~ 3 як батьки, тому графік перегляду тепер говорить, що maint ~ 3 об'єднаний. Отже, ви, мабуть, хочете скористатися параметром -m також для "git merge", щоб пояснити, що цей maint ~ 3 фіксація насправді ігнорується!

Заключна команда просто об'єднує решту maint (maint ~ 2..maint) у master, щоб ви все знову синхронізувались.


5
Я думаю, що якщо вам потрібно відкласти злиття цього комітету, у вас є мало іншого вибору, крім того, щоб пропустити його (злиття - наше) і пізніше застосувати його за допомогою команди cherry-pick. Після того, як фіксація є доступною від головного, вона не може бути об'єднана знову - уникнення об'єднання однієї зміни двічі є однією з головних цілей git.
araqnid

3
Що стосується прикладу вашої підгалузі: я підозрюю, що після того як ви об'єднали підгалузь, ви опинитесь в точно такій самій ситуації, як і після другого кроку моєї посади. Створення додаткових гілок не має жодних значень для взаємозв'язку.
araqnid

5
Просто з інтересу, якщо ви просто хочете опустити одну зміну, чому б вам не просто зробити єдине злиття і не повернути цей один набір змін, а не виконати три злиття? Це призведе до того, що менша кількість наборів змін буде здійснена для сховища та більш явна історія.
Марк Бут

3
Часто простіше чітко називати коміти. Тому вам просто потрібно переглянути git журнал гілки, що підлягає об'єднанню, і відзначити хеші комітету, які не слід об'єднувати, та попередній - замість підрахунку
комітетів

14
@MarkBooth: Комісія, яку ви хочете пропустити, може виникнути у величезному конфлікті з гілкою, у яку ви хочете об'єднатися. Простіше просто пропустити її, а не виправити конфлікти, а потім повернути цю зміну та знову виправити конфлікти
SztupY

39

IMHO, найлогічніше, що потрібно зробити, - це злити все, а потім використовувати git revert (commit_you_dont_want) для його видалення .

Приклад:

git merge master
git revert 12345678

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

git merge master
git revert -n 123456
git revert -n abcdef
git commit -m "... Except commits 123456 and abcdef"

Тоді ваша історія може виглядати так:

| ... Except 123456 and abcdef
|\ Merge branch 'master' into 'your_branch'

Якщо у вас виникли конфлікти, пов’язані ТІЛЬКИ ці зобов’язання "ігнорувати", ви можете використовувати:

git merge master -X ours

Тож ваша версія зберігатиметься над іншою. Навіть без повідомлень про помилки, ви все одно можете "повернути" ці небажані комісії, оскільки вони можуть мати інші зміни, які не суперечать, і ви все одно не хочете їх.

Якщо у вас виникають конфлікти, пов’язані НЕ ТІЛЬКИ, що потрібно "ігнорувати", ви повинні вирішити їх вручну, і, ймовірно, доведеться їх вирішувати ще раз під час скасування.


2
Якщо ви хочете пізніше об'єднати ці повернені коміти у гілку під питанням, чи все ж Git їх ігнорує?
Anriëtte Myburgh

@ AnriëtteMyburgh Ви можете скасувати реверсивні зобов’язання, щоб пізніше їх об'єднати - те, що ви насправді не можете зробити так легко зі стратегією "злиття-з нашою".
Лілі Чунг

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

17

До складу комітетів входить рід. Ви не можете об'єднати комісію без об'єднання попередніх комісій.

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


1
Спасибі, вишневий вибір зробить роботу. Не так приємно, як те, на що я сподівався, але це зроблять.
Бред Робінсон


3

Своєрідна реклама мого проекту яка в основному завершує процес, описаний @araqnid.

Це свого роду помічник, який вводить наступний потік GIT:

  • є щоденне / щотижневе повідомлення про очікувані злиття від відділень технічного обслуговування у відділ dev / master
  • Менеджер відділення перевіряє стан і вирішує, чи потрібні всі зобов’язання, або блокувати їх, або просить розробників заблокувати себе. Врешті-решт гілка технічного обслуговування об'єднується у верхню частину.

Цитата зі сторінки проекту:

Залежно від робочого циклу, можливо мати відділення з обслуговування або конкретні клієнти разом з головним відділенням. Ці гілки також називаються гілками LTS.

Часто гарячі виправлення надходять у гілки, де повідомляється про помилку, а потім фіксація об'єднується назад у головну гілку.

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

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

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


0

Створіть третю гілку для потрібних змін у master10, але не в master20. Завжди вважайте master10 своїм "господарем", найбільш стабільною галуззю усіх. Гілка всіх інших гілок хоче постійно підтримувати синхронізацію.


Я думаю, це могло б спрацювати, але я вже потрапив у цей стан, і третя гілка, можливо, збентежить мене ще більше. :)
Бред Робінсон

0

Замість того revertчиcherry-pick в цьому випадку вам потрібно отримати git, щоб вважати зміни, які ви пропускаєте, старішими за внесені вами зміни.

Так:

  1. з’єднайте останнє зобов’язання перед скоєними комісіями. Це, звичайно, об'єднує всі попередні зобов'язання. git merge ccc
  2. об'єднати комісії, які потрібно пропустити. git merge fff --no-commit
  3. стадіюйте будь-які злиття, зніміть усі зміни, скасуйте всі зміни. (Можливо, для цього є команди, що не мають дурнів, але я би просто виконав цю частину в інтерфейсі користувача - проте ви знаєте, як)
  4. завершити порожнє злиття git merge --continue
  5. з’єднайте комісії ПІСЛЯ тієї, яку ви хотіли пропустити. git merge source-branch-head

Після кроку 4, git розгляне вашу філію більш пізньою, ніж ця фіксація, оскільки ви вже вирішили її (вибравши зберегти ВАШІ версії речей).

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