web-dev-qa-db-fra.com

Comment rédigez-vous les commits dans un patch avec git format-patch?

J'ai huit commits sur une branche que j'aimerais envoyer par courrier électronique à des personnes qui ne sont pas encore éclairées. Jusqu'à présent, tout ce que je fais me donne 8 patchs ou commence à me donner des patchs pour chaque commit dans l'historique de la branche, depuis le début des temps. J'ai utilisé git rebase --interactive pour écraser les commits, mais maintenant, tout ce que j'essaie me donne des zillions de correctifs depuis le début des temps. Qu'est-ce que je fais mal?

git format-patch master HEAD # yields zillions of patches, even though there's 
                             # only one commit since master
161
skiphoppy

Je vous recommande de faire ceci sur une branche jetable comme suit. Si vos commits se trouvent dans la branche "nouvelles lignes" et que vous êtes déjà revenu dans votre branche "maître", voici le résultat:

[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

J'espère que cela t'aides!

179
Adam Alexander

Juste pour ajouter une solution supplémentaire au pot: Si vous utilisez ceci à la place:

git format-patch master --stdout > my_new_patch.diff

Ensuite, il y aura toujours 8 correctifs ... mais ils seront tous dans un seul fichier de correctif et s'appliqueront en tant que tel avec:

git am < my_new_patch.diff
129
Taryn East

J'utilise toujours git diff donc dans votre exemple, quelque chose comme

git diff master > patch.txt
20
Rob Di Marco

Comme vous le savez déjà, un git format-patch -8 HEAD vous donnera huit patchs.

Si vous voulez que vos 8 commits apparaissent comme un seul et qu’il ne vous dérange pas de réécrire l’historique de votre branche (o-o-X-A-B-C-D-E-F-G-H), vous pourriez :

git rebase -i
// squash A, B, C, D, E ,F, G into H

ou, et ce serait une meilleure solution, rejouez tous vos 8 commits de X (le commit avant vos 8 commits) sur une nouvelle branche

git branch delivery X
git checkout delivery
git merge --squash master
git format-patch HEAD

De cette façon, vous n’avez qu’un commit sur la branche "livraison", et cela représente tous vos 8 derniers commit.

18
VonC

Ceci est une adaptation de la réponse d'Adam Alexander, au cas où vos modifications seraient dans la branche principale. Cela fait ce qui suit:

  • Crée une nouvelle branche "tmpsquash" à partir du point souhaité (recherchez la clé SHA exécutant "git --log" ou avec gitg). Sélectionnez le commit que vous souhaitez utiliser, tmpsquash les commits qui sont après cela dans le maître seront les commits écrasés).
  • Fusionne les modifications de master à tmpsquash.
  • Valide les modifications écrasées dans tmpsquash.
  • Crée le patch avec les commits écrasés.
  • Retourne à la branche master

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)$
18
rec

Format-patch entre deux tags:

git checkout <source-tag>
git checkout -b <tmpsquash>
git merge --squash <target-tag>
git commit -a -m "<message>"
git format-patch <source-tag>
4
kashesandr

Le moyen le plus simple est d'utiliser git diff, et ajouter dans git log si vous voulez le message de validation combiné que la méthode squash produirait. Par exemple, pour créer le correctif entre commit abcd et 1234:

git diff abcd..1234 > patch.diff
git log abcd..1234 > patchmsg.txt

Ensuite, lors de l'application du patch:

git apply patch.diff
git add -A
git reset patch.diff patchmsg.txt
git commit -F patchmsg.txt

N'oubliez pas le --binary argument pour git diff lorsqu’il s’agit de fichiers autres que du texte, par exemple images ou vidéos.

4
woojoo666

Basé sur la réponse d'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
0
Julien W