Question Git-svn fusionne deux branches SVN


J'ai lu de nombreuses questions et blogs SO git-svn et fusion. Certains d'entre eux (notamment git-svn page de manuel) avertit contre en utilisant la fusion n'importe où près de la branche, je prévois de dcommit de.

D'autres comme ça SO réponse, déclarez que la fusion est correcte tant que j'utilise unique fonctionnalités branches que je supprime avant dcommitting.

J'ai une configuration avec deux branches SVN (et git) de longue durée:

  • tronc (git-svn: svn/trunk, git: master) - la branche stable
  • branches / devel (git-svn: svn/devel, git: devel) - la principale branche de développement à partir de laquelle je décompose des branches (et je peux vivre avec leur rebasage). devel au lieu de fusionner).

Snapshot of current state in Source Tree

Dans l'image ci-dessus, (1) montre l'histoire passée de SVN, où branches/devel a été fusionné dans trunk.

(2) montre que j'ai réussi dcommitted mon développement actuel dans SVN.

La question: puis-je utiliser git-svn fusionner deux branches SVN pour que l'historique montre le point de fusion (comme le fait SVN lui-même)? En d'autres termes: que se passe-t-il si je devais dcommit de master comme représenté sur la (3)?

Est-ce que ça va gâcher mon histoire SVN (ou git)? Ou est-ce que tout simplement oublier que devel a été fusionné dans master du tout?

MODIFIER: Si git oublie juste que devel a été fusionné dans master, y a-t-il une différence entre dcommiting du point (3) et en appliquant tous les commits en un seul pièce?


16
2018-04-18 08:33


origine


Réponses:


En creusant un peu plus sur la question, j'ai découvert que git prend en charge la configuration svn:mergeinfo propriété sur la branche SVN lorsque dcommit'ing:

git svn dcommit --mergeinfo "/branches/somebranch:1-3"

NB! la svn:mergeinfo est écrasé avec tout ce qui est donné sur la ligne de commande, alors faites attention à la liste fusion précédente aussi.

Alors que la version plus récente de git a ajouté le paramètre config pour définir automatiquement cette propriété:

config key: svn.pushmergeinfo

J'ai eu quelques problèmes avec la fusion automatique des informations - pour une raison ou une autre, le GIT l'a mal calculé et je ne pouvais pas le faire fonctionner.

SOLUTION: git-merge-svn

Pour automatiser le processus, j'ai écrit un script shell git-merge-svn qui peut être utilisé pour fusionner deux branches SVN avec correct svn:mergeinfo mis sur le dcommit.

Le script gère les deux situations:

  • la branche n'est pas fusionnée dans git - fera l'affaire git merge préalablement
  • les branches ont déjà été fusionnées dans git (mais pas dans SVN) - elles traverseront jusqu'à l'ancêtre précédent pour les révisions de validation fusionnées.

Avec ce script, j'ai été en mesure de produire ces fusions uniquement sur un côté et de conserver les informations de fusion pour que le graphique de GIT montre bien le journal:

git-merge-svn result

Exemple d'utilisation:

  1. Faites des engagements sur devel6
  2. dcommit  devel6 à SVN (Champs obligatoires obtenir les numéros de révision SVN pour les commits)
  3. check-out testtunk6 - oui, je sais que j'ai fait une faute de frappe dans le nom ;-)
  4. git merge-svn devel6

Les dernières sorties:

% git merge-svn devel6
About to do an SVN merge: devel6 -> testtunk6

* NEW MERGE COMMIT
|\
| * devel6 [7b71187] (r102)
* | testtunk6 [0682a45] (r101)
 \|
  * [273d6d6] (r100)


STEP 1: GIT merge
Executing:
  git merge devel6

Continue? (y/n) [n]: y
Merge made by the 'recursive' strategy.
 testfile | 1 +
 1 file changed, 1 insertion(+)

STEP 2: SVN dcommit

executing:
git svn dcommit --mergeinfo
/idp/branches/devel:9-32,35-41 /idp/branches/devel6:89 /idp/branches/devel6:94 /idp/branches/devel6:93 /idp/branches/devel6:96 /idp/branches/devel6:97 /idp/branches/devel6:99 /idp/branches/devel6:100 /idp/branches/devel6:102

Continue? (y/n) [n]: y
Committing to https://my.svn.host/svn/auth/idp/branches/testtunk6 ...
  M testfile
Committed r103
  M testfile
Found merge parent (svn:mergeinfo prop): 7b71187fc371d3f86658c5850009e63be88157ac
r103 = 87759323cbadd38bac78087d57b6870a926287e7 (refs/remotes/svn/testtunk6)
No changes between 3fb2168cfbbe605fbd810d76513443203a85a549 and refs/remotes/svn/testtunk6
Resetting to the latest refs/remotes/svn/testtunk6

14
2018-04-23 09:20



Git et Svn ont une structure de données différente pour garder un historique.

Svn utilise un arbre simple. C'est à dire. chaque commit n'a qu'un seul parent, mais un commit peut avoir plusieurs enfants (branches). Donc, Svn ne supporte pas les fusions. La chose qu'ils appellent "fusion" est en fait le portage des modifications, l'analogie la plus proche de git est rebase ou peut-être cherry-pick. A partir de la version 1.5, Svn prend en charge une propriété metainfo svn:mergeinfo ce qui aide en quelque sorte à suivre ce qui a été "fusionné", mais cela semble surtout être une solution de contournement, ce qui explique pourquoi les branches dans Svn sont si difficiles à utiliser. Le point de fusion est un commit qui écrase tous les changeset et la résolution de conflit fusionnés en un seul ensemble de modifications, probablement annoté avec le svn:mergeinfo propriété.

Git utilise Graphe acyclique dirigé ce qui est une manière très naturelle de décrire la fusion et la ramification de l’histoire. Un point de fusion est juste un autre engagement avec deux (ou plus!) Parents. Donc, votre (3) sur l'image est un commit de fusion. Ainsi, toute l’histoire semble naturelle, toutes les commits sont accessibles sur un graphe d’historique à partir du point actuel.

Le pont Git-Svn essaie de faire de son mieux pour gérer les inconvénients de la conception Svn, avant de le faire dcommit il renverse généralement tous les commits fusionnés au sommet de la branche Svn actuelle. Asof ~ il y a 2 ans, git-svn n'a pas pu fournir svn:mergeinfo, alors la chose que vous demandez est impossible. De plus, quand tu es dcommitDans ce cas, git crée un commit "twin" lié à un commit svn, donc il réécrit le commit original.


4
2018-04-18 20:49