Como escolher com compromissos múltiplos
-
13-09-2019 - |
Pergunta
Eu tenho dois galhos. Comprometer-se a
é o chefe de um, enquanto o outro tem b
, c
, d
, e
e f
Em cima de a
. Eu quero me mover c
, d
, e
e f
para primeiro ramificar sem compromisso b
. Usando a colheita de cereja é fácil: checkout First Branch Cherry-Pick um por um c
para f
e refazer a segunda filial no primeiro. Mas existe alguma maneira de escolher tudo c
-f
em um comando?
Aqui está uma descrição visual do cenário (obrigado JJD):
Solução
O Git 1.7.2 introduziu a capacidade de correr uma variedade de commits. De Notas de liberação:
Git Cherry-Pick "Aprendeu a escolher uma variedade de commits (por exemplo," Cherry-Pick A..B "e" Cherry-Pick-Stdin "), assim como" Git Revert "; estes não suportam o controle de sequenciamento mais agradável" Rebase [-i] "tem, no entanto.
Incluindo comentários importantes (créditos para os respectivos autores)
Nota 1: Na forma "Cherry-pick a..b", a deve ser mais antigo que B. Se eles são a ordem errada, o comando silenciosamente falhará. - Damian
Nota 2: Além disso, isso não vai escolher a Cherry A, mas tudo depois de um B.-JB Rainsberger
Nota 3: Para incluir um tipo de apenas tipo de cereja a^.. b-sschaef
Outras dicas
A maneira mais simples de fazer isso é com o onto
opção para rebase
. Suponha que o ramo que atual termine em a
é chamado mybranch e este é o ramo que você deseja mover c
-f
para.
# checkout mybranch
git checkout mybranch
# reset it to f (currently includes a)
git reset --hard f
# rebase every commit after b and transplant it onto a
git rebase --onto a b
Ou a linha solicitada:
git rebase --onto a b f
Você pode usar uma combinação serial de git rebase
e git branch
Para aplicar um grupo de comérteis em outro ramo. Como já Postado por Wolfc O primeiro comando realmente copia os compromissos. No entanto, a alteração não é visível até você adicionar um nome de ramificação ao topo mais comprometido do grupo.
Por favor, abra a imagem em uma nova guia ...
Para resumir os comandos em forma de texto:
- Abrir Gitk Como um processo independente usando o comando:
gitk --all &
. - Corre
git rebase --onto a b f
. - Imprensa F5 dentro Gitk. Nada muda. Mas não
HEAD
é marcado. - Corre
git branch selection
- Imprensa F5 dentro Gitk. O novo ramo com seus compromissos aparece.
Isso deve esclarecer as coisas:
- Comprometer-se
a
é o novo destino raiz do grupo. - Comprometer-se
b
é o compromisso antes do primeiro compromisso do grupo (exclusivo). - Comprometer-se
f
é o último compromisso do grupo (inclusive).
Depois, você pode usar git checkout feature && git reset --hard b
Para excluir os compromissos c
até f
de feature
ramo.
Além desta resposta, escrevi um Postagem do blog que descreve os comandos em outro cenário que devem ajudar a usá -lo geralmente.
Para aplicar os comentários de JB Rainsberger e Sschaef para responder especificamente à pergunta ... para usar um alcance de pick-pick neste exemplo:
git checkout a
git cherry-pick b..f
ou
git checkout a
git cherry-pick c^..f
Se você tem revisões seletivas para mesclar, digamos A, C, F, J de A, B, C, D, E, F, G, H, I, J Cometida, basta usar o comando abaixo:
Git Cherry-Pick ACFJ
git rev-list --reverse b..f | xargs -n 1 git cherry-pick
Para escolher de um ID de compromisso até a ponta da filial, você pode usar:
git cherry-pick commit_id^..branch_name
git format-patch --full-index --binary --stdout range... | git am -3
Na verdade, a maneira mais simples de fazer isso pode ser:
- Registre a base de mesclagem entre os dois ramos:
MERGE_BASE=$(git merge-base branch-a branch-b)
- Avanço rápido ou rebase o ramo mais antigo no ramo mais recente
Rebaseie o ramo resultante, começando na base de mesclagem da Etapa 1, e remova manualmente os commits que não são desejados:
git rebase ${SAVED_MERGE_BASE} -i
Como alternativa, se houver apenas algumas novas comissões, pule a etapa 1 e simplesmente use
git rebase HEAD^^^^^^^ -i
na primeira etapa, usando o suficiente
^
para superar a base de mesclagem.
Você verá algo assim no Rebase Interactive:
pick 3139276 commit a
pick c1b421d commit b
pick 7204ee5 commit c
pick 6ae9419 commit d
pick 0152077 commit e
pick 2656623 commit f
Em seguida, remova as linhas B (e as outras que desejar)
Aqui está um script que permitirá que você coloque vários compromissos em uma linha simplesmente dizendo ao script quais ramificações de origem e alvo para as escolhas de cereja e o número de commits:
https://gist.github.com/nickboldt/99ac1dc4eb4c9ff003a1eff2eb2d81
Para escolher de sua filial para mestre (usa a filial atual como fonte):
./gcpl.sh -m
Para escolher as mais recentes 5 compromissos da sua filial 6.19.x para mestre:
./gcpl.sh -c 5 -s 6.19.x -t master