2011-09-12 3 views
13

Je sépare un référentiel Git en utilisant l'option --subdirectory-filter de filter-branch qui fonctionne très bien, sauf qu'il ramène tout à la racine du référentiel.Filtre de sous-répertoire Git avec la structure de répertoire existante

J'ai actuellement

ABC 
    - DEF 
     - GHI 
     - JKL 
    - MNO 

Et le résultat de cette commande:

git filter-branch -f --subdirectory-filter ABC/DEF --prune-empty -- --all 

Génère ceci:

GHI 
JKL 

Où ce que je veux vraiment est la suivante:

ABC 
    - DEF 
     - GHI 
     - JKL 

Je ne vois rien dans les documents Git qui montre une option de filtre qui préserve (ou définit) la structure du répertoire et je n'ai pas pu trouver une commande que je peux exécuter après le filtrage pour remapper la structure à la façon dont je le veux.

Est-ce possible?

Répondre

3

Je trouve une réponse here qui fait l'affaire.

La commande:

git filter-branch -f --index-filter 'git ls-files -s \ 
| sed "s-\t-&ABC/DEF/-" \ 
| GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info \ 
&& mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' 

fonctionne parfaitement

+1

parfaitement pour moi aussi. Merci de l'avoir posté. Je devrais ajouter que cette commande ne remplace pas la commande '--subdirectory-filter'; vous l'exécutez toujours. Cette commande remplace la commande 'git mv * ...' que d'autres documents recommandent. Mais sans le commit massif moche le 'git mv' aurait généré. –

+0

Malheureusement, cela ne fonctionne pas pour moi. Je suis sur Windows exécutant git-bash, et il échoue en disant qu'il ne peut pas trouver index.new ($ GIT_INDEX_FILE.new). J'aimerais pouvoir utiliser cette solution. –

+0

@BerinLoritsch $ GIT_INDEX_FILE est une variable d'environnement que la plupart des outils que j'ai utilisés pour vous; MsysGit et CygWin avec plusieurs git bash pour Windows alternatives. Quelle est votre configuration exacte? – JRoughan

1

Je n'ai donné ce test rapide moi-même, mais je pense que vous pouvez utiliser avec git filter-branch--tree-filter pour réécrire la branche, mais en supprimant tous les fichiers en dehors de ceux dans le sous-répertoire ABC/DEF, avec quelque chose comme ce qui suit:

git filter-branch --tree-filter \ 
    'find . -path ./ABC/DEF -prune -o -type f -print0 | xargs -0 rm -f' \ 
    --prune-empty HEAD 

Notez que la commande find supprime uniquement les fichiers, pas les répertoires, mais puisque git ne stocke pas les répertoires vides, cela devrait toujours produire le résultat souhaité.

+0

Merci pour cela. Avec la taille de ce dépôt j'ai vraiment besoin de quelque chose qui fonctionne sur l'index (filtre d'index plutôt que filtre d'arbre). Votre réponse est certainement sur la bonne voie, mais aurait été très lente dans ma situation. J'ai trouvé une réponse mais je ne suis pas sûr de l'étiquette d'accepter ma propre réponse alors que cela conviendrait probablement à la plupart des cas. – JRoughan

+0

[Répondre à votre propre question est encouragé] (http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/) et si c'est la réponse qui a résolu votre question, vous devriez l'accepter aussi. Vous devez [attendre 48 heures] (http://blog.stackoverflow.com/2009/01/accept-your-own-answers/). La commande '--tree-filter' version que j'ai testée ci-dessus était en effet assez lente, mais typiquement avec filter-branch c'est une chose unique, donc je ne m'inquiéterais pas si je devais la laisser partir du jour au lendemain ... –

Questions connexes