Переместить любой коммит Git из одной ветви в другую - PullRequest
3 голосов
/ 24 января 2012

У меня есть следующее дерево коммитов Git:

R - A - B - C - D (master)

Мне бы хотелось:

R - A - B - D' (master)
        \ - C  (new-branch)

Как я мог это сделать (предполагая, что это даже возможно)?

Я начал использовать git cherry-pick, но мне не удалось удалить коммит из главной ветви.

Спасибо.

Ответы [ 4 ]

3 голосов
/ 25 января 2012

Избегайте ненужных вишневых кирок, создавая новую ветку непосредственно в C, а затем просто перебазируйте master, чтобы удалить коммит C:

На мастере:

git branch new-branch sha1-of-C
git rebase --onto sha1-of-C^ sha1-of-C master

Вторая команда удаляет C из master, перебазируя master ("branch" на странице руководства git-rebase), фиксируя, начиная с sha1-of-C ("upstream"), до фиксации до sha1-of-C.

Или вы можете сделать перебаз в интерактивном режиме, если эта вторая команда слишком запутанная:

git rebase -i sha1-of-C^

В интерактивном перебазировании просто удалите коммит C, сохраните и выйдите.

Во время перебазирования, если git жалуется на конфликты слияния, разрешите их git add и git rebase --continue. Вам придется разрешать эти конфликты независимо от выбранного вами метода.

3 голосов
/ 24 января 2012

Вы не можете получить именно то, что вы хотите, поскольку в коммитах будут различия, но содержимое файлов будет таким, как вы хотите, если вы это сделаете:

$ git checkout master
$ git reset --hard sha1-of-B  # set master back to B
$ git cherry-pick sha1-of-D   # set master to R-A-B-D'
$ git checkout -b new-branch sha1-of-B   # set new-branch to B
$ git cherry-pick sha1-of-C   # set new-branch to R-A-B-C'

Обратите внимание, что вам не нужно выбирать вишню, чтобы установить new-branch, и вы можете сделать это так же просто:

$ git reset sha1-of-C

пока вы проверяли новую ветку Это на самом деле даст вам R-A-B-C вместо R-A-B-C '. Обратите внимание, что единственная разница между C и C '- это время фиксации.

После того, как вы выполните сброс, вам может быть трудно найти хэши sha1 различных коммитов (они доступны в reflog), поэтому вы можете захотеть поместить теги во все перед началом или сохранить где-нибудь историю .

1 голос
/ 24 января 2012

На мастере:

git branch new-branch
git reset --hard B
git cherry-pick D
git checkout new-branch
git reset --hard C
0 голосов
/ 25 января 2012

Рецепт, не включающий переменные, такие как B или sha1-of-C :

git checkout master, если еще не извлечены.

git branch tempD              # create temporary branch, pointing to D
git branch new-branch HEAD^   # create new-branch, pointing to C
git reset --hard HEAD^^       # reset master to B
git cherry-pick tempD         # apply D's changeset onto B
git branch -D tempD           # remove temporary branch
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...