2017-01-23 2 views
10

Je vais essayer de rester bref.Comment puis-je fusionner des changements d'une branche qui contient un sous-ensemble de répertoires d'un autre?

Nous avons un référentiel git qui agit comme un miroir SVN (géré par BitBucket). Ce dépôt contient chaque projet dans la société depuis le début des temps et ayant chaque clone de développeur ce n'est pas une demande raisonnable (25 + 33GiB full clone et 15 + GiB shallow) Mais même alors, nous n'avons pas besoin d'un clone complet de l'ensemble du dépôt, juste un sous-ensemble des répertoires à l'intérieur. En utilisant git-subtree, j'ai réussi à séparer tous les répertoires d'intérêt et j'ai pensé que nous pourrions ajouter ces répertoires dans nos dépôts locaux en utilisant git-subtree add. Ce processus est transparent pour le dépôt svn. Cela fonctionne bien et la taille est beaucoup plus gérable (clone complet 9 + 6GiB et 8GiB peu profond). Le problème est que je ne sais pas comment nous pourrions prendre les changements que nous faisons dans ces "clones partiels" et les fusionner dans la branche principale. Je pensais que nous serions en mesure d'utiliser les demandes de tirage habituelles pour les entrer mais comme les arbres des branches sont différents, il ne se comporte pas comme je le voudrais (les répertoires manquants sont traités comme déménagements). Je veux juste fusionner les changements des répertoires clonés et laisser les autres intacts.

Je ne pense pas que l'utilisation d'une caisse clairsemée aiderait ici puisque nous aurions encore à cloner le repo complet pour le faire fonctionner ce qui est exactement ce que j'essaie d'éviter.

Y at-il une combinaison de commandes que je peux utiliser pour que tout cela fonctionne?


est ici (modifié) scripts que j'ai utilisé pour diviser les répertoires et à la caisse les répertoires d'intérêt:

split_projects.sh
je git-sous-arbre de diviser et de rejoindre les répertoires et git utilisés -réplace pour améliorer la vitesse de resplissage (pour traiter uniquement les nouveaux commits). Notez que le rejoin est pas commis au dépôt principal (je ne suis pas disposé à commettre cela surtout avec le miroir svn).

initial_setup.sh
Ceci est le script pour préparer le dépôt local. A utiliser par les utilisateurs de Windows, dont beaucoup n'ont pas beaucoup d'expérience avec les outils git ou en ligne de commande.

checkout_projects.sh
Le script de paiement actuel.

Il y en a une autre qui extrait les mises à jour des sous-répertoires séparés, mais je ne l'inclue pas ici.

+0

Qu'est-ce qui ne va pas avec les options subtree lors de la fusion? – jthill

+0

Je crois comprendre que l'utilisation de cette stratégie fusionne les branches où l'une est entièrement contenue dans l'autre. c'est-à-dire que la branche A est déjà une sous-arborescence de la branche B. Dans ma situation, la branche A contient un sous-ensemble des répertoires de la branche B et ne fonctionnerait pas. –

+0

Vous devrez peut-être joindre la liste de diffusion ([email protected]) pour obtenir de l'aide. Mon instinct, cependant, est qu'il n'y a peut-être pas de solution, puisque vous cherchez à appliquer les changements faits dans les sous-arbres au dépôt racine, et je ne peux pas imaginer comment cela serait possible sans informations sur les commits dans le root repo. Si vos développeurs utilisent Windows, le projet GVFS récemment ouvert peut être ce que vous cherchez. – Pockets

Répondre

2

dans votre cas, je crains que vous devez utiliser cerises choix pour déplacer les changements au référentiel d'origine

4

Si vous ne voulez pas certains changements refusionnés, faites votre fusion --no-commit et annuler les modifications dans le résultat de la fusion avant de valider. Pour les suppressions indésirables, juste git checkout la version que vous voulez. Pour les mecs de changement non désirés, git checkout --patch.

Une autre option, ce qui pourrait liquider plus simple si elle est vraiment plier juste sous-arbres toplevel manquants de la branche issue de la fusion, est de faire de la fusion et de la modifier par la suite, un (git ls-tree @; git ls-tree @^1|grep ^04)|sort -usk4 | git mktree va générer le bon arbre assez facilement,

fixup=`(git ls-tree @; git ls-tree @^1|grep ^04)|sort -usk4|git mktree` 

commit=`git show -s --pretty=%B @|git commit-tree -p @^1 -p @^2 $fixup` 

git update-ref -m 'fold in missing subdirectories' @ $commit 

après la fusion et vous avez terminé.

+0

Je pense que je pourrais être en mesure de mettre en place un script pour le faire. Probablement intégré avec les demandes de pull à une branche spéciale que je vais créer. –

+0

Cela semble réalisable. – jthill

+0

Je me dirigerai dans cette direction quand j'aurai plus de temps pour travailler dessus (c'est sur le backburner pour l'instant). Ce sera le plus proche que je puisse avoir avec ça. –

2

La meilleure solution que j'ai est pour vous d'exécuter ce qui suit dans une caisse clairsemée d'un clone peu profond du référentiel racine:

git checkout -b branch-to-PR-in 
git fetch remote-with-subtree-as-root 
git merge -s recursive -X theirs -X subtree=path/in/root/to/subtree/ remote-with-subtree-as-root/master --allow-unrelated-histories -X theirs 
2

Si je comprends vos scripts correctement:

intérieur bigrepo, un $project a son histoire sur branchesubdirs/$project, et son contenu dans le répertoire racine du repo
par exemple: si vous exécutez git checkout subdirs/$project dans bigrepo, le contenu des mensonges du projet dans / (pas dans un sous-répertoire supplémentaire).

Si tel est le cas:

Je pense qu'une séquence de git subdir push -P $project devrait fonctionner:

  • un de tout "repo local" à la prise en pension split
  • un de la prise en pension de scission au bigrepo
+0

Alors que cela pousserait vers les branches de séparation, je veux finalement les ramener à la branche maître. De cette façon, les changements des utilisateurs git reviennent au svn repo. –

+0

@JeffMercado: à partir des docs ('git help subtree') vous devriez être capable de pousser vers n'importe quelle branche que vous aimez. Sinon, vous pouvez construire votre arbre et le valider à la main, comme suggéré par @jthill. – LeGEC