Как переместить определенные коммиты на основе другой ветки в git? - PullRequest
346 голосов
/ 03 марта 2010

Ситуация:

  • Мастер находится в 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, но без двух коммитов, которые относятся к quickfix1.

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

Я пытался создать патч из определенной ревизии в quickfix2, но патч не сохраняет историю коммитов. Есть ли способ сохранить мою историю коммитов, но иметь ветку без изменений в quickfix1?

Ответы [ 5 ]

341 голосов
/ 03 марта 2010

Это классический случай 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 .

142 голосов
/ 03 марта 2010

Вы можете использовать git cherry-pick, чтобы просто выбрать коммит, который вы хотите скопировать.

Вероятно, лучший способ - создать ветку из master, затем в этой ветке использовать git cherry-pick на 2 коммитах из quickfix2, которые вы хотите.

129 голосов
/ 15 августа 2012

Самое простое, что вы можете сделать, это выбрать диапазон вишни. Он делает то же самое, что и rebase --onto, но легче для глаз:)

git cherry-pick quickfix1..quickfix2
25 голосов
/ 03 марта 2010

Я считаю, что это:

git checkout master
git checkout -b good_quickfix2
git cherry-pick quickfix2^
git cherry-pick quickfix2
0 голосов
/ 31 июля 2017

Единственный рабочий способ, который я нашел:

git show>~/some_file.txt
git checkout master
git checkout -b new_branch
git apply -stat ~/some_file.txt
git apply -check ~/some_file.txt
git apply ~/some_file.txt

Затем вам нужно снова зафиксировать изменения, но это намного проще, чем делать это вручную ...

...