Était-ce utile?

La solution

Mise à jour : Ce processus est si commun, que l'équipe git fait beaucoup plus simple avec un nouvel outil, git subtree. Voir ici: Détacher (déplacer) sous-répertoire dans le référentiel Git séparé


Vous voulez cloner votre dépôt et ensuite utiliser pour marquer tout git filter-branch mais le sous-répertoire que vous voulez dans votre nouveau repo à recueillir les déchets.

  1. Pour cloner votre référentiel local:

    git clone /XYZ /ABC
    

    (Note:. Le dépôt sera cloné en utilisant les liens physiques, mais qui ne sont pas un problème car les fichiers difficiles liés ne seront pas modifiés en eux-mêmes - de nouveaux seront créés)

  2. Maintenant, Conservons les branches intéressantes que nous voulons réécrire ainsi, puis retirez l'origine pour éviter de pousser là-bas et faire en sorte que les anciens commits ne seront pas référencés par l'origine:

    cd /ABC
    for i in branch1 br2 br3; do git branch -t $i origin/$i; done
    git remote rm origin
    

    ou pour toutes les branches à distance:

    cd /ABC
    for i in $(git branch -r | sed "s/.*origin\///"); do git branch -t $i origin/$i; done
    git remote rm origin
    
  3. Maintenant, vous pouvez également supprimer les balises qui ont aucun rapport avec le sous-projet; vous pouvez aussi le faire plus tard, mais vous devrez peut-être élaguer à nouveau votre pension. Je ne le faisais pas et a obtenu un pour tous les tags WARNING: Ref 'refs/tags/v0.1' is unchanged (car ils étaient tous sans rapport avec le sous-projet); En outre, après avoir retiré ces étiquettes plus d'espace seront remises en état. Apparemment, devrait être en mesure git tag -l | xargs git tag -d de réécrire d'autres balises, mais je ne pouvais pas vérifier. Si vous souhaitez supprimer tous les tags, utilisez --tag-name-filter cat --prune-empty.

  4. Ensuite, utilisez le filtre-branche et remis à zéro pour exclure les autres fichiers, afin qu'ils puissent être élagué. Ajoutons également supprimer commits -- --all vides et de réécrire les balises (notez que cela devra dépouiller leur signature):

    git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter ABC -- --all
    

    ou bien, de réécrire uniquement la branche de la tête et ne pas tenir compte des balises et d'autres branches:

    git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter ABC HEAD
    
  5. Ensuite, supprimez les reflogs de sauvegarde si l'espace peut être vraiment récupéré (bien que maintenant l'opération est destructive)

    git reset --hard
    git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
    git reflog expire --expire=now --all
    git gc --aggressive --prune=now
    

    et maintenant vous avez un dépôt git local du sous-répertoire ABC avec toute son histoire préservée.

Note: Pour la plupart des utilisations, en effet devrait avoir all le paramètre ajouté <=>. Oui, c'est vraiment - - Espace - - <=>. Cela doit être les derniers paramètres de la commande. Comme Matli a découvert, ce qui maintient les branches du projet et les balises incluses dans le nouveau repo.

