J'ai un référentiel Git qui contient un certain nombre de sous-répertoires. Maintenant, j'ai constaté que l'un des sous-répertoires n'est pas lié à l'autre et doit être détaché dans un référentiel séparé.
Comment puis-je faire cela tout en conservant l'historique des fichiers dans le sous-répertoire?
Je suppose que je pourrais faire un clone et supprimer les parties indésirables de chaque clone, mais je suppose que cela me donnerait l'arborescence complète lors de la vérification d'une ancienne révision, etc. Cela pourrait être acceptable, mais je préférerais pouvoir prétendre que le deux référentiels n'ont pas d'historique partagé.
Juste pour être clair, j'ai la structure suivante:
XYZ/
.git/
XY1/
ABC/
XY2/
Mais je voudrais plutôt ceci:
XYZ/
.git/
XY1/
XY2/
ABC/
.git/
ABC/
git filter-branch
voir ma réponse ci-dessous.Réponses:
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) le sous-répertoire dans un référentiel Git séparéVous souhaitez cloner votre référentiel, puis utiliser
git filter-branch
pour tout marquer, sauf le sous-répertoire que vous souhaitez dans votre nouveau référentiel pour être récupéré.Pour cloner votre référentiel local:
(Remarque: le référentiel sera cloné à l'aide de liens durs, mais ce n'est pas un problème car les fichiers liés durement ne seront pas modifiés en eux-mêmes - de nouveaux seront créés.)
Maintenant, préservons les branches intéressantes que nous voulons réécrire également, puis supprimons l'origine pour éviter d'y pousser et pour nous assurer que les anciens commits ne seront pas référencés par l'origine:
ou pour toutes les succursales distantes:
Maintenant, vous pouvez également supprimer les balises qui n'ont aucun rapport avec le sous-projet; vous pouvez également le faire plus tard, mais vous devrez peut-être à nouveau tailler votre repo. Je ne l'ai pas fait et j'ai obtenu un
WARNING: Ref 'refs/tags/v0.1' is unchanged
pour toutes les balises (car elles n'étaient pas toutes liées au sous-projet); en outre, après la suppression de ces balises, plus d'espace sera récupéré. Apparemmentgit filter-branch
, je devrais pouvoir réécrire d'autres balises, mais je n'ai pas pu le vérifier. Si vous souhaitez supprimer toutes les balises, utilisezgit tag -l | xargs git tag -d
.Utilisez ensuite filter-branch et reset pour exclure les autres fichiers, afin qu'ils puissent être élagués. Ajoutons également
--tag-name-filter cat --prune-empty
de supprimer les validations vides et de réécrire les balises (notez que cela devra supprimer leur signature):ou bien, pour réécrire uniquement la branche HEAD et ignorer les balises et autres branches:
Ensuite, supprimez les reflogs de sauvegarde afin que l'espace puisse être véritablement récupéré (bien que maintenant l'opération soit destructrice)
et maintenant vous avez un dépôt git local du sous-répertoire ABC avec toute son histoire préservée.
Remarque: Pour la plupart des utilisations,
git filter-branch
devrait en effet avoir le paramètre ajouté-- --all
. Oui c'est vraiment --space--all
. Ce doit être les derniers paramètres de la commande. Comme l'a découvert Matli, cela conserve les branches et les balises du projet incluses dans le nouveau référentiel.Edit: diverses suggestions de commentaires ci-dessous ont été incorporées pour s'assurer, par exemple, que le référentiel est réellement réduit (ce qui n'était pas toujours le cas auparavant).
la source
--no-hardlinks
? La suppression d'un lien physique n'affectera pas l'autre fichier. Les objets Git sont immuables aussi. Uniquement si vous souhaitez modifier les autorisations de propriétaire / fichier dont vous avez besoin--no-hardlinks
.filter-branch
est--prune-empty
de supprimer les validations maintenant vides.-- --all
. J'ai également courugit remote rm origin
, etgit tag -l | xargs git tag -d
avant lagit filter-branch
commande. Cela a réduit mon.git
répertoire de 60M à ~ 300K. Notez que j'avais besoin d'exécuter ces deux commandes pour obtenir la réduction de taille.The Easy Way ™
Il s'avère que c'est une pratique tellement courante et utile que les suzerains de Git ont rendu les choses vraiment faciles, mais vous devez avoir une version plus récente de Git (> = 1.7.11 mai 2012). Voir l' annexe pour savoir comment installer la dernière version de Git. En outre, il y a un exemple réel dans la procédure pas à pas ci-dessous.
Préparer l'ancien repo
Remarque: ne
<name-of-folder>
doit PAS contenir de caractères de début ou de fin. Par exemple, le dossier nommésubproject
DOIT être transmis en tant quesubproject
, PAS./subproject/
Remarque pour les utilisateurs de Windows: lorsque la profondeur de votre dossier est> 1, vous
<name-of-folder>
devez avoir un séparateur de dossier de style * nix (/). Par exemple, le dossier nommépath1\path2\subproject
DOIT être transmis commepath1/path2/subproject
Créer le nouveau référentiel
Liez le nouveau dépôt à GitHub ou n'importe où
Nettoyage à l'intérieur
<big-repo>
, si désiréRemarque : Cela laisse toutes les références historiques dans le référentiel.Voir l' annexe ci-dessous si vous êtes réellement inquiet d'avoir validé un mot de passe ou si vous devez réduire la taille du fichier de votre
.git
dossier....
Procédure pas à pas
Ce sont les mêmes étapes que ci - dessus , mais en suivant mes étapes exactes pour mon référentiel au lieu d'utiliser
<meta-named-things>
.Voici un projet que j'ai pour implémenter des modules de navigateur JavaScript dans le nœud:
Je souhaite diviser un dossier unique
btoa
en un référentiel Git séparéJ'ai maintenant une nouvelle branche,
btoa-only
qui n'a que des commitsbtoa
et je veux créer un nouveau dépôt.Ensuite, je crée un nouveau dépôt sur GitHub ou Bitbucket, ou autre chose et l'ajoute comme
origin
Bonne journée!
Remarque: Si vous avez créé un référentiel avec un
README.md
,.gitignore
etLICENSE
, vous devrez d'abord tirer:Enfin, je veux supprimer le dossier du plus grand dépôt
...
annexe
Dernier Git sur macOS
Pour obtenir la dernière version de Git en utilisant Homebrew :
Dernier Git sur Ubuntu
Si cela ne fonctionne pas (vous avez une très ancienne version d'Ubuntu), essayez
Si cela ne fonctionne toujours pas, essayez
Merci à rui.araujo des commentaires.
Effacer votre historique
Par défaut, la suppression de fichiers de Git ne les supprime pas réellement, il confirme simplement qu'ils ne sont plus là. Si vous souhaitez réellement supprimer les références historiques (c'est-à-dire que vous avez un mot de passe validé), vous devez le faire:
Après cela, vous pouvez vérifier que votre fichier ou dossier n'apparaît plus du tout dans l'historique Git
Cependant, vous ne pouvez pas "pousser" les suppressions vers GitHub et autres. Si vous essayez, vous obtiendrez une erreur et vous devrez le faire
git pull
avant de pouvoirgit push
- et vous reviendrez à tout avoir dans votre histoire.Donc, si vous souhaitez supprimer l'historique de "l'origine" - c'est-à-dire le supprimer de GitHub, Bitbucket, etc. - vous devrez supprimer le dépôt et repousser une copie élaguée du dépôt. Mais attendez - il y a plus ! - Si vous voulez vraiment vous débarrasser d'un mot de passe ou de quelque chose comme ça, vous devrez tailler la sauvegarde (voir ci-dessous).
Rendre
.git
plus petitLa commande de suppression de l'historique susmentionnée laisse toujours un tas de fichiers de sauvegarde - parce que Git est trop gentil pour vous aider à ne pas ruiner votre dépôt par accident. Il supprimera éventuellement les fichiers orphelins au fil des jours et des mois, mais il les laissera là pendant un certain temps au cas où vous réaliseriez que vous avez accidentellement supprimé quelque chose que vous ne vouliez pas.
Donc, si vous voulez vraiment vider la corbeille pour réduire la taille du clone d'un dépôt immédiatement, vous devez faire toutes ces choses vraiment étranges:
Cela dit, je vous recommande de ne pas effectuer ces étapes à moins que vous ne sachiez que vous devez - juste au cas où vous auriez élagué le mauvais sous-répertoire, vous savez? Les fichiers de sauvegarde ne doivent pas être clonés lorsque vous appuyez sur le dépôt, ils seront simplement dans votre copie locale.
Crédit
la source
git subtree
fait toujours partie du dossier «contrib» et n'est pas installé par défaut sur toutes les distributions. github.com/git/git/blob/master/contrib/subtreepopd
etpushd
rend cela plutôt implicite et plus difficile à comprendre ce qu'elle a l'intention de faire ...La réponse de Paul crée un nouveau référentiel contenant / ABC, mais ne supprime pas / ABC de / XYZ. La commande suivante supprimera / ABC de / XYZ:
Bien sûr, testez-le d'abord dans un référentiel «clone --no-hardlinks» et suivez-le avec les commandes Paul de reset, gc et prune.
la source
git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch ABC" --prune-empty HEAD
et ce sera beaucoup plus rapide. le filtre d'index fonctionne sur l'index tandis que le filtre d'arbre doit tout extraire et tout mettre en scène pour chaque commit .--index-filter
méthode, vous pouvez également le fairegit rm -q -r -f
, de sorte que chaque appel n'imprime pas de ligne pour chaque fichier qu'il supprime.J'ai constaté que pour supprimer correctement l'ancien historique du nouveau référentiel, vous devez faire un peu plus de travail après l'
filter-branch
étape.Faites le clone et le filtre:
Supprimez toutes les références à l'ancienne histoire. "Origin" gardait une trace de votre clone, et "original" est l'endroit où la branche de filtre enregistre les vieux trucs:
Même maintenant, votre historique peut être coincé dans un fichier pack que fsck ne touchera pas. Déchirez-le en lambeaux, créant un nouveau packfile et supprimant les objets inutilisés:
Il y a une explication à cela dans le manuel de la branche de filtre .
la source
git gc --aggressive --prune=now
qu'il manque quelque chose comme ça , non?git gc --aggressive --prune=now
réduit une grande partie du nouveau repoEdit: script Bash ajouté.
Les réponses données ici n'ont fonctionné que partiellement pour moi; Beaucoup de gros fichiers sont restés dans le cache. Ce qui a finalement fonctionné (après des heures en #git sur freenode):
Avec les solutions précédentes, la taille du référentiel était d'environ 100 Mo. Celui-ci l'a ramené à 1,7 Mo. Peut-être que cela aide quelqu'un :)
Le script bash suivant automatise la tâche:
la source
Ce n'est plus si complexe que vous pouvez simplement utiliser la commande git filter-branch sur un clone de votre référentiel pour éliminer les sous-répertoires que vous ne voulez pas, puis pousser vers la nouvelle télécommande.
la source
The result will contain that directory (and only that) as its project root.
et c'est ce que vous obtiendrez, c'est-à-dire que la structure du projet d'origine n'est pas conservée.Mise à jour : Le module git-subtree était si utile que l'équipe git l'a intégré dans le noyau et l'a créé
git subtree
. Voir ici: Détacher (déplacer) le sous-répertoire dans un référentiel Git séparégit-subtree peut être utile pour cela
http://github.com/apenwarr/git-subtree/blob/master/git-subtree.txt (obsolète)
http://psionides.jogger.pl/2010/02/04/sharing-code-between-projects-with-git-subtree/
la source
Voici une petite modification à CoolAJ86 de « The Easy Way ™ » réponse afin de diviser plusieurs sous - dossiers (disons
sub1
etsub2
) dans un nouveau dépôt git.The Easy Way ™ (plusieurs sous-dossiers)
Préparer l'ancien repo
Remarque: ne
<name-of-folder>
doit PAS contenir de caractères de début ou de fin. Par exemple, le dossier nommésubproject
DOIT être transmis en tant quesubproject
, PAS./subproject/
Remarque pour les utilisateurs de Windows: lorsque la profondeur de votre dossier est> 1, vous
<name-of-folder>
devez avoir un séparateur de dossier de style * nix (/). Par exemple, le dossier nommépath1\path2\subproject
DOIT être passé en tant quepath1/path2/subproject
. De plus n'utilisez pas demv
commande maismove
.Note finale: la différence unique et grande avec la réponse de base est la deuxième ligne du script "
git filter-branch...
"Créer le nouveau référentiel
Liez le nouveau dépôt à Github ou n'importe où
Nettoyage, si désiré
Remarque : Cela laisse toutes les références historiques dans le référentiel.Voir l' annexe dans la réponse d'origine si vous êtes réellement inquiet d'avoir validé un mot de passe ou si vous devez réduire la taille du fichier de votre
.git
dossier.la source
sub1
etsub2
dossiers n'existaient pas avec la version initiale, je devais modifier mon--tree-filter
script comme suit:"mkdir <name-of-folder>; if [ -d sub1 ]; then mv <sub1> <name-of-folder>/; fi"
. Pour la deuxièmefilter-branch
commande, j'ai remplacé <sub1> par <sub2>, omis la création de <name-of-folder>, et inclus-f
aprèsfilter-branch
pour remplacer l'avertissement d'une sauvegarde existante.La question d'origine veut que XYZ / ABC / (* fichiers) devienne ABC / ABC / (* fichiers). Après avoir implémenté la réponse acceptée pour mon propre code, j'ai remarqué qu'il change en fait XYZ / ABC / (* fichiers) en ABC / (* fichiers). La page de manuel filter-branch dit même:
En d'autres termes, il promeut le dossier de niveau supérieur "vers le haut" d'un niveau. C'est une distinction importante parce que, par exemple, dans mon histoire, j'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ù j'ai fait le renommage.
Ma réponse à la question est alors de faire 2 copies du référentiel et de supprimer manuellement le ou les dossiers que vous souhaitez conserver dans chacun. La page de manuel me soutient avec ceci:
la source
targetdir
ait été renommé à un moment donné et l'agit filter-branch
simplement appelé un jour, supprimant toutes les validations effectuées avant le renommage! Choquant, compte tenu de la capacité de Git à suivre de telles choses et même à migrer des morceaux de contenu individuels!git rm
prend plusieurs arguments, il n'y a donc aucune raison de l'exécuter pour chaque fichier / dossier:BYEBYE="dir/subdir2 dir2 file1 dir/file2"; git filter-branch -f --index-filter "git rm -q -r -f --cached --ignore-unmatch $BYEBYE" --prune-empty -- --all
Pour ajouter à la réponse de Paul , j'ai trouvé que pour récupérer de l'espace, je dois pousser HEAD vers un référentiel propre et qui réduit la taille du répertoire .git / objects / pack.
c'est à dire
Après le pruneau gc, faites également:
Ensuite, vous pouvez faire
et la taille de ABC / .git est réduite
En fait, certaines des étapes fastidieuses (par exemple git gc) ne sont pas nécessaires avec le push to clean repository, c'est-à-dire:
la source
La bonne façon est maintenant la suivante:
git filter-branch --prune-empty --subdirectory-filter FOLDER_NAME [first_branch] [another_branch]
GitHub a maintenant même un petit article sur de tels cas.
Mais assurez-vous de cloner votre dépôt d'origine dans un répertoire séparé en premier (car cela supprimerait tous les fichiers et autres répertoires et vous devrez probablement travailler avec eux).
Votre algorithme devrait donc être:
git filter-branch
uniquement des fichiers de gauche dans un sous-répertoire, pousser vers une nouvelle télécommandela source
Il semble que la plupart (toutes?) Des réponses ici reposent sur une certaine forme de
git filter-branch --subdirectory-filter
et ses semblables. Cela peut fonctionner "la plupart du temps" cependant pour certains cas, par exemple le cas où vous avez renommé le dossier, ex:Si vous effectuez un style de filtre git normal pour extraire "move_me_renamed", vous perdrez l'historique des modifications de fichiers survenues de l'arrière quand il était initialement move_this_dir ( ref ).
Il apparaît donc que la seule façon de vraiment garder tout l' historique des modifications (si le vôtre est un cas comme celui-ci), est, par essence, de copier le référentiel (créer un nouveau référentiel, définir cela comme étant l'origine), puis nuke tout le reste et renommez le sous-répertoire en parent comme ceci:
git branch -a
git checkout --track origin/branchABC
cp -r oldmultimod simple
cd simple
git rm otherModule1 other2 other3
git mv moduleSubdir1/* .
rmdir moduleSubdir1
git status
git remote set-url origin http://mygithost:8080/git/our-splitted-module-repo
git remote -v
git push
git checkout branch2
Cela suit le doc github "Fractionner un sous-dossier dans un nouveau référentiel" étapes 6-11 pour pousser le module vers un nouveau référentiel .
Cela ne vous permettra pas d'économiser de l'espace dans votre dossier .git, mais cela préservera tout votre historique des modifications pour ces fichiers, même à travers les renommages. Et cela ne vaut peut-être pas la peine s'il n'y a pas "beaucoup" d'histoire perdue, etc. Mais au moins, vous êtes assuré de ne pas perdre les commits plus anciens!
la source
Je recommande le guide de GitHub pour diviser les sous-dossiers en un nouveau référentiel . Les étapes sont similaires à la réponse de Paul , mais j'ai trouvé leurs instructions plus faciles à comprendre.
J'ai modifié les instructions afin qu'elles s'appliquent à un référentiel local, plutôt qu'à un hébergé sur GitHub.
la source
If you create a new clone of the repository, you won't lose any of your Git history or changes when you split a folder into a separate repository.
Pourtant, selon les commentaires sur toutes les réponses icifilter-branch
et lesubtree
script entraînent la perte de l'historique partout où un sous-répertoire a été renommé. Y a-t-il quelque chose qui puisse être fait pour résoudre ce problème?Lors de l'exécution
git filter-branch
avec une version plus récente degit
(2.22+
peut-être?), Il indique d'utiliser ce nouvel outil git-filter-repo . Cet outil m'a certainement simplifié les choses.Filtrage avec Filter-Repo
Commandes pour créer le
XYZ
référentiel à partir de la question d'origine:hypothèses: * le repo XYZ distant était nouveau et vide avant le push
Filtrage et déplacement
Dans mon cas, je voulais également déplacer quelques répertoires pour une structure plus cohérente. Au début, j'ai exécuté cette
filter-repo
commande simple, suivie pargit mv dir-to-rename
, mais j'ai trouvé que je pouvais obtenir un historique légèrement "meilleur" en utilisant l'--path-rename
option. Au lieu de voir la dernière modification des5 hours ago
fichiers déplacés dans le nouveau référentiel, je vois maintenantlast year
(dans l'interface utilisateur de GitHub), qui correspond aux heures modifiées dans le référentiel d'origine.Au lieu de...
J'ai finalement couru ...
Remarques:git filter-repo --subdirectory-filter dir-matching-new-repo-name
). Cette commande a correctement converti ce sous-répertoire à la racine du référentiel local copié, mais elle a également abouti à un historique des trois validations uniquement nécessaires pour créer le sous-répertoire. (Je n'avais pas réalisé que cela--path
pouvait être spécifié plusieurs fois; évitant ainsi la nécessité de créer un sous-répertoire dans le référentiel source.) Étant donné que quelqu'un s'était engagé dans le référentiel source au moment où j'ai remarqué que je n'avais pas réussi à poursuivre la histoire, j'ai juste utiliségit reset commit-before-subdir-move --hard
après laclone
commande, et ajouté--force
à lafilter-repo
commande pour le faire fonctionner sur le clone local légèrement modifié.git
, mais finalement j'ai cloné git-filter-repo et l'ai lié à$(git --exec-path)
:la source
filter-repo
outil (que j'ai présenté le mois dernier dans stackoverflow.com/a/58251653/6309 )git-filter-repo
devrait certainement être l'approche préférée à ce stade. C'est beaucoup, beaucoup plus rapide et plus sûr quegit-filter-branch
, et des protections contre de nombreux pièges que l'on peut rencontrer lors de la réécriture de l'historique de Git. J'espère que cette réponse attirera davantage l'attention, car c'est celle à laquelle il faut répondregit-filter-repo
.J'ai eu exactement ce problème mais toutes les solutions standard basées sur git filter-branch étaient extrêmement lentes. Si vous avez un petit dépôt, ce n'est peut-être pas un problème, c'était pour moi. J'ai écrit un autre programme de filtrage git basé sur libgit2 qui, dans un premier temps, crée des branches pour chaque filtrage du référentiel principal, puis les pousse à nettoyer les référentiels comme étape suivante. Sur mon référentiel (500 Mo 100 000 commits), les méthodes standard de filtrage de branche git ont pris des jours. Mon programme prend quelques minutes pour effectuer 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 que c'est utile à quelqu'un.
la source
Utilisez cette commande de filtre pour supprimer un sous-répertoire, tout en préservant vos balises et branches:
la source
Pour ce que ça vaut, voici comment utiliser GitHub sur une machine Windows. Supposons que vous ayez un dépôt cloné dans votre domicile
C:\dir1
. La structure du répertoire ressemble à ceci:C:\dir1\dir2\dir3
. ledir3
répertoire est celui que je veux être un nouveau référentiel séparé.Github:
MyTeam/mynewrepo
Invite bash:
$ cd c:/Dir1
$ git filter-branch --prune-empty --subdirectory-filter dir2/dir3 HEAD
Renvoyé:
Ref 'refs/heads/master' was rewritten
(fyi: dir2 / dir3 est sensible à la casse.)$ git remote add some_name [email protected]:MyTeam/mynewrepo.git
git remote add origin etc
. n'a pas fonctionné, est revenu "remote origin already exists
"$ git push --progress some_name master
la source
Comme je l'ai mentionné ci-dessus , j'ai dû utiliser la solution inverse (supprimer tous les commits ne touchant pas le mien
dir/subdir/targetdir
) qui semblait assez bien supprimer environ 95% des commits (comme souhaité). Il reste cependant deux petits problèmes.D'abord , a
filter-branch
fait un travail de suppression des commits qui introduisent ou modifient du code mais apparemment, les commits de fusion sont sous sa station dans le Gitiverse.C'est un problème cosmétique avec lequel je peux probablement vivre (dit-il ... reculer lentement les yeux détournés) .
DEUXIÈMEMENT, les quelques commits qui restent sont à peu près TOUS dupliqués! Il me semble avoir acquis une seconde chronologie redondante qui couvre à peu près toute l'histoire du projet. La chose intéressante (que vous pouvez voir sur l'image ci-dessous), c'est que mes trois succursales locales ne sont pas toutes sur la même chronologie (ce qui est certainement la raison pour laquelle elle existe et n'est pas seulement récupérée).
La seule chose que je peux imaginer est que l'une des validations supprimées était, peut-être, la validation de fusion unique qui a
filter-branch
effectivement été supprimée , et qui a créé la chronologie parallèle car chaque brin non fusionné a pris sa propre copie des validations. ( haussement d'épaules Où est mon TARDiS?) Je suis presque sûr de pouvoir résoudre ce problème, même si j'aimerais vraiment comprendre comment cela s'est produit.Dans le cas du mergefest-O-RAMA fou, je vais probablement laisser celui-là seul car il s'est si solidement ancré dans mon histoire de commit - me menaçant à chaque fois que je m'approche -, il ne semble pas vraiment causer tous les problèmes non cosmétiques et parce que c'est assez joli dans Tower.app.
la source
La manière la plus simple
git splits
. Je l'ai créé comme une extension git, basée sur la solution de jkeating .Fractionner les répertoires en 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
Créez un dépôt vide quelque part. Nous supposerons que nous avons créé un dépôt vide appelé
xyz
sur GitHub qui a un chemin:[email protected]:simpliwp/xyz.git
Poussez vers le nouveau dépôt.
#add a new remote origin for the empty repo so we can push to the empty repo on GitHub git remote add origin_xyz [email protected]:simpliwp/xyz.git #push the branch to the empty repo's master branch git push origin_xyz XYZ:master
Clonez le référentiel distant 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 [email protected]:simpliwp/xyz.git
la source
git splits
)Vous pourriez avoir besoin de quelque chose comme "git reflog expire --expire = now --all" avant le garbage collection pour réellement nettoyer les fichiers. git filter-branch supprime simplement les références dans l'historique, mais ne supprime pas les entrées reflog qui contiennent les données. Bien sûr, testez ceci en premier.
Mon utilisation du disque a chuté de façon spectaculaire, même si mes conditions initiales étaient quelque peu différentes. Peut-être que --subdirectory-filter annule ce besoin, mais j'en doute.
la source
Découvrez le projet git_split sur https://github.com/vangorra/git_split
Transformez les répertoires git en leurs propres référentiels dans leur propre emplacement. Aucune entreprise drôle de sous-arbre. Ce script prendra un répertoire existant dans votre référentiel git et transformera ce répertoire en un référentiel indépendant. En cours de route, il copiera tout l'historique des modifications du répertoire que vous avez fourni.
la source
Mettez ceci dans votre gitconfig:
la source
Je suis sûr que le sous-arbre git est très bien et merveilleux, mais mes sous-répertoires de code géré par git que je voulais déplacer étaient tous en éclipse. Donc, si vous utilisez egit, c'est extrêmement simple. Prenez le projet que vous souhaitez déplacer et équipe-> déconnectez-le, puis équipe-> partagez-le au nouvel emplacement. Par défaut, il tentera d'utiliser l'ancien emplacement du référentiel, mais vous pouvez décocher la sélection existante et choisir le nouvel emplacement pour le déplacer. Salut à tous.
la source
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 problèmes que j'ai rencontrés dans les étapes ci-dessus sont
Dans cette commande
git filter-branch --prune-empty --subdirectory-filter FOLDER-NAME BRANCH-NAME
L'BRANCH-NAME
est maîtresi la dernière étape échoue lors de la validation en raison d'un problème de protection, suivez - https://docs.gitlab.com/ee/user/project/protected_branches.html
la source
J'ai trouvé une solution assez simple, L'idée est de copier le référentiel puis de supprimer simplement la partie inutile. Voilà comment cela fonctionne:
1) Clonez un référentiel que vous souhaitez diviser
2) Déplacer vers le dossier git
2) Supprimez les dossiers inutiles et validez-le
3) Supprimer l'historique des formulaires de dossiers inutiles avec BFG
4) Vérifiez que l'historique ne contient pas les fichiers / dossiers que vous venez de supprimer
5) Vous avez maintenant un référentiel propre sans ABC, il vous suffit donc de le pousser vers une nouvelle origine
C'est ça. Vous pouvez répéter les étapes pour obtenir un autre référentiel,
supprimez simplement XY1, XY2 et renommez XYZ -> ABC à l'étape 3
la source