2010-06-24 7 views
2

J'ai le problème suivant: Nous avons un grand produit qui est dans la branche maître. Nous avons aussi d'autres branches qui ont seulement quelques fichiers, les fichiers qui sont spécifiques à cette branche seulement. Chacune de ces branches représente un plugin au produit principal. Ainsi par exemple quand vous obtenez le produit principal, vous recevez beaucoup de fichiers, les installez, etc. et plus tard quand vous décidez d'obtenir un plugin, vous recevez un paquet contenant seulement plusieurs fichiers et en téléchargeant ces fichiers (et en remplaçant les originaux) vous obtenez le plugin installé.Git: comment fusionner les fichiers modifiés seulement

J'ai un paiement.php dans la branche principale (ainsi que de nombreux autres fichiers). Et j'ai la branche paypal qui a un seul fichier qui est payment.php. Maintenant, je corrige un bug dans le fichier payment.php de master et je veux fusionner ce correctif dans la branche paypal. Cependant quand je cours la fusion, absolument tous les dossiers sont ajoutés à cette branche. Donc, à la fin, la branche paypal a tous les fichiers de la branche maître. Avez-vous par hasard savoir comment cela peut être réparé? Je veux que GIT fusionne uniquement les fichiers qui existent dans cette branche, donc dans l'exemple ci-dessus la branche paypal devrait toujours avoir un seul fichier (payment.php) avec le correctif de bogue fusionné.

+0

Comme d'autres disent, vous ne voulez probablement pas avoir une branche qui manque tous les fichiers. Si vous souhaitez vraiment suivre le plugin séparément, il doit s'agir d'un référentiel distinct, éventuellement inclus en tant que sous-module dans le projet principal. Si vous ne voulez pas qu'il soit séparé, alors bien sûr, il peut avoir sa propre branche de développement, mais en tant que branche du référentiel du projet, cette branche doit contenir le projet entier, pas seulement un plugin. – Cascabel

Répondre

4

C'est pourquoi il est important de gérez bien vos agences, en particulier pour utiliser des branches thématiques et fusionner vers le haut.

Vous devez faire ce correctif sur une branche de sujet, fourchue d'un ancêtre commun de toutes les branches qui ont besoin de la solution, puis fusionner à la fois maître et paypal:

x - x - x - x ------------- X (master) 
|\       | 
| x - x - x ---- X (paypal) | 
\   /  /
    x (bugfix) --------------- 

Si vous avez déjà fait votre bugfix, et vous tort fait sur maître au lieu de partir de la base de fusion appropriée, et l'histoire sur le maître n'a pas été publié, vous devriez écrémer ou rebasage au bon endroit:

# If the bugfix commit is not at the tip of master, you can rebase to get it there: 
git rebase -i <commit before the bugfix> master 
# rearrange the list of commits to put the bugfix at the tip, save and quit 

# Now either cherry-pick or rebase the commit to the right place 
# (rebase is easier if the bugfix is actually several commits) 

# Cherry-pick 
# make a branch and cherry-pick 
git checkout -b bugfix <SHA1 of merge base> 
git cherry-pick <SHA1 of bugfix> 
# remove the commit from master, assuming it's still on the tip 
git checkout master 
git reset --hard master^ 

# or rebase 
# make the bugfix branch (assuming it's still on the tip) 
git branch bugfix master 
# and remove the commit from master (assuming it's still on the tip) 
git checkout master 
git reset --hard master^ # or if the bugfix is composed of n commits, master~n 
# rebase the bugfix branch to the right place 
git rebase --onto <SHA1 of merge base> master bugfix 

Si l'histoire a été publiés, tout ce que vous pouvez faire est de choisir la cerise sur la branche bugfix paypal, et rappelez-vous de le faire dès la prochaine fois:

git checkout paypal 
git cherry-pick <SHA1 of bugfix> 
+0

Salut, je pensais avoir la branche paypal et fusionner le maître de temps en temps. Donc, quand j'ai besoin de nouvelles fonctionnalités ou de bugs corrigés, je le ferai dans les fichiers master et avant la sortie, je fusionnerai les changements dans la branche paypal (pour que le paypal puisse avoir les nouvelles corrections et fonctionnalités). Je suis assez nouveau dans ce domaine, alors corrigez-moi si je ne vois pas de problèmes cachés. Plus tôt, j'ai fait ce travail manuellement. Donc, je mettais en œuvre la nouvelle fonctionnalité dans le maître, puis manuellement la copie des morceaux de code à la branche paypal. – Eugene

+0

Dans l'exemple ci-dessus, les deux branches semblent être très différentes (toutes les validations après point de branchement) alors que mes branches ont généralement une seule différence (fonctionnalité paypal par exemple). Tout le reste est le même et le travail principal est de garder les nouvelles modifications de code vont toujours dans les deux branches. Bien sûr, j'ai parfois un correctif spécifique pour la branche paypal mais c'est plutôt rare car ce code est bien testé à ce moment là. – Eugene

+0

@Eugene: Je ne suis pas vraiment sûr de ce que vous essayez de demander dans ces commentaires. Quoi qu'il en soit, vous pouvez toujours faire les modifications à partir du bon point de la branche, puis les fusionner dans toutes les branches qui en ont besoin. Peu importe à quel point ces branches sont différentes, tant que votre patch s'applique toujours ... – Cascabel

1

Pourquoi pas vos autres branches contiennent tous les fichiers qui font partie de la branche maîtresse? Vous êtes en train de vous compliquer la tâche en supprimant tous les autres fichiers. Surtout si vous avez plus tard besoin de changer un autre fichier que vous avez déjà supprimé.

0

Vous pouvez faire quelque chose de similaire à ceci: http://nvie.com/git-model

(J'espère que cela fonctionne)

master continuera à être votre branche principale. Vous créez un deuxième maître de branche appelé bugfix. Vous créez une troisième branche hors de correction de bug appelée plugin-foo.

Dans plugin-foo vous supprimez tous les fichiers qui ne sont pas nécessaires. Maintenant, chaque fois que vous apportez une modification aux fichiers qui ne sont pas dans la branche du plugin, vous effectuez ceux-ci sur la branche master. Toutes les corrections de bugs vont dans la branche bugfix. Vous fusionnez périodiquement la branche bugfix dans les branches master et plugin. Ce qui conduit à des corrections de bogues dans ces deux branches.

1

Vous vous trompez. Vous êtes censé avoir tous les fichiers dans la branche.

C'est le travail de Git de garder une trace des fichiers qui diffèrent entre les branches, pas les vôtres. C'est en quelque sorte l'un des points d'utilisation d'un VCS.

Si vous souhaitez distribuer uniquement les fichiers qui diffèrent entre les branches, ceux-ci peuvent facilement être extraits par un script.

+1

Salut, merci pour votre réponse. Je teste cette solution au moment présent et je l'utiliserai très probablement. – Eugene

0

Isoler vos plugins dans leur propre repo git vous permet de les faire évoluer indépendamment sur un projet parent.

Si, cependant, vous devez les directement inclus dans votre projet, les versions récentes de Git (git1.7.11, Juin 2012), comprend le git subtree script (anciennement developed on GitHub par apenwarr, maintenant fusionné dans git ligne principale)

De cette façon , vous pouvez fusionner un référentiel (et son historique) dans un autre, en gardant l'option d'extraire son historique plus tard (par opposition à la fusion de sous-arborescence).
Cela pourrait être considéré comme une alternative aux sous-modules git.

Une autre alternative est git slave, pour maintenir les parents et les sous-modules étroitement synchronisés.