Разрешенная проверка в Git 1.7.0?
С новой разреженной функцией проверки в Git 1.7.0 можно ли просто получить содержимое подкаталога, например, как вы может в SVN? Я нашел этот пример, но он сохраняет полную структуру каталогов. Представьте себе, что я просто хотел содержимое каталога perl, без фактического каталога с именем perl.
- EDIT -
Пример:
Мой репозиторий Git содержит следующие пути
repo/.git/
repo/perl/
repo/perl/script1.pl
repo/perl/script2.pl
repo/images/
repo/images/image1.jpg
repo/images/image2.jpg
repo/doc/
repo/doc/readme.txt
repo/doc/help.txt
То, что я хочу, - это возможность создать из вышеперечисленного репозитория этот макет:
repo/.git/
repo/script1.pl
repo/script2.pl
Однако с текущей разреженной функцией проверки кажется, что можно получить
repo/.git/
repo/perl/script1.pl
repo/perl/script2.pl
который НЕ является тем, что я хочу.
Ответы
Ответ 1
Вам все равно нужно клонировать весь репозиторий, в котором будут все файлы. Вы можете использовать флаг --depth
только для получения ограниченного количества истории.
После клонирования репозитория трюк read-tree ограничивает ваше "представление" репозитория только теми файлами или каталогами, которые находятся в файле .git/info/sparse-checkout
.
Я написал быстрый script, чтобы помочь справиться с разреженностью, поскольку на данный момент это немного недружелюбно:
#!/bin/sh
echo > .git/info/sparse-checkout
for i in "[email protected]"
do
echo "$i" >> .git/info/sparse-checkout
done
git read-tree -m -u HEAD
Если вы сохраните этот script как git-sparse.sh
в пути, указанном при вызове git --exec-path
, вы можете запустить git sparse foo/ bar/
только для "проверки" каталогов foo и bar или git sparse '*'
, чтобы вернуть все еще раз.
Ответ 2
Короткий ответ - нет. Git видит все файлы как единое целое.
Я рекомендую вам разбить репозитории на логические куски. Отдельный для perl, изображений и документов. Если вам также необходимо поддерживать стиль реплики uber, вы можете создать репо, состоящее из Submodules.
Ответ 3
richq ответ был близок, но он пропустил шаг. Вам нужно явно разрешить разреженный checkout:
git config core.sparsecheckout true
В этом сообщении блога четко указаны следующие шаги:
http://blog.quilitz.de/2010/03/checkout-sub-directories-in-git-sparse-checkouts/comment-page-1/#comment-3146
Ответ 4
Теперь, не вдаваясь в подробности о том, почему вы хотите это сделать, ваша проблема может быть (возможно) легко решена с помощью символической ссылки/ярлыка.
Чтобы ответить на вопрос - нет, и со значимой причиной. Вся история репо загружается даже с "редкой проверкой". Чтобы прояснить, почему это необходимо - иначе отслеживание переименованных файлов было бы болью в... шейке. Представьте, что вы перемещаете файл /repo_root/asd/file1.cpp
в /repo_root/fgh/file1.cpp
- теперь, если вы только загрузили /repo_root/fgh
deltas, вы не будете знать о file1.cpp. Таким образом, это означает, что вы должны скачать все дельта. Но тогда у вас есть полный репозиторий; а не только папку, вырезанная из этого, поэтому просто папка /rero_root/fgh
не является самой репо. Это может показаться не очень важным при оформлении заказа, но когда вы совершаете фиксацию, git может не знать достаточно, чтобы нормально работать.
Обходной путь: если вы действительно этого хотите, вы можете создать script, который вызывает git -checkout таким образом (для оболочки sh, пакет для окон не должен быть трудным для создания):
!/bin/sh
curDir=`pwd`
cd $2
git-checkout $1
cp -R $3/* $4
cd $curDir
Здесь первый аргумент - ветвь для проверки, вторая - папка, в которой сейчас находится репо, третий - субдилер, который вы действительно хотите использовать, а четвертый - место, в которое вы хотите его скопировать.
Предупреждение: мои навыки оболочки практически отсутствуют, поэтому используйте это после тестирования. Не должно быть сложно воссоздать обратную сторону этого script, который копирует материал, чтобы он мог быть привязан к репо.
Ответ 5
git filter-branch --subdirectory-filter
- это то, что вам нужно, см. Отсоединить (переместить) подкаталог в отдельный репозиторий Git.
Вот немного bash script, чтобы сделать это.
Сначала вы создадите рабочую копию исходного репо, а затем фильтруйте ветку с помощью фильтра подкаталогов, чтобы получить то, что вы хотите.
#!/bin/bash
#
# git-subdir.sh
#
git clone --no-hardlinks $1 $2
cd $2
git filter-branch --subdirectory-filter $2 --prune-empty --tag-name-filter cat HEAD -- --all
git reset --hard
git remote rm origin
refbak=$(git for-each-ref --format="%(refname)" refs/original/)
if [ -n "$refbak" ];then
echo -n $refbak | xargs -n 1 git update-ref -d
fi
git reflog expire --expire=now --all
git repack -ad
git gc --aggressive --prune=now
Используйте для примера в вопросе, git-subdir.sh repo perl
будет работать.
Ответ 6
Вы можете попробовать оплетку - она отслеживает удаленные объекты, сравнивая их с дорожкой.
https://github.com/evilchelu/braid/wiki
Ответ 7
Похоже, что вы пытаетесь переименовать дерево каталогов, чтобы ваши файлы оказались в другом месте. Мне кажется, что то, что вы просите, - это анти-шаблон для управления кодом/проектом по двум пунктам: категоризация модулей (java-бит в java node, perl под perl node) и наличие проекта с файлы в разных местах, откуда разработчик визуализирует их. Поскольку git поддерживает хеши содержимого каталога, чтобы увидеть, что изменилось, это также нарушает git как таковой.
Daemeon Reiydelle