Как мне клонировать только подкаталог Git-репозитория?

У меня есть мой Git-репозиторий, в корне которого есть два подкаталога:

/finisht
/static

Когда это было в SVN, /finisht был проверен в одном месте, в то время как /static был проверен в другом месте, вот так:

svn co svn+ssh://admin@domain.com/home/admin/repos/finisht/static static

Есть ли способ сделать это с помощью Git?

32 ответа

Решение

РЕДАКТИРОВАТЬ: Начиная с Git 2.19, это наконец возможно, как можно увидеть в этом ответе: /questions/47669957/kak-mne-klonirovat-tolko-podkatalog-git-repozitoriya/47669972#47669972.

Подумайте об этом ответе.

Примечание: в Git 2.19 реализована только поддержка на стороне клиента, поддержка на стороне сервера по-прежнему отсутствует, поэтому она работает только при клонировании локальных репозиториев. Также обратите внимание, что крупные хосты Git, например GitHub, на самом деле не используют сервер Git, они используют свою собственную реализацию, поэтому даже если поддержка появляется на сервере Git, это не означает, что она автоматически работает на хостах Git. (OTOH, поскольку они не используют Git-сервер, они могли бы реализовать его быстрее в своих собственных реализациях, прежде чем он появится на Git-сервере.)


Нет, это невозможно в Git.

Внедрение чего-то подобного в Git было бы существенным усилием, и это означало бы, что целостность клиентского репозитория больше не может быть гарантирована. Если вам интересно, поищите обсуждения "sparse clone" и "sparse fetch" в списке рассылки git.

В целом, в сообществе Git единодушно то, что если у вас есть несколько каталогов, которые всегда извлекаются независимо, то это действительно два разных проекта, которые должны находиться в двух разных репозиториях. Вы можете склеить их вместе, используя Git Submodules.

