Est-ce que git-svn dcommit après la fusion avec git est dangereux?

Ma motivation pour essayer gitsvn est la fusion et la ramification sans effort. Puis j’ai remarqué que l’homme git-svn (1) dit:

Lancer git-merge ou git-pull n’est PAS recommandé sur une twig à partir de laquelle vous envisagez de vous déconnecter. Subversion ne représente pas des fusions de manière raisonnable ou utile; Les utilisateurs utilisant Subversion ne peuvent donc voir aucune fusion effectuée. De plus, si vous fusionnez ou extrayez une twig git qui est un miroir d’une twig SVN, dcommit peut s’engager dans la mauvaise twig.

Est-ce que cela signifie que je ne peux pas créer une twig locale de svn / trunk (ou une twig), pirater, fusionner en svn / trunk, puis dcommit? Je crois comprendre que les utilisateurs de svn verront le même désordre qui a toujours été associé à svn pre 1.5.x, mais y a-t-il d’autres inconvénients? Cette dernière phrase m’inquiète aussi. Est-ce que les gens font régulièrement ce genre de choses?

En fait, j’ai trouvé un moyen encore meilleur avec l’option --no-ff sur git merge. Toute cette technique de squash utilisée auparavant n’est plus nécessaire.

Mon nouveau stream de travail est maintenant le suivant:

  • J’ai une twig “master” qui est la seule twig que je n’autorise pas et qui clone le repository SVN ( -s supposons que vous avez une disposition SVN standard dans le trunk/ du référentiel trunk/ , twigs/ , et tags/ ):

     git svn clone [-s]  
  • Je travaille sur une twig locale “work” ( -b crée la twig “work”)

     git checkout -b work 
  • engagez-vous localement dans la twig “work” ( -s pour signer votre message de validation). Dans la suite, je suppose que vous avez fait 3 commits locaux

     ... (work)$> git commit -s -m "msg 1" ... (work)$> git commit -s -m "msg 2" ... (work)$> git commit -s -m "msg 3" 

