Редкая проверка в 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 как такового.
Демеон Рейделл