То, что вы пытаетесь сделать, называется разреженной проверкой, и эта функция была добавлена ​​в git 1.7.0 (февраль 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 в вашей файловой системе (с этими путями все еще), и никаких других путей нет.

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

Как функция:

function git_sparse_clone() (
  rurl="$1" localdir="$2" && 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"

Обратите внимание, что при этом все хранилище будет загружено с сервера - только размер извлечения уменьшается. На данный момент невозможно клонировать только один каталог. Но если вам не нужна история хранилища, вы можете по крайней мере сэкономить на пропускной способности, создав мелкий клон. См . Ответ Удондана ниже для получения информации о том, как объединить мелкий клон и редкую проверку.

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 сервер не поддерживается, но его уже можно локально протестировать.

СДЕЛАТЬ: --filter=blob:none пропускает все BLOB-объекты, но по-прежнему выбирает все объекты дерева. Но в обычном репо это должно быть крошечным по сравнению с самими файлами, так что это уже достаточно хорошо. На вопрос: https://www.spinics.net/lists/git/msg342006.html Разработчики ответили --filter=tree:0 находится в работе, чтобы сделать это.

Помни что --depth 1 уже подразумевает --single-branchСмотрите также: Как мне клонировать одну ветку в Git?

file://$(path) требуется преодолеть git clone Протокол Shenanigans: Как отмелить клонирование локального репозитория git с относительным путем?

Формат --filter задокументировано man git-rev-list,

Для поддержки этой функции было сделано расширение к протоколу Git remote.

Документы по дереву Git:

Проверьте это

#!/usr/bin/env bash
set -eu

list-objects() (
  git rev-list --all --objects
  echo "master commit SHA: $(git log -1 --format="%H")"
  echo "mybranch commit SHA: $(git log -1 --format="%H")"
  git ls-tree master
  git ls-tree mybranch | grep mybranch
  git ls-tree master~ | grep root
)

# Reproducibility.
export GIT_COMMITTER_NAME='a'
export GIT_COMMITTER_EMAIL='a'
export GIT_AUTHOR_NAME='a'
export GIT_AUTHOR_EMAIL='a'
export GIT_COMMITTER_DATE='2000-01-01T00:00:00+0000'
export GIT_AUTHOR_DATE='2000-01-01T00:00:00+0000'

rm -rf server_repo local_repo
mkdir server_repo
cd server_repo

# Create repo.
git init --quiet
git config --local uploadpack.allowfilter 1
git config --local uploadpack.allowanysha1inwant 1

# First commit.
# Directories present in all branches.
mkdir d1 d2
printf 'd1/a' > ./d1/a
printf 'd1/b' > ./d1/b
printf 'd2/a' > ./d2/a
printf 'd2/b' > ./d2/b
# Present only in root.
mkdir 'root'
printf 'root' > ./root/root
git add .
git commit -m 'root' --quiet

# Second commit only on master.
git rm --quiet -r ./root
mkdir 'master'
printf 'master' > ./master/master
git add .
git commit -m 'master commit' --quiet

# Second commit only on mybranch.
git checkout -b mybranch --quiet master~
git rm --quiet -r ./root
mkdir 'mybranch'
printf 'mybranch' > ./mybranch/mybranch
git add .
git commit -m 'mybranch commit' --quiet

echo "# List and identify all objects"
list-objects
echo

# Restore master.
git checkout --quiet master
cd ..

# Clone. Don't checkout for now, only .git/ dir.
git clone --depth 1 --quiet --no-checkout --filter=blob:none "file://$(pwd)/server_repo" local_repo
cd local_repo

# List missing objects from master.
echo "# Missing objects after --no-checkout"
git rev-list --all --quiet --objects --missing=print
echo

echo "# Git checkout fails without internet"
mv ../server_repo ../server_repo.off
! git checkout master
echo

echo "# Git checkout fetches the missing directory from internet"
mv ../server_repo.off ../server_repo
git checkout master -- d1/
echo

echo "# Missing objects after checking out d1"
git rev-list --all --quiet --objects --missing=print

GitHub вверх по течению.

Выход в Git v2.19.0:

# List and identify all objects
c6fcdfaf2b1462f809aecdad83a186eeec00f9c1
fc5e97944480982cfc180a6d6634699921ee63ec
7251a83be9a03161acde7b71a8fda9be19f47128
62d67bce3c672fe2b9065f372726a11e57bade7e
b64bf435a3e54c5208a1b70b7bcb0fc627463a75 d1
308150e8fddde043f3dbbb8573abb6af1df96e63 d1/a
f70a17f51b7b30fec48a32e4f19ac15e261fd1a4 d1/b
84de03c312dc741d0f2a66df7b2f168d823e122a d2
0975df9b39e23c15f63db194df7f45c76528bccb d2/a
41484c13520fcbb6e7243a26fdb1fc9405c08520 d2/b
7d5230379e4652f1b1da7ed1e78e0b8253e03ba3 master
8b25206ff90e9432f6f1a8600f87a7bd695a24af master/master
ef29f15c9a7c5417944cc09711b6a9ee51b01d89
19f7a4ca4a038aff89d803f017f76d2b66063043 mybranch
1b671b190e293aa091239b8b5e8c149411d00523 mybranch/mybranch
c3760bb1a0ece87cdbaf9a563c77a45e30a4e30e
a0234da53ec608b54813b4271fbf00ba5318b99f root
93ca1422a8da0a9effc465eccbcb17e23015542d root/root
master commit SHA: fc5e97944480982cfc180a6d6634699921ee63ec
mybranch commit SHA: fc5e97944480982cfc180a6d6634699921ee63ec
040000 tree b64bf435a3e54c5208a1b70b7bcb0fc627463a75    d1
040000 tree 84de03c312dc741d0f2a66df7b2f168d823e122a    d2
040000 tree 7d5230379e4652f1b1da7ed1e78e0b8253e03ba3    master
040000 tree 19f7a4ca4a038aff89d803f017f76d2b66063043    mybranch
040000 tree a0234da53ec608b54813b4271fbf00ba5318b99f    root

# Missing objects after --no-checkout
?f70a17f51b7b30fec48a32e4f19ac15e261fd1a4
?8b25206ff90e9432f6f1a8600f87a7bd695a24af
?41484c13520fcbb6e7243a26fdb1fc9405c08520
?0975df9b39e23c15f63db194df7f45c76528bccb
?308150e8fddde043f3dbbb8573abb6af1df96e63

# Git checkout fails without internet
fatal: '/home/ciro/bak/git/test-git-web-interface/other-test-repos/partial-clone.tmp/server_repo' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

# Git checkout fetches the missing directory from internet
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1/1), 45 bytes | 45.00 KiB/s, done.
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1/1), 45 bytes | 45.00 KiB/s, done.

