"git export"(예 : "svn export")가 있습니까?


2356

.git저장소 디렉토리 없이 트리의 사본을 작성하는 좋은 "git export"솔루션이 있는지 궁금합니다 . 내가 아는 적어도 세 가지 방법이 있습니다.

  1. git clone그런 다음 .git저장소 디렉토리 를 제거하십시오 .
  2. git checkout-index 이 기능을 암시하지만 "원하는 트리를 인덱스로 읽어야합니다 ..."로 시작합니다.
  3. git-export본질적 git clone으로 임시 위치에 이어 rsync --exclude='.git'최종 목적지로 들어가는 타사 스크립트입니다 .

이 솔루션들 중 어느 것도 실제로 만족스럽지 않습니다. 두 svn export옵션 모두 대상 디렉토리를 먼저 비워야하기 때문에 가장 가까운 옵션은 옵션 1 일 수 있습니다. 그러나 트리를 인덱스로 읽는 것이 무엇을 의미하는지 알 수 있다고 가정하면 옵션 2가 훨씬 더 좋아 보입니다.


1
@rnrTom : Somov의 답변을 참조하십시오. (tar 아카이브에는 "압축 된"것이 없습니다).
etarion

23
@mrTom git archive --format zip --output "output.zip" master -0은 압축되지 않은 아카이브를 제공합니다 (-0은 압축되지 않은 플래그). git-scm.com/docs/git-archive .

7
@mrTom과 동의하며 보관 파일의 압축 여부는 주요 문제라고 생각하지 않습니다. SVN을 사용하면 export원격 리포지토리에서 직접 250kB 하위 디렉토리를 사용할 수 있습니다 (그렇지 않으면 수정본을 제외하고 크기는 200MB 일 수 있음). 로 git, archive(나는 그것을 시도하지 수) 서버에서 활성화해야합니다 - clone --depth 1서버에서 여전히 말 25메가바이트의 REPO 검색 할 수 있습니다 .git만 하위 폴더 15메가바이트을 걸립니다. 따라서 나는 여전히 대답이 "아니오"라고 말할 것입니다.
sdaau

@mrTom 그 대답은 사실 그렇습니다 OP의 대답을보십시오-명령은git checkout-index
nocache

다음은 훌륭하고 간단한 방법입니다.git archive -o latest.zip HEAD
Evgeni Sergeev

답변:


2396

아마도 이것을 달성하는 가장 간단한 방법은입니다 git archive. 확장 된 트리 만 정말로 필요하다면 이와 같은 것을 할 수 있습니다.

git archive master | tar -x -C /somewhere/else

대부분의 경우 git에서 무언가를 '내보내기'해야 할 때마다 압축 아카이브를 원하므로 이와 같은 작업을 수행해야합니다.

git archive master | bzip2 >source-tree.tar.bz2

ZIP 아카이브 :

git archive --format zip --output /full/path/to/zipfile.zip master 

git help archive 자세한 내용은 매우 유연합니다.


아카이브에 .git 디렉토리가 포함되어 있지 않더라도 .gitignore, .gitattributes 등과 같은 다른 숨겨진 git 특정 파일이 포함됩니다. 아카이브에 원하지 않는 경우, .gitattributes 파일에서 export-ignore 속성을 사용하고 아카이브를 수행하기 전에이를 커밋하십시오. 더 읽어보기 ...


참고 : 색인 내보내기에 관심이있는 경우 명령은

git checkout-index -a -f --prefix=/destination/path/

(자세한 내용은 Greg의 답변 을 참조하십시오)


198
ZIP 아카이브 :git archive --format zip --output /full/path master
Vadim

221
아카이브는 .git 디렉토리를 포함하지 않지만 .gitignore, .gitattributes 등과 같은 다른 숨겨진 git 특정 파일을 포함한다는 점에 유의하십시오. 원하지 않는 경우, .gitattributes 파일을 보관하고 아카이브하기 전에이를 커밋하십시오. 참조 feeding.cloud.geek.nz/2010/02/...
mj1531

54
Streams에 대한 후속 조치 참고 : '--prefix = something /'문자열을 명령에 추가하여 zip 안에 압축 될 디렉토리 이름을 제어 할 수 있습니다. 예를 들어, git archive --format zip --output /path/to/file.zip --prefix=newdir/ master출력 을 사용 하면 'file.zip'이되지만 압축을 풀면 최상위 디렉토리는 'newdir'이됩니다. --prefix 속성을 생략하면 최상위 디렉토리는 'file'이됩니다.
Alan W. Smith

89
가장 쉬운 방법 : git archive -o latest.zip HEAD현재 분기의 최신 커밋 내용을 포함하는 Zip 아카이브를 만듭니다. 출력 형식은 출력 파일의 확장자로 유추됩니다.
nacho4d

37
git 서브 모듈을 지원하지 않습니다 :(
umpirsky

320

옵션 2의 의미를 알았습니다. 저장소에서 다음을 수행 할 수 있습니다.

git checkout-index -a -f --prefix=/destination/path/

경로 끝에 슬래시가 중요합니다. 그렇지 않으면 접두어가 'path'인 파일이 / destination에있게됩니다.

정상적인 상황에서 인덱스는 저장소의 내용을 포함하기 때문에 "원하는 트리를 인덱스로 읽는"특별한 작업은 없습니다. 이미 있습니다.

-a플래그 (나는 확실히 그것이 내가하고 싶은 일을하지 않기 때문에,이 상황에서이 플래그를 생략 할 것이 무엇을 의미하는지 모르겠어요) 인덱스에있는 모든 파일을 확인하는 데 필요합니다. -f이 명령이 정상적으로 수행하지 않는 출력의 기존 파일을 덮어 플래그 힘.

이것은 내가 찾던 일종의 "git export"인 것으로 보입니다.


73
... 그리고
conny

1
git add명령은 색인의 내용을 변경하므로 git status"약속"으로 표시되는 것은 HEAD와 색인 내용의 차이 입니다.
Greg Hewgill

7
@conny : 코멘트를 읽고, 잊어 버리고 슬래시없이 명령을 실행하십시오. 팁 : conny의 조언을 따르십시오 -.-
Znarkus

35
코니의 조언을 +1하십시오. 또한 '~ / dest /'를 만들지 마십시오. 실제로 원하는 디렉토리가 아닌 작업 디렉토리에 '~'라는 디렉토리가 만들어지기 때문입니다. 당신이 어리석게 입력시 실행되는 사항 추측 RF RM은 ~
카일 Heironimus

5
@KyleHeironimus-쉘이 물결표 확장을 수행하지 않도록 지시하는 접두사 경로 주위에 따옴표를 사용하는 경우 '~ / dest /`사용에 대한 경고는 사실입니다. 작업 디렉토리에 ~( '~'! 아님) 이라는 디렉토리 가 생성됩니다. git checkout-index이와 관련하여 특별한 것은 없습니다 : 동일합니다 mkdir '~/dest'( 하지 마십시오! ). 인용이 필요한 파일 이름 (예 : 공백이있는 파일)을 피하는 또 다른 좋은 이유 :-)
Matt Wallis

254

git archive 원격 저장소와도 작동합니다.

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master | tar -xf -

repo 내부의 특정 경로를 내보내려면 git의 마지막 인수만큼 원하는 경로를 추가하십시오.

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master path1/ path2/ | tar -xv

6
이것은 내가 가장 좋아하는 옵션입니다. 베어 리포지토리에서도 작동한다는 추가 이점이 있습니다.
innaM

5
개선 된 버전은 다음과 같습니다. git archive --format=tar --prefix=PROJECT_NAME/ --remote=USER@SERVER:PROJECT_NAME.git master | tar -xf - (아카이브가 폴더에 있음)
Nick

7
참고 : 서버는이 기능을 활성화해야합니다.
Jakub Narębski

12
나는 시도했다 : git archive --format=zip --output foo.zip --remote=https://github.com/xxx.git master치명적 : 프로토콜이 지원하지 않는 작업. 예기치 않은 명령 스트림 끝.
andyf

7
@andyf GitHub는 독자적인 방법을 가지고 있습니다 : 문서curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -
주교

62

여기에 이미지 설명을 입력하십시오

리포지토리가 GitHub에서 호스팅되는 경우 특별한 사례 답변입니다.

그냥 사용하십시오 svn export.

내가 아는 한 Github은 허용하지 않습니다 archive --remote. GitHub는 svn 호환 가능 하지만 모든 git repos에 svn액세스 할 수 있으므로 svn exportGitHub URL을 약간 조정하여 정상적으로 사용할 수 있습니다.

예를 들어 전체 저장소를 내보내 trunk려면 URL이 어떻게 바뀌는 지 master(또는 프로젝트의 HEAD 브랜치가 무엇 으로 설정되어 있는지 ) 확인하십시오.

svn export https://github.com/username/repo-name/trunk/

단일 파일 또는 특정 경로 또는 폴더를 내보낼 수도 있습니다.

svn export https://github.com/username/repo-name/trunk/src/lib/folder

jQuery JavaScript 라이브러리를 사용한 예제

HEAD지점 또는 마스터 분기 가능한 사용 될 것입니다 trunk:

svn ls https://github.com/jquery/jquery/trunk

HEAD 지점 은 다음에서 액세스 할 수 있습니다 /branches/.

svn ls https://github.com/jquery/jquery/branches/2.1-stable

동일한 방식으로 아래 에있는 모든 태그/tags/ :

svn ls https://github.com/jquery/jquery/tags/2.1.3

1
git archive만큼 당신이 자식 프로토콜을 사용할 때, 그냥 교체, GitHub의 함께 잘 작동 https://으로 git://의 URL입니다. GitHub이 왜이 숨겨진 기능을 광고하지 않는지 모르겠습니다.
Neil Mayhew

1
@NeilMayhew 그것은 나를 위해 작동하지 않습니다 fatal: The remote end hung up unexpectedly. jQuery github repo를 사용하여 두 개의 다른 서버에서 시도했습니다.
Anthony Hatzopoulos

네가 옳아. git config url.<base>.insteadOf원격 저장소를 캐시하는 데 사용하고 있음을 잊었습니다 . 따라서 file://실제로 URL을 사용하고있었습니다 . URL 이 원격 끝에서 실행될 수 있어야하기 때문에 URL에서 git archive작동 할 수 있는지 의심 스럽습니다 . github에서 허용하지 않는 것을 제외하고 는 프로토콜을 사용하는 것이 가능해야 합니다 ( ). git://git-upload-archivesshInvalid command: 'git-upload-archive'
Neil Mayhew

내부 호스팅 git 리포지토리에서 github과 같은 로컬 서버 도구를 사용하는 방법은 무엇입니까?
kriss

1
upvoted-Git이이 기능을 가지고 있지 않다는 것은 완전히 기괴한 일이며 우리는 svn에 의지해야합니다
Jason S

40

로부터 힘내 설명서 :

git-checkout-index를 사용하여 "전체 트리 내보내기"

접두사 기능은 기본적으로 git-checkout-index를 "트리로 내보내기"기능으로 사용하는 것이 간단합니다. 원하는 트리를 인덱스로 읽고 다음을 수행하십시오.

$ git checkout-index --prefix=git-export-dir/ -a


19
나는 혼란이 "원하는 나무를 색인으로 읽는다"라는 문구라고 생각합니다.
davetron5000

4
브랜치 바에서 foo 디렉토리를 내보내려면 다음 git read-tree bar:foo과 같이 git checkout-index --prefix=export_dir/ -a해야합니다.git update-index master
Pascal Rosin

1
@JohnWeldon 먼저 저장소를 복제해야합니까? 만약 그렇다면, 서브 디렉토리의 "svn export"의 요점은 그 서브 디렉토리의 사본을 직접 얻는 것이므로 그것을 받아들이지 않을 것입니다. 누군가 1GB Git 저장소를 가지고 있고 원하는 모든 것이 10kB 하위 디렉토리라면 모든 것을 복제해야한다는 것은 미친 짓입니다.
Jason S

3
또한 @ davetron5000을 에코하여 "원하는 트리를 인덱스로 읽습니다"라는 의미로 의미가 무엇인지 모릅니다.
Jason S

38

다음 git-checkout-index과 같이 사용할 수 있는 간단한 래퍼를 작성했습니다 .

git export ~/the/destination/dir

대상 디렉토리가 이미 존재하지 않으면 추가해야합니다 -f--force.

설치는 간단합니다. 에서 스크립트를 삭제하고 PATH실행 파일인지 확인하십시오.

의 github 저장소 git-export


15
이 랩퍼는 플랫폼에 구애받지 않습니다. / bin / sh에 의존합니다. Windows에서있어 경우에 따라서,이 솔루션은 아마 당신을 위해 작동하지 않습니다.
shovavnik

18
어,이 스크립트는 57 줄의 문서, 공백, 설정, 인자 파싱, 실제로 무언가를하는 한 줄입니다 ...
Vladimir Panteleev

36

이것은 SVN보다 Git의 문제가 적은 것으로 보입니다. Git은 저장소 루트에 .git 폴더 만 저장하고 SVN은 모든 하위 디렉토리에 .svn 폴더를 저장합니다. 따라서 "svn export"는 재귀적인 명령 줄 마술을 피하지만 Git 재귀는 필요하지 않습니다.


26
SVN 1.7부터 .svn 폴더도 하나 있습니다. subversion.apache.org/docs/release-notes/1.7.html#single-db
kostmo

이것은 svn export가 삭제하는 추가 빌드 파일을 제거하지 않습니다. 따라서 이것은 대답이 아닙니다.
ygoe

28

동등한

svn export . otherpath

기존 레포 내부

git archive branchname | (cd otherpath; tar x)

동등한

svn export url otherpath

이다

git archive --remote=url branchname | (cd otherpath; tar x)

1
감사합니다, 이것은 내가 누락 된 것입니다 ... 또한 내보내기 타임 스탬프 (파일과 같이 보존되지 않음)를 확인하려면 git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)...을 사용하십시오 . 그러나 타임 스탬프로 보관하는 것은 정확하지 않습니다. 아래 예 .
sdaau

1
서브 쉘 대신 tar에 C 옵션을 사용할 수 있습니다. git archive branchname | tar xC otherpath
James Moore

것을 머리까지 C타르에 대한 옵션은 GNU 타르입니다.
aredridel

22

파일을 제외하지 않으면 .gitattributes export-ignore다음을 시도하십시오.git checkout

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout -f -q

-f
색인에서 경로를 체크 아웃 할 때 병합되지 않은 항목에 대해 실패하지 마십시오. 대신 병합되지 않은 항목은 무시됩니다.

-q
자세한 정보를 피하십시오

또한 SHA1을 추가하기 만하면 SVN과 같은 특정 커밋 수정본 또는 분기 또는 태그를 얻을 수 있습니다 (Git의 SHA1은 SVN의 수정본 번호와 동일 함)

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout 2ef2e1f2de5f3d4f5e87df7d8 -f -q -- ./

/path/to/checkout/망할 놈의 모든 파일을 삭제하지 않습니다, 비어 있어야하지만, 경고없이 동일한 이름의 파일을 덮어 쓰게됩니다

업데이트 : 태그, 분기 또는 SHA1로 내보내기에 체크 아웃을 사용할 때 참수 된 문제를 피하거나 작업 저장소를 그대로 유지 -- ./하려면 끝에 추가해야합니다

이중 대시 --는 git에게 대시 뒤의 모든 것이 경로 또는 파일임을 알리고이 경우 git checkout에는 변경하지 말라고 지시 합니다.HEAD

예 :

이 명령은 libs 디렉토리와 readme.txt정확히 커밋 된 파일을 가져옵니다.

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout fef2e1f2de5f3d4f5e87df7d8 -f -q -- ./libs ./docs/readme.txt

이것은 my_file_2_behind_HEAD.txt머리 뒤에 두 개의 커밋 을 생성 (덮어 쓰기) 합니다HEAD^2

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout HEAD^2 -f -q -- ./my_file_2_behind_HEAD.txt

다른 지점의 수출을 얻으려면

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout myotherbranch -f -q -- ./

공지 사항 ./저장소의 루트에 상대적인


실제로 많은 다른 사람들과 공감하는 사람들 사이에서 압축없이 나에게 가장 효과적이며 베어 리포지토리 (gitolite)와 잘 작동했습니다.
takeshin

1
SHA1 체크 아웃은 리포지토리에 "
behead

실제로 @ITGabs는 ".git"폴더를 다운로드하지 않습니다. 따라서 다운로드 한 폴더는 git 저장소가 아니므로 기술적으로 "참수"되지 않습니다
Fabio Marreco

@FabioMarreco 참수 문제는 내보내거나 다운로드 한 파일이 아닌 저장소에 있습니다. 자세한 내용은 답변을 업데이트하겠습니다
user5286776117878

3
이것은 나를 위해 잘 작동했습니다. 그러나 처음에는 "git 저장소 아님"오류 메시지가 나타납니다. 그런 다음 "/ path / to / repo /"가 .git 폴더를 가리켜 야한다는 것을 알았습니다. --git-dir = / path / to / repo / .git
philburk

21

git-submodule을 광범위하게 사용합니다. 이것은 나를 위해 작동합니다 :

rsync -a ./FROM/ ./TO --exclude='.*'

1
이름이 .htaccess? 로 시작하는 파일을 그리워하지 않습니까?
Greg Hewgill

8
좋은 해결책은 --exclude = '. *'를 --exclude = '. git *'로
바꾸는 것입니다

18
--exclude-VCS는이 전술이 걸릴 거라고 경우
터벅 터벅 걷는

./FROM/이 원격 저장소가 될 수 있습니까?
디자인 저항

2
참고로, 내 사본 rsync에는 인수가로 나열되어 --cvs-exclude있습니다. 또한, 여전히 복사 .gitattributes.gitignore
Ryan Ransford

19

자식 저장소를 내보내는 방법을 찾을 때이 페이지를 자주 방문했습니다. 이 질문에 대한 나의 대답은 svn이 중앙 집중식 저장소 접근 방식을 따르기 때문에 svn 내보내기가 git과 비교하여 설계 상으로 갖는 세 가지 속성을 고려합니다.

  • 모든 개정을 내 보내지 않아 원격 저장소 위치로의 트래픽을 최소화합니다.
  • 내보내기 디렉토리에 메타 정보가 포함되어 있지 않습니다
  • svn을 사용하여 특정 분기를 내보내려면 적절한 경로를 지정하십시오.

    git clone --depth 1 --branch master git://git.somewhere destination_path
    rm -rf destination_path/.git
    

특정 릴리스를 빌드 할 때는 안정적인 분기를 복제하는 것이 좋습니다 ( 예 : --branch stable또는) --branch release/0.9.


대상이 존재하고 비어 있지 않으면 작동하지 않습니다.
시조

2
하나의 진정한 답변 : 그것은 깊이에서 발생합니다. git archive | tar방식은 POSIX 비 호환 쉘 환경 (예 : AppVeyor의 CMD 또는 PowerShell 기반 CI)에는 적용 할 수 없으며 이는 비 이상적입니다. 이 git checkout접근 방식은 기본 작업 트리의 색인을 수정합니다. 이 git checkout-index접근 방식을 사용하려면 기본 작업 트리의 색인을 미리 수정해야합니다. 기존의 git clone접근 방식은 해당 기록을 삭제하기 전에 전체 저장소 기록을 복제하므로 낭비입니다. 이것은 유일한 제정신 솔루션입니다.
Cecil Curry

1
로컬로 내보내려면 복제 할 Git 작업 트리의 절대 경로 앞에 file://프로토콜 (예 :)을 붙여야합니다 git clone --depth 1 --branch v3.14.15 file:///home/me/src_repo trg_repo. 그렇게하지 않으면 "warning: --depth is ignored in local clones; use file:// instead."얕은 복제보다는 표준을 방출 하고 수행하여이 답변의 전체 목적을 무효화합니다. 살 루드!
세실 커리

16

.dot 파일을 제외한 모든 내용이 복사됩니다. git 복제없이 git clone 프로젝트를 내 웹 앱의 git repo로 내보내는 데 사용합니다.

cp -R ./path-to-git-repo / path / to / destination /

평범한 오래된 배쉬는 잘 작동합니다 :)


왜 리모컨에 밀어 넣지 않겠습니까? bash보다 훨씬 간단합니다.
nurettin

2
웹 응용 프로그램의 일부인 파일은 이름이 점으로 시작합니까? :) .htaccess에 대해 생각
Artur

3
때로는에있는 내용을 무시하고 싶지만 .gitignore그렇지 않습니다.
fregante

14

클론처럼 간단하고 .git 폴더를 삭제하십시오.

git clone url_of_your_repo path_to_export && rm -rf path_to_export/.git


4
솔직히-이 답변은 질문에서 1 위입니다-99 %의 시간을 할 것입니다. 이러한 답변의 대부분은 너무 복잡합니다.
Geoff Nixon

11

GitHub 사용자의 경우 내보내기 URL이 임시이므로git archive --remote 메소드가 직접 작동하지 않습니다 . URL을 GitHub에 요청한 다음 해당 URL을 다운로드해야합니다. 그것을 쉽게 만든다 :curl

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -

이렇게하면 내 보낸 코드가 로컬 디렉토리에 제공됩니다. 예:

$ curl -L https://api.github.com/repos/jpic/bashworks/tarball | tar xzf -
$ ls jpic-bashworks-34f4441/
break  conf  docs  hack  LICENSE  mlog  module  mpd  mtests  os  README.rst  remote  todo  vcs  vps  wepcrack

편집
코드가 github의 임의의 디렉토리가 아닌 기존 의 특정 디렉토리에 저장되도록 하려면 다음을 수행하십시오.

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | \
tar xzC /path/you/want --strip 1

11

예, 이것은 아카이브에 git 포함없이 코드를 아카이브하는 깔끔하고 깔끔한 명령이며 git commit history에 대해 걱정하지 않고 전달하는 것이 좋습니다.

git archive --format zip --output /full/path/to/zipfile.zip master 

이것은 훌륭합니다. 후에 gitignore를 제거하고 완료되고 공유 할 준비가되었습니다.
Sogger

.gitgnore 등의 제거를 허용 대답 코멘트에 언급되어 사용이 파일을 .gitattributes, 참조 feeding.cloud.geek.nz/posts/excluding-files-from-git-archive
Sogger

10

난 당신이있는 경우에 지적하고 싶습니다

  1. 저장소의 하위 폴더 내보내기 (SVN 내보내기 기능 사용 방법)
  2. 해당 폴더에서 배포 대상으로 모든 내용을 복사해도 괜찮습니다.
  3. 이미 전체 리포지토리의 복사본을 가지고 있기 때문에.

그런 다음 cp foo [destination]언급 된 대신 사용할 수 있습니다 git-archive master foo | -x -C [destination].


9

커밋에서 원격 저장소를 zip 파일로 보관할 수 있습니다.

git archive --format=zip --output=archive.zip --remote=USERNAME@HOSTNAME:PROJECTNAME.git HASHOFGITCOMMIT

8

자식 내보내기의 대쉬 구현.

.empty 파일 생성 및 제거 프로세스를 'git-archive'구현에서 재사용하기 위해 자체 기능으로 분할했습니다 (나중에 게시 될 예정입니다).

또한 대상 내보내기 폴더에서 원하지 않는 파일을 제거하기 위해 '.gitattributes'파일을 프로세스에 추가했습니다. 'git-export'기능을보다 효율적으로 만들면서 프로세스에 자세한 정보가 포함되었습니다.

EMPTY_FILE = ". empty";

function create_empty () {
## Processing path (target-dir):
    TRG_PATH="${1}";
## Component(s):
    EXCLUDE_DIR=".git";
echo -en "\nAdding '${EMPTY_FILE}' files to empty folder(s): ...";
    find ${TRG_PATH} -not -path "*/${EXCLUDE_DIR}/*" -type d -empty -exec touch {}/${EMPTY_FILE} \;
#echo "done.";
## Purging SRC/TRG_DIRs variable(s):
    unset TRG_PATH EMPTY_FILE EXCLUDE_DIR;
    return 0;
  }

declare -a GIT_EXCLUDE;
function load_exclude () {
    SRC_PATH="${1}";
    ITEMS=0; while read LINE; do
#      echo -e "Line [${ITEMS}]: '${LINE%%\ *}'";
      GIT_EXCLUDE[((ITEMS++))]=${LINE%%\ *};
    done < ${SRC_PATH}/.gitattributes;
    GIT_EXCLUDE[${ITEMS}]="${EMPTY_FILE}";
## Purging variable(s):
    unset SRC_PATH ITEMS;
    return 0;
  }

function purge_empty () {
## Processing path (Source/Target-dir):
    SRC_PATH="${1}";
    TRG_PATH="${2}";
echo -e "\nPurging Git-Specific component(s): ... ";
    find ${SRC_PATH} -type f -name ${EMPTY_FILE} -exec /bin/rm '{}' \;
    for xRULE in ${GIT_EXCLUDE[@]}; do
echo -en "    '${TRG_PATH}/{${xRULE}}' files ... ";
      find ${TRG_PATH} -type f -name "${xRULE}" -exec /bin/rm -rf '{}' \;
echo "done.'";
    done;
echo -e "done.\n"
## Purging SRC/TRG_PATHs variable(s):
    unset SRC_PATH; unset TRG_PATH;
    return 0;
  }

function git-export () {
    TRG_DIR="${1}"; SRC_DIR="${2}";
    if [ -z "${SRC_DIR}" ]; then SRC_DIR="${PWD}"; fi
    load_exclude "${SRC_DIR}";
## Dynamically added '.empty' files to the Git-Structure:
    create_empty "${SRC_DIR}";
    GIT_COMMIT="Including '${EMPTY_FILE}' files into Git-Index container."; #echo -e "\n${GIT_COMMIT}";
    git add .; git commit --quiet --all --verbose --message "${GIT_COMMIT}";
    if [ "${?}" -eq 0 ]; then echo " done."; fi
    /bin/rm -rf ${TRG_DIR} && mkdir -p "${TRG_DIR}";
echo -en "\nChecking-Out Index component(s): ... ";
    git checkout-index --prefix=${TRG_DIR}/ -q -f -a
## Reset: --mixed = reset HEAD and index:
    if [ "${?}" -eq 0 ]; then
echo "done."; echo -en "Resetting HEAD and Index: ... ";
        git reset --soft HEAD^;
        if [ "${?}" -eq 0 ]; then
echo "done.";
## Purging Git-specific components and '.empty' files from Target-Dir:
            purge_empty "${SRC_DIR}" "${TRG_DIR}"
          else echo "failed.";
        fi
## Archiving exported-content:
echo -en "Archiving Checked-Out component(s): ... ";
        if [ -f "${TRG_DIR}.tgz" ]; then /bin/rm ${TRG_DIR}.tgz; fi
        cd ${TRG_DIR} && tar -czf ${TRG_DIR}.tgz ./; cd ${SRC_DIR}
echo "done.";
## Listing *.tgz file attributes:
## Warning: Un-TAR this file to a specific directory:
        ls -al ${TRG_DIR}.tgz
      else echo "failed.";
    fi
## Purgin all references to Un-Staged File(s):
   git reset HEAD;
## Purging SRC/TRG_DIRs variable(s):
    unset SRC_DIR; unset TRG_DIR;
    echo "";
    return 0;
  }

산출:

$ git-export /tmp/rel-1.0.0

빈 폴더에 '.empty'파일 추가 : ... 완료.

체크 아웃 색인 구성 요소 : ... 완료.

HEAD 및 색인 재설정 : ... 완료.

힘내 특정 구성 요소 제거 : ...

'/tmp/rel-1.0.0/{.buildpath}'파일 ... 완료. '

'/tmp/rel-1.0.0/{.project}'파일 ... 완료. '

'/tmp/rel-1.0.0/{.gitignore}'파일 ... 완료. '

'/tmp/rel-1.0.0/{.git}'파일 ... 완료. '

'/tmp/rel-1.0.0/{.gitattributes}'파일 ... 완료. '

'/tmp/rel-1.0.0/{*.mno}'파일 ... 완료. '

'/tmp/rel-1.0.0/{*~}'파일 ... 완료. '

'/tmp/rel-1.0.0/{.*~}'파일 ... 완료. '

'/tmp/rel-1.0.0/{*.swp}'파일 ... 완료. '

'/tmp/rel-1.0.0/{*.swo}'파일 ... 완료. '

'/tmp/rel-1.0.0/{.DS_Store}'파일 ... 완료. '

'/tmp/rel-1.0.0/{.settings}'파일 ... 완료. '

'/tmp/rel-1.0.0/{.empty}'파일 ... 완료. '

끝난.

체크 아웃 된 구성 요소 아카이브 : ... 완료.

-rw-r--r-- 1 관리자 휠 25445901 3 11 월 12:57 /tmp/rel-1.0.0.tgz

이제 'git archive'기능을 'create_empty'기능 및 기타 기능을 사용하는 단일 프로세스에 통합했습니다.

function git-archive () {
    PREFIX="${1}"; ## sudo mkdir -p ${PREFIX}
    REPO_PATH="`echo "${2}"|awk -F: '{print $1}'`";
    RELEASE="`echo "${2}"|awk -F: '{print $2}'`";
    USER_PATH="${PWD}";
echo "$PREFIX $REPO_PATH $RELEASE $USER_PATH";
## Dynamically added '.empty' files to the Git-Structure:
    cd "${REPO_PATH}"; populate_empty .; echo -en "\n";
#    git archive --prefix=git-1.4.0/ -o git-1.4.0.tar.gz v1.4.0
# e.g.: git-archive /var/www/htdocs /repos/domain.name/website:rel-1.0.0 --explode
    OUTPUT_FILE="${USER_PATH}/${RELEASE}.tar.gz";
    git archive --verbose --prefix=${PREFIX}/ -o ${OUTPUT_FILE} ${RELEASE}
    cd "${USER_PATH}";
    if [[ "${3}" =~ [--explode] ]]; then
      if [ -d "./${RELEASE}" ]; then /bin/rm -rf "./${RELEASE}"; fi
      mkdir -p ./${RELEASE}; tar -xzf "${OUTPUT_FILE}" -C ./${RELEASE}
    fi
## Purging SRC/TRG_DIRs variable(s):
    unset PREFIX REPO_PATH RELEASE USER_PATH OUTPUT_FILE;
    return 0;
  }

사용법 : git-archive [/ var / www / htdocs] /repos/web.domain/website:rel-1.0.0
tocororo

8

서브 모듈과 작동하는 것을 원한다면 이것은 가치가 있습니다.

노트 :

  • MASTER_DIR = 하위 모듈을 체크 아웃 한 상태에서도 체크 아웃
  • DEST_DIR =이 내보내기가 끝나는 곳
  • 당신이 rsync를 가지고 있다면, 당신은 훨씬 적은 공 통증으로 같은 일을 할 수 있다고 생각합니다.

가정 :

  • MASTER_DIR의 상위 디렉토리 (예 : MASTER_DIR cd ..)에서이를 실행해야합니다.
  • DEST_DIR이 생성 된 것으로 가정합니다. 원하는 경우 DEST_DIR 작성을 포함하도록 수정하기가 매우 쉽습니다.

cd MASTER_DIR && tar -zcvf ../DEST_DIR/export.tar.gz --exclude = '. git *'. && cd ../DEST_DIR/ && tar xvfz export.tar.gz && rm export.tar.gz


6

내 선호는 실제로 거리 를 갖는 것입니다 Makefile (또는 다른 빌드 시스템)에 배포 가능한 코드 아카이브 (.tar.bz2, .zip, .jar 또는 적절한 것)를 내보내는 대상 입니다. GNU autotools 또는 Perl의 MakeMaker 시스템을 사용하고 있다면 이것이 자동으로 존재한다고 생각합니다. 그렇지 않은 경우 추가하는 것이 좋습니다.

ETA (2012-09-06) : 와우, 가혹한 다운 보트. 여전히 소스 코드 제어 도구가 아닌 빌드 도구를 사용하여 배포판을 작성하는 것이 좋습니다. 빌드 도구를 사용하여 아티팩트를 빌드한다고 생각합니다. 나의 현재 직업에서, 우리의 주요 제품은 개미 대상으로 만들어졌습니다. 우리는 스위칭 소스 코드 제어 시스템의 한가운데에 있으며,이 개미 대상의 존재는 마이그레이션의 번거 로움을 줄여줍니다.


내가 생각한 프로젝트는 코드 프로젝트가 아닙니다. 그것은 웹 사이트 프로젝트의 라인을 따라 더 많이 발생합니다.
Greg Hewgill

질문을 다루지 않습니다.
Andrew Ferrier

1
예, 그러한 답변은 모든 사람의 요구에 맞지 않을 수도 있지만, 공감대는 기괴합니다. 그것은 이다 , 많은 시나리오에서, 참으로 유일한 정답 완전히 유효한 대답합니다. 이 문제를 "vc 도구 문제"로 생각하는 것은 종종 잘못된 길을 가고 있다는 것이 매우 타당합니다.
snogglethorpe

6

커밋 범위 (C ~ G)의 파일을 tar 파일로 복사합니다. 참고 : 이것은 커밋 된 파일 만 가져옵니다. 전체 저장소가 아닙니다. 여기 에서 약간 수정

커밋 히스토리 예

A-> B-> C-> D-> E-> F-> G- > H-> I

git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT C~..G | xargs tar -rf myTarFile.tar

git-diff-tree 매뉴얼 페이지

-r-> 하위 트리로 재귀

--no-commit-id-> git diff-tree는 적용 가능한 경우 커밋 ID가있는 행을 출력합니다. 이 플래그는 커밋 ID 출력을 억제했습니다.

--name-only-> 변경된 파일 이름 만 표시합니다.

--diff-filter = ACMRT->이 파일들만 선택하십시오. 전체 파일 목록은 여기를 참조하십시오

C..G->이 커밋 범위의 파일

C ~-> Commit C의 파일을 포함합니다. Commit C 이후의 파일 만이 아닙니다.

| xargs tar -rf myTarFile-> tar로 출력


5

질문을 이해함에 따라 로컬 리포지토리에서 상태를 추출하지 않고 서버에서 히스토리없이 다른 분기의 데이터없이 서버에서 특정 상태를 다운로드하는 것이 더 중요합니다.

다음과 같이 할 수 있습니다 :

git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \
&& rm -rf repo/.git/
  • --single-branch Git 1.7.10 (2012 년 4 월)부터 사용할 수 있습니다.
  • --depth(was?)에 결함이있는 것으로보고 되었지만, 수출의 경우 언급 된 문제는 중요하지 않습니다.

참고 : 방금 2 페이지의 답변이 있음을 알았습니다. 게시하기 전에 한 페이지 만 보았습니다. 하나만있는 유사한 anwser가 있습니다 --depth. 이것은 주어진 --single-branch경우 --no-single-branch가 아니면 암시 합니다 . 이는 아마도 동일한 효과가 있음을 의미합니다. 확실하지 않으면 일부 전문가가 확인할 수 있습니까?
Ondra Žižka

4

배포 스크립트에 이것이 필요했으며 위에서 언급 한 접근법을 사용할 수 없었습니다. 대신 다른 해결책을 찾았습니다.

#!/bin/sh
[ $# -eq 2 ] || echo "USAGE $0 REPOSITORY DESTINATION" && exit 1
REPOSITORY=$1
DESTINATION=$2
TMPNAME="/tmp/$(basename $REPOSITORY).$$"
git clone $REPOSITORY $TMPNAME
rm -rf $TMPNAME/.git
mkdir -p $DESTINATION
cp -r $TMPNAME/* $DESTINATION
rm -rf $TMPNAME

읽기 트리 / 체크 아웃 인덱스 또는 아카이브 솔루션의 문제점은 무엇입니까? 내가 말할 수있는 한 mkdir -p "$2" && git --git-dir="$1" archive HEAD | tar -x -C "$2"다소 더 오래 감기 는 것과 동등한 것을했습니다 .
CB Bailey

1
원격 저장소에서 작동하기 위해 읽기 트리를 가져올 수 없으며 아카이브 솔루션이 github에서 작동하지 않습니다.
troelskn

예 아카이브와 잘못된 명령을받을 : '자식 업로드 아카이브'... 오류와 나는 그나마 유무 core.gitProxy 설정 옵션과 GIT_PROXY_COMMAND 환경 변수 설정
tgkprog

4

쉬운 방법으로 .bash_profile의 기능으로 현재 위치에서 아카이브의 압축을 직접 풀고 먼저 일반적인 [url : path]를 구성하십시오. 참고 :이 기능을 사용하면 복제 작업을 피할 수 있으며 원격 리포지토리에서 직접 가져옵니다.

gitss() {
    URL=[url:path]

    TMPFILE="`/bin/tempfile`"
    if [ "$1" = "" ]; then
        echo -e "Use: gitss repo [tree/commit]\n"
        return
    fi
    if [ "$2" = "" ]; then
        TREEISH="HEAD"
    else
        TREEISH="$2"
    fi
    echo "Getting $1/$TREEISH..."
    git archive --format=zip --remote=$URL/$1 $TREEISH > $TMPFILE && unzip $TMPFILE && echo -e "\nDone\n"
    rm $TMPFILE
}

.gitconfig의 별칭, 동일한 구성이 필요합니다 (.git 프로젝트 내에서 명령을 실행하도록주의 하십시오 . 이것은 고정 될 때까지 항상 이전에 기본 디렉토리로 이동합니다.

ss = !env GIT_TMPFILE="`/bin/tempfile`" sh -c 'git archive --format=zip --remote=[url:path]/$1 $2 \ > $GIT_TMPFILE && unzip $GIT_TMPFILE && rm $GIT_TMPFILE' -

4

지금까지 내가 본 가장 쉬운 방법은 git bundle다음과 같습니다 ( Windows에서도 작동) .

git bundle create /some/bundle/path.bundle --all

자세한 내용은이 답변을 참조하십시오 : USB 드라이브를 통해 Windows 시스템에서 Linux 시스템으로 git 저장소를 복사하는 방법은 무엇입니까?


git bundle.gitOP가 원하지 않는 폴더를 포함합니다 . git archive더 적절한 방법으로 보인다
ssc

--all스위치의 설명서는 어디에 있습니까 ?
Garret Wilson

4

내보내기를 만들려는 컴퓨터에 리포지토리의 로컬 복사본이 있으면 잘 작동하는 다른 솔루션이 있습니다. 이 경우이 저장소 디렉토리로 이동하고 다음 명령을 입력하십시오.

GIT_WORK_TREE=outputdirectory git checkout -f

이것은 git 저장소로 웹 사이트를 관리하고에서 깨끗한 버전을 체크 아웃하려는 경우 특히 유용합니다 /var/www/. 이 경우 .git/hooks/post-receive스크립트 에이 명령을 추가하십시오 ( hooks/post-receive이 상황에 더 적합한 베어 저장소에 있음).


3

@Aredridel 의 게시물이 가장 가깝다고 생각 하지만 조금 더 있습니다. 여기에 추가하겠습니다. 건에서, svn당신은 환매 특약의 하위 폴더에있어, 그리고 당신이 할 경우 :

/media/disk/repo_svn/subdir$ svn export . /media/disk2/repo_svn_B/subdir

그런 다음 svn개정 관리중인 모든 파일을 내보낼 것입니다 (새로 추가되거나 수정 된 상태 일 수 있음)-해당 디렉토리에 다른 "정크"가있는 경우 ( .svn여기서는 하위 폴더를 세지 않지만 .o파일 과 같이 보이는 항목은 계산하지 않습니다 ) , 그것은 것입니다 하지 내보낼 수; SVN 저장소에 등록 된 파일 만 내 보냅니다. 나를 위해, 하나의 좋은 일이 수출 또한 한 지역 변경 파일이 포함되어 있다는 것입니다 하지 아직 커밋을; 또 다른 좋은 점은 내 보낸 파일의 타임 스탬프가 원본 파일의 타임 스탬프와 동일하다는 것입니다. 또는, 같은 svn help export풋 그것은 :

  1. 수정 된 REV (있는 경우), WORKING (있는 경우), PATH2로 지정된 PATH1에 지정된 작업 사본에서 클린 디렉토리 트리를 내 보냅니다. ... REV를 지정하지 않으면 모든 로컬 변경 사항이 유지됩니다. 버전 관리 대상이 아닌 파일은 복사되지 않습니다.

git타임 스탬프가 유지되지 않도록 하려면 이 명령의 출력 ( git선택한 리포지토리의 하위 폴더에 있음 )을 비교하십시오.

/media/disk/git_svn/subdir$ ls -la .

... 그리고 :

/media/disk/git_svn/subdir$ git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)

... 어쨌든 git archive보관 된 파일의 모든 타임 스탬프가 동일하게됩니다. git help archive말한다 :

git archive는 트리 ID가 주어 졌을 때와 커밋 ID 또는 태그 ID가 주어 졌을 때 다르게 작동합니다. 첫 번째 경우 현재 시간은 아카이브에있는 각 파일의 수정 시간으로 사용됩니다. 후자의 경우 참조 된 커밋 개체에 기록 된 커밋 시간이 대신 사용됩니다.

...하지만 분명히 두 경우 모두 " 파일의 수정 시간"을 설정합니다 . 이에 되지 해당 파일의 실제 타임 스탬프를 보존 !

따라서 타임 스탬프를 유지하기 위해 여기에는 bash다소 복잡하지만 실제로는 "한 줄짜리"스크립트가 있습니다. 아래에는 여러 줄로 표시됩니다.

/media/disk/git_svn/subdir$ git archive --format=tar master | (tar tf -) | (\
  DEST="/media/diskC/tmp/subdirB"; \
  CWD="$PWD"; \
  while read line; do \
    DN=$(dirname "$line"); BN=$(basename "$line"); \
    SRD="$CWD"; TGD="$DEST"; \
    if [ "$DN" != "." ]; then \
      SRD="$SRD/$DN" ; TGD="$TGD/$DN" ; \
      if [ ! -d "$TGD" ] ; then \
        CMD="mkdir \"$TGD\"; touch -r \"$SRD\" \"$TGD\""; \
        echo "$CMD"; \
        eval "$CMD"; \
      fi; \
    fi; \
    CMD="cp -a \"$SRD/$BN\" \"$TGD/\""; \
    echo "$CMD"; \
    eval "$CMD"; \
    done \
)

컨텐츠를 "현재"디렉토리 (위의 /media/disk/git_svn/subdir)로 내보내는 것으로 가정하고 내보내는 대상이 다소 불편하지만 DEST환경 변수에 있다고 가정 합니다. 이 스크립트로; 당신은DEST위 스크립트를 실행하기 전에 직접 디렉토리를 직접 .

스크립트가 실행 된 후에는 다음을 비교할 수 있어야합니다.

ls -la /media/disk/git_svn/subdir
ls -la /media/diskC/tmp/subdirB   # DEST

... 그리고 버전 관리하에있는 파일에 대해 동일한 타임 스탬프가 표시되기를 바랍니다.

이것이 누군가에게 도움이
되기를 바랍니다 , 건배!


3

접두사 (예 : 디렉토리 이름)를 추가하는 동안 zip 아카이브로 git 내보내기 :

git archive master --prefix=directoryWithinZip/  --format=zip -o out.zip


1

내 .bashrc 파일에 다음 유틸리티 기능이 있습니다 .git 저장소에 현재 분기의 아카이브를 만듭니다.

function garchive()
{
  if [[ "x$1" == "x-h" || "x$1" == "x" ]]; then
    cat <<EOF
Usage: garchive <archive-name>
create zip archive of the current branch into <archive-name>
EOF
  else
    local oname=$1
    set -x
    local bname=$(git branch | grep -F "*" | sed -e 's#^*##')
    git archive --format zip --output ${oname} ${bname}
    set +x
  fi
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.