Si je souhaite fusionner dans une branche Git les modifications apportées uniquement à certains des fichiers modifiés dans un commit particulier qui inclut des modifications sur plusieurs fichiers, comment cela peut-il être réalisé?
Supposons que le git commit appelé stuff
a des modifications aux fichiers A
, B
, C
et , D
mais je veux fusionner seulement des stuff
changements de » aux fichiers A
et B
. Cela ressemble à un travail git cherry-pick
mais cherry-pick
ne sait que fusionner des validations entières, pas un sous-ensemble des fichiers.
la source
git checkout .
je recommanderais égalementgit clean -f
de supprimer tous les fichiers nouveaux mais indésirables introduits par le commit choisi par les cerises.git add -p
ce qui vous permet de décider de manière interactive quelles modifications vous souhaitez ajouter à l'index par fichiergit reset -p HEAD
. C'est l'équivalentadd -p
mais très peu savent qu'il existe.Les autres méthodes n'ont pas fonctionné pour moi car le commit a eu beaucoup de changements et de conflits avec beaucoup d'autres fichiers. Ce que j'ai trouvé, c'était simplement
Il ne s'agit pas réellement
add
des fichiers ou ne fait pas de commit pour vous, vous devrez donc peut-être le suivre avecOu si vous souhaitez ignorer l'ajout, vous pouvez utiliser l'
--cached
argument pourgit apply
Vous pouvez également faire la même chose pour des répertoires entiers
la source
show SHA -- file | apply
fondamentalement la même chosecheckout SHA -- file
que dans la réponse de Mark Longair ?checkout SHA -- file
vérifiera exactement la version sur SHA, tandis queshow SHA -- file | apply
n'appliquera que les changements dans SHA (tout comme le fait le choix de la cerise). Cela importe si (a) il y a plus d'un commit qui change le fichier donné dans la branche source, ou (b) il y a un commit qui change le fichier dans votre branche cible actuelle.git revert
annule la validation entière). Dans ce cas, utilisez simplementgit show -R SHA -- file1.txt file2.txt | git apply -
git diff SHA -- file1.txt file2.txt | git apply -
signifie appliquer toutes les différences entre la version actuelle du fichier et la version de SHA à la version actuelle. En substance, c'est la même chose quegit checkout SHA -- file1.txt file2.txt
. Voir mon commentaire précédent pour savoir pourquoi cela est différent de ce que lagit show
version.git apply -3 -
au lieu de simplementgit apply -
, puis si un conflit se produit, vous pouvez utiliser votre technique de résolution de conflit standard, y compris en utilisantgit mergetool
.J'utilise généralement le
-p
drapeau avec une vérification git de l'autre branche que je trouve plus facile et plus granulaire que la plupart des autres méthodes que j'ai rencontrées.En principe:
exemple:
Vous obtenez alors une boîte de dialogue vous demandant quelles modifications vous voulez dans les "blobs", cela fonctionne à peu près à chaque bloc de changement de code continu que vous pouvez ensuite signaler
y
(Oui)n
(Non), etc. pour chaque bloc de code.L' option
-p
oupatch
fonctionne pour une variété de commandes dans git notammentgit stash save -p
qui vous permet de choisir ce que vous voulez cacher de votre travail actuelJ'utilise parfois cette technique lorsque j'ai fait beaucoup de travail et que je voudrais le séparer et effectuer des validations basées sur des sujets en utilisant
git add -p
et en choisissant ce que je veux pour chaque validation :)la source
git-add -p
, mais je ne savais pas qu'ilgit-checkout
y avait également un-p
indicateur - cela résout-il les problèmes de fusion de la non--p
réponse ?-p
permettrait une modification manuelle pour une section aussi conflictuelle, quicherry-pick
donnerait probablement aussi de toute façon. Je testerai cela la prochaine fois que j'en aurai besoin, certainement une approche intéressantegit reset -p HEAD
permet également de-p
quitter ce qui est pratique lorsque vous souhaitez uniquement supprimer certains correctifs de l'index.L'avantage de cette méthode par rapport à la réponse de Jefromi est peut-être que vous n'avez pas à vous rappeler quel comportement de git reset est le bon :)
la source
cherry-pick
et utiliser directementgit checkout stuff -- A B
? Et avecgit commit -C stuff
le message de validation resterait le même aussistuff
n'ont pas été modifiés sur votre branche actuelle ou n'importe où entre l'ancêtre commun deHEAD
etstuff
et la pointe destuff
. Si c'est le cas,cherry-pick
crée le résultat correct (essentiellement le résultat d'une fusion), tandis que votre méthode supprimerait les modifications dans la branche actuelle et conserverait toutes les modifications de l'ancêtre commun jusqu'àstuff
- pas seulement celles de ce validation unique.stuff
celui que le résultat de la sélection de cerises laisseraitA
etB
avec un contenu différent de leur contenu dans le commitstuff
. Cependant, si ce devait être la même chose, vous avez raison - vous pouvez simplement faire ce que vous dites.Cherry pick consiste à sélectionner les modifications à partir d'un "commit" spécifique. La solution la plus simple consiste à sélectionner toutes les modifications de certains fichiers est d'utiliser
Par exemple:
Sources et explication complète http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/
MISE À JOUR:
Avec cette méthode, git ne fusionnera pas le fichier, il remplacera simplement toute autre modification effectuée sur la branche de destination. Vous devrez fusionner les modifications manuellement:
la source
La situation:
Vous êtes sur votre branche, disons
master
et vous avez votre engagement sur une autre branche. Vous devez choisir un seul fichier de ce commit particulier.L'approche:
Étape 1: Caisse sur la branche requise.
Étape 2: assurez-vous d'avoir copié le hachage de validation requis.
Étape 3: Vous avez maintenant les modifications du fichier requis sur la branche souhaitée. Il vous suffit de les ajouter et de les valider.
la source
Je choisirais simplement tout, puis je ferais ceci:
Ensuite, je reviendrais sur les modifications que je ne veux pas, puis je ferais un nouveau commit.
la source
Utilisez
git merge --squash branch_name
ceci pour obtenir toutes les modifications de l'autre branche et préparer un commit pour vous. Maintenant, supprimez toutes les modifications inutiles et laissez celle que vous souhaitez. Et git ne saura pas qu'il y a eu une fusion.la source
J'ai trouvé un autre moyen qui empêche toute fusion conflictuelle sur la cueillette des cerises dont l'OMI est assez facile à retenir et à comprendre. Étant donné que vous n'êtes pas en train de choisir un commit, mais une partie de celui-ci, vous devez d'abord le diviser, puis créer un commit qui conviendra à vos besoins et le choisir.
Créez d'abord une branche à partir du commit que vous souhaitez fractionner et extrayez-la:
Revenez ensuite au commit précédent:
Ajoutez ensuite les fichiers / modifications que vous souhaitez sélectionner:
et engagez-le:
notez le hachage de validation, appelons-le PICK-SHA et revenons à votre branche principale, master forçant par exemple le checkout:
et choisissez le commit:
vous pouvez maintenant supprimer la branche temporaire:
la source
Fusionnez une branche en une nouvelle (squash) et supprimez les fichiers inutiles:
la source
Par souci d'exhaustivité, ce qui fonctionne le mieux pour moi est:
Il fait exactement ce que souhaite OP. Il résout les conflits en cas de besoin, de la même manière
merge
. Ce n'estadd
pascommit
le cas mais pas vos nouveaux changements.la source
Vous pouvez utiliser:
La notation
<commit>^
spécifie le (premier) parent de<commit>
. Par conséquent, cette commande diff sélectionne les modifications apportées au<path>
commit<commit>
.Notez que cela
git cherry-pick
n'engagera rien encore (comme le fait). Donc, si vous le souhaitez, vous devrez faire:la source