Edit:. Diverses suggestions de commentaires ci-dessous ont été intégrés pour vous assurer, par exemple, que le dépôt est en fait diminué (ce qui n'a pas toujours été le cas avant)

Autres conseils

The Easy Way ™

Il se trouve que c'est une pratique courante et utile que les suzerains de git fait vraiment facile, mais vous devez avoir une version plus récente de git (> = 1.7.11 mai 2012). Voir annexe pour savoir comment installer la dernière git. En outre, il y a un par exemple dans le monde réel soluce ci-dessous.

  1. Préparer l'ancien repo

    pushd <big-repo>
    git subtree split -P <name-of-folder> -b <name-of-new-branch>
    popd
    

    Remarque: <name-of-folder> ne doivent pas contenir des caractères avant ou arrière. Par exemple, le dossier nommé DOIT être passé subproject comme ./subproject/, NOT path1\path2\subproject

    Remarque pour les utilisateurs de Windows: lorsque la profondeur du dossier est> 1, doit avoir * path1/path2/subproject séparateur de dossiers de style nix (/). Par exemple, le dossier nommé DOIT être passé .git comme <meta-named-things>

  2. Créer le nouveau repo

    mkdir <new-repo>
    pushd <new-repo>
    
    git init
    git pull </path/to/big-repo> <name-of-new-branch>
    
  3. Lier le nouveau repo à Github ou chaque fois que

    git remote add origin <git@github.com:my-user/new-repo.git>
    git push origin -u master
    
  4. Nettoyage, si on le souhaite

    popd # get out of <new-repo>
    pushd <big-repo>
    
    git rm -rf <name-of-folder>
    

    Remarque : Cela laisse toutes les références historiques dans le repository.See le ci-dessous si vous êtes réellement concernés Annexe d'avoir commis un mot de passe ou vous avez besoin pour diminuer la la taille du fichier de votre dossier btoa.

...

Walkthrough

Ce sont les mêmes étapes ci-dessus , mais après mes étapes exactes pour mon dépôt au lieu d'utiliser btoa-only.

Voici un projet que j'ai pour la mise en œuvre des modules de navigateur JavaScript dans le noeud:

tree ~/Code/node-browser-compat

node-browser-compat
├── ArrayBuffer
├── Audio
├── Blob
├── FormData
├── atob
├── btoa
├── location
└── navigator

Je veux diviser un seul dossier, origin, dans un dépôt git séparé

pushd ~/Code/node-browser-compat/
git subtree split -P btoa -b btoa-only
popd

J'ai maintenant une nouvelle branche, README.md, qui a seulement pour commits et je veux .gitignore créer un nouveau référentiel.

mkdir ~/Code/btoa/
pushd ~/Code/btoa/
git init
git pull ~/Code/node-browser-compat btoa-only

Ensuite, je crée un nouveau repo sur Github ou bitbucket, ou tout et ajoutez-le LICENSE (BTW, « origine » est juste une convention, ne fait pas partie de la commande - vous pouvez l'appeler « serveur distant » ou ce que vous voulez)

git remote add origin git@github.com:node-browser-compat/btoa.git
git push origin -u master

Happy day!

Remarque: Si vous avez créé une prise en pension avec un git pull, et git push <=>, vous devrez tirer d'abord:

git pull origin -u master
git push origin -u master

Enfin, je veux supprimer le dossier du plus grand repo

git rm -rf btoa

...

Annexe

Dernières git sur OS X

Pour obtenir la dernière version de git:

brew install git

Pour brasser pour OS X:

http://brew.sh

Dernières git sur Ubuntu

sudo apt-get update
sudo apt-get install git
git --version

Si cela ne fonctionne pas (vous avez une version très ancienne de ubuntu), essayez

sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git

Si cela ne fonctionne toujours pas, essayez

sudo chmod +x /usr/share/doc/git/contrib/subtree/git-subtree.sh
sudo ln -s \
/usr/share/doc/git/contrib/subtree/git-subtree.sh \
/usr/lib/git-core/git-subtree

Merci à rui.araujo des commentaires.

effacer votre historique

Par défaut la suppression des fichiers de git ne les supprime pas réellement de git, il engage juste qu'ils ne sont plus là. Si vous voulez réellement supprimer les références historiques (à savoir que vous avez un commis un mot de passe), vous devez faire ceci:

git filter-branch --prune-empty --tree-filter 'rm -rf <name-of-folder>' HEAD

Après cela, vous pouvez vérifier que votre fichier ou le dossier ne montre plus dans l'histoire git du tout

git log -- <name-of-folder> # should show nothing

Cependant, vous ne pouvez pas "pousser" supprime à github et similaires. Si vous essayez de vous obtiendrez une erreur et vous devrez avant de pouvoir <=> <=> -. Et vous êtes de retour à avoir tout dans votre histoire

Donc, si vous voulez supprimer l'historique de la « origine » - ce qui signifie pour le supprimer de GitHub, bitbucket, etc - vous devrez supprimer le repo et re-pousser une copie élagué du repo. Mais attendez - il y a plus ! -. Si vous êtes vraiment préoccupé de se débarrasser d'un mot de passe ou quelque chose comme ça, vous aurez besoin d'élaguer la sauvegarde (voir ci-dessous)

faire plus petits h2>

La commande Supprimer l'histoire ci-dessus laisse encore derrière un tas de fichiers de sauvegarde - parce que git est trop gentil pour vous aider à ne pas ruiner votre repo par accident. Il finira par supprimer des fichiers orphelins au cours des jours et des mois, mais il y laisse pendant un certain temps dans le cas où vous vous rendez compte que vous avez accidentellement supprimé quelque chose que vous ne vouliez pas.

Donc, si vous voulez vraiment vider la corbeille réduire la taille du clone d'unrepo immédiatement vous devez faire tout ce genre de choses vraiment bizarre:

rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune=now

git reflog expire --all --expire-unreachable=0
git repack -A -d
git prune

Cela dit, je vous recommande de ne pas effectuer ces étapes sauf si vous savez que vous devez - juste au cas où vous ne taillez le mauvais sous-répertoire, tu vois? Les fichiers de sauvegarde ne doivent pas se clonés lorsque vous appuyez sur le repo, ils seront juste dans votre copie locale.

Crédit

réponse de Paul crée un nouveau référentiel contenant / ABC, mais ne supprime pas / ABC de l'intérieur / XYZ. La commande suivante supprime / ABC de l'intérieur / XYZ:

git filter-branch --tree-filter "rm -rf ABC" --prune-empty HEAD

Bien sûr, le tester dans un «clone --no-référentiel de liens physiques d'abord, et de le suivre avec les commandes de réinitialisation, gc et pruneau liste Paul.

J'ai trouvé que pour supprimer correctement l'histoire ancienne du nouveau référentiel, vous devez faire un peu plus de travail après l'étape filter-branch.

  1. Faites le clone et le filtre:

    git clone --no-hardlinks foo bar; cd bar
    git filter-branch --subdirectory-filter subdir/you/want
    
  2. Supprimer toute référence à l'histoire ancienne. « Origine » a été suivi de votre clone, et « original » est l'endroit où le filtre branche enregistre les vieux trucs:

    git remote rm origin
    git update-ref -d refs/original/refs/heads/master
    git reflog expire --expire=now --all
    
  3. Même maintenant, votre histoire pourrait être coincé dans un packfile que fsck ne touche pas. Déchirer en lambeaux, créant ainsi une nouvelle packfile et de supprimer les objets non utilisés:

    git repack -ad
    

Il est une explication de cette dans le pour le filtre-branche .

Edit: script Bash ajouté

.

Les réponses ont travaillé ici que partiellement pour moi; Beaucoup de gros fichiers sont restés dans le cache. Ce qui a finalement travaillé (après les heures à #git sur freenode):

git clone --no-hardlinks file:///SOURCE /tmp/blubb
cd blubb
git filter-branch --subdirectory-filter ./PATH_TO_EXTRACT  --prune-empty --tag-name-filter cat -- --all
git clone file:///tmp/blubb/ /tmp/blooh
cd /tmp/blooh
git reflog expire --expire=now --all
git repack -ad
git gc --prune=now

Avec les solutions précédentes, la taille du référentiel était d'environ 100 MB. Celui-ci a apporté à 1,7 MB. Peut-être que cela aide quelqu'un:)


Le script bash suivant automatise la tâche:

!/bin/bash

if (( $# < 3 ))
then
    echo "Usage:   $0 </path/to/repo/> <directory/to/extract/> <newName>"
    echo
    echo "Example: $0 /Projects/42.git first/answer/ firstAnswer"
    exit 1
fi


clone=/tmp/${3}Clone
newN=/tmp/${3}

git clone --no-hardlinks file://$1 ${clone}
cd ${clone}

git filter-branch --subdirectory-filter $2  --prune-empty --tag-name-filter cat -- --all

git clone file://${clone} ${newN}
cd ${newN}

git reflog expire --expire=now --all
git repack -ad
git gc --prune=now

Ce ne l'est plus complexe, vous pouvez simplement utiliser le commande sur un clone de vous repo à abattre les sous-répertoires que vous ne voulez pas et pousser à la nouvelle télécommande.

git filter-branch --prune-empty --subdirectory-filter <YOUR_SUBDIR_TO_KEEP> master
git push <MY_NEW_REMOTE_URL> -f .

Mise à jour : Le module git-sous-arbre était si utile que l'équipe git tiré dans noyau et fait git subtree. Voir ici: Détacher (déplacer) sous-répertoire dans le référentiel Git séparé

git-sous-arbre peut être utile pour cette

http://github.com/apenwarr/git -subtree / blob / maître / git-subtree.txt (obsolète)

http: // psionides.jogger.pl/2010/02/04/sharing-code-between-projects-with-git-subtree/

Voici une petite modification CoolAJ86 's " The Easy Way ™ » répondre afin de diviser plusieurs sous-dossiers (disons et sub1 sub2) dans un nouveau dépôt git.

The Easy Way ™ (Multiple sous-dossiers)

  1. Préparer l'ancien repo

    pushd <big-repo>
    git filter-branch --tree-filter "mkdir <name-of-folder>; mv <sub1> <sub2> <name-of-folder>/" HEAD
    git subtree split -P <name-of-folder> -b <name-of-new-branch>
    popd
    

    Remarque: <name-of-folder> ne doivent pas contenir des caractères avant ou arrière. Par exemple, le dossier nommé DOIT être passé subproject comme ./subproject/, NOT path1\path2\subproject

    Remarque pour les utilisateurs de Windows: lorsque la profondeur du dossier est> 1, doit avoir * path1/path2/subproject séparateur de dossiers de style nix (/). Par exemple, le dossier nommé DOIT être passé mv comme move. De plus, ne pas utiliser la commande mais git filter-branch... .git.

    Note finale: la différence unique et grande avec la réponse de base est la deuxième ligne du script "<=>"

  2. Créer le nouveau repo

    mkdir <new-repo>
    pushd <new-repo>
    
    git init
    git pull </path/to/big-repo> <name-of-new-branch>
    
  3. Lier le nouveau repo à Github ou chaque fois que

    git remote add origin <git@github.com:my-user/new-repo.git>
    git push origin -u master
    
  4. Nettoyage, si on le souhaite

    popd # get out of <new-repo>
    pushd <big-repo>
    
    git rm -rf <name-of-folder>
    

    Remarque : Cela laisse toutes les références historiques dans le repository.See le si vous êtes réellement concernés Annexe dans la réponse originale d'avoir commis un mot de passe ou vous avez besoin à la diminution de la taille du fichier de votre dossier <=>.

La question initiale veut XYZ / ABC / (* fichiers) pour devenir ABC / ABC / (fichiers *). Après la mise en œuvre de la réponse acceptée pour mon propre code, j'ai remarqué que cela change réellement XYZ / ABC / (* fichiers) dans (fichiers *) ABC /. La page de manuel filter-branch dit même,

  

Le résultat contiendra ce répertoire (et seulement) comme racine du projet « .

En d'autres termes, il favorise le dossier haut niveau « haut » un niveau. C'est une distinction importante parce que, par exemple, dans mon histoire, je l'avais renommé un dossier de niveau supérieur. En faisant la promotion des dossiers « up » d'un niveau, git perd la continuité au commit où je l'ai fait le changement de nom.

J'ai perdu contiuity après filtre branche

Ma réponse à la question est alors de faire 2 copies du dépôt et supprimer manuellement le dossier (s) que vous souhaitez conserver dans chaque. La page de manuel me soutient avec ceci:

  

[...] éviter d'utiliser [cette commande] si un engagement simple, suffirait à résoudre votre problème

Pour ajouter réponse de Paul , je trouve que pour récupérer finalement l'espace, je dois pousser la tête d'un référentiel propre et que les garnitures sur la taille de la .git / objects / pack.

i.e..

$ mkdir ...ABC.git
$ cd ...ABC.git
$ git init --bare

Après la pruneau gc, faire aussi:

$ git push ...ABC.git HEAD

Ensuite, vous pouvez faire

$ git clone ...ABC.git

et la taille de ABC / .git est réduit

En fait, de temps en temps des étapes consommation (par exemple git gc) ne sont pas nécessaires avec la poussée pour nettoyer dépôt, i.e.:.

$ git clone --no-hardlinks /XYZ /ABC
$ git filter-branch --subdirectory-filter ABC HEAD
$ git reset --hard
$ git push ...ABC.git HEAD

Une bonne façon est maintenant le suivant:

git filter-branch --prune-empty --subdirectory-filter FOLDER_NAME [first_branch] [another_branch]

GitHub maintenant ont même petit article sur ces cas.

Mais assurez-vous de cloner votre repo d'origine dans le répertoire séparé premier (car il supprimerait tous les fichiers et d'autres répertoires et vous avez besoin probable de travailler avec eux).

Ainsi, votre algorithme doit être:

  1. cloner votre repo à distance dans un autre répertoire
  2. en utilisant uniquement les fichiers laissés git filter-branch sous un sous-répertoire, appuyez sur la nouvelle télécommande
  3. Que engager à supprimer ce sous-répertoire de votre repo à distance d'origine

Il semble que la plupart (tous?) Des réponses comptent ici sur une certaine forme de son acabit et git filter-branch --subdirectory-filter. Cela peut fonctionner « la plupart du temps » mais pour certains cas, par exemple le cas quand vous avez renommé le dossier, ex:

 ABC/
    /move_this_dir # did some work here, then renamed it to

ABC/
    /move_this_dir_renamed

Si vous faites un style de filtre git normale pour extraire « move_me_renamed » vous perdrez l'historique des changements de fichier qui a eu lieu du dos quand il a d'abord été move_this_dir ( ref ).

Il apparaît donc que la seule façon de vraiment garder tous l'histoire du changement (si le vôtre est un cas comme celui-ci), est, en substance, de copier le référentiel (créer un nouveau repo, définissez que être à l'origine), l'arme nucléaire alors tout le reste et renommer le sous-répertoire parent comme ceci:

  1. Clone localement le projet multi-module
  2. Branches - vérifier ce qui est là: git branch -a
  3. Faites une caisse pour chaque branche à inclure dans la division pour obtenir une copie locale sur votre poste de travail: git checkout --track origin/branchABC
  4. Faites une copie dans un nouveau répertoire: cp -r oldmultimod simple
  5. Allez dans la nouvelle copie du projet: cd simple
  6. Débarrassez-vous des autres modules qui ne sont pas nécessaires dans ce projet:
  7. git rm otherModule1 other2 other3
  8. Maintenant que le subdir du module cible reste
  9. Débarrassez-vous du module subdir de sorte que la racine du module devient la nouvelle racine du projet
  10. git mv moduleSubdir1/* .
  11. Supprimer la relique subdir: rmdir moduleSubdir1
  12. Vérifier les modifications à tout moment: git status
  13. Créer le nouveau git et copier son URL pour pointer ce projet en elle:
  14. git remote set-url origin http://mygithost:8080/git/our-splitted-module-repo
  15. Vérifiez ce qui est bon: git remote -v
  16. Appuyez sur les modifications à la prise en pension à distance: git push
  17. Aller à la prise en pension à distance et vérifiez qu'il est là tous
  18. Répéter pour toute autre branche nécessaire: git checkout branch2

le github doc " fractionnement d'un sous-dossier sur dans un nouveau dépôt " étapes 6-11 pour pousser le module à un nouveau repo.

Cela ne vous sauvera pas d'espace dans votre dossier .git, mais il conservera tout votre historique des modifications pour les fichiers même à travers renomme. Et cela peut ne pas être la peine s'il n'y a pas « beaucoup » de l'histoire perdue, etc. Mais au moins vous êtes assuré de ne pas perdre plus engage!

J'ai eu exactement ce problème, mais toutes les solutions standard basées sur git filtre branche est extrêmement lent. Si vous avez un petit dépôt, alors ce ne peut pas être un problème, il était pour moi. J'ai écrit un autre programme de filtrage git basé sur libgit2 qui, comme une première étape crée des branches pour chaque filtrage du dépôt primaire et pousse alors ceux-ci pour nettoyer les dépôts comme l'étape suivante. Sur mon dépôt (500Mo) 100000 commits les méthodes git filtre standard branche ont jours. Mon programme prend quelques minutes pour faire le même filtrage.

Il a le nom fabuleux de git_filter et vit ici:

https://github.com/slobobaby/git_filter

sur GitHub.

J'espère qu'il est utile à quelqu'un.

Pour ce que ça vaut la peine, voici comment l'utilisation GitHub sur une machine Windows. Disons que vous avez une prise en pension clonés résidant à C:\dir1. La structure du répertoire ressemble à ceci: C:\dir1\dir2\dir3. Le répertoire est celui dir3 je veux être un nouveau repo séparé.

Github:

  1. Créez votre nouveau référentiel: MyTeam/mynewrepo

Bash Invite:

  1. $ cd c:/Dir1
  2. $ git filter-branch --prune-empty --subdirectory-filter dir2/dir3 HEAD
    Renvoyée: Ref 'refs/heads/master' was rewritten (fyi. Dir2 / dos3 est sensible à la casse)

  3. $ git remote add some_name git@github.com:MyTeam/mynewrepo.git
    git remote add origin etc. ne fonctionnait pas, retourné "remote origin already exists"

  4. $ git push --progress some_name master

Comme je l'ai mentionné plus haut , je devais utiliser l'inverse solution (suppression ne touche pas tous les commits mon dir/subdir/targetdir) qui semblait fonctionner assez bien enlever environ 95% des commits (comme on le souhaite). Cependant, il y a deux petites questions en suspens.

FIRST , a fait un coup filter-branch up travail d'enlever commits qui introduisent ou modifient le code, mais apparemment, fusion commits sont sous sa station dans le Gitiverse.

Ceci est un problème esthétique que je peux probablement vivre avec (il dit ... reculant lentement en détournant les yeux) .

SECOND les quelques commits qui restent sont à peu près ALL en double! Il me semble avoir acquis une seconde, le calendrier redondant qui couvre à peu près toute l'histoire du projet. La chose intéressante (que vous pouvez voir sur la photo ci-dessous), est que mes trois branches locales ne sont pas tous sur la même ligne de temps (ce qui est, sans aucun doute pourquoi il existe et est non seulement les déchets collectés).

La seule chose que je peux imaginer que l'un des commits supprimés était, peut-être, la fusion unique commit que <=> en fait ne supprimer , et qui a créé la chronologie parallèle chaque maintenant unmerged volet a sa propre copie des commits. ( haussement Où est mon TARDIS?) Je suis sûr que je peux résoudre ce problème, mais je vraiment aime comprendre comment il est arrivé.

Dans le cas de fou mergefest-O-RAMA, je vais probablement quittais qu'une seule personne car elle a donc se fermement ancrée dans mon histoire commettre menaçant à moi chaque fois que je viens quasi, il ne semble pas être à l'origine en fait des problèmes non esthétiques et parce qu'il est tout à fait assez dans Tower.app.

Utilisez cette commande de filtre pour supprimer un sous-répertoire, tout en préservant vos balises et des branches:

git filter-branch --index-filter \
"git rm -r -f --cached --ignore-unmatch DIR" --prune-empty \
--tag-name-filter cat -- --all

La façon plus facile

  1. git splits. Je l'ai créé comme une extension git, basé sur la solution jkeating .
  2. Split les répertoires dans une branche locale #change into your repo's directory cd /path/to/repo #checkout the branch git checkout XYZ
    #split multiple directories into new branch XYZ git splits -b XYZ XY1 XY2

  3. Créer un vide quelque part repo. Nous supposons que nous avons créé un repo vide appelé sur GitHub qui xyz a chemin: git@github.com:simpliwp/xyz.git

  4. Appuyez sur la nouvelle prise en pension. #add a new remote origin for the empty repo so we can push to the empty repo on GitHub git remote add origin_xyz git@github.com:simpliwp/xyz.git #push the branch to the empty repo's master branch git push origin_xyz XYZ:master

  5. Cloner la prise en pension à distance nouvellement créé dans un nouveau répertoire local
    #change current directory out of the old repo cd /path/to/where/you/want/the/new/local/repo #clone the remote repo you just pushed to git clone git@github.com:simpliwp/xyz.git

Je recommande guide de GitHub à fendre les sous-dossiers dans un nouveau dépôt . Les étapes sont similaires à réponse de Paul , mais je trouve leurs instructions plus faciles à comprendre.

Je l'ai modifié les instructions afin qu'ils appliquent un dépôt local, au lieu d'un hébergé sur GitHub.


  

Fractionnement d'un sous-dossier sur en nouveau dépôt

     
      
  1. Ouvrir Git Bash.

  2.   
  3. Changer le répertoire de travail en cours à l'endroit où vous souhaitez créer votre nouveau référentiel.

  4.   
  5. Clonage du référentiel contenant le sous-dossier.

  6.   
     

git clone OLD-REPOSITORY-FOLDER NEW-REPOSITORY-FOLDER
     
      
  1. Changer le répertoire de travail en cours dans votre dépôt cloné.
  2.   
     

cd REPOSITORY-NAME
     
      
  1. Pour filtrer le sous-dossier du reste des fichiers dans le référentiel, exécutez git filter-branch, fournissant ces informations:      
        
    • FOLDER-NAME: Le dossier dans votre projet que vous souhaitez créer un dépôt séparé.      
          
      • Astuce:. Les utilisateurs de Windows doivent utiliser pour délimiter les dossiers /
      •   
    •   
    • BRANCH-NAME. La branche par défaut pour votre projet en cours, par exemple, ou master gh-pages
    •   
  2.   
     

git filter-branch --prune-empty --subdirectory-filter FOLDER-NAME  BRANCH-NAME 
# Filter the specified branch in your directory and remove empty commits
Rewrite 48dc599c80e20527ed902928085e7861e6b3cbe6 (89/89)
Ref 'refs/heads/BRANCH-NAME' was rewritten

Vous pourriez avoir besoin quelque chose comme « git reflog expire --expire Annule = maintenant --all » avant la collecte des ordures pour nettoyer effectivement les fichiers sur. git filtre branche supprime simplement les références dans l'histoire, mais ne supprime pas les entrées de reflog qui contiennent les données. Bien sûr, ce premier essai.

Mon utilisation du disque a chuté de façon spectaculaire en faisant cela, bien que mes conditions initiales étaient quelque peu différentes. Peut-être --subdirectory-filtre nie ce besoin, mais je doute.

Consultez projet git_split https://github.com/vangorra/git_split

Activer les répertoires git dans leurs propres référentiels dans leur propre emplacement. Pas de sous-arbre drôle d'affaires. Ce script prendra un répertoire existant dans votre dépôt git et transformer ce répertoire dans un dépôt indépendant de son propre. Sur le chemin, il copie sur toute l'histoire du changement pour le répertoire que vous avez fourni.

./git_split.sh <src_repo> <src_branch> <relative_dir_path> <dest_repo>
        src_repo  - The source repo to pull from.
        src_branch - The branch of the source repo to pull from. (usually master)
        relative_dir_path   - Relative path of the directory in the source repo to split.
        dest_repo - The repo to push to.

Mettre cela dans votre gitconfig:

reduce-to-subfolder = !sh -c 'git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter cookbooks/unicorn HEAD && git reset --hard && git for-each-ref refs/original/ | cut -f 2 | xargs -n 1 git update-ref -d && git reflog expire --expire=now --all && git gc --aggressive --prune=now && git remote rm origin'

Je suis sous-arbre git sûr est tout beau et merveilleux, mais mes sous-répertoires de code managé git que je voulais aller était tout éclipsée. Donc, si vous utilisez egit, il est douloureusement facile. Prenez le projet que vous souhaitez déplacer et d'équipe> Se déconnecter, puis en équipe> partager au nouvel emplacement. Il sera par défaut d'essayer d'utiliser l'ancien emplacement des prises en pension, mais vous pouvez décocher la sélection de l'utilisation existante et choisir le nouveau lieu pour le déplacer. Tous egit de grêle.

J'ai trouvé la solution avant tout droit, L'idée est de copier référentiel, puis retirer une partie seulement inutile. Voici comment cela fonctionne:

1) Cloner un dépôt que vous souhaitez diviser

git clone git@git.thehost.io:testrepo/test.git

2) Déplacer vers un dossier git

cd test/

2) Supprimer les dossiers inutiles et commettre

rm -r ABC/
git add .
enter code here
git commit -m 'Remove ABC'

3) Supprimer l'historique de forme de dossier inutile (s) avec BFG

cd ..
java -jar bfg.jar --delete-folders "{ABC}" test
cd test/
git reflog expire --expire=now --all && git gc --prune=now --aggressive
  

pour les dossiers se multiplient, vous pouvez utiliser des virgules

java -jar bfg.jar --delete-folders "{ABC1,ABC2}" metric.git

4) Vérifiez que l'histoire ne contient pas les fichiers / dossiers que vous venez de supprimer

git log --diff-filter=D --summary | grep delete

5) Vous avez maintenant référentiel propre sans ABC, si juste le pousser dans une nouvelle origine

remote add origin git@github.com:username/new_repo
git push -u origin master

Voilà. Vous pouvez répéter les étapes pour obtenir un autre dépôt,

il suffit de retirer XY1, XY2 et renommer XYZ -> ABC à l'étape 3

Vous pouvez facilement essayer https://help.github.com/enterprise/2.15/user/articles/splitting-a-subfolder-out-into-a-new-repository/

Cela a fonctionné pour moi. Les questions que j'ai rencontrés dans les étapes indiquées ci-dessus sont

  1. dans cette commande git filter-branch --prune-empty --subdirectory-filter FOLDER-NAME BRANCH-NAME Le BRANCH-NAME est maître

  2. si la dernière étape échoue lors de la validation du fait de suivi de problème de protection - https://docs.gitlab.com/ee/user/project/protected_branches.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top