Como você se compromete com um patch com o Git Format-Patch?
-
03-07-2019 - |
Pergunta
Eu tenho oito commits em um ramo que gostaria de enviar um e -mail para algumas pessoas que não são iluminadas, ainda. Até agora, tudo o que faço me dá 8 arquivos de patch ou começa a me dar arquivos de patch para cada commit no histórico da filial, desde o início dos tempos. Eu usei o Git Rebase -interativo para esmagar os compromissos, mas agora tudo o que tento me dá zilhões de patches desde o início dos tempos. O que estou fazendo errado?
git format-patch master HEAD # yields zillions of patches, even though there's
# only one commit since master
Solução
Eu recomendo fazer isso em um ramo descartável da seguinte maneira. Se seus compromissos estiverem na filial "NewLines" e você já voltou para a sua filial "mestre", isso deve fazer o truque:
[adam@mbp2600 example (master)]$ git checkout -b tmpsquash
Switched to a new branch "tmpsquash"
[adam@mbp2600 example (tmpsquash)]$ git merge --squash newlines
Updating 4d2de39..b6768b2
Fast forward
Squash commit -- not updating HEAD
test.txt | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
[adam@mbp2600 example (tmpsquash)]$ git commit -a -m "My squashed commits"
[tmpsquash]: created 75b0a89: "My squashed commits"
1 files changed, 2 insertions(+), 0 deletions(-)
[adam@mbp2600 example (tmpsquash)]$ git format-patch master
0001-My-squashed-commits.patch
Espero que isto ajude!
Outras dicas
Apenas para adicionar mais uma solução ao pote: se você usar isso:
git format-patch master --stdout > my_new_patch.diff
Depois, ainda serão 8 patches ... mas todos estarão em um único PatchFile e se aplicarão como um com:
git am < my_new_patch.diff
Eu sempre uso o git diff então no seu exemplo, algo como
git diff master > patch.txt
Esta é uma adaptação da resposta de Adam Alexander, caso suas alterações estejam no ramo principal. Isso faz o seguinte:
- Cria um novo ramo descartável "tmpsquash" a partir do ponto que queremos (procure a chave SHA em execução "Git - -Log" ou com Gitg. Selecione a confirmação que deseja ser tmpsquash Head, os compromissos que estão depois disso em mestre serão os compromissos esmagados).
- Mescla as alterações de mestre para tmpsquash.
- Comete as mudanças esmagadas no TMPSQUASH.
- Cria o patch com os commites esmagados.
- Volte para o Master Branch
laura@rune:~/example (master)$ git branch tmpsquash ba3c498878054e25afc5e22e207d62eb40ff1f38
laura@rune:~/example (master)$ git checkout tmpsquash
Switched to branch 'tmpsquash'
laura@rune:~/example (tmpsquash)$ git merge --squash master
Updating ba3c498..40386b8
Fast-forward
Squash commit -- not updating HEAD
[snip, changed files]
11 files changed, 212 insertions(+), 59 deletions(-)
laura@rune:~/example (tmpsquash)$ git commit -a -m "My squashed commits"
[test2 6127e5c] My squashed commits
11 files changed, 212 insertions(+), 59 deletions(-)
laura@rune:~/example (tmpsquash)$ git format-patch master
0001-My-squashed-commits.patch
laura@rune:~/example (tmpsquash)$ git checkout master
Switched to branch 'master'
laura@rune:~/example (master)$
Como você já sabe, um git format-patch -8 HEAD
darei oito patches.
Se você quiser, seus 8 compromissos aparecem como um e não se importe de reescrever a história do seu ramo (o-o-X-A-B-C-D-E-F-G-H
), você poderia :
git rebase -i
// squash A, B, C, D, E ,F, G into H
ou, e seria uma solução melhor, reproduza todos os seus 8 compromissos de X
(o compromisso antes de seus 8 começos) em um novo ramo
git branch delivery X
git checkout delivery
git merge --squash master
git format-patch HEAD
Dessa forma, você só tem um compromisso no ramo de "entrega" e representa todos os seus últimos 8 compromissos
Patch de formato entre duas tags:
git checkout <source-tag>
git checkout -b <tmpsquash>
git merge --squash <target-tag>
git commit -a -m "<message>"
git format-patch <source-tag>
Maneira mais fácil é usar git diff
, e adicionar git log
Se você deseja a mensagem de confirmação combinada que o método de abóbora será lançado. Por exemplo, para criar o patch entre o compromisso abcd
e 1234
:
git diff abcd..1234 > patch.diff
git log abcd..1234 > patchmsg.txt
Então, ao aplicar o patch:
git apply patch.diff
git add -A
git reset patch.diff patchmsg.txt
git commit -F patchmsg.txt
Não se esqueça do --binary
argumento para git diff
Ao lidar com arquivos não textos, por exemplo, imagens ou vídeos.
Baseado na resposta de Adam Alexander:
git checkout newlines
## must be rebased to master
git checkout -b temporary
# squash the commits
git rebase -i master
git format-patch master