Maintenant, vous voulez vous engager sur le serveur SVN

  • [Eventuellement] ranger les modifications que vous ne voulez pas voir commises sur le serveur SVN (souvent vous avez commenté du code dans le fichier principal simplement parce que vous voulez accélérer la compilation et vous concentrer sur une fonctionnalité donnée)

     (work)$> git stash 
  • rebase la twig master avec le repository SVN (pour mettre à jour depuis le serveur SVN)

     (work)$> git checkout master (master)$> git svn rebase 
  • retourner à la twig de travail et rebaser avec le maître

     (master)$> git checkout work (work)$> git rebase master 
  • Assurez-vous que tout fonctionne bien, par exemple:

     (work)$> git log --graph --oneline --decorate 
  • Maintenant il est temps de fusionner les trois commits de la twig “work” en “master” en utilisant cette merveilleuse option --no-ff

     (work)$> git checkout master (master)$> git merge --no-ff work 
  • Vous pouvez noter le statut des journaux:

     (master)$> git log --graph --oneline --decorate * 56a779b (work, master) Merge branch 'work' |\ | * af6f7ae msg 3 | * 8750643 msg 2 | * 08464ae msg 1 |/ * 21e20fa (git-svn) last svn commit 
  • Maintenant, vous voudrez probablement modifier ( amend ) le dernier commit pour vos mecs SVN (sinon ils ne verront qu’un seul commit avec le message “Fusionner la twig”

     (master)$> git commit --amend 
  • Enfin, validez sur le serveur SVN

     (master)$> git svn dcommit 
  • Retournez au travail et récupérez éventuellement vos fichiers cachés:

     (master)$> git checkout work (work)$> git stash pop 

Créer des twigs locales est définitivement possible avec git-svn. Tant que vous n’utilisez que des twigs locales pour vous-même, et que vous n’essayez pas d’utiliser git pour fusionner entre les twigs svn en amont, vous devriez vous en sortir.

J’ai une twig “master” que j’utilise pour suivre le serveur svn. C’est la seule twig à laquelle je m’engage. Si je travaille, je crée une twig de sujet et travaille dessus. Quand je veux le commettre, je fais ce qui suit:

  1. Tout engager dans la twig thématique
  2. git svn rebase (résout les conflits entre votre travail et svn)
  3. git checkout master
  4. git svn rebase (ceci fait de la prochaine étape une fusion rapide, voir les commentaires d’Aaron ci-dessous)
  5. git merge topic_branch
  6. résoudre tous les conflits de fusion (il ne devrait y en avoir aucun à ce stade)
  7. git svn dcommit

J’ai aussi une autre situation où je dois maintenir des modifications locales (pour le débogage) qui ne devraient jamais être transmises à svn. Pour cela, j’ai la twig master ci-dessus mais aussi une twig appelée “work” où je travaille normalement. Les twigs de sujet sont dérivées du travail. Quand je veux y mettre du travail, je vérifie ma commande et utilise cherry-pick pour choisir les commits de la twig de travail que je veux engager pour svn. C’est parce que je veux éviter de commettre les trois commits de changements locaux. Ensuite, je me déconnecte de la twig principale et rebase tout.

Il est utile de git svn dcommit -n premier pour vous assurer que vous êtes sur le sharepoint valider exactement ce que vous avez l’intention de valider. Contrairement à git, la réécriture de l’historique dans svn est difficile!

Je pense qu’il doit y avoir une meilleure façon de fusionner le changement sur une twig de sujet en ignorant ces modifications de modification locales qu’en utilisant la sélection par cerise, donc si quelqu’un a des idées, il serait le bienvenu.

Solution simple: supprimer la twig ‘travail’ après la fusion

Réponse courte: Vous pouvez utiliser git comme bon vous semble (voir ci-dessous pour un workflow simple), y compris la fusion. Assurez-vous de suivre chaque « travail de fusion » avec « git branch-d work » pour supprimer la twig de travail temporaire.

Explication d’arrière-plan: Le problème de fusion / dcommit est que chaque fois que vous lancez svn dcommit ‘une twig, l’historique de fusion de cette twig est “aplati”: git oublie toutes les opérations de fusion qui sont entrées dans cette twig: mais le fait que ce contenu (partiellement) provient d’une autre twig spécifique est perdu. Voir: Pourquoi git svn dcommit perd l’historique des commits de fusion pour les twigs locales?

(Note: git-svn ne peut pas faire grand chose à ce sujet: svn ne comprend tout simplement pas les fusions git beaucoup plus puissantes. Donc, dans le repository svn, ces informations de fusion ne peuvent en aucun cas être représentées.)

Mais c’est tout le problème. Si vous supprimez la twig ‘work’ après sa fusion dans la twig ‘master’, alors votre repository git est 100% propre et ressemble exactement à votre repository svn.

Mon stream de travail: Bien sûr, j’ai d’abord cloné le référentiel svn distant dans un repository git local (cela peut prendre du temps):

 $> git svn clone   

Tout le travail se passe alors dans le “répertoire local”. Chaque fois que je dois obtenir des mises à jour du serveur (comme «svn update»), je fais:

 $> git checkout master $> git svn rebase 

Je fais tout mon travail de développement dans une twig séparée «travail» créée comme ceci:

 $> git checkout -b work 

Bien sûr, vous pouvez créer autant de twigs pour votre travail que vous le souhaitez et fusionner et réorganiser à votre guise (supprimez-les simplement lorsque vous en avez terminé – comme indiqué ci-dessous). Dans mon travail normal, je m’engage très fréquemment:

 $> git commit -am '-- finished a little piece of work' 

La prochaine étape (git rebase -i) est facultative — il suffit de nettoyer l’historique avant de l’archiver sur svn: une fois que j’ai atteint un mile stable que je veux partager avec d’autres, je réécris l’historique de ce travail. twigz et nettoyez les messages de validation (les autres développeurs n’ont pas besoin de voir toutes les petites étapes et les erreurs que j’ai faites sur le chemin — juste le résultat). Pour cela, je fais

 $> git log 

et copier le hachage sha-1 du dernier commit qui est actif dans le repository svn (comme indiqué par un git-svn-id). Alors j’appelle

 $> git rebase -i 74e4068360e34b2ccf0c5869703af458cde0cdcb 

Il suffit de coller le hash sha-1 de notre dernier svn commit à la place du mien. Vous pouvez lire la documentation avec ‘git help rebase’ pour plus de détails. En bref: cette commande ouvre tout d’abord un éditeur présentant vos commits – changez simplement “pick” en “squash” pour tous les commits que vous voulez écraser avec les commits précédents. Bien sûr, la première ligne devrait restr un «choix». De cette façon, vous pouvez condenser vos nombreux petits engagements en une ou plusieurs unités significatives. Enregistrez et quittez l’éditeur. Un autre éditeur vous demandera de réécrire les messages du journal de validation.

En bref: après avoir terminé le «piratage de code», je masse ma twig «travail» jusqu’à ce que je veuille la présenter aux autres programmeurs (ou comment je veux voir le travail dans quelques semaines lorsque je consulterai l’historique) .

Afin de pousser les modifications dans le repository svn, je fais:

 $> git checkout master $> git svn rebase 

Maintenant, nous sums de retour à l’ancienne twig ‘master’ mise à jour avec toutes les modifications qui se sont produites entre-temps dans le repository svn (vos nouvelles modifications sont cachées dans la twig ‘work’).

Si des modifications peuvent entrer en conflit avec vos nouvelles modifications apscopes au «travail», vous devez les résoudre localement avant de pouvoir utiliser votre nouveau travail (voir les détails ci-dessous). Ensuite, nous pouvons pousser nos modifications sur svn:

 $> git checkout master $> git merge work # (1) merge your 'work' into 'master' $> git branch -d work # (2) remove the work branch immediately after merging $> git svn dcommit # (3) push your changes to the svn repository 

Note 1: La commande ‘git branch -d work’ est assez sûre: elle vous permet uniquement de supprimer les twigs dont vous n’avez plus besoin (car elles sont déjà intégrées dans votre twig actuelle). Si vous exécutez cette commande par erreur avant de fusionner votre travail avec la twig ‘master’, vous obtenez un message d’erreur.

Note 2: Assurez-vous de supprimer votre twig avec ‘git branch -d work’ entre la fusion et dcommit: Si vous essayez de supprimer la twig après dcommit, vous obtenez un message d’erreur: lorsque vous faites ‘git svn dcommit’, git votre twig a été fusionnée avec «master». Vous devez le retirer avec «git branch-D work» qui ne fait pas le contrôle de sécurité.

Maintenant, je crée immédiatement une nouvelle twig «travail» pour éviter de pirater accidentellement la twig «maître»:

 $> git checkout -b work $> git branch # show my twigs: master * work 

Intégrer votre travail avec les modifications sur svn: Voici ce que je fais quand «git svn rebase» révèle que d’autres ont modifié le repository svn pendant que je travaillais sur ma twig «travail»:

 $> git checkout master $> git svn rebase # 'svn pull' changes $> git checkout work # go to my work $> git checkout -b integration # make a copy of the branch $> git merge master # integrate my changes with theirs $> ... check/fix/debug ... $> ... rewrite history with rebase -i if needed $> git checkout master # try again to push my changes $> git svn rebase # hopefully no further changes to merge $> git merge integration # (1) merge your work with theirs $> git branch -d work # (2) remove twigs that are merged $> git branch -d integration # (2) remove twigs that are merged $> git svn dcommit # (3) push your changes to the svn repository 

Des solutions plus puissantes existent: le workflow présenté est simpliste: il utilise les puissances de git uniquement dans chaque tour de ‘update / hack / dcommit’ — mais laisse l’historique de projet à long terme aussi linéaire que le référentiel svn. Ce n’est pas grave si vous voulez juste commencer à utiliser les fusions git dans les petites étapes initiales d’un projet svn hérité.

Lorsque vous vous familiarisez avec la fusion de git, n’hésitez pas à explorer d’autres workflows: Si vous savez ce que vous faites, vous pouvez mélanger les fusions git avec svn merges ( Utiliser git-svn (ou similaire) pour aider svn merge? )

Greg Hewgill répond que ce n’est pas sûr! Si de nouveaux commits apparaissent sur le tronc entre les deux “git svn rebase”, la fusion ne sera pas rapide.

Cela peut être assuré en utilisant l’option “–ff-only” sur git-merge, mais je ne lance généralement pas “git svn rebase” dans la twig, mais uniquement “git rebase master” (en supposant qu’il ne s’agit que d’un local twig). Ensuite, un “git merge thebranch” est garanti pour une avance rapide.

Un moyen sûr de fusionner des twigs svn dans git consiste à utiliser git merge –squash. Cela créera un seul commit et s’arrêtera pour vous permettre d’append un message.

Disons que vous avez une twig de sujet svn, appelée svn-branch.

 git svn fetch git checkout remotes/trunk -b big-merge git merge --squash svn-branch 

à ce stade, vous avez tous les changements de la twig svn-branchés dans un commit en attente dans l’index

 git commit 

Rebase la twig git locale sur la twig git principale puis dcommit et de cette façon, il semble que vous ayez fait tous ces commits en séquence, donc les utilisateurs de SVN peuvent le voir de manière linéaire. Donc, en supposant que vous avez une twig locale appelée sujet, vous pouvez faire

 git rebase master topic 

qui jouera ensuite vos commits sur la twig maître prête à vous rendre