Як перемістити певні комісії на основі іншої гілки в git?


381

Ситуація:

  • майстер на X
  • quickfix1 знаходиться на рівні X + 2

Такий як:

o-o-X (master HEAD)
     \
      q1a--q1b (quickfix1 HEAD)

Тоді я почав працювати над quickfix2, але випадково взяв quickfix1 як джерельну гілку для копіювання, а не як master. Тепер quickfix2 знаходиться на рівні X + 2, + 2 відповідних коміти.

o-o-X (master HEAD)
     \
      q1a--q1b (quickfix1 HEAD)
              \
               q2a--q2b (quickfix2 HEAD)

Тепер я хочу мати гілку з quickfix2, але без 2-х комітів, що належать до quickfix1.

      q2a'--q2b' (quickfix2 HEAD)
     /
o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)

Я намагався створити виправлення з певної версії у quickfix2, але патч не зберігає історію фіксації. Чи є спосіб зберегти історію фіксації, але мати гілку без змін у quickfix1?



8
@Kevin Це питання задає лише питання про переміщення комітетів з однієї гілки в іншу, в цьому є додаткова вимога не включати комітети quickfix1. (Зауважте також різницю у відповідях.)
Скотт Велдон

Відповіді:


372

Це класичний випадок rebase --onto:

 # let's go to current master (X, where quickfix2 should begin)
 git checkout master

 # replay every commit *after* quickfix1 up to quickfix2 HEAD.
 git rebase --onto master quickfix1 quickfix2 

Тож вам слід піти

o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)
              \
               q2a--q2b (quickfix2 HEAD)

до:

      q2a'--q2b' (new quickfix2 HEAD)
     /
o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)

Це найкраще робити на чистому робочому дереві.
Дивітьсяgit config --global rebase.autostash true , особливо після Git 2.10 .


24
Слідкуйте за тим, щоб ці кроки змінили історію quickfix2, тому якщо ви вже поділилися гілкою, використовуйте замість цього вибір вишні (див. Наступні відповіді).
Макс Черняк

Тільки для запису: з журналом просто перетягнути SmartGit в q2aна Xі виберіть Rebase 2 коммітов з варіантів події діалогу.
Томас С.

1
@ThomasS. Цікаво. Це приємна реалізація графічного інтерфейсу a git rebase --onto.
VonC

1
Маю визнати, я займаюся дурними речами, такими як вчинення на неправильну гілку частіше, ніж мені справді слід, графічний інтерфейс інтерфейсу SmartGit врятував мене стільки разів при одній і тій же ситуації.
РОБОТИ

1
@Cosine Погодився. Я відредагував свою відповідь, щоб додати посилання на rebase.autostashконфігурацію: це дозволить уникнути будь-якої втрати незавершеної роботи в робочому дереві при виконанні ребайз.
VonC

155

Ви можете git cherry-pickпросто вибрати команду, яку ви хочете скопіювати.

Мабуть, найкращий спосіб - це створити гілку з головного, тоді в цій гілці використовуйте git cherry-pick2 комітети з quickfix2, які ви хочете.


Це також найкращий варіант, якщо ви хочете перемістити лише одну команду. Дякую.
Олексій

142

Найпростіше, що ви можете зробити - це вишня вибору асортименту. Це так само, як і, rebase --ontoале легше для очей :)

git cherry-pick quickfix1..quickfix2

6
Крім того, він не втрачає оригінальних зобов’язань, IIUC, тому здається кращим для "play-it-sefes", як я;) або rebase --ontoтакож зберігає оригінальні зміни?
akavel

6
обидва rebaseі cherry-pickдамо вам нові ключі SHA. Це тому, що кожен коміт - це унікальний знімок сховища.
Крістоф

6
Що означав @akavel, це те, що вишня збереже оригінали зобов’язань у своїй галузі, що правда
Mr_and_Mrs_D

4
Що б там не було, я намагався дотримуватися cherry-pickтакої кількості, як у цій відповіді, і це переплутало мою репо. Я повинен був робити індивідуальний cherry-picks для кожного вчинку. (І, можливо, само собою зрозуміло, але якщо хтось бореться, ви повинні cherry-pickв хронологічному порядку застосовувати ваші зобов’язання.)
карменізм

3
git checkoutтут має вирішальне значення. який твій ГОЛОВА :)?
Славомір Ленарт

28

Я вважаю, що це:

git checkout master
git checkout -b good_quickfix2
git cherry-pick quickfix2^
git cherry-pick quickfix2

3
cherry-pickпрацює з хешами фіксації, тому, якщо ви просто хочете взяти команду звідкись і помістити її десь ще, це шлях. Просто переконайтеся, що ви робите checkout <branch>правильну гілку спочатку.
Джон Лейдегрен

-1
// on your branch that holds the commit you want to pass
$ git log
// copy the commit hash found
$ git checkout [branch that will copy the commit]
$ git reset --hard [hash of the commit you want to copy from the other branch]
// remove the [brackets]

Інші більш корисні команди тут із поясненням: Git Guide

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