2009-06-02 9 views
5

Nous avons une configuration SVN avec une ligne de réseau stable et une branche de développement instable. Le travail de développement est (principalement) effectué sur la branche puis fusionné au tronc avant le déploiement.Comment tromper git-svn pour reconnaître les fusions faites avec svn?

J'utilise git-svn comme mon client SVN. Mon processus de fusion de tronc instable est la suivante:

git svn fetch 
git co -b trunk svn/trunk 
git merge --no-ff svn/unstable 
git svn dcommit 

svn/* sont les branches SVN à distance.

Bien sûr, exige que personne ne commet quoi que ce soit au tronc avant que je suis fait, mais ce n'est pas un problème dans la pratique.

Les avantages de ce processus est que git enregistre maintenant les parents de la fusion engagent dans mon référentiel local. Cela ne profite pas à mes collègues, mais cela permet à git de calculer l'ancêtre commun quand I fait la fusion. C'est très souhaitable.

Et voici le frotter. Quand quelqu'un d'autre fait une fusion, git ne le sait pas. Voici un exemple:

o-...-A---o---C--- unstable 
/
X--...--B---o---o--- stable 

La branche instable a été créée au point X. Au point A, nous décidons de fusionner les changements de la branche instable dans la branche stable au point B. L'ancêtre commun est correctement X.

Étant donné que la fusion n'est pas enregistrée dans l'historique git, la fusion suivante en C suppose à nouveau que X est l'ancêtre commun. Je voudrais que ce soit A, comme dans le graphique suivant:

o-...-A---o---C--- unstable 
/  \ 
X---...---B---o---o--- stable 

Il n'est pas absolument nécessaire d'obtenir un graphique qui ressemble exacly comme celui sur la photo. N'importe quel graphique, qui reconnaîtrait A comme l'ancêtre commun, est parfait pour moi.

J'ai quelques options à l'esprit, comme une bonne utilisation de la branche filtre-git ou un « faux » commit qui est jamais dcommited à SVN. Cependant, aucune de mes tentatives n'a suffisamment fonctionné jusqu'à présent.

Je suis reconnaissant pour toutes les idées que vous pouvez présenter. La procédure ne doit pas nécessairement être automatique. Les fusions sont assez rares et je peux vivre avec la douleur de le faire "à la main".

Répondre

2

Une alternative supplémentaire serait d'utiliser le fichier Grafts, qui vous permet de remplacer les parents d'un commit sans réellement manipuler l'historique. Cela signifie qu'après avoir vu une fusion dans le référentiel SVN, il suffit d'ajouter une ligne à .git/info/greffes avec les SHA-1 de la validation de fusion (M) et ses parents (A, B).

 o-...-A---o---D--- unstable 
    /  
    X-----B---M---o---o--- stable 

A = 31423cd8a838f984547a908777308d846043cbda 
B = d99cfccb1f859a8f1dbfac95eec75227fe518b23 
M = 13319a54d3e3d61b501e7cc6474c46f37784aaa3 

Afin de créer le lien de AM, vous devez spécifier les parents de M comme B et A. Le format du fichier greffons est assez simple:

commit newparent1 ... newparentN 

Cela signifie que vous ajoutez ce qui suit (assez longue) ligne à vos greffes fichier:

13319a54d3e3d61b501e7cc6474c46f37784aaa3 d99cfccb1f859a8f1dbfac95eec75227fe518b23 31423cd8a838f984547a908777308d846043cbda 

Git va maintenant prétendre que cette fusion a effectivement eu lieu. Comme inconvénient, cela ne se propage pas via git push/fetch/clone, mais cela ne devrait pas être un problème majeur pour le développement personnel.

+0

Merci! C'est la première fois que j'ai entendu parler de greffes. Toujours bon d'apprendre plus. –

2

Votre problème est un peu comme SVN populating svnmergeinfo from git merges dans le sens inverse:
Vous ne voulez pas SVN pour enregistrer des fusions de Git, mais Git pour enregistrer les fusions depuis SVN;)

Depuis git-svn ne se soucie pas svnmergeinfo attribut lors de l'importation de SVN, qui laissent une option "opération manuelle".

Je ne recommanderais pas une solution git-filter-branch ou quoi que ce soit qui réécrit l'histoire du côté Git.
Si vous êtes au courant d'une fusion « A->B » sur SVN, vous devez faire fusionner sur Git ** dans une branche « fusion », puis fusionner retour dans la branche stable (fusion trivial à ce point), ainsi ajouter une nouvelle validation à votre historique stable actuel. Puis, une fusion de C vers stable doit avoir A comme ancêtre commun.

+0

droit! Donc, la clé est de faire _two_ commits intermédiaires, dont l'un se retrouve également dans SVN. Cela semble fonctionner au moins sur le papier. Merci pour l'information! Je me demande s'il est possible de presser ceci dans un alias git ... –

+0

Vous avez oublié de terminer votre "**" (gras) dans "... Git ** dans une branche" fusionner "..." –

0

Attention aux fichiers de greffe tu.

  1. Est-ce qu'ils ont tort et un gc git (après un certain temps) déposer des parties de l'histoire
  2. Si vous poussez vers un autre hôte, il ne saura pas des greffes et peut finir par l'histoire brisée.
Questions connexes