Разрешенная проверка в 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.

Ответ 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