Как клонировать подкаталог только репозитория 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 с относительным путем?формат
--filter
is задокументировано наman git-rev-list
.Docs on git tree: