Удалите ссылки / оригинал / головы / мастера из репозитория git после filter-branch --tree-filter?

182

У меня возник тот же вопрос, что и здесь: Новый репозиторий git в корневом каталоге для добавления существующего репозитория в подкаталог

Я следовал за этим ответом здесь: Новый репозиторий git в корневом каталоге, чтобы включить существующий репозиторий в подкаталог

Теперь gitk --allпоказаны две истории: одна кульминационная в текущем master, а другая названная original/refs/heads/master.

Я не знаю, что это за вторая история или как ее удалить из репо. Мне не нужны две истории в моем хранилище.

Как мне от этого избавиться?

Воспроизвести себя:

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'

Теперь у нас есть проблема оригинального плаката. Давайте переместим корень git-репозитория в project-root, используя ответ, связанный выше:

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

Теперь посмотрим на мою текущую проблему:

gitk --all &
git show-ref

Как мне избавиться от refs/original/heads/masterвсей связанной истории?

goofeedude
источник
1
Возможный дубликат Как удалить старую историю после запуска git filter-branch?
пользователь

Ответы:

323

refs/original/*Это резервная копия на случай, если вы испортите свою ветку фильтра. Поверьте мне, это действительно хорошая идея.

После проверки результатов и уверенности в том, что у вас есть то, что вы хотите, вы можете удалить резервную копию ссылки:

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

или если вы сделали это со многими рефери и хотите стереть все это:

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

(Это взято непосредственно из страницы ветки фильтра.)

Это не относится к вам, но к другим, которые могут найти это: если вы выполняете ветвь фильтра, которая удаляет контент, занимающий значительное дисковое пространство, вы также можете захотеть запустить git reflog expire --expire=now --allи git gc --prune=nowзавершить свои журналы и удалить неиспользуемые объекты , (Предупреждение: полностью, полностью необратимый. Будьте уверены, прежде чем сделать это.)

Cascabel
источник
После выполнения update-ref, reflog expire и gc оба эти файла по-прежнему ссылаются на исходные ref: .git / info / refs и .git / pack-refs. Похоже, что вместо этого следует сказать следующее:git update-ref -d refs/original/refs/heads/master
lhunath
1
Наверное, вы случайно перепутали слова: если я прав, так и должно быть git update-ref -d original/refs/heads/master? Однако у меня работала только ваша вторая команда.
JJD
4
Это git update-ref -d refs/original/refs/heads/masterкстати. Вы можете увидеть полное имя, используя git show-ref.
тыкай
4
Как насчет короче git show-ref refs/original/* --hash | xargs -n 1 git update-ref -d?
CharlesB
11

И если вы в Windows PowerShell:

git for-each-ref --format="%(refname)" refs/original/ | foreach-object -process { git update-ref -d $_ }
Гильерме Дуарте
источник
7

filter-branchхранит резервные копии, поэтому репозиторий должен убирать reflogs и собирать мусор. Убедитесь, что вам не нужны эти резервные копии перед удалением:

rm -Rf .git/refs/original
git gc --aggressive --prune=now
Кирилл Пляшкевич
источник