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

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

67 голосов
/ 25 февраля 2010

С новой редкой функцией проверки в 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 ]

26 голосов
/ 26 февраля 2010

Вам все еще нужно клонировать весь репозиторий, в котором будут все файлы. Вы можете использовать флаг --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 '*', чтобы вернуть все обратно.

16 голосов
/ 17 марта 2010

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

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

7 голосов
/ 08 января 2012

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

git config core.sparsecheckout true

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

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

5 голосов
/ 07 августа 2011

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

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

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

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

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

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

3 голосов
/ 01 марта 2012

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 будет работать.

2 голосов
/ 31 декабря 2010

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

0 голосов
/ 05 марта 2015

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

Daemeon Reiydelle

...