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):

enter image description here

Foi útil?

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 ...

Workflow

Para resumir os comandos em forma de texto:

  1. Abrir Gitk Como um processo independente usando o comando: gitk --all &.
  2. Corre git rebase --onto a b f.
  3. Imprensa F5 dentro Gitk. Nada muda. Mas não HEAD é marcado.
  4. Corre git branch selection
  5. 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:

  1. Registre a base de mesclagem entre os dois ramos: MERGE_BASE=$(git merge-base branch-a branch-b)
  2. Avanço rápido ou rebase o ramo mais antigo no ramo mais recente
  3. 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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top