Git 저장소의 하위 디렉토리 만 복제하려면 어떻게합니까?


1409

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

/finisht
/static

이에있을 때 SVN , /finisht동안, 한 곳에서 체크 아웃 한 /static과 같이, 다른 곳에서 체크 아웃 한 :

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

Git으로 이것을 할 수있는 방법이 있습니까?



1
2014 년 사용자에게 git clone가장 간단한 명령 은 무엇 입니까? 나는 간단한 대답을 사용했다 . 더 간단한 것이 있다면, 논평하십시오
Peter Krauss

루트 폴더를 만들지 않고 리포지토리의 내용을 복제하려는 경우 매우 쉬운 해결책입니다. stackoverflow.com/questions/6224626/…
Marc

@JoachimBreitner :이 질문은 Git의 서브 디렉토리를 체크 아웃하는 것에 관한 것이고 (이것은 쉬운) Git의 서브 디렉토리를 클로닝하는 것에 관한 것 입니다 (불가능한).
Jörg W Mittag

@ NickSergeant : 3 주 전에 릴리스 된 Git 2.19부터는 이것이 가능합니다. stackoverflow.com/a/52269934/2988 지금 수락하십시오. 참고 : Git 2.19에서는 클라이언트 측 지원 만 구현되고 서버 측 지원은 여전히 ​​누락되어 로컬 리포지토리를 복제 할 때만 작동합니다. 또한 GitHub와 같은 대형 Git 호스트는 실제로 Git 서버를 사용하지 않고 자체 구현을 사용하므로 Git 서버에 지원이 표시 되더라도 Git 호스트에서 작동한다는 것을 자동으로 의미하지는 않습니다. (OTOH, 그들은 더 빨리 구현할 수 있습니다.)
요 르그 W MITTAG에게

답변:


612

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

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

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


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

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

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


6
시나리오에 따라 git 하위 모듈 대신 git 하위 트리를 사용할 수 있습니다.
C Pirate

9
@StijndeWitt : 스파 스 체크 아웃 git-read-tree은 이후에 발생 get-fetch합니다. 문제는 하위 디렉토리 만 체크 아웃하는 것이 아니라 하위 디렉토리 만 복제 하는 것이 었습니다 . git-read-tree클론이 이미 완료된 후에 실행 되기 때문에 스파 스 체크 아웃이 어떻게 할 수 있는지 알 수 없습니다 .
Jörg W Mittag

9
이 "스텁"대신 Chronial이 맨 위로 이동할 수 있도록이 답변을 삭제 하시겠습니까? 수락되었으므로 운영자가 직접 삭제할 수는 없습니다. 당신은 너무 오래 되었기 때문에 당신이 얻은 명성을 유지할 것입니다. (누군가 "링크 전용"으로 플래그를 지정했기 때문에이 문제가 발생했습니다. :-)
Cody Grey

1
@CodyGray : Chronial 답변 은 하위 디렉토리 뿐만 아니라 여전히 전체 저장소를 복제합니다 . (마지막 단락에도 명시 적으로 나와 있습니다.) Git 에서는 하위 디렉토리 만 복제 할 수 없습니다 . 네트워크 프로토콜은이를 지원하지 않으며 스토리지 형식은이를 지원하지 않습니다. 이 질문에 대한 모든 단일 답변은 항상 전체 저장소를 복제합니다. 문제는 간단한 예 / 아니오 질문하고, 대답은 두 자 : 전혀 아니하면, 내 대답은 불필요하다 오래 되지 짧은.
Jörg W Mittag

1
@ JörgWMittag : Ciro Santili의 대답 은 당신과 모순되는 것 같습니다.
Dan Dascalescu

1524

당신이하려고하는 것은 스파 스 체크 아웃 이며 그 기능은 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/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 2.25.0 (Jan 2020)부터 실험 스파 스 체크 아웃 명령이 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

14
Apple에서는 '-f'둘레가 작동하지 않습니다. 그냥 git remote add origin <url>없이 -f를 추가하십시오
Anno2001

135
그것은 개선되었지만 여전히 원격 저장소의 전체 사본을 다운로드하여 저장해야합니다. 원본은 코드베이스의 일부에만 관심이 있거나 필자의 경우와 같은 문서 하위 폴더가있는 경우 전혀 피할 수 있습니다. )
a1an

56
원하는 디렉토리 내용 (디렉토리 자체가 아닌)을 저장소에 바로 복제 할 수있는 방법이 있습니까? 예를 들어, https://github.com/Umkus/nginx-boilerplate/tree/master/src오른쪽의 복제 내용 을/etc/nginx
mac

25
@Chronial, @ErikE : P는 : 당신이 바로 / 잘못된 모두있어 git remote add명령 않습니다 하지 페치 의미하지만, git remote add -f여기에 사용 된 바와 같이, 않습니다! 그것이 -f의미 하는 바입니다.
ntc2

21
이것을 사용하여 --depth=14.9GB의 전체 깜박임 소스 + 기록 대신 338MB의 Chromium Devtools를 복제했습니다. 우수한.
Rudie

443

git clone --filter 힘내 2.19에서

이 옵션은 실제로 서버에서 불필요한 객체 가져 오기를 건너 뜁니다. 또한 --filter=tree:0Git 2.20--filter=combineGit 2.24에 추가 된 복합 필터를 포함하여 다음 과 같이 끝납니다.

git clone \
  --depth 1 \
  --filter=combine:blob:none+tree:0 \
  --no-checkout \
  "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하고 실제로 불필요한 객체 가져 오기를 건너 뛰기 위해 Git 원격 프로토콜이 확장 되었지만, 당시에는 서버 지원이 없습니다. 그러나 이미 로컬에서 테스트 할 수 있습니다.

명령 분석 :

의 형식은 --filter에 설명되어 man git-rev-list있습니다.

힘내 나무에 대한 문서 :

그것을 테스트

#!/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의 상류 .

힘내 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

추악한 타사 확장 프로그램없이 리포에 거대한 얼룩을 직접 저장 한다고 상상해보십시오 .

GitHub가 별 및 권한과 같은 파일 / 디렉토리 메타 데이터를 허용한다고 가정하면 모든 개인 정보를 단일 저장소에 저장할 수 있습니다.

하위 모듈이 정확히 일반 디렉토리처럼 취급되었다고 상상해보십시오 . 트리 SHA를 요청하고 DNS와 같은 메커니즘이 먼저 로컬~/.git 을 찾은 다음 더 가까운 서버 (엔터프라이즈의 미러 / 캐시)를 찾고 GitHub에서 끝나는 요청을 해결합니다 .


이상하게도, git 버전 2.20.1 (Apple Git-117)을 사용하는 macOS에서는 "여러 필터 사양을 결합 할 수 없습니다"
muru

1
슬프게도 macOS git 버전에서는 운이 없습니다. fatal: invalid filter-spec 'combine:blob:none+tree:0'어쨌든 고마워! 아마도 최신 버전에서 작동 할 것입니다.
muru December

1
GIT 2.24.1을 사용하여 Windows 10에서 시도하면 실패합니다. 리눅스에서 같은 버전의 매력으로 일했습니다.
Oyvind

1
@Ciro Santilli git 버전 2.26.1.windows.1에서 "sha1 파일을 읽을 수 없습니다 ..."와 함께 여전히 실패합니다. 버그 리포트를 열었습니다 : github.com/git-for-windows/git/issues/2590
nharrer April

1
정보 감사합니다 @nharrer!
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

405

스파 스 체크 아웃얕은 복제 기능을 결합 할 수 있습니다 . 얕은 클론의 역사와 오프 삭감 스파 스 체크 아웃 만 패턴과 일치하는 파일을 가져옵니다.

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.


21
이 방법은 유용하며 최상의 답변이 될 수 있지만 체크 아웃에 표시되지 않더라도 상관없는 내용 ( 풀이 는 지점에있는 경우)을 복제 합니다.
nobar

1
자식 버전은 무엇입니까? 자식 도움말에 따르면 깊이 옵션을 사용할 수 있습니까?
우동 단

2
마지막 명령이없는 경우 나를 위해 작동하지 않습니다 git pull --depth=1 origin master하지만 git pull --depth=1 origin <any-other-branch>. 이것은 너무 이상하다, 나의 질문을 여기에서보십시오 : stackoverflow.com/questions/35820630/…
Shuman

5
Windows에서 마지막에서 두 번째 행은 따옴표를 생략해야합니다. 그렇지 않으면 풀이 실패합니다.
nateirvin

4
여전히 모든 데이터를 다운로드합니다! svn을 사용하여이 솔루션을 찾았습니다. stackoverflow.com/a/18324458/2302437
electronix384128

157

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
}

참고이 방법은 폴더를 다운로드하고 복제 / 체크 아웃하지 않습니다. 변경 사항을 다시 저장소로 푸시 할 수 없습니다. 반면에, 이로 인해 스파 스 체크 아웃 또는 얕은 체크 아웃에 비해 다운로드 크기가 줄어 듭니다.


9
github에서 나를 위해 일한 버전 만. git 명령은> 10k 파일을 체크 아웃했으며 svn은 원하는 700 만 내 보냅니다. 감사!
Christopher Lörken

4
이 작업을 시도했습니다 https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/trunk/udacity 했지만 svn: E170000: URL 'https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/trunk/udacity' doesn't exist오류 가 발생했습니다. (
zthomas.nc

9
@ zthomas.nc udacity 앞에있는 'trunk'를 제거하고 / tree / master /를 / trunk /로 바꾸십시오.
Speedy

2
이 명령은 저에게 효과적이었습니다! 방금 리포지토리에서 파일 복사본을 가져 와서 로컬에서 수정할 수있었습니다. 구조에 좋은 오래된 SVN!
Michael J

3
작동하지만 느리게 보입니다. 시작하는 데 약간의 시간이 걸리고 파일이 상대적으로 느리게 롤됩니다
Aryeh Beitz

73

복제 한 리포지토리와 상호 작용하지 않으려는 경우 전체 작업을 수행 할 수 있습니다 자식 복제를 수행 하고 git filter-branch --subdirectory-filter를 사용하여 저장소를 다시 작성할 수 있습니다 . 이런 식으로, 최소한 역사는 보존 될 것입니다.


11
명령을 모르는 사람들을 위해git filter-branch --subdirectory-filter <subdirectory>
Jaime Hablutzel 14

9
이 방법은 선택한 하위 디렉토리가 새 리포지토리의 루트가되므로 이점이 있습니다.
Andrew Schulman

그것은 사용하기에 가장 좋고 가장 쉬운 방법입니다. 다음은 하위 디렉토리 필터를 사용하는 원스텝 명령입니다.git clone https://github.com/your/repo_xx.git && cd repo_xx && git filter-branch --subdirectory-filter repo_xx_subdir
Alex

66

이것은 훨씬 간단 해 보인다 :

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

17
github 에서이 작업을 수행하면 치명적입니다. 프로토콜에서 지원하지 않는 작업입니다. 예기치 않은 명령 스트림 끝
Michael Fox

1
프로토콜 오류는 HTTPS 또는 : repo url에서 발생했을 수 있습니다. ssh 키가 없기 때문일 수도 있습니다.
Umair A.

2
github를 사용한다면 svn export대신 사용할 수 있습니다
Milo Wielondek

2
Github-> Invalid command : 'git-upload-archive'xxx / yyy.git ''에서는 작동하지 않습니다. ssh를 사용하여 git : // URL을 복제 한 것으로 보입니다. core.gitProxy 구성 옵션 및 GIT_PROXY_COMMAND 환경 변수가 설정되어 있지 않은지 확인하십시오. 치명적인 : 원격 끝이 예기치 않게 끊어졌습니다
Nianliang

3
이것이 GitHub에서 작동하지 않는 이유 : "우리는 git-archive를 사용하여 GitHub에서 직접 아카이브를 가져 오는 것을 지원하지 않습니다. repo를 로컬로 복제하고 git-archive를 실행하거나, ZIP 다운로드 버튼을 클릭하십시오. 리포지토리 페이지 " github.com/xuwupeng2000/capistrano-scm-gitcopy/issues/16
Donn Lee

63

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

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


37

Git으로 만 서브 디렉토리를 복제 할 수는 없지만 아래의 해결 방법은 거의 없습니다.

필터 브랜치

리포지토리를 다시 작성하여 trunk/public_html/프로젝트 루트 인 것처럼 보이고 다른 모든 히스토리를 삭제하고 (을 사용하여 filter-branch) 이미 체크 아웃 분기를 시도하십시오.

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

참고 : --필터 분기 옵션과 개정 옵션을 구분하고 --all모든 분기와 태그를 다시 작성합니다. 원래 커밋 시간 또는 병합 정보를 포함한 모든 정보가 유지 됩니다. 이 명령 .git/info/graftsrefs/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
    

이제 현재 디렉토리에서 폴더를 선택 했어야합니다.

디렉토리 레벨이 너무 많거나 분기를 필터링하는 경우 기호 링크를 고려할 수 있습니다.



겠습니까의 필터 지점은 여전히 당신이 할 수 있습니다 pull?
sam

2
@ 샘 : 아니오. filter-branch부모 커밋을 다시 작성하여 서로 다른 SHA1 ID를 가지므로 필터링 된 트리에는 원격 트리와 공통 커밋이 없습니다. git pull어디에서 병합하려고하는지 몰랐습니다.
Peter Cordes 2016 년

이 접근법은 대부분 내 경우에 대한 만족스러운 답변입니다.
Abbas

10

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

용법:

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

11
참고로, 그것은 GitHub 전용입니다.
Sz.

9
그리고 분명히 이것은 모든 메타 데이터로 리포지토리를 복제 하지 않고 디렉토리 를 다운로드 하기 위한 것입니다.
LarsH

5
다른 곳이 아닌 여기에 코드를 포함시켜야합니다.
jww

urllib2.HTTPError : HTTP 오류 403 : 속도 제한 초과
diyism

9

그러면 특정 폴더가 복제되고 폴더와 관련이없는 모든 기록이 제거됩니다.

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-filter-branch 문서 에는 다소 긴 경고 목록이 있습니다.
Oyvind

6

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

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

2
멋진 스크립트, 수정되어야하는 것만 심볼릭 링크 ln -s ./.$localRepo/$subDir $localRepo입니다ln -s ./.$localRepo$subDir $localRepo
valentin_nasta

2

나는 썼다 .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

왜 이것이 작동 L=${1##*/} L=${L%.git}합니까? 공간은 연산자입니까?
Gulzt

2

리눅스를 사용하십니까? 작업 트리에 쉽게 액세스하고 청소하고 싶습니까? 기계의 나머지 코드를 방해하지 않습니다. 심볼릭 링크를 사용해보십시오 !

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

1

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

주어진 리포지토리 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

스파 스 체크 아웃 옵션을 원래 저장소에 설정해야한다고 잘못 생각했습니다. 원격에서 가져 오기 전에 로컬에서 원하는 디렉토리를 정의하십시오. 이 설명이 다른 사람에게 도움이되기를 바랍니다.


0

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/

0

실제로 디렉토리의 최신 개정 파일에 관심이있는 경우 Github에서는 리포지토리를 포함하지 않는 Zip 파일로 리포지토리를 다운로드 할 수 있습니다. 따라서 다운로드 속도가 훨씬 빠릅니다.


0

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

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

폴더 이름 만 있으면됩니다.

wpm/*

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

git config core.sparsecheckout true

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

wpm/*

체크 아웃 명령 저장 및 실행

git checkout master

결과는 내 저장소에서 예상되는 폴더 였고 이것이 당신에게 효과가 있다면 공감할만한 것은 없었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.