Supprimer refs / original / heads / master de git repo après filter-branch --tree-filter?

180

J'ai eu la même question que celle posée ici: Nouveau référentiel git dans le répertoire racine pour subsumer un référentiel existant dans un sous-répertoire

J'ai suivi cette réponse ici: Nouveau référentiel git dans le répertoire racine pour subsumer un référentiel existant dans un sous-répertoire

Maintenant, gitk --allmontre deux histoires: une culminant dans le courant masteret une nommée original/refs/heads/master.

Je ne sais pas ce qu'est cette deuxième histoire, ni comment la supprimer du repo. Je n'ai pas besoin de deux historiques dans mon référentiel.

Comment m'en débarrasser?

Pour vous reproduire:

mkdir -p project-root/path/to/module
cd project-root/path/to/module
mkdir dir1 dir2 dir3 
for dir in * ; do touch $dir/source-file-$dir.py ; done
git init
git add .
git commit -m 'Initial commit'

Nous avons maintenant le problème de l'affiche originale. Déplaçons la racine du dépôt git vers la racine du projet en utilisant la réponse ci-dessus:

git filter-branch --tree-filter 'mkdir -p path/to/module ; git mv dir1 dir2 dir3 path/to/module' HEAD
rm -rf path
cd ../../../ # Now PWD is project-root
mv path/to/module/.git .
git reset --hard

Maintenant, voyez mon problème actuel:

gitk --all &
git show-ref

Comment puis-je me débarrasser de refs/original/heads/mastertoute l'histoire associée?

goofeedude
la source

Réponses:

321

refs/original/*est là comme sauvegarde, au cas où vous gâcheriez votre branche de filtre. Croyez-moi, c'est une très bonne idée.

Une fois que vous avez inspecté les résultats et que vous êtes convaincu d'avoir ce que vous voulez, vous pouvez supprimer la référence sauvegardée:

git update-ref -d refs/original/refs/heads/master

ou si vous avez fait cela à de nombreuses références et que vous voulez tout effacer:

git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d

(Cela provient directement de la page de manuel filter-branch.)

Cela ne s'applique pas à vous, mais à d'autres qui peuvent trouver ceci: Si vous faites une branche de filtre qui supprime le contenu occupant un espace disque important, vous pouvez également vouloir exécuter git reflog expire --expire=now --allet git gc --prune=nowfaire expirer vos reflogs et supprimer les objets maintenant inutilisés . (Attention: complètement, totalement irréversible. Soyez très sûr avant de le faire.)

Cascabel
la source
Après avoir fait update-ref, reflog expire et gc, ces deux fichiers font toujours référence à la référence originale: .git / info / refs et .git / packing-refs On dirait que cela devrait peut-être dire ceci à la place:git update-ref -d refs/original/refs/heads/master
lhunath
1
Je suppose que vous avez accidentellement mélangé les mots: si j'ai raison, ça devrait être git update-ref -d original/refs/heads/master? Cependant, seule votre deuxième commande a fonctionné pour moi.
JJD
4
C'est git update-ref -d refs/original/refs/heads/masterbtw. Vous pouvez voir le nom complet en utilisant git show-ref.
poke le
4
Et le plus court git show-ref refs/original/* --hash | xargs -n 1 git update-ref -d?
CharlesB
11

Et si vous êtes dans Windows PowerShell:

git for-each-ref --format="%(refname)" refs/original/ | foreach-object -process { git update-ref -d $_ }
Guilherme Duarte
la source
7

filter-branchconserve les sauvegardes, le référentiel doit donc nettoyer les reflogs et le ramasse-miettes. Assurez-vous que vous n'avez pas besoin de ces sauvegardes avant la suppression:

rm -Rf .git/refs/original
git gc --aggressive --prune=now
Kiryl Plyashkevich
la source