82 votes

Avec GIT, comment puis-je extraire / fusionner de manière sélective les modifications d'un autre fichier?

Prenez ce scénario:

  1. Je décide de "fork" d'une base de code sur github.com et commencer à faire ma routine: Modifier - Commit - Push; aka hack hack hack.
  2. Après j'ai fait quelques changements, je vois des changements d'une autre personne a fait sur le même projet, et je les aime!
  3. Je décide de les fusionner dans la mienne. Le problème est, je veux seulement une "partie" de l'un particulier d'engager, de plusieurs commits il a fait.

Quelle serait la méthode la plus efficace d'obtenir sélectionnez la quantité de changements, fusionnées dans ma fourche?

119voto

Tim Points 926

Après la pêche à la traîne par les vagues de l'IRC monde, quelqu'un a donné une excellente solution:

git cherry-pick SHA1 --no-commit
git add --patch

J'espère que ça aide quelqu'un d'autre avec la même question!

EDIT: OK, peut-être qu'il n'est pas tout à fait aussi simple que cela. Voici les étapes plein:

  1. Tout d'abord vous devez être dans votre référentiel, faire le nécessaire, cd-ing pour accéder à votre répertoire de travail.

  2. Vous devez maintenant ajouter la branche distante, puis aller le chercher. Pour ce faire:

    git remote add someUser git://github.com/someUser/someRepo.git

    git fetch someUser

  3. Vous pouvez maintenant exécuter des commandes comme git log someUser/master de trouver la validation SHA1 vous souhaitez fusionner dans 'partiellement'.

  4. Une fois que vous avez la SHA, vous pouvez exécuter:

    git cherry-pick -n SHA1

    SHA1 est le commit SHA, duh!

  5. Il y a très probablement des conflits, selon la façon dont les vieux de la validation et de la fréquence de ce secteur particulier de la modifications de projet. Désolé, mais vous avez à résoudre manuellement avec votre fidèle éditeur. Afin de sortir de VIM, ou ce que vous utilisez, et de bidouiller les conflits jusqu'à ce que vous arrivez à l'étape où vous aimez les changements.

  6. Maintenant, vous devez réinitialiser l'index à la TÊTE de révision, puis vous pouvez ensuite utiliser le fidèle, GIT add --patch de commande pour sélectionner et choisir quelles modifications vous souhaitez:

    git reset HEAD

    git add --patch ou git add -p

  7. Yay!!! Au moment de la validation:

    git commit -m "I merged a select amount of changes"

  8. Pour nettoyer le gâchis (Les trucs que vous a dit non à en git add --patch) et de ne garder que la sélection des modifications dans votre référentiel de travail, exécutez:

    git reset --hard HEAD

    Apparemment git checkout -f est une autre option.

3voto

Mike Dacre Points 28

J'aime vraiment Tim solution, mais parfois, j'aime bricoler dans vimdiff. Ma solution à ce problème est brut, mais cela fonctionne pour moi parce que j'aime vim.

J'ai vimdiff définir comme mon difftool, puis de manière sélective fusionner j'diff de la direction générale:

git difftool <branch> <file>

Ensuite, je vais à la fenêtre avec le courant de la direction générale de la version et de l'édition de l'original dans vim (parfois, ce n'est pas nécessaire, mais parfois vimdiff ouvre une version dans /tmp) et désactiver le mode lecture seule:

:e <file>
:set readonly!

Maintenant, je peux utiliser vim le patch d'outils tels que do et dp d'appliquer ce que je veux, et faire d'autres petites modifications que je vais. Quand je suis en fait, j'ai enregistrer le fichier, quitter vim, et puis la scène et de valider le fichier dans git comme un modifier.

Comme je l'ai dit, ce n'est pas particulièrement sophistiqué, mais il est très puissant, et encore uniquement dans la ligne de commande. Juste être sûr d'ajouter un clair message de commit, comme git de ne pas inclure automatiquement fusionner message pour vous.

vimdiff example

2voto

hgmnz Points 7239

Je ne comprends pas ce que tu veux. Si vous souhaitez importer uniquement certains commits d'autres fourchettes, vous pouvez utiliser git cherry-pick SHA . Explication complète sur gitready .

1voto

Bombe Points 34185

Si vous ne voulez que le port d'un commit, vous feriez probablement mieux de choisir le commit que vous souhaitez et de réinitialiser les fichiers que vous ne souhaitez pas toucher.

 git cherry-pick SHA1
git checkout HEAD file1 file2 ... fileN
 

Bien sûr, si vous avez plusieurs parties modifiées dans un fichier et que vous ne souhaitez en conserver que certaines, vous n'avez pas d'autre choix que de modifier le fichier manuellement, en supprimant leurs modifications.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X