Як об'єднати певний комітет у Git


1034

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

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

git branch -b a-good-feature
git pull repository master
git checkout master
git merge a-good-feature
git commit -a
git push

Якщо ви намагаєтесь зробити це стосовно github, ця стаття перегляне вас через це. markosullivan.ca/how-to-handle-a-pull-request-from-github
johndpope

Відповіді:


1173

" git cherry-pick" повинна бути вашою відповіддю тут.

Застосуйте зміни, внесені існуючим комітетом.

Не забудьте прочитати відповідь bdonlan про наслідок вибору вишень у цій публікації:
"Витягніть всі комісії з гілки, пересуньте вказані комісії до іншої" , де:

A-----B------C
 \
  \
   D

стає:

A-----B------C
 \
  \
   D-----C'

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

Де C 'має інший SHA-1ідентифікатор.
Крім того, вишневий вибір вибору з однієї гілки на іншу в основному передбачає генерування патча, а потім його застосування, тим самим втрачаючи історію і таким чином.

Ця зміна ідентифікаторів комітів порушує функцію об'єднання git серед інших речей (хоча, якщо використовувати їх економно, є евристика, яка буде надрукована на цьому).
Що ще важливіше, вона ігнорує функціональні залежності - якщо C фактично використовував функцію, визначену в B, ви ніколи не дізнаєтесь .


1
@ openid000: "Більш дрібнозернисті гілки": це справді саме те, що запропонував Бдонлан у своїй відповіді.
VonC

8
Примітка: "git rebase" також змінює SHA-1. Дивіться також "git rebase vs. git merge ( stackoverflow.com/questions/804115/git-rebase-vs-git-merge ) та" git workflow "( stackoverflow.com/questions/457927/… ) для випадків, коли" git rebase "є законним.
VonC

1
Між "дрібнозернистими гілками", "вишневим набором" та "ребазом" ви матимете всі можливості для управління кодом у гілках з git.
VonC

@VonC "дрібнозернисті гілки" так. У мене було дві гілки, і я здійснив оновлення до певного модуля візуалізації в одній гілці. Цей модуль не залежав від усіх інших кодів, тому вишневим вибору було проклято зручно застосовувати ці зміни також до іншої гілки
Cheeku

1
Але зауважте, що при злитті обидва символи C 'і C будуть переважати в історії комісій.
Рахул Шах

738

Ви можете використовувати git cherry-pick, щоб застосувати єдиний комітет до вашої поточної гілки.

Приклад: git cherry-pick d42c389f


68
+1 для вашої колишньої публікації про збирання вишні ( stackoverflow.com/questions/880957/… ). Я взяв на себе сміття скопіювати його уривок у власній відповіді вище.
VonC

4
Напевно, git cherry-pick d42cчи git cherry-pick d42c3 спрацює. Git розумний. ;)
guneysus

2
фатально: погана ревізія
Найда

2
Я щойно виконував цю команду і, здається, спрацював, але коли я виконую статус git, він говорить "нічого робити, чи працюю дерево чистим". Коли я оновлюю сторінку Commits на своїй веб-сторінці bitbucket, вона не відображається. Але він з'являється, коли я виконую журнал git. І я бачу змінений код. Чи може хтось пояснити, чи потрібно робити якісь додаткові кроки?
Рей

1
На жаль, це не відповідає на питання: насправді це не створює злиття. Тут немає жодного роду d42c389f. Можливо, ОП не переймалася створенням злиття як такої, але різниця буває важлива.
LarsH

29

Спробуємо взяти приклад і зрозуміти:

У мене є гілка, скажімо, майстер , вказуючи на X <commit-id>, і у мене є нова гілка, яка вказує на Y <sha1>.

Де Y <commit-id> = <master> філія здійснює - кілька комітів

Тепер скажіть, що для гілки Y я повинен закрити коміти між головною гілкою та новою гілкою. Нижче описана процедура, яку ми можемо дотримуватися:

Крок 1:

git checkout -b local origin/new

де локальна назва філії. Будь-яке ім’я можна дати.

Крок 2:

  git merge origin/master --no-ff --stat -v --log=300

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

Для отримання додаткової інформації та параметрів щодо злиття Git зверніться до:

git merge --help

Також якщо вам потрібно об'єднати певну комісію, ви можете використовувати:

git cherry-pick <commit-id>

Ви змінили визначення Yу своєму 3d-реченні? "У мене є нова гілка, яка вказує на Y" проти "Зараз скажімо, для Y гілка", це здається, що Y раніше був
комітетом,

як я можу це зробити з певного пункту фіксації гілки, яку я хочу об'єднати
Kulbhushan Singh

3

У моєму випадку ми мали аналогічну потребу в CD-диску CI. Ми використовували git flow з розробкою та освоєнням гілок. Розробники вільні об'єднати там зміни безпосередньо, щоб розробитись або через запит на виклик із функції функції. Однак для того, щоб оволодіти, ми з’єднуємо лише стабільні коміти з галузі розвитку автоматизовано за допомогою Дженкінса.

У цьому випадку робити вишню не дуже вдалий варіант. Однак ми створюємо локальну гілку з ідентифікатора комітету, а потім об'єднуємо цю локальну гілку для управління та виконання mvn clean verify (ми використовуємо maven). Якщо успіх, тоді випустіть артефакт виробничої версії до nexus, використовуючи плагін випуску Maven з localCheckout = true опцією та pushChanges = false. Нарешті, коли все успішно, тоді натисніть зміни та позначте походження.

Зразок фрагмента коду:

Якщо припустити, що ви перебуваєте на майстру, якщо це зробити вручну Однак на jenkins, коли ви оформили замовлення на репо, ви будете на гілці за замовчуванням (майстер, якщо він налаштований).

git pull  // Just to pull any changes.
git branch local-<commitd-id> <commit-id>  // Create a branch from the given commit-id
git merge local-<commit-id>  // Merge that local branch to master.
mvn clean verify   // Verify if the code is build able
mvn <any args> release:clean release:prepare release:perform // Release artifacts
git push origin/master  // Push the local changes performed above to origin.
git push origin <tag>  // Push the tag to origin

Це дасть вам повний контроль з безстрашним злиттям або конфліктом пекла.

Не соромтеся порадити, якщо є кращий варіант.


3

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

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

Наприклад, правдива історія злиття може бути бажаною, наприклад, якщо ваш процес збирання використовує переваги git, щоб автоматично встановлювати рядки версій на основі останнього тегу (використовуючи git describe).

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

Припустимо, ви перебуваєте на гілці, Aі ви хочете об'єднати комітку на кінчику гілки B:

git checkout A
git merge --no-commit B

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

(Можливо, буде простий спосіб повернути стан робочого каталогу та індексу назад таким чином, як це було до злиття, щоб у вас був чистий аркуш, на якому в першу чергу виберіть потрібний комітет. Але Я не знаю, як досягти цього чистого шиферу. git checkout HEADІ git reset HEADвони обидва видалять стан злиття, перемагаючи мету цього методу.)

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

git revert --no-commit 012ea56

за кожне небажане вчинення 012ea56.

Закінчивши коригування речей, створіть свою команду:

git commit -m "Merge in commit 823749a from B which tweaked the timeout code"

Тепер у вас є лише зміна, яку ви хотіли, і дерево прабатьків показує, що ви технічно злилися з Б.

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