특정 개정 / 변경 세트로 git 저장소를 복제하는 방법은 무엇입니까?


393

Mercurial에서 일반적으로하는 것과 같이 특정 개정으로 git 저장소를 복제하는 방법은 무엇입니까?

hg clone -r 3 /path/to/repository

3
변경 세트 또는 개정에만 해당되는 것이 아니라 특정 지점에서 최신 복제가 효과적 일 수 있습니다. git clone -b 10.1 https://github.com/MariaDB/server.git --depth=1 mariadb-server-src
MrMesees

가능한 중복 중복 Git
SlightlyCuban을

역사가 얕아지기를 원하십니까? 예를 들어 개정판 3 만 포함하거나 부모입니까?
sschuberth

문제의 저장소가 다른 저장소 내부에서 복제되고 특정 저장소에서 해당 내부 저장소를 복제하려는 경우 git 하위 모듈이 자동으로 자동 수행됩니다.
J0hnG4lt 10

답변:


202

업데이트 2 Git 2.5.0 부터 아래에 설명 된 기능은 서버 측에서 구성 변수를 사용하여 활성화 할 수 있습니다 uploadpack.allowReachableSHA1InWant. 여기서 GitHub 기능 요청GitHub 커밋은이 기능을 활성화합니다 . 일부 Git 서버는 기본적으로이 옵션을 활성화합니다 (예 : Bitbucket Server는 버전 5.5 이상 부터 활성화했습니다) . 구성 옵션을 활성화하는 방법에 대한 자세한 내용 은 Stackexchange 에서이 답변을 참조하십시오 .

업데이트 1 Git 버전의 1.7 < v < 2.5경우 Vaibhav Bajpai의 답변에 설명 된대로 git clone 및 git reset을 사용하십시오.

전체 저장소를 가져 오지 않으려면을 사용하지 않아야합니다 clone. 항상 가져 오기를 사용하여 가져올 분기를 선택할 수 있습니다. 나는 hg 전문가가 아니므로 세부 사항을 -r모르지만 git에서는 이와 같은 것을 할 수 있습니다.

# make a new blank repository in the current directory
git init

# add a remote
git remote add origin url://to/source/repository

# fetch a commit (or branch or tag) of interest
# Note: the full history up to this commit will be retrieved unless 
#       you limit it with '--depth=...' or '--shallow-since=...'
git fetch origin <sha1-of-commit-of-interest>

# reset this repository's master branch to the commit of interest
git reset --hard FETCH_HEAD

32
나는 효과가 없다고 생각 git fetch origin <sha1>합니다. 태그 또는 분기 이름과 같은 명명 된 참조를 전달해야하는 것 같습니다. 참조 kerneltrap.org/mailarchive/git/2009/1/13/4707444
아르투르

48
@ artur : 당신은 그것이 작동하지 않는다고 생각하거나 시도했지만 작동하지 않습니까?
CB Bailey

37
git 1.4를 사용 git fetch origin <SHA1>하면 원격에서 마스터를 가져 와서 reset --hard실제로 로컬로 분기를 인스턴스화 한 후 원하는 개정으로 전환 할 수 있음을 알았습니다 . 개별 개정판을 직접 가져올 수 없었습니다. git 1.7에서는 git fetch origin <SHA1>@artur 가보고 한대로 작동하지 않았습니다. git checkout <SHA1>뒤에을 사용해야 합니다 reset --hard.
Joe McMahon

6
SHA-1로 가져 오기는 http 및 rsync 프로토콜에서만 작동합니다. 참조 kerneltrap.org/mailarchive/git/2009/1/14/4716044/...
CharlesB

23
이 답변은 구식입니다. 이것은 git 1.7 또는 git 1.8에서 작동하지 않으며 https : // 또는 ssh 프로토콜에서는 작동하지 않습니다. ( "원격 심판 df44398762393c67af487edeb0831ad9579df4aa를 찾을 수 없습니다"– 심판이 아니며, 커밋입니다.
Paŭlo Ebermann

838
$ git clone $URL
$ cd $PROJECT_NAME
$ git reset --hard $SHA1

가장 최근의 커밋으로 다시 돌아가려면

$ git pull

13
이것은 커밋이 마스터 브랜치에있는 경우에만 작동하며 로컬 참조를 엉망으로 만들지 않습니다. 왜 처음에 git checkout이 아닌 git reset?
Joky

72
이것은 모든 것을 가져 오기 때문에 큰 repos에는 좋은 옵션이 아닙니다.
시크릿

1
이 솔루션은 맨 위에 있어야합니다. 그것이 "최적화되지 않은"것은 아무도 걱정하지 않고 OP가 요구 한 것입니다. 구체적으로 : "특정 버전으로 git 저장소를 어떻게 복제합니까?"
Florian Segginger

20
@FlorianSegginger 특정 개정판을 복제하려는 경우 모든 것을 복제하지 않고 해당 개정판 만 복제하고 싶을 것입니다. 나에게 그 질문은 물었다. 이 솔루션은 다른 질문에 대답합니다. "내 리포지토리의 특정 개정을 보려면 어떻게해야합니까?" 전체 레포를 가져 오는 것은 많은 사람들이 피하고 싶어하는 것입니다.
Renato

1
실제 질문 IMHO는 다루지 않습니다. 복제 중에 개정을 지정할 수 있기 때문에 --depth큰 저장소에 매우 중요한 것을 사용할 수 있기 때문 입니다. 이 솔루션을 사용하려면 모든 객체를 가져온 다음 이전 버전으로 재설정해야합니다. 이것은 시간이 많이 걸리고 낭비되는 네트워크 대역폭입니다.
void.pointer

54

git 리포지토리를 복제하면 전체 리포지토리가 복제됩니다. 복제 할 리비전을 하나만 선택할 수있는 방법은 없습니다. 그러나 일단 수행 한 후에는을 수행 git clone하여 특정 개정을 체크 아웃 할 수 있습니다 checkout <rev>.


4
하나의 수정본 만 복제하고 싶지 않습니다. 복제 제한을 지정하고 싶습니다. 즉, 지정된 개정판까지 모든 것을 복제하고 싶습니다.
John

6
당신은 그렇게 할 수 없습니다. git clone전체 저장소를 가져옵니다. 가지고 있으면 특정 개정판을 체크 아웃 할 수 있습니다.

4
한가지주의 할 점; Git은 일반적으로 히스토리를 저장하는 데 매우 효율적이므로 수정본의 절반 만 복제하여 방대한 공간을 절약하지는 않습니다.
Amber

"공간 절약"에 관한 것이 아닙니다. 새로운 변경으로 인해 버그가 발생했을 때와 같이 특정 개정에만 도달하는 것입니다. 그래서 나는 그 새로운 변경을 원하지 않습니다. 이? 예전 버전으로 롤백 할 수 없는데 왜 소스 컨트롤이 필요한가요?
BrainSlugs83

1
"복제 할 하나의 수정본 만 선택할 수있는 방법은 없습니다"– 예, 다음이 있습니다 :git clone --single-branch ...
morxa

33

특정 브랜치 또는 태그에서 하나의 특정 커밋 만 복제하려면 다음을 사용하십시오.

git clone --depth=1 --branch NAME https://github.com/your/repo.git

불행히도, NAME분기 이름 또는 태그 이름 만 될 수 있습니다 (SHA를 커밋하지 않음).

--depth플래그를 생략하여 전체 히스토리를 다운로드 한 후 해당 분기 또는 태그를 체크 아웃하십시오.

git clone --branch NAME https://github.com/your/repo.git

이것은 최신 버전의 git에서 작동합니다 (버전으로했습니다 2.18.0).


그러나 이전 버전 2.17.1에는 해당되지 않음
RzR

4
더 많은 투표가 필요합니다. 이것은 다른 오래된 답변보다 훨씬 낫습니다.
Étienne

32

처음부터 특정 지점까지 모든 것을 가져오고 싶다면 Charles Bailey의 대답이 완벽합니다. 반대로하고 현재 날짜부터 되돌아온 기록의 하위 세트를 검색하려면 다음을 사용할 수 있습니다.git clone --depth [N] 여기서 N은 원하는 기록의 수입니다. 하나:

--깊이

지정된 수의 개정판으로 기록이 잘린 얕은 복제본을 만듭니다. 얕은 저장소에는 여러 가지 제한이 있지만 (복제하거나 가져올 수 없으며, 밀어 넣거나 넣을 수는 없습니다), 오랜 역사를 가진 대규모 프로젝트의 최근 기록에만 관심이 있고 적절할 경우 적합합니다. 수정 사항을 패치로 보내십시오.


4
최신 버전의 git은 얕은 복제본을 향상 시켰으며 끌어 낼 수 있습니다.
orion78fr

26

요약하면 (git v. 1.7.2.1) :

  1. git clone당신이 repo를 원하는 곳 에서 규칙적으로 행동하십시오.
  2. git checkout <sha1 rev> 당신이 원하는 rev의
  3. git reset --hard
  4. git checkout -b master

6
3 단계와 4 단계는 무엇을합니까?
BrainSlugs83

4 단계는 저에게 효과가 없었지만 3 단계까지는 트릭을 수행했습니다. – 감사
Gene Bo

@ BrainSlugs83 : 4 단계는 로컬 브랜치를 생성하고 master이를 전환합니다.
LarsH

3
@ phill : 왜 git reset --hard? 이에 대한 문서는 "인덱스 및 작업 트리를 재설정합니다. <commit> [이제 기본값은 HEAD (현재는 현재) 임) 이후 작업 트리에서 추적 된 파일에 대한 모든 변경 내용 <sha1 rev>은 무시됩니다." 그러나이 시점에서 복제 이후 아무런 변화가 없었으므로 목적은 무엇입니까? 에서 현재 분기를 자르 <sha1 rev>나요?
LarsH

19

TL; DR-복제하려는 커밋에 대해 소스 저장소에 태그를 작성하고 fetch 명령에서 태그를 사용하십시오. 나중에 원본 리포지토리에서 태그를 삭제하여 정리할 수 있습니다.

글쎄, 그것의 2014 년과 2010 년에 Charles Bailey가 받아 들인 대답은 지금까지는 완전히 구식이며 다른 답변의 대부분 (모두?)은 많은 사람들이 피하고 싶어하는 복제와 관련이 있습니다.

다음 솔루션은 OP 및 다른 많은 사람들이 찾고있는 것을 달성합니다. 이는 히스토리를 포함하여 저장소의 사본을 작성하지만 특정 커밋까지만 작성하는 방법입니다.

다음은 git 버전 2.1.2와 함께 로컬 저장소 (예 : 다른 디렉토리의 저장소)를 특정 지점까지 복제하는 데 사용한 명령입니다.

# in the source repository, create a tag against the commit you want to check out
git tag -m "Temporary tag" tmptag <sha1>

# create a new directory and change into that directory
cd somewhere_else;mkdir newdir;cd newdir

# ...and create a new repository
git init

# add the source repository as a remote (this can be a URL or a directory)
git remote add origin /path/to/original/repo

# fetch the tag, which will include the entire repo and history up to that point
git fetch origin refs/tags/tmptag

# reset the head of the repository
git reset --hard FETCH_HEAD

# you can now change back to the original repository and remove the temporary tag
cd original_repo
git tag -d tmptag

이 솔루션이 몇 년 동안 계속 작동하기를 바랍니다. :-)


2
이것은 당신이 repo의 소유자라는 것을 잘 알고 있습니다. 그것이 당신이 관리하지 않는 공개 저장소와 함께 작동하는지 확실하지 않습니다
Suhaib

18

간단하게 사용할 수 있습니다 git checkout <commit hash>

이 순서로

bash git clone [URLTORepository] git checkout [commithash]

커밋 해시는이 "45ef55ac20ce2389c9180658fdba35f4a663d204"와 같습니다.


이전과 마찬가지로-복제 후 체크 아웃 해야하는 이유. 를 복제하면 로컬 리포지토리에 전체 기록이 있습니다. 이 답변에 공감 수가 너무 많은 이유는 무엇입니까?
Dmitry Perfilyev

2

위의 답변 중 2 개 사용 ( 특정 개정 / 변경 세트로 git 저장소를 복제하는 방법특정 개정 / 변경 세트로 git 저장소를 복제하는 방법? )를 사용하여 결정을 내릴 수있었습니다. 포인트까지 복제하려면 해당 포인트는 단순히 SHA가 아닌 태그 / 분기 여야합니다. 그렇지 않으면 FETCH_HEAD가 혼동됩니다. git fetch set 다음에 분기 또는 태그 이름을 사용하면 응답을 얻습니다. 단순히 SHA-1을 사용하면 응답하지 않습니다.
여기 내가 한 일이 있습니다 :-실제 원점에서 전체 저장소의 전체 작업 복제본을 만듭니다.

cd <path to create repo>
git clone git@<our gitlab server>:ui-developers/ui.git 

그런 다음 흥미로운 지점에서 로컬 지점을 만듭니다.

git checkout 2050c8829c67f04b0db81e6247bb589c950afb14
git checkout -b origin_point

그런 다음 로컬 사본을 원본으로 사용하여 새 빈 저장소를 만듭니다.

cd <path to create repo>
mkdir reduced-repo
cd reduced-repo
git init
git remote add local_copy <path to create repo>/ui
git fetch local_copy origin_point

그 시점에서 나는이 응답을 얻었다. 위의 분기 대신 SHA-1을 사용하면 아무 일도 일어나지 않으므로 응답이 작동한다는 것을 알기 때문에

/ var / www / html / ui-hacking $ 자식 패치 local_copy origin_point
원격 : 개체 수 : 45493, 완료.
원격 : 객체 압축 : 100 % (15928/15928) 완료
원격 : 총 45493 (델타 27508), 재사용 45387 (델타 27463)
받는 물건 : 100 % (45493/45493), 53.64 MiB | 50.59 MiB / s 완료
델타 해결 : 100 % (27508/27508) 완료
/ var / www / html / ui에서
 * 분기 origin_point-> FETCH_HEAD
 * [새 지점] origin_point-> origin / origin_point

이제 내 경우에는 신선한 리포지토리로 gitlab에 다시 넣어야했습니다.

git remote add origin git@<our gitlab server>:ui-developers/new-ui.git

즉, git --git-dir=../ui/.git format-patch -k -1 --stdout <sha1> | git am -3 -k원격 체리 선택 을 사용하여 origin_point에서 내 repo를 다시 빌드 git push origin하고 전체 로트를 새 집으로 다시 업로드하는 데 사용할 수 있습니다.

누군가를 돕는 희망


"FETCH_HEAD가 혼란스러워진다"는 의미를 설명 할 수 있습니까? 그리고 git fetch local_copy origin_pointJamesGs 와 어떻게 다릅니 까 git fetch origin refs/tags/tmptag?
not2qubit

git fetch local_copy origin_point빈과 상태에 당신을 떠날 reduced-repo단지를 포함, 디렉토리 .git. 이 지침에 빠진 것이 있습니다 ...
not2qubit

2

내 버전은 인정되고 가장 많이 찬성 된 답변의 조합이었습니다. 그러나 모두가 SHA1을 사용하지만 아무도 그것을 얻는 방법을 알려주지 않기 때문에 조금 다릅니다.

$ git init
$ git remote add <remote_url>
$ git fetch --all

이제 모든 분기 및 커밋을 볼 수 있습니다

$ git branch -a
$ git log remotes/origin/master <-- or any other branch

마지막으로 원하는 커밋의 SHA1을 알고 있습니다.

git reset --hard <sha1>

1

나는이 코드를 GNU make와 함께 사용하여 개정 태그, 분기 또는 해시를 닫습니다.

git 버전 2.17.1에서 테스트되었습니다.

${dir}:
    mkdir -p ${@D}
    git clone --recursive --depth 1 --branch ${revison} ${url} ${@} \
 || git clone --recursive --branch ${revison} ${url} ${@} \
 || git clone ${url} ${@}
    cd ${@} && git reset --hard ${revison}
    ls $@





0

git clone https://github.com/ORGANIZATION/repository.git (저장소 복제)

cd repository (navigate to the repository)

git fetch origin 2600f4f928773d79164964137d514b85400b09b2

git checkout FETCH_HEAD


2
왜 복제 후 가져 오십시오. 를 복제하면 로컬 리포지토리에 전체 기록이 있습니다. 이 답변에 두 개의 공감대가있는 이유는 무엇입니까?
madhairsilence

0
# clone special tag/branch without history
git clone  --branch=<tag/branch> --depth=1 <repository>


# clone special revision with minimal histories
git clone --branch <branch> <repository> --shallow-since=yyyy-MM-ddTHH:mm:ss  # get the commit time
cd <dir>
git reset --hard <revision> 

uploadpack.allowReachableSHA1InWant=true서버 측에서 설정하지 않으면 기록이없는 개정을 얻을 수 없지만 대신 태그를 작성하고 특수 태그를 복제 할 수 있습니다.


-3

간단 해. 현재 브랜치의 업스트림을 설정해야합니다.

$ git clone repo
$ git checkout -b newbranch
$ git branch --set-upstream-to=origin/branch newbranch
$ git pull

그게 다야


-4
git clone -o <sha1-of-the-commit> <repository-url> <local-dir-name>

gitorigin널리 알려진 단어 대신 단어 를 사용합니다revision

다음은 매뉴얼의 스 니펫입니다. $ git help clone

--origin <name>, -o <name>
    Instead of using the remote name origin to keep track of the upstream repository, use <name>.

4
왜 당신이 여기에 억류되고 있는지 모릅니다. 이것은 내가 유스 케이스에 대해보고 싶었던 것입니다. 버전에서 특정 버전의 Linux 커널을 얻는 것은 릴리스로 태그를 지정하는 것이 좋지 않습니다 (RPi 사람들에게 문제가있는 것으로 보임). Linux의 전체 멀티 기가 바이트 기록을 다운로드합니다. 덧붙여서, 그것은 대접을했습니다.
Fordi

1
--depth=1답변에 언급되어 있지 않으므로 여기에 언급되지 않은 것을 더 추가하면 왜이 답변이 효과가 있다고 말할까요? 문제가 해결되어 기쁘지만이 답변은 오해의 소지가 있으며 부분적으로는 질문에 답변하지 않습니다. 따라서 downvotes.
Emil Styrke

5
@Fordi :이 답변을 사용 번호 그대로 당신에게 얻을 정확히 당신이 바닐라에서 얻을 것 같은 나무를 git clone <url> <local_dir_name>단지 자신을 위해보십시오. 유일한 차이점은 원격 (을 사용하여 git remote표시됨)이 관례적인 "origin"이라는 이름 대신 일부 암호화 된 sha1 시퀀스라고합니다. 즉, <sha1-of-the-commit>이 답변에서 언급이없는 있는 개정 분기 체크 아웃 할 서버 또는 어떤에서 페치 무엇이든지 베어링.
Emil Styrke

6
@ Fordi : 방금 했어 git clone -o 896066ee1cf4d653057dac4e952f49c96ad16fa7 https://github.com/torvalds/linux.git linux --depth=1. 이것은 나에게 수정을 제공 8a28d674하고 있지 896066ee 당신이 대답 주장으로.
Emil Styrke

4
"원산지"는 "개정"과 관련이 없으며이 답변은 완전히 잘못되었습니다.
Eevee
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.