# Missing objects after checking out d1
?8b25206ff90e9432f6f1a8600f87a7bd695a24af
?41484c13520fcbb6e7243a26fdb1fc9405c08520
?0975df9b39e23c15f63db194df7f45c76528bccb

Выводы: все капли снаружи d1/ не хватает. Например 0975df9b39e23c15f63db194df7f45c76528bccb, который d2/b нет там после проверки d1/a,

Обратите внимание, что root/root а также mybranch/mybranch также отсутствуют, но --depth 1 скрывает это от списка отсутствующих файлов. Если вы удалите --depth 1Затем они отображаются в списке отсутствующих файлов.

Вы можете объединить функции " Редкий заказ" и " Мелкий клон". Мелкий клон отсекает историю, а редкая проверка извлекает только файлы, соответствующие вашим шаблонам.

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.

Таким образом, вы все равно сможете толкать, что невозможно с 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/ с '/trunk/'.

Как скрипт bash:

git-download(){
    folder=${@/tree\/master/trunk}
    folder=${folder/blob\/master/trunk}
    svn export $folder
}

Примечание. Этот метод загружает папку, а не клонирует / извлекает ее. Вы не можете отправить изменения обратно в хранилище. С другой стороны - это приводит к меньшей загрузке по сравнению с редкой проверкой или мелкой проверкой.

2022 Ответ

Я не уверен, почему так много сложных ответов на этот вопрос. Это можно легко сделать, выполнив разреженное клонирование репо в нужную папку.

  1. Перейдите в папку, в которую вы хотите клонировать подкаталог.
  2. Открытьcmdи выполните следующие команды.
  3. git sparse-checkout add %subdirectory-to-be-cloned%
  4. cd %your-subdirectory%

Вуаля! Теперь вы клонировали только тот подкаталог, который хотите!

Объяснение. Что на самом деле делают эти команды?

git clone --filter=blob:none --sparse %your-git-repo-url%

В приведенной выше команде

  • --filter=blob:none=> Вы говорите git, что хотите клонировать только файлы метаданных. Таким образом, git собирает основные сведения о ветке и другие метаданные с удаленного сервера, что гарантирует, что ваши будущие проверки из источника будут гладкими.
  • --sparse=> Сообщите git, что это разреженный клон. В этом случае Git извлечет только корневой каталог.

Теперь git проинформирован о метаданных и готов к извлечению любых подкаталогов/файлов, с которыми вы хотите работать.

      git sparse-checkout add gui-workspace ==> Checkout folder

git sparse-checkout add gui-workspace/assets/logo.png ==> Checkout a file

Разреженный клон особенно полезен, когда есть большой репозиторий с несколькими подкаталогами, и вы не всегда работаете со всеми ними . Экономит много времени и трафика , когда вы делаете разреженное клонирование в большом репо.

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

      git switch -c  %new-branch-name% origin/%parent-branch-name% (or) git checkout -b %new-branch-name% origin/%parent-branch-name% 
git commit -m "Initial changes in sparse clone branch"
git push origin %new-branch-name%

Если вы никогда не планируете взаимодействовать с репозиторием, из которого вы клонировали, вы можете сделать полный клон git и переписать свой репозиторий, используя git filter-branch --subdirectory-filter. Таким образом, по крайней мере, история будет сохранена.

Это выглядит намного проще:

git archive --remote=<repo_url> <branch> <path> | tar xvf -

Git 1.7.0 имеет "редкие проверки". См. "Core.sparseCheckout" на справочной странице git config, "Sparse checkout" на справочной странице git read-tree и "Skip-worktree bit" на справочной странице git update-index.

Интерфейс не так удобен, как в SVN (например, нет способа сделать редкую проверку во время первоначального клона), но теперь доступна базовая функциональность, на которой могут быть построены более простые интерфейсы.

Невозможно клонировать подкаталог только с помощью Git, но ниже приведено несколько обходных путей.

Ветвь фильтра

Вы можете переписать хранилище так, чтобы оно выглядело как trunk/public_html/ был корнем проекта, и откажитесь от всей другой истории (используя filter-branch), попробуйте на уже оформленную ветку:

git filter-branch --subdirectory-filter trunk/public_html -- --all

Примечания: -- который отделяет параметры ветви фильтра от параметров ревизии, и --all переписать все ветки и теги. Вся информация, включая исходное время фиксации или информацию о слиянии, будет сохранена. Эта команда отличием .git/info/grafts файл и ссылки в refs/replace/ пространство имен, так что если у вас есть какие-либо трансплантаты или замена refs После запуска этой команды они станут постоянными.

Предупреждение! Переписанная история будет иметь разные имена объектов для всех объектов и не будет сходиться с исходной ветвью. Вы не сможете легко перемещать и распространять переписанную ветвь поверх оригинальной ветки. Пожалуйста, не используйте эту команду, если вы не знаете всех последствий, и избегайте ее использования в любом случае, если для решения вашей проблемы будет достаточно простого коммита.


Редкий заказ

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

  1. Репозиторий клонов как обычно (--no-checkout необязательно):

    git clone --no-checkout git@foo/bar.git
    cd bar
    

    Вы можете пропустить этот шаг, если ваш репозиторий уже клонирован.

    Подсказка: для больших репо рассмотрим мелкий клон (--depth 1) оформить только последнюю версию или / и --single-branch только.

  2. включить sparseCheckout опция:

    git config core.sparseCheckout true
    
  3. Укажите папку (и) для разреженной проверки (без пробела в конце):

    echo "trunk/public_html/*"> .git/info/sparse-checkout
    

    или редактировать .git/info/sparse-checkout,

  4. Оформить заказ в филиале (например, master):

    git checkout master
    

Теперь вы должны были выбрать папки в вашем текущем каталоге.

Вы можете рассмотреть символические ссылки, если у вас слишком много уровней каталогов или фильтрующих веток.


Я только что написал скрипт для GitHub.

Использование:

python get_git_sub_dir.py path/to/sub/dir <RECURSIVE>

Это клонирует конкретную папку и удаляет всю историю, не связанную с ней.

git clone --single-branch -b {branch} git@github.com:{user}/{repo}.git
git filter-branch --subdirectory-filter {path/to/folder} HEAD
git remote remove origin
git remote add origin git@github.com:{user}/{new-repo}.git
git push -u origin master

вот что я делаю

      git init
git sparse-checkout init
git sparse-checkout set "YOUR_DIR_PATH"
git remote add <REMOTE_NAME> https://github.com/AUTH/REPO.git
git pull --depth 1 Github <SHA1_or_BRANCH_NAME>

Простая заметка

  • редкая касса

  • git sparse-checkout init многие статьи скажут вам установить git sparse-checkout init --cone Если я добавлю --cone получу файлы, которые мне не нужны.

  • git sparse-checkout set "..." установит .git\info\sparse-checkout содержимое файла как ...

    Предположим, вы не хотите использовать эту команду. Вместо этого вы можете открыть git\info\sparse-checkout а затем отредактируйте.


Пример

Предположим, я хочу получить 2 папки с полным размером репо >10 ГБ ↑ (включая git) , как показано ниже, общий размер <2 МБ

  1. хром / общие / расширения / API
  2. хром / общие / расширения / разрешения
      git init
git sparse-checkout init
// git sparse-checkout set "chrome/common/extensions/api/"
start .git\info\sparse-checkout   👈 open the "sparse-checkut" file

/* .git\info\sparse-checkout  for example you can input the contents as below 👇
chrome/common/extensions/api/
!chrome/common/extensions/api/commands/     👈 ! unwanted : https://www.git-scm.com/docs/git-sparse-checkout#_full_pattern_set
!chrome/common/extensions/api/devtools/
chrome/common/extensions/permissions/
*/

git remote add Github https://github.com/chromium/chromium.git
start .git\config

/* .git\config
[core]
    repositoryformatversion = 1
    filemode = false
    bare = false
    logallrefupdates = true
    symlinks = false
    ignorecase = true
[extensions]
    worktreeConfig = true
[remote "Github"]
    url = https://github.com/chromium/chromium.git
    fetch = +refs/heads/*:refs/remotes/Github/*
    partialclonefilter = blob:none  // 👈 Add this line, This is important. Otherwise, your ".git" folder is still large (about 1GB)
*/
git pull --depth 1 Github 2d4a97f1ed2dd875557849b4281c599a7ffaba03
// or
// git pull --depth 1 Github master

  • partialclonefilter = blob:none

    Я знаю, что нужно добавить эту строку, потому что знаю: git clone --filter=blob:noneон напишет эту строку. поэтому я имитирую.

версия git: git version 2.29.2.windows.3

У меня это сработало (git версия 2.35.1)

      git init
git remote add origin <YourRepoUrl>
git config core.sparseCheckout true
git sparse-checkout set <YourSubfolderName>
git pull origin <YourBranchName>

Используете Linux? И хотите только легкодоступное и чистое рабочее дерево? не беспокоя остальной код на вашем компьютере. попробуйте символические ссылки!

git clone https://github.com:{user}/{repo}.git ~/my-project
ln -s ~/my-project/my-subfolder ~/Desktop/my-subfolder

Контрольная работа

cd ~/Desktop/my-subfolder
git status

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

Дано: существующий репозиторий git, напримерgit@github.com:some-user/full-repo.git, с одним или несколькими каталогами, которые вы хотите извлечь независимо от остальной части репозитория, например, каталоги с именемapp1 а также app2

Предполагая, что у вас есть репозиторий git, как указано выше...

Затем: вы можете выполнить следующие шаги, чтобы извлечь только определенные каталоги из этого большего репо:

mkdir app1
cd app1
git init
git remote add origin git@github.com:some-user/full-repo.git
git config core.sparsecheckout true
echo "app1/" >> .git/info/sparse-checkout
git pull origin master

Я ошибочно подумал, что параметры разреженной проверки должны быть установлены в исходном репозитории: это не так. Вы определяете, какие каталоги хотите локально, до того, как получить их с пульта. Надеюсь, это разъяснение поможет кому-то другому.

Вот сценарий оболочки, который я написал для сценария использования единственного подкаталога разреженной проверки

coSubDir.sh

localRepo=$1
remoteRepo=$2
subDir=$3


# 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 init <repo>
cd <repo>
git remote add origin <url>
git config core.sparsecheckout true
echo "<path you want to clone>/*" >> .git/info/sparse-checkout
git pull --depth=1 origin <branch you want to fetch>

Пример клонирования только папки Jetsurvey из этого репозитория

      git init MyFolder
cd MyFolder 
git remote add origin git@github.com:android/compose-samples.git
git config core.sparsecheckout true
echo "Jetsurvey/*" >> .git/info/sparse-checkout
git pull --depth=1 origin main

Ответ @Chronial больше не применим к последним версиям, но это был полезный ответ, поскольку он предложил сценарий.

Учитывая информацию, которую я собрал, и тот факт, что я хотел проверить только подкаталог ветки, я создал следующую функцию оболочки. Он получает поверхностную копию только самой последней версии ветки для указанных каталогов.

      function git_sparse_clone_branch() (
  rurl="$1" localdir="$2" branch="$3" && shift 3

  git clone "$rurl" --branch "$branch" --no-checkout "$localdir" --depth 1  # limit history
  cd "$localdir"

  # git sparse-checkout init --cone  # fetch only root file

  # Loops over remaining args
  for i; do
    git sparse-checkout set "$i"
  done

  git checkout "$branch"
)

Итак, пример использования:

      git_sparse_clone_branch git@github.com:user/repo.git localpath branch-to-clone path1_to_fetch path2_to_fetch

В моем случае клон был «всего» 23 МБ против 385 МБ для полного клона.

Протестировано с git версии 2.36.1.

Здесь много замечательных отзывов, но я хотел добавить, что использование кавычек вокруг имен каталогов не помогло мне в Windows Sever 2016. Файлы просто не загружались.

Вместо

      "mydir/myfolder"

Мне пришлось использовать

      mydir/myfolder

Кроме того, если вы хотите просто загрузить все подкаталоги, просто используйте

      git sparse-checkout set *

Я написал .gitconfig [alias]для выполнения "разреженной проверки". Проверьте это (без каламбура):

В Windows запустить в cmd.exe

git config --global alias.sparse-checkout "!f(){ [ $# -eq 2 ] && L=${1##*/} L=${L%.git} || L=$2; mkdir -p \"$L/.git/info\" && cd \"$L\" && git init --template= && git remote add origin \"$1\" && git config core.sparseCheckout 1; [ $# -eq 2 ] && echo \"$2\" >> .git/info/sparse-checkout || { shift 2; for i; do echo $i >> .git/info/sparse-checkout; done }; git pull --depth 1 origin master;};f"

Иначе:

git config --global alias.sparse-checkout '!f(){ [ $# -eq 2 ] && L=${1##*/} L=${L%.git} || L=$2; mkdir -p "$L/.git/info" && cd "$L" && git init --template= && git remote add origin "$1" && git config core.sparseCheckout 1; [ $# -eq 2 ] && echo "$2" >> .git/info/sparse-checkout || { shift 2; for i; do echo $i >> .git/info/sparse-checkout; done }; git pull --depth 1 origin master;};f'

Использование:

# Makes a directory ForStackExchange with Plug checked out
git sparse-checkout https://github.com/YenForYang/ForStackExchange Plug

# To do more than 1 directory, you have to specify the local directory:
git sparse-checkout https://github.com/YenForYang/ForStackExchange ForStackExchange Plug Folder

В git config команды уменьшены для удобства и хранения, но вот псевдоним расширен:

# Note the --template= is for disabling templates.
# Feel free to remove it if you don't have issues with them (like I did)
# `mkdir` makes the .git/info directory ahead of time, as I've found it missing sometimes for some reason
f(){
    [ "$#" -eq 2 ] && L="${1##*/}" L=${L%.git} || L=$2;
    mkdir -p "$L/.git/info"
        && cd "$L"
        && git init --template=
        && git remote add origin "$1"
        && git config core.sparseCheckout 1;
    [ "$#" -eq 2 ]
        && echo "$2" >> .git/info/sparse-checkout
        || {
            shift 2;
            for i; do
                echo $i >> .git/info/sparse-checkout;
            done
        };
    git pull --depth 1 origin master;
};
f

Если вас действительно интересуют только файлы последней версии каталога, Github позволяет вам загрузить репозиторий в виде Zip-файла, который не содержит истории. Так что загрузка происходит намного быстрее.

(расширяя этот ответ )

Клонирование подкаталога в определенном теге

Если вы хотите клонировать определенный подкаталог определенного тега, вы можете выполнить следующие шаги.

Я клонирую подкаталог репозитория github в cxf-3.5.4ярлык.

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

      git clone --depth 1 --filter=blob:none --sparse https://github.com/apache/cxf
cd cxf/
git sparse-checkout set distribution/src/main/release/samples/
git fetch --depth 1 origin cxf-3.5.4
# This is the hash on which the tag points, however using the tag does not work.
git switch --detach 3ef4fde

Клонирование подкаталога в определенной ветке

я клонируюdistribution/src/main/release/samples/подкаталог репозитория cxfcxf github в 2.6.x-fixesветвь.

      git clone --depth 1 --filter=blob:none --sparse https://github.com/apache/cxf --branch 2.6.x-fixes
cd cxf/
git sparse-checkout set distribution/src/main/release/samples/

degit делает копии репозиториев git. Когда вы запускаете degit some-user/some-repo, он находит последнюю фиксацию на https://github.com/some-user/some-repo и загружает связанный tar-файл в ~/.degit/some-user/some-repo/commithash.tar.gz, если он еще не существует локально. (Это намного быстрее, чем использование git clone, потому что вы не загружаете всю историю git.)

      degit <https://github.com/user/repo/subdirectory> <output folder>

Узнайте больше https://www.npmjs.com/package/degit

Хотя я ненавижу использовать svn при работе с репозиториями git:/ Я использую это все время;

function git-scp() (
  URL="$1" && shift 1
  svn export ${URL/blob\/master/trunk}
)

Это позволяет копировать URL-адрес github без изменений. Применение;

--- /tmp » git-scp https://github.com/dgraph-io/dgraph/blob/master/contrib/config/kubernetes/helm                                                                                                                  1 ↵
A    helm
A    helm/Chart.yaml
A    helm/README.md
A    helm/values.yaml
Exported revision 6367.

--- /tmp » ls | grep helm
Permissions Size User    Date Modified    Name
drwxr-xr-x     - anthony 2020-01-07 15:53 helm/

Вы все еще можете использовать svn:

      svn export https://admin@domain.com/home/admin/repos/finisht/static static --force

к " git clone"подкаталог, а затем" git pull"этот подкаталог.

(Он не предназначен для фиксации и нажатия.)

Выше много хороших идей и скриптов. Я ничего не мог с собой поделать и объединил их в сценарий bash с помощью и проверкой ошибок:

      #!/bin/bash

function help {
  printf "$1
Clones a specific directory from the master branch of a git repository.

Syntax:
  $(basename $0) [--delrepo] repoUrl sourceDirectory [targetDirectory]

If targetDirectory is not specified it will be set to sourceDirectory.
Downloads a sourceDirectory from a Git repository into targetdirectory.
If targetDirectory is not specified, a directory named after `basename sourceDirectory`
will be created under the current directory.

If --delrepo is specified then the .git subdirectory in the clone will be removed after cloning.


Example 1:
Clone the tree/master/django/conf/app_template directory from the master branch of
git@github.com:django/django.git into ./app_template:

\$ $(basename $0) git@github.com:django/django.git django/conf/app_template

\$ ls app_template/django/conf/app_template/
__init__.py-tpl  admin.py-tpl  apps.py-tpl  migrations  models.py-tpl  tests.py-tpl  views.py-tpl


Example 2:
Clone the django/conf/app_template directory from the master branch of
https://github.com/django/django/tree/master/django/conf/app_template into ~/test:

\$ $(basename $0) git@github.com:django/django.git django/conf/app_template ~/test

\$ ls test/django/conf/app_template/
__init__.py-tpl  admin.py-tpl  apps.py-tpl  migrations  models.py-tpl  tests.py-tpl  views.py-tpl

"
  exit 1
}

if [ -z "$1" ]; then help "Error: repoUrl was not specified.\n"; fi
if [ -z "$2" ]; then help "Error: sourceDirectory was not specified."; fi

if [ "$1" == --delrepo ]; then
  DEL_REPO=true
  shift
fi

REPO_URL="$1"
SOURCE_DIRECTORY="$2"
if [ "$3" ]; then
  TARGET_DIRECTORY="$3"
else
  TARGET_DIRECTORY="$(basename $2)"
fi

echo "Cloning into $TARGET_DIRECTORY"
mkdir -p "$TARGET_DIRECTORY"
cd "$TARGET_DIRECTORY"
git init
git remote add origin -f "$REPO_URL"
git config core.sparseCheckout true

echo "$SOURCE_DIRECTORY" > .git/info/sparse-checkout
git pull --depth=1 origin master

if [ "$DEL_REPO" ]; then rm -rf .git; fi
  • Если ты хочешь clone

            git clone --no-checkout <REPOSITORY_URL>
    cd <REPOSITORY_NAME>
    
    1. Теперь установите конкретный файл/каталог, который вы хотите перенести в рабочий каталог:
       
    2. После этого вы должны жестко сбросить свой рабочий каталог до коммита, который вы хотите получить.

      Например, мы сбросим его на значение по умолчанию. origin/masterкоммит HEAD.

                git reset --hard HEAD
      
  • Если ты хочешь git initа потом remote add

            git init
    git remote add origin <REPOSITORY_URL>
    
    1. Теперь установите конкретный файл/каталог, который вы хотите перенести в рабочий каталог:
                git sparse-checkout set <PATH_TO_A_SPECIFIC_DIRECTORY_OR_FILE_TO_PULL>
      
    2. Вытащите последний коммит:
                git pull origin master
      

ПРИМЕЧАНИЕ:

Если вы хотите добавить еще один каталог/файл в свой рабочий каталог, вы можете сделать это следующим образом:

       git sparse-checkout add <PATH_TO_ANOTHER_SPECIFIC_DIRECTORY_OR_FILE_TO_PULL>

Если вы хотите добавить весь репозиторий в рабочий каталог, сделайте это так:

       git sparse-checkout add *

Если вы хотите очистить рабочий каталог, сделайте это так:

       git sparse-checkout set empty

Если вы хотите, вы можете просмотреть статус указанных вами отслеживаемых файлов, выполнив:

      git status

Если вы хотите выйти из разреженного режима и клонировать весь репозиторий, вы должны запустить:

      git sparse-checkout set *
git sparse-checkout set init
git sparse-checkout set disable

Я не знаю, удалось ли кому-нибудь вытащить конкретный каталог, вот мой опыт: git clone --filter=blob:none --single-branch <repo>, немедленно отменить при загрузке объектов, войти в репо, затем git checkout origin/master <каталог>, игнорировать ошибки (sha1), ввести каталог, повторить проверку (используя новый каталог) для каждого подкаталога. Мне удалось быстро получить исходные файлы таким образом

просто.

      git clone <repo>
mv <repo-folder>/path/to/folder <new-name>
rm -rf <repo-folder>
Другие вопросы по тегам