Eu tenho o seguinte layout de repositório:
- filial mestre (produção)
- integração
- trabalhando
O que eu quero alcançar é escolher uma variedade de confirmações do ramo de trabalho e mesclá-lo no ramo de integração. Eu sou muito novo no git e não consigo descobrir como fazer exatamente isso (a escolha inicial do commit varia em uma operação e não na mesclagem) sem atrapalhar o repositório. Alguma indicação ou opinião sobre isso? Obrigado!
git
git-merge
git-cherry-pick
crazybyte
fonte
fonte
Respostas:
Quando se trata de uma variedade de confirmações, a escolha da cereja
énão foi prático.Conforme mencionado abaixo por Keith Kim , o Git 1.7.2+ introduziu a capacidade de escolher uma variedade de confirmações (mas você ainda precisa estar ciente das conseqüências da escolha da cereja para mesclagem futura )
damian comenta e nos adverte:
Se você quer escolher a gama
B
através deD
(inclusive) que seriaB^..D
.Consulte " Git create branch a partir do intervalo de confirmações anteriores? " Como uma ilustração.
Como Jubobs menciona nos comentários :
Nota: a partir do Git 2.9.x / 2.10 (terceiro trimestre de 2016), você pode escolher um intervalo de confirmação diretamente em um ramo órfão (cabeça vazia): consulte " Como tornar um ramo existente um órfão no git ".
Resposta original (janeiro de 2010)
A
rebase --onto
seria melhor, onde você reproduz o intervalo determinado de confirmação no topo do seu ramo de integração, como Charles Bailey descreveu aqui .(também, procure "Aqui está como você transplantaria uma ramificação de tópico com base em uma ramificação para outra" na página do manual git rebase , para ver um exemplo prático de
git rebase --onto
)Se sua ramificação atual for integração:
Isso repetirá tudo entre:
first_SHA-1_of_working_branch_range
(daí o~1
): o primeiro commit que você deseja reproduzirintegration
" (que aponta para o último commit que você deseja reproduzir, a partir daworking
ramificação)para "
tmp
" (que aponta para ondeintegration
estava apontando antes)Se houver algum conflito quando uma dessas confirmações for repetida:
git rebase --continue
".git rebase --skip
"git rebase --abort
" (e recoloque ointegration
ramo notmp
ramo)Depois disso
rebase --onto
,integration
voltaremos ao último commit da ramificação de integração (isto é "tmp
" branch + todas as confirmações reproduzidas)Com a seleção de cereja ou
rebase --onto
, não se esqueça, isso tem consequências nas mesclagens subsequentes, conforme descrito aqui .Uma
cherry-pick
solução " " pura é discutida aqui e envolveria algo como:Mas de qualquer maneira, quando você precisar "repetir" uma série de confirmações, a palavra "repetir" deve empurrá-lo para usar o
rebase
recurso " " do Git.fonte
-m
opção, como você lida com essas confirmações? Ou existe uma maneira de filtrar esses commits?-m
deve lidar com eles para você, selecionando a linha principal referenciada pelo-m
parâmetro que você escolheu para essa escolha de cereja.-m
opção somente quando atinge um commit pai quando o intervalo de commit é escolhido? No momento, se eu passar-m
comogit cherry-pick a87afaaf..asfa789 -m 1
se aplica a todos os commits dentro do intervalo.error: Commit 8fcaf3b61823c14674c841ea88c6067dfda3af48 is a merge but no -m option was given.
eu realmente percebi que você poderia apenasgit cherry-pick --continue
e seria muito bem (mas não incluiria o pai cometer)A partir do git v1.7.2, o cherry pick pode aceitar uma variedade de confirmações:
fonte
cherry-pick A..B
não vai se comprometer A (você precisariaA~1..B
para isso), e se existem quaisquer conflitos git não continuará automaticamente como rebase faz (pelo menos a partir de 1.7.3.1)git cherry-pick A..B C
não funciona como você esperaria, ingenuamente. Ele não seleciona tudo no intervaloA..B
e confirmaC
! Para fazer isso, você precisa se dividir em duas linhas, primeirogit cherry-pick A..B
e depoisgit cherry-pick C
. Portanto, sempre que houver um intervalo, você precisará executá-lo separadamente.Suponha que você tenha 2 ramos,
"branchA": inclui confirmações que você deseja copiar (de "commitA" para "commitB"
"branchB": o ramo que você deseja que as confirmações sejam transferidas de "branchA"
1)
2) obtenha os IDs de "commitA" e "commitB"
3)
4)
5) Caso você tenha um conflito, resolva-o e digite
para continuar o processo de escolha da cereja.
fonte
Tem certeza de que não deseja mesclar os galhos? Se o ramo de trabalho tiver algumas confirmações recentes que você não deseja, basta criar um novo ramo com um HEAD no ponto desejado.
Agora, se você realmente deseja escolher uma variedade de confirmações, por qualquer motivo, uma maneira elegante de fazer isso é apenas puxar um conjunto de patches e aplicá-lo ao seu novo ramo de integração:
Isso é essencialmente o que o git-rebase está fazendo de qualquer maneira, mas sem a necessidade de jogar. Você pode adicionar
--3way
paragit-am
se você precisa mesclar. Verifique se não há outros arquivos * .patch no diretório em que você faz isso, se você seguir as instruções literalmente ...fonte
A^
incluídoA
.Enrolei o código do VonC em um script bash short,
git-multi-cherry-pick
, para facilitar a execução:Atualmente, estou usando isso ao reconstruir o histórico de um projeto que tinha código e personalizações de terceiros misturados no mesmo tronco svn. Agora, estou dividindo o código principal de terceiros, os módulos de terceiros e as personalizações em suas próprias ramificações git para entender melhor as personalizações daqui para frente.
git-cherry-pick
é útil nessa situação, pois tenho duas árvores no mesmo repositório, mas sem um ancestral compartilhado.fonte
Todas as opções acima solicitarão que você resolva conflitos de mesclagem. Se você estiver mesclando alterações confirmadas para uma equipe, é difícil resolver os conflitos de mesclagem dos desenvolvedores e prosseguir. No entanto, "git merge" fará a mesclagem de uma só vez, mas você não pode passar por uma série de revisões como argumento. nós precisamos usar os comandos "git diff" e "git apply" para fazer a mesclagem de rotações. Eu observei que "git apply" falhará se o arquivo de correção tiver diff para muitos arquivos, portanto, precisamos criar um patch por arquivo e depois aplicar. Observe que o script não poderá excluir os arquivos excluídos na ramificação de origem. Este é um caso raro, você pode excluir manualmente esses arquivos do ramo de destino. O status de saída de "git apply" não é zero se não for possível aplicar o patch,
Abaixo está o script.
fonte
Eu testei isso alguns dias atrás, depois de ler a explicação muito clara de Vonc.
Meus passos
Começar
dev
: ABCDEFGHIJtarget
: ABCDE
nemH
Etapas para copiar recursos sem as etapas E e H na ramificação
dev_feature_wo_E_H
git checkout dev
git checkout -b dev_feature_wo_E_H
git rebase --interactive --rebase-merges --no-ff D
onde eu coloco nadrop
frenteE
eH
no editor rebasecommit
Etapas para copiar o ramo
dev_feature_wo_E_H
no destino.git checkout target
git merge --no-ff --no-commit dev_feature_wo_E_H
commit
Algumas observações
cherry-pick
nos dias anterioresgit cherry-pick
é poderoso e simples, masmerge
, tenho que resolver conflitos de confirmações iniciais e duplicatas, portanto, para um ou doischerry-pick
, não há problema em "escolher", mas, para mais, é muito detalhado e o ramo se tornará muito complexogit rebase --onto
fonte
Outra opção pode ser mesclar a estratégia nossa com o commit antes do intervalo e, em seguida, um 'normal' mesclar com o último commit desse intervalo (ou ramificar quando ele for o último). Portanto, suponha que apenas 2345 e 3456 confirmam o mestre a serem mesclados no ramo de recurso:
na ramificação do recurso:
fonte