Как переместить определенные коммиты на основе другой ветки в git?
Ситуация:
- мастер в X
- quickfix1 в X + 2 коммитов
Такой, что:
o-o-X (master HEAD)
\
q1a--q1b (quickfix1 HEAD)
Затем я начал работать с quickfix2, но случайно взял в качестве источника ветку quickfix1, а не мастер. Теперь 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?
Ответы
Ответ 1
Это классический случай rebase --onto
:
# let 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.
Ответ 2
Вы можете использовать git cherry-pick
, чтобы просто выбрать коммит, который вы хотите скопировать.
Вероятно, лучший способ - создать ветвь из мастера, а затем в этой ветки использовать git cherry-pick
для 2 коммитов из quickfix2, которые вы хотите.
Ответ 3
Простейшая вещь, которую вы можете сделать, - это вишня, выбирающая диапазон. Он делает то же самое, что и rebase --onto
, но легче для глаз:)
git cherry-pick quickfix1..quickfix2
Ответ 4
Я считаю, что это:
git checkout master
git checkout -b good_quickfix2
git cherry-pick quickfix2^
git cherry-pick quickfix2
Ответ 5
// 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
Ответ 6
Единственный рабочий способ, который я нашел:
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
Затем вам нужно снова зафиксировать изменения, но это намного проще, чем сделать это вручную...