Редкая проверка в Git 1.7.0?

С новой функцией разреженной проверки в Git 1.7.0, возможно ли просто получить содержимое подкаталога, как, например, в SVN? Я нашел этот пример, но он сохраняет полную структуру каталогов. Представьте, что я просто хотел получить содержимое каталога 'perl' без фактического каталога с именем 'perl'.

-- РЕДАКТИРОВАТЬ --

Пример:

Мой репозиторий 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

что не то, что я хочу.

7 ответов

Вам все еще нужно клонировать весь репозиторий, в котором будут все файлы. Вы могли бы использовать --depth флаг, чтобы получить только ограниченное количество истории.

Как только репозиторий клонирован, трюк дерева чтения ограничивает ваш "вид" репозитория только теми файлами или каталогами, которые находятся в .git/info/sparse-checkout файл.

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

#!/bin/sh
echo > .git/info/sparse-checkout
for i in "$@"
do
    echo "$i" >> .git/info/sparse-checkout
done
git read-tree -m -u HEAD

Если вы сохраните этот скрипт как git-sparse.sh в путь, сообщенный по телефону git --exec-pathтогда вы можете запустить git sparse foo/ bar/ только "оформить" каталоги foo и bar, или git sparse '*' чтобы вернуть все обратно.

Краткий ответ: нет. Git видит все файлы как единое целое.

Я рекомендую разбивать ваши репозитории на логические куски. Отдельный для Perl, изображений и документов. Если вам также необходимо сохранить стиль убер-репо, вы можете создать репо из подмодулей.

Ответ Рича был близок, но он пропустил шаг. Вам необходимо явно включить разреженную проверку:

git config core.sparsecheckout true

В этом блоге все шаги четко обозначены:

http://blog.quilitz.de/2010/03/checkout-sub-directories-in-git-sparse-checkouts/comment-page-1/

Теперь, не вдаваясь в детали того, почему вы хотите это сделать, ваша проблема (вероятно) может быть легко решена с помощью символической ссылки / ярлыка.

Ответить на вопрос - нет и с весомой причиной. Вся история репо загружается даже с "редкой проверкой". Чтобы выяснить, почему это необходимо - в противном случае отслеживание переименованных файлов будет болью в... шее. Представьте, что вы перемещаете файл /repo_root/asd/file1.cpp в /repo_root/fgh/file1.cpp - теперь, если вы только скачали /repo_root/fgh deltas, вы не будете знать о file1.cpp. Так что это означает, что вы должны загрузить все дельты. Но тогда у вас есть полный репозиторий; не только папка вырезать его, поэтому просто /rero_root/fgh папка не является самой репо. Это может показаться неважным, когда вы оформляете заказ, но когда вы делаете коммит, git может не знать достаточно, чтобы работать нормально.

Обходной путь: Если вы действительно хотите, вы можете создать скрипт, который вызывает git-checkout таким образом (для оболочки sh, пакет для окон не должен быть сложным):

!/bin/sh
curDir=`pwd`
cd $2
git-checkout $1
cp -R $3/* $4
cd $curDir

Здесь первый аргумент - это ветвь для извлечения, второй - папка, в которой в данный момент находится репо, третий - подкаталог, который вы действительно хотите использовать, а четвертый - место, куда вы хотите его скопировать.

Предупреждение: мои навыки работы с оболочкой практически отсутствуют, поэтому используйте их после тестирования. Не должно быть сложно воссоздать обратную сторону этого сценария, который копирует обратно материал, чтобы его можно было зафиксировать в репо.

git filter-branch --subdirectory-filter это то, что вам нужно, смотрите раздел Отсоединение (перемещение) в отдельный Git-репозиторий.

Вот маленький bash-скрипт для этого.

Сначала будет создана рабочая копия исходного репо, а затем отфильтрована ветвь с использованием фильтра подкаталогов, чтобы получить то, что вы хотите.

#!/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 должно сработать.

Вы можете попробовать оплетку - она ​​отслеживает пульты, сопоставляя их с путями. https://github.com/evilchelu/braid/wiki

Похоже, вы пытаетесь переименовать дерево каталогов так, чтобы ваши файлы оказались в другом месте. Мне кажется, что вы просите сделать анти-шаблон для управления кодом / проектом по двум причинам: категоризация модулей (биты java под узлом java, perl под узлом perl) и наличие проекта с файлами в разных местах откуда разработчик визуализирует их. Поскольку git поддерживает хэши содержимого каталога, чтобы увидеть, что изменилось, это также нарушает работу git как такового.

Демеон Рейделл

Другие вопросы по тегам