Se eu quiser mesclar em uma ramificação Git, as alterações feitas apenas em alguns dos arquivos alterados em uma confirmação específica que inclui alterações em vários arquivos, como isso pode ser alcançado?
Suponha que o git commit chamada stuff
tem alterações em arquivos A
, B
, C
, e D
, mas eu quero fundir apenas stuff
mudanças 's para arquivos A
e B
. Parece um trabalho para, git cherry-pick
mas cherry-pick
só sabe mesclar confirmações inteiras, não um subconjunto dos arquivos.
fonte
git checkout .
recomendar, tambémgit clean -f
remova todos os arquivos novos, porém indesejados, introduzidos pelo commit escolhido pela cereja.git add -p
que lhe permite decidir de forma interactiva que muda você deseja adicionar ao índice por ficheirogit reset -p HEAD
. É o equivalente a,add -p
mas muito poucos sabem que ele existe.Os outros métodos não funcionaram para mim, pois o commit teve muitas alterações e conflitos em muitos outros arquivos. O que eu vim com foi simplesmente
Na verdade, ele não copia
add
os arquivos ou faz um commit para você; portanto, talvez seja necessário segui-loOu, se você quiser pular a adição, use o
--cached
argumento paragit apply
Você também pode fazer o mesmo por diretórios inteiros
fonte
show SHA -- file | apply
basicamente, não faz o mesmocheckout SHA -- file
que na resposta de Mark Longair ?checkout SHA -- file
fará o checkout exatamente da versão no SHA, enquantoshow SHA -- file | apply
aplicará apenas as alterações no SHA (assim como o cherry-pick faz). É importante se (a) houver mais de uma confirmação alterando o arquivo especificado na ramificação de origem ou (b) houver uma confirmação alterando o arquivo em sua ramificação de destino atual.git revert
desfaz todo o commit). Nesse caso, basta usargit show -R SHA -- file1.txt file2.txt | git apply -
git diff SHA -- file1.txt file2.txt | git apply -
significa aplicar todas as diferenças entre a versão atual do arquivo e a versão no SHA para a versão atual. Em essência, é o mesmo quegit checkout SHA -- file1.txt file2.txt
. Veja meu comentário anterior para saber por que isso é diferente do que agit show
versão.git apply -3 -
vez de apenasgit apply -
; se ocorrer um conflito, você poderá usar sua técnica padrão de resolução de conflitos, incluindo o usogit mergetool
.Normalmente, uso a
-p
flag com um checkout git do outro ramo, que acho mais fácil e mais granular do que a maioria dos outros métodos que encontrei.Em princípio:
exemplo:
Você então recebe uma caixa de diálogo perguntando quais alterações você deseja em "blobs", isso praticamente funciona em cada parte da mudança contínua de código que você pode sinalizar
y
(Sim)n
(Não) etc para cada parte do código.A opção
-p
oupatch
funciona para uma variedade de comandos no git, incluindo ogit stash save -p
que permite que você escolha o que deseja esconder do seu trabalho atualÀs vezes uso essa técnica quando tenho feito muito trabalho e gostaria de separá-la e confirmar em mais confirmações baseadas em tópicos, usando
git add -p
e escolhendo o que eu quero para cada confirmação :)fonte
git-add -p
, mas não sabia quegit-checkout
também tem uma-p
bandeira - isso corrige os problemas de fusão que a não-p
resposta tem?-p
permitiria uma edição manual para uma seção tão conflitante, quecherry-pick
provavelmente também produziria de qualquer maneira. Eu vou testar esta próxima vez que eu precisar dele, definitivamente uma abordagem interessantegit reset -p HEAD
também permite o-p
que pode ser útil quando você deseja remover apenas alguns patches do índice.Talvez a vantagem desse método sobre a resposta de Jefromi seja que você não precisa se lembrar de qual comportamento do git reset é o correto :)
fonte
cherry-pick
e usar diretamentegit checkout stuff -- A B
? E comgit commit -C stuff
a mensagem de commit permaneceria o mesmo bemstuff
não foram modificados em seu ramo atual ou em qualquer lugar entre o ancestral comum deHEAD
estuff
e a pontastuff
. Se houver,cherry-pick
cria o resultado correto (essencialmente o resultado de uma mesclagem), enquanto seu método descartaria as alterações no ramo atual e manteria todas as alterações do ancestral comum atéstuff
- e não apenas as que confirmação única.stuff
que o resultado da escolha da cereja sairiaA
eB
com conteúdo diferente do conteúdo no commitstuff
. No entanto, se for o mesmo, você está certo - você pode fazer o que diz.Escolha de cereja é escolher as alterações de um "commit" específico. A solução mais simples é escolher todas as alterações de determinados arquivos é usar
No exemplo:
Fontes e explicação completa http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/
ATUALIZAR:
Com esse método, o git não MERGE o arquivo, substituirá qualquer outra alteração feita na ramificação de destino. Você precisará mesclar as alterações manualmente:
fonte
A situação:
Você está no seu ramo, digamos,
master
e você tem seu commit em qualquer outro ramo. Você precisa escolher apenas um arquivo dessa confirmação específica.A abordagem:
Etapa 1: finalize a compra na filial necessária.
Etapa 2: verifique se você copiou o hash de confirmação necessário.
Etapa 3: Agora você tem as alterações do arquivo necessário no seu ramo desejado. Você só precisa adicionar e confirmar.
fonte
Gostaria apenas de escolher tudo de cereja e fazer o seguinte:
Depois, reverteria as alterações que não quero e, em seguida, faria um novo commit.
fonte
Use
git merge --squash branch_name
isso para obter todas as alterações do outro ramo e preparará uma confirmação para você. Agora remova todas as alterações desnecessárias e deixe a que você deseja. E o git não saberá que houve uma fusão.fonte
Eu encontrei uma outra maneira que impede qualquer fusão conflitante na escolha da cereja, que é fácil de lembrar e entender da IMO. Como na verdade você não escolhe um commit, mas faz parte dele, é necessário dividi-lo primeiro e depois criar um commit que atenda às suas necessidades e selecioná-lo.
Primeiro, crie uma ramificação a partir do commit que você deseja dividir e faça o checkout:
Reverta a confirmação anterior:
Em seguida, adicione os arquivos / alterações que deseja escolher:
e comprometa-o:
observe o hash de confirmação, vamos chamá-lo de PICK-SHA e voltar para sua ramificação principal, mestre por exemplo, forçando o checkout:
e escolha a submissão:
agora você pode excluir o ramo temporário:
fonte
Mesclar uma ramificação em uma nova (squash) e remover os arquivos não necessários:
fonte
Por uma questão de completude, o que funciona melhor para mim é:
Faz exatamente o que o OP quer. Faz a resolução de conflitos quando necessário, da mesma forma que
merge
faz. Faz,add
mas nãocommit
suas novas alterações.fonte
Você pode usar:
A notação
<commit>^
especifica o (primeiro) pai de<commit>
. Portanto, este comando diff seleciona as alterações feitas<path>
no commit<commit>
.Observe que isso ainda não confirma nada (como
git cherry-pick
faz). Então, se você quiser, terá que fazer:fonte