Как клонировать подкаталог только репозитория Git?
у меня есть репозиторий Git, который в корне имеет два подкаталога:
/finisht
/static
когда это было в SVN,/finisht было проверено в одном месте, в то время как /static был проверен в другом месте, вот так:
svn co svn+ssh://admin@domain.com/home/admin/repos/finisht/static static
есть ли способ сделать это с помощью Git?
11 ответов:
нет, это невозможно в Git.
реализация чего-то подобного в Git будет значительным усилием, и это будет означать, что целостность репозитория на стороне клиента больше не может быть гарантирована. Если вам интересно, найдите обсуждения по "sparse clone" и "sparse fetch" в почтовом списке git.
В общем, консенсус в сообществе Git заключается в том, что если у вас есть несколько каталогов, которые всегда проверяются независимо, то это действительно два разных проекта и должны жить в двух разных хранилищах. Вы можете склеить их обратно вместе с помощью В Git Подмодулей.
то, что вы пытаетесь сделать, называется неполное извлечение, и эта функция была добавлена в git 1.7.0 (Feb. 2012). Шаги, чтобы сделать разреженный клон следующим образом:
mkdir <repo> cd <repo> git init git remote add -f origin <url>это создает пустой репозиторий с удаленным, и извлекает все объекты, но не проверяет их. Тогда сделайте:
вы должны определить, какие файлы/папки вы хотите на самом деле проверить. Это делается путем перечисления их вgit config core.sparseCheckout true.git/info/sparse-checkout, например:echo "some/dir/" >> .git/info/sparse-checkout echo "another/sub/tree" >> .git/info/sparse-checkoutи последнее, но не менее важное: обновите пустое РЕПО с состоянием с пульта дистанционного управления:
git pull origin masterтеперь у вас будут файлы "проверено" для
some/dirиanother/sub/treeв вашей файловой системе (с этими путями все еще), и никаких других путей нет.возможно, вы захотите взглянуть на расширенный учебник и вы, вероятно, должны прочитать официальный документация для разреженной проверки.
как a функция:
function git_sparse_clone() ( rurl="" localdir="" && shift 2 mkdir -p "$localdir" cd "$localdir" git init git remote add -f origin "$rurl" git config core.sparseCheckout true # Loops over remaining args for i; do echo "$i" >> .git/info/sparse-checkout done git pull origin master )использование:
git_sparse_clone "http://github.com/tj/n" "./local/location" "/bin"
обратите внимание, что это по – прежнему будет загружать весь репозиторий с сервера-только проверка уменьшается в размере. На данный момент невозможно клонировать только один каталог. Но если вам не нужна история репозитория, вы можете по крайней мере сэкономить на пропускной способности, создав мелкий клон. Смотрите udondan это ниже для получения информации о том, как совместить мелкое клон и редкий выезд.
Вы можете комбинировать неполное извлечение и мелкий клон функции. Элемент мелкий клон отрезает историю и неполное извлечение только тянет файлы, соответствующие вашей модели.
git init <repo> cd <repo> git remote add origin <url> git config core.sparsecheckout true echo "finisht/*" >> .git/info/sparse-checkout git pull --depth=1 origin masterдля этого вам понадобится минимальный git 1.9. Лично проверял только с 2.2.0 и 2.2.2.
таким образом, вы все еще сможете push, что невозможно с
git archive.
для других пользователей, которые просто хочу скачать файл / папка из github, просто используйте:
svn export <repo>/trunk/<folder>например
svn export https://github.com/lodash/lodash.com/trunk/docs(да, это svn здесь. по-видимому, в 2016 году вам все еще нужно svn, чтобы просто загрузить некоторые файлы github)
вежливость: загрузите одну папку или каталог из репозитория GitHub
важно - убедитесь, что вы обновили URL-адрес github и заменили
/tree/master/С '/ствол.'/как bash-скрипт:
git-download(){ folder=${@/tree\/master/trunk} folder=${folder/blob\/master/trunk} svn export $folder }Примечание Этот метод загружает папку, не клонирует/не извлекает ее. Вы не можете вернуть изменения обратно в репозиторий. С другой стороны-это приводит к меньшей загрузке по сравнению с редкой проверкой или мелкой проверкой.
Git 1.7.0 имеет "редкие проверки". Видеть "сердечник.sparseCheckout" в git config manpage, "Редкий выезд" в git read-tree manpage, и "Skip-worktree бит" в git update-index manpage.
интерфейс не так удобен, как SVN (например, нет способа сделать разреженную проверку во время начального клона), но базовая функциональность, на которой проще интерфейсы могут быть построены теперь доступны.
Если вы не планируете взаимодействовать с репозиторием, из которого вы клонировали, вы можете сделать полный git clone и перепишите свой репозиторий с помощью git filter-branch --subdirectory-filter. Таким образом, по крайней мере, история будет сохранена.
этой выглядит гораздо проще:
git archive --remote=<repo_url> <branch> <path> | tar xvf -
невозможно клонировать подкаталог только с помощью Git, но ниже приведены несколько обходных путей.
филиала фильтра
вы можете переписать репозиторий, чтобы выглядеть так, как будто
trunk/public_html/был его корень проекта, и отбросить все другие истории (используяfilter-branch), попробуйте на уже проверенной ветке:git filter-branch --subdirectory-filter trunk/public_html -- --allПримечания:
--это отделяет параметры ветви фильтра от параметров ревизии и--allпереписать все ветви и метить. Вся информация, включая исходное время фиксации или слияния информации будет сохранил. Эта команда чтит.git/info/graftsфайл и ссылки вrefs/replace/пространство имен, так что если у вас есть какие трансплантаты или заменыrefsопределено, выполнение этой команды сделает их постоянными.предупреждение! Переписанная история будет иметь разные имена объектов для всех объектов и не будет сходиться с исходной ветвью. Вы не сможете легко нажать и распределите переписанную ветвь поверх исходной ветви. Пожалуйста, не используйте эту команду, если вы не знаете всех последствий, и не используйте ее в любом случае, если простой однократной фиксации будет достаточно, чтобы решить вашу проблему.
неполное извлечение
вот простые шаги с неполное извлечение подход, который будет заполнять рабочий каталог редко, так что вы можете сказать Git, какие папки или файлы в рабочем каталоге стоит проверить.
клонировать репозиторий как обычно (
--no-checkoutне является обязательным):git clone --no-checkout git@foo/bar.git cd barвы можете пропустить этот шаг, если ваш репозиторий уже клонирован.
подсказка: для больших РЕПО, рассмотрим мелкий клон (
--depth 1) для проверки только последней редакции или / и--single-branchтолько.включить :
git config core.sparseCheckout trueуказать папка(ы) для разреженной проверки (без пробел в конце):
echo "trunk/public_html/*"> .git/info/sparse-checkoutили редактировать
.git/info/sparse-checkout.проверка филиала (например
master):git checkout masterтеперь вы должны были выбрать папки в текущем каталоге.
вы можете рассмотреть символические ссылки, если у вас слишком много уровней каталогов или ветви фильтрации вместо этого.
Я просто написал скрипт на GitHub.
использование:
python get_git_sub_dir.py path/to/sub/dir <RECURSIVE>
вот сценарий оболочки, который я написал для случая использования одного подкаталога sparse checkout
coSubDir.sh
localRepo= remoteRepo= subDir= # Create local repository for subdirectory checkout, make it hidden to avoid having to drill down to the subfolder mkdir ./.$localRepo cd ./.$localRepo git init git remote add -f origin $remoteRepo git config core.sparseCheckout true # Add the subdirectory of interest to the sparse checkout. echo $subDir >> .git/info/sparse-checkout git pull origin master # Create convenience symlink to the subdirectory of interest cd .. ln -s ./.$localRepo$subDir $localRepo
git clone --filterот Git 2.19этот параметр фактически пропускает извлечение ненужных объектов с сервера:
git clone --depth 1 --no-checkout --filter=blob:none \ "file://$(pwd)/server_repo" local_repo cd local_repo git checkout master -- mydir/сервер должен быть настроен с:
git config --local uploadpack.allowfilter 1 git config --local uploadpack.allowanysha1inwant 1по состоянию на v2.19.0 поддержка сервера отсутствует, но ее уже можно протестировать локально.
TODO:
--filter=blob:noneпропускает все капли, но все равно извлекает все объекты дерева. Но в обычном РЕПО это должно быть крошечным по сравнению с самими файлами, так что это уже достаточно хорошо. Спросил по адресу:https://www.spinics.net/lists/git/msg342006.html разработчики ответили a--filter=tree:0находится в работе, чтобы сделать это.помните, что
--depth 1подразумевает--single-branchСмотрите также: как клонировать одну ветку в git?
file://$(path)требуется преодолетьgit cloneпротокол махинаций: как мелко клонировать локальный репозиторий git с относительным путем?формат
--filteris задокументировано наman git-rev-list.Docs on git tree: