etc./StackOverFlow

Git 리포지토리의 하위 디렉터리만 복제하려면 어떻게 합니까?

청렴결백한 만능 재주꾼 2022. 1. 22. 07:12
반응형

질문자 :Nick Sergeant


루트에 두 개의 하위 디렉토리가 있는 Git 저장소가 있습니다.

 /finisht /static

이것이 SVN에 있을 때 /finisht 는 한 곳에서 체크아웃되었지만 /static 은 다음과 같이 다른 곳에서 체크아웃되었습니다.

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

Git으로 이 작업을 수행할 수 있는 방법이 있습니까?



당신이 하려는 것은 스파스 체크아웃(sparse checkout ) 이라고 하며, 그 기능은 git 1.7.0(2012년 2월)에 추가되었습니다. 희소 복제 를 수행하는 단계는 다음과 같습니다.

 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/diranother/sub/tree 에 대해 "체크 아웃"된 파일이 있고(해당 경로는 그대로 유지됨) 다른 경로는 없습니다.

확장된 튜토리얼을 보고 싶을 수도 있고 아마도 sparse checkoutread-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"

이것은 여전히 서버에서 전체 리포지토리를 다운로드합니다. 체크아웃만 크기가 줄어듭니다. 현재로서는 단일 디렉토리만 복제할 수 없습니다. 그러나 리포지토리의 기록이 필요하지 않은 경우 얕은 복제본을 만들어 대역폭을 최소한 절약할 수 있습니다. 얕은 복제 와 스파스 체크 아웃을 결합하는 방법에 대한 정보는 아래 udondan의 답변을 참조하십시오.


git 2.25.0(2020년 1월)부터 실험적인 sparse-checkout 명령이 git에 추가되었습니다.

 git sparse-checkout init # same as: # git config core.sparseCheckout true git sparse-checkout set "A/B" # same as: # echo "A/B" >> .git/info/sparse-checkout git sparse-checkout list # same as: # cat .git/info/sparse-checkout

Chronial

git clone --filter 가 이제 GitHub에서 작동합니다(2021-01-14 테스트, git 2.30.0).

이 옵션은 원격 프로토콜 업데이트와 함께 추가되었으며 서버에서 개체가 다운로드되는 것을 실제로 방지합니다.

예를 들어 이 최소 테스트 저장소의 d1 에 필요한 개체만 복제하려면 다음을 수행합니다. https://github.com/cirosantilli/test-git-partial-clone 다음 을 수행할 수 있습니다.

 git clone \ --depth 1 \ --filter=blob:none \ --sparse \ https://github.com/cirosantilli/test-git-partial-clone \ ; cd test-git-partial-clone git sparse-checkout set d1

https://github.com/cirosantilli/test-git-partial-clone-big-small에서 덜 최소적이고 더 현실적인 버전이 있습니다.

 git clone \ --depth 1 \ --filter=blob:none \ --sparse \ https://github.com/cirosantilli/test-git-partial-clone-big-small \ ; cd test-git-partial-clone-big-small git sparse-checkout set small

해당 저장소에는 다음이 포함됩니다.

  • 10개의 10MB 파일이 있는 큰 디렉토리
  • 1바이트 크기의 1000개 파일이 있는 작은 디렉토리

모든 내용은 의사 난수이므로 압축할 수 없습니다.

내 36.4Mbps 인터넷의 복제 시간:

  • 전체: 24초
  • 부분: "즉각적인"

sparse-checkout 부분도 불행히도 필요합니다. 훨씬 더 이해하기 쉬운 특정 파일만 다운로드할 수도 있습니다.

 git clone \ --depth 1 \ --filter=blob:none \ --no-checkout \ https://github.com/cirosantilli/test-git-partial-clone \ ; cd test-git-partial-clone git checkout master -- d1

그러나 그 방법은 어떤 이유로 파일을 하나씩 매우 느리게 다운로드 하므로 디렉토리에 파일이 거의 없으면 사용할 수 없습니다.

최소 저장소의 개체 분석

복제 명령은 다음 항목만 얻습니다.

  • master 브랜치의 끝이 있는 단일 커밋 객체
  • 저장소의 모든 4개의 트리 개체:
    • 커밋의 최상위 디렉토리
    • 세 개의 디렉토리 d1 , d2 , master

그런 다음 git sparse-checkout set 명령은 서버에서 누락된 blob(파일)만 가져옵니다.

  • d1/a
  • d1/b

더 좋은 점은 나중에 GitHub에서 다음을 지원하기 시작할 것입니다.

 --filter=blob:none \ --filter=tree:0 \

여기서 --filter=tree:0 from Git 2.20 은 모든 트리 개체의 불필요한 clone checkout 으로 지연되도록 허용합니다. 그러나 내 2020-09-18 테스트에서 다음과 같이 실패합니다.

 fatal: invalid filter-spec 'combine:blob:none+tree:0'

아마도 --filter=combine: 복합 필터(Git 2.24에 추가됨, 다중 --filter 암시됨)가 아직 구현되지 않았기 때문일 수 있습니다.

어떤 객체를 가져왔는지 관찰했습니다.

 git verify-pack -v .git/objects/pack/*.pack

언급 된대로 : 데이터베이스의 모든 자식 개체를 나열하는 방법은 무엇입니까? 각 개체가 정확히 무엇인지에 대한 명확한 표시를 제공하지는 않지만 각 개체의 유형( commit , tree , blob )을 알려주고 해당 최소 저장소에 개체가 너무 적기 때문에 무엇을 명확하게 추론할 수 있습니다. 각 개체는.

git rev-list --objects --all 은 트리/블롭에 대한 경로가 있는 더 명확한 출력을 생성했지만 불행히도 실행할 때 일부 개체를 가져오기 때문에 언제 무엇을 가져왔는지 확인하기 어렵습니다. 더 나은 명령.

TODO는 지원을 시작했을 때 GitHub 발표를 찾았습니다. https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/ from 2020-01-17 이미 언급 --filter blob:none .

git sparse-checkout

이 명령은 "나는 이 하위 트리에만 관심이 있습니다"라는 설정 파일을 관리하여 향후 명령이 해당 하위 트리에만 영향을 미치도록 하기 위한 것이라고 생각합니다. 그러나 현재 문서가 약간 ... 희소하기 때문에 확신하기가 약간 어렵습니다. ;-)

그 자체로는 얼룩 가져오기를 방지하지 않습니다.

이 이해가 맞다면 git clone --filter 보완하는 것이 좋습니다. 복제된 부분 저장소에서 git 작업을 수행하려는 경우 의도하지 않은 추가 객체 가져오기를 방지할 수 있기 때문입니다.

Git 2.25.1에서 시도했을 때:

 git clone \ --depth 1 \ --filter=blob:none \ --no-checkout \ https://github.com/cirosantilli/test-git-partial-clone \ ; cd test-git-partial-clone git sparse-checkout init

init 실제로 모든 객체를 가져왔기 때문에 작동하지 않았습니다.

그러나 Git 2.28에서는 원하는 대로 개체를 가져오지 않았습니다. 하지만 내가 할 경우 :

 git sparse-checkout set d1

d1 은 다음과 같이 명시적으로 명시되어 있음에도 불구하고 페치 및 체크아웃되지 않습니다. https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/#sparse -checkout-and-partial-clone 면책 조항 포함:

부분 복제 기능이 일반 출시될 때까지 계속 지켜봐 주십시오[1].

[1]: GitHub는 이 기능이 일부 리포지토리(이 게시물에 사용된 예 포함)에서 활성화되어 있는 동안 여전히 내부적으로 이 기능을 평가하고 있습니다. 기능이 안정화되고 성숙해짐에 따라 진행 상황을 계속 업데이트해 드리겠습니다.

네, 현재로서는 확신하기가 너무 어렵습니다. 부분적으로는 GitHub가 비공개 소스라는 기쁨 덕분입니다. 하지만 계속 지켜보자.

명령 분석

서버는 다음으로 구성해야 합니다.

 git config --local uploadpack.allowfilter 1 git config --local uploadpack.allowanysha1inwant 1

명령 분석:

--filter 형식은 man git-rev-list 에 문서화되어 있습니다.

Git 트리의 문서:

로컬에서 테스트

다음 스크립트는 https://github.com/cirosantilli/test-git-partial-clone 리포지토리를 로컬에서 재현 가능하게 생성하고 로컬 복제를 수행하며 복제된 항목을 관찰합니다.

 #!/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/rootmybranch/mybranch 도 누락되었지만 --depth 1 은 누락된 파일 목록에서 이를 숨깁니다. --depth 1 을 제거하면 누락된 파일 목록에 표시됩니다.

나에게는 꿈이 있다

이 기능은 Git에 혁명을 일으킬 수 있습니다.

기업의 모든 코드 기반을 상상해 하나의 repo에 없는 같은 추한 타사 도구 repo .

추악한 타사 확장 없이 저장소에 직접 거대한 blob을 저장 한다고 상상해 보십시오.

GitHub에서 별 및 권한과 같은 파일/디렉토리 별 메타데이터를 허용하여 모든 개인 항목을 단일 저장소에 저장할 수 있다고 상상해 보세요.

하위 모듈이 일반 디렉토리와 똑같이 취급된다고 상상해 보십시오. 트리 SHA를 요청하면 DNS와 유사한 메커니즘이 요청을 해결 하고 먼저 로컬 ~/.git 살펴본 다음 더 가까운 서버(기업의 미러/캐시)로 이동하여 종료합니다. GitHub에.


Ciro Santilli 新疆再教育营六四事件法轮功郝海东

편집 : Git 2.19부터 이 답변 에서 볼 수 있듯이 마침내 가능합니다.

그 대답을 찬성하는 것을 고려하십시오.

참고: Git 2.19에서는 클라이언트 측 지원만 구현되고 서버 측 지원은 여전히 누락되어 로컬 리포지토리를 복제할 때만 작동합니다. 또한 GitHub와 같은 대규모 Git 호스트는 실제로 Git 서버를 사용하지 않고 자체 구현을 사용하므로 Git 서버에 지원이 표시되더라도 Git 호스트에서 작동한다는 것을 자동으로 의미하지는 않습니다. (OTOH, Git 서버를 사용하지 않기 때문에 Git 서버에 나타나기 전에 자체 구현에서 더 빠르게 구현할 수 있습니다.)


아니요, Git에서는 불가능합니다.

Git에서 이와 같은 것을 구현하는 것은 상당한 노력이 될 것이며 클라이언트 측 저장소의 무결성을 더 이상 보장할 수 없음을 의미합니다. 관심이 있으시면 git 메일링 리스트에서 "sparse clone" 및 "sparse fetch"에 대한 토론을 검색하십시오.

일반적으로 Git 커뮤니티의 합의는 항상 독립적으로 체크아웃되는 여러 디렉토리가 있는 경우 실제로 두 개의 다른 프로젝트이며 두 개의 다른 저장소에 있어야 한다는 것입니다. Git Submodules 를 사용하여 다시 붙일 수 있습니다.


Jörg W Mittag

스파스 체크아웃얕은 복제 기능을 결합할 수 있습니다. 얕은 복제 는 기록을 잘라내고 스파스 체크아웃 은 패턴과 일치하는 파일만 가져옵니다.

 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에서는 불가능한 푸시 git archive .


udondan

github에서 파일/폴더 를 다운로드하려는 다른 사용자의 경우 다음을 사용하기만 하면 됩니다.

 svn export <repo>/trunk/<folder>

 svn export https://github.com/lodash/lodash.com/trunk/docs

(예, 여기 svn이 있습니다. 분명히 2016년에도 일부 github 파일을 다운로드하려면 svn이 여전히 필요합니다)

제공: GitHub 리포지토리에서 단일 폴더 또는 디렉터리 다운로드

중요 - github URL을 업데이트하고 /tree/master/ 를 '/trunk/'로 바꿔야 합니다.

bash 스크립트로:

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

참고 이 방법은 폴더를 다운로드하며 복제/체크아웃하지 않습니다. 변경 사항을 리포지토리로 다시 푸시할 수 없습니다. 반면에, 이는 스파스 체크아웃 또는 얕은 체크아웃에 비해 다운로드가 더 적습니다.


Anona112

복제한 저장소와 상호 작용할 계획이 없다면 전체 git 복제를 수행 하고 git filter-branch --subdirectory-filter 를 사용하여 저장소를 다시 작성할 수 있습니다. 이렇게 하면 최소한 역사는 보존될 것입니다.


hillu

훨씬 간단 같습니다 :

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

ErichBSchulz

Git 1.7.0에는 "스파스 체크아웃"이 있습니다. git config 맨페이지 의 “core.sparseCheckout” , git read-tree 맨페이지 의 “Sparse checkout” 및 git update-index 맨페이지의 “Skip-worktree bit”를 참조하십시오.

인터페이스는 SVN만큼 편리하지 않지만(예: 초기 복제 시 스파스 체크아웃을 할 방법이 없음) 더 간단한 인터페이스를 구축할 수 있는 기본 기능을 이제 사용할 수 있습니다.


Chris Johnsen

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

    저장소가 이미 복제된 경우 이 단계를 건너뛸 수 있습니다.

    힌트: 큰 리포지토리의 경우 최신 개정판만 체크아웃하거나 --single-branch체크아웃하려면 얕은 복제 ( --depth 1


Community Wiki

방금 GitHub스크립트를 작성했습니다 .

용법:

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

david_adler

이렇게 하면 특정 폴더가 복제되고 관련되지 않은 모든 기록이 제거됩니다.

 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

BARJ

여기에 있는 훌륭한 답변 중 일부를 명확히 하기 위해 많은 답변에 설명된 단계는 이미 어딘가에 원격 저장소가 있다고 가정합니다.

주어진: 기존 git 저장소(예: git@github.com:some-user/full-repo.git , 나머지 리포지토리와 독립적 으로 가져오려는 하나 이상의 디렉토리( app1app2 라는 디렉토리)

위와 같은 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

sparse-checkout 옵션이 원래 저장소에 설정되어야 한다고 잘못 생각했지만 이것은 그렇지 않습니다. 원격에서 가져오기 전에 로컬에서 원하는 디렉토리를 정의합니다. 원격 저장소는 저장소의 일부만 추적하려는 사용자에 대해 알지 못하거나 신경 쓰지 않습니다.

이 설명이 다른 사람에게 도움이 되기를 바랍니다.


Everett

다음은 단일 하위 디렉토리 스파스 체크아웃의 사용 사례에 대해 작성한 셸 스크립트입니다.

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

jxramos

리눅스 사용? 그리고 접근하기 쉽고 깨끗한 작업 트리만 원하십니까? 컴퓨터의 나머지 코드를 방해하지 않고 심볼릭 링크를 시도하십시오!

 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

Nasir Iqbal

"희박한 체크아웃"을 수행하기 위해 .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

YenForYang

디렉토리의 최신 버전 파일에만 관심이 있다면 Github를 사용하여 리포지토리를 기록이 포함되지 않은 Zip 파일로 다운로드할 수 있습니다. 따라서 다운로드가 훨씬 빠릅니다.


weberjn

여기에는 많은 훌륭한 답변이 있지만 Windows Sever 2016에서 디렉터리 이름 주위에 따옴표를 사용하는 것이 실패했다고 덧붙이고 싶었습니다. 파일이 다운로드되지 않았을 뿐입니다.

대신에

 "mydir/myfolder"

나는 사용해야했다

 mydir/myfolder

또한 모든 하위 디렉토리를 단순히 다운로드하려면 다음을 사용하십시오.

 git sparse-checkout set *

Eric Stricklin

여기 내가 하는 일이 있습니다

 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 열고 편집할 수 있습니다.


예시

총 크기 < 2MB 와 같이 2개의 폴더 전체 저장소 크기>10GB↑ (git 포함)를 원한다고 가정합니다.

  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 version 2.29.2.windows.3


Carson

나는 git repos를 다룰 때 실제로 svn을 사용하는 것을 싫어하지만:/ 나는 이것을 항상 사용합니다.

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

이렇게 하면 수정 없이 github URL에서 복사할 수 있습니다. 용법;

 --- /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/

expelledboy

위의 많은 좋은 아이디어와 스크립트. 나는 스스로를 도울 수 없었고 도움말 및 오류 검사를 통해 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

Mike Slinn

그래서 나는이 트레드에서 모든 것을 시도했지만 아무 것도 효과가 없었습니다 ... Git 버전 2.24 (이 답변 당시 cpanel과 함께 제공되는 버전)에서는 이것을 할 필요가 없습니다.

 echo "wpm/*" >> .git/info/sparse-checkout

폴더 이름만 있으면 됩니다

 wpm/*

그래서 간단히 말해서 당신은 이것을합니다

 git config core.sparsecheckout true

그런 다음 .git/info/sparse-checkout을 편집하고 끝에 /*를 사용하여 폴더 이름(한 줄에 하나씩)을 추가하여 하위 폴더와 파일을 가져옵니다.

 wpm/*

체크아웃 명령 저장 및 실행

 git checkout master

결과는 내 repo의 예상 폴더였으며 이것이 당신을 위해 일한 경우 Upvote


Patrick Simard

출처 : http:www.stackoverflow.com/questions/600079/how-do-i-clone-a-subdirectory-only-of-a-git-repository

반응형