베어 git 저장소를 일반 저장소로 어떻게 변환합니까?


81

베어 git 저장소가 있지만 ssh (사용자 경험과 같은 파일 관리자에서)를 통해 컨텐츠에 액세스하고 찾아 볼 필요가 있습니다.

나는 그것을 복제 할 수 있다고 가정합니다.

git clone -l <path_to_bare_repo> <new_normal_repo>

그러나 내 저장소의 크기는 약 20GB이며 복제 할 공간이 없습니다. 베어 저장소를 제자리에서 변환하여 작업 복사본을 만드는 방법이 있습니까?


5
테스트되지 않았지만 베어 저장소의 내용을 .git디렉토리 bare에 넣고 구성 의 매개 변수를 false로 설정하면 git checkout파일을 가져올 수있는 일반 저장소처럼 동작해야합니다 .
Noufal Ibrahim

당신이 "내용을 찾아"무슨 뜻인지에 따라, 당신은 아마 당신이 사용하는 베어의 repo에서 원하는 모든 것을 할 수 git showgit cat-file
윌리엄 Pursell

유용한 힌트 주셔서 감사합니다. 그래도 경험과 같은 파일 관리자가 더 필요합니다 (질문 편집).
nyi

파일 시스템이 하드 링크를 지원하고 동일한 파일 시스템으로 복제하는 경우 clone -l은 모든 개체를 하드 링크하기 때문에 더 이상 디스크 공간을 차지하지 않습니다. 그러나 다른 사람들이 언급했듯이 체크 아웃을위한 공간이 필요합니다.
Neil Mayhew 2014

1
귀하의 경우 베어 저장소는 디스크 공간 20GB의를 차지, 얼마나 더 작업 트리 필요 것? 당신이 할 정말 그렇게 많은 공간이?
ADTC

답변:


113

참고 : 나는 이것을 매우 간단한 1- 커밋 저장소 에서 테스트했습니다 . 이것을 다시 확인하고 man 페이지를 읽고 StackOverflow에서 찾은 조언을 따르기 전에 항상 백업 해 두십시오. (백업하지?)

--bare저장소를 베어가 아닌 것으로 변환하려면 다음을 수행하십시오.

  1. .git저장소의 최상위 수준에 폴더를 만듭니다 .
  2. 방금 만든 저장소 관리 항목 ( HEAD branches config description hooks info objects refs등)을 이동합니다 .git.
  3. git config --local --bool core.bare false로컬 git-repository를 non-bare로 변환하려면 실행하십시오 .
  4. ( Tamas Pap의 의견을 통해 ) # 3 단계 후에는 브랜치 master(또는 메인 브랜치)에 있고 모든 파일이 삭제되고 삭제가 준비 되었음을 알 수 있습니다 . 그것은 정상입니다. 그냥 수동으로 체크 아웃 master, 또는을 git reset --hard, 그리고 당신이 완료됩니다.
  5. ( Royi 가보고 한 문제를 해결하기 위해 ) 섹션 에서 .git/configfetch = +refs/heads/*:refs/remotes/origin/*을 추가하여 파일을 편집 합니다 . 그렇지 않으면 다른 원산지의 분기를 볼 수 없습니다 .url = <...>[remote "origin"]git fetchorigin/master

이 단계의 반대 방향에있는 이 질문에 , "보통 자식 - 변환이 저장소 베어하기"- 특정 주에서 이 대답 (어느 방향으로, 나는 가정에서) 위의 단계가한다고, 다른 을하고부터 git-clone. 그것이 당신과 관련이 있는지 확실하지 않지만 git clone질문에서 언급 했습니다.


2
나는 모두 작성했지만 여전히 파일을 푸시 할 때 표시되지 않습니다. 그것은 무엇 일 수 있습니까 (또한 denyCurrentBranch를 무시하도록 전환했습니다)?
Royi

감사합니다! 어느 날 직장에 들어 와서 다른 곳에 여러 개의 워크 트리가있는 메인 저장소가 자신이 "베어"라고보고하는 것을 발견했습니다. 다른 모든 작업 트리는 괜찮 았습니다. 결혼하지 않는 방법을 몰랐지만이 답변을 찾았고 훌륭하게 작동했습니다.
davidbak

17

약간 다른 시나리오가 있습니다.

해결책:

  • 해당 컨텐츠의 베어 저장소를 .git디렉토리 에 복제하십시오 .
    git clone --bare https://github.com/user/project .git
  • 비 베어 리포지토리로 표시 :
    git config --local --bool core.bare false
  • 인덱스를 (A 이후, 그렇지 않으면, 모든 삭제 된 믿고 다시 .git 베어 의 repo 파일 '을 포함하지 않는 index'.)
    git reset HEAD -- .
    복원합니다 그 .git/index.

이전에 얻은 콘텐츠를 보존하면서 베어 저장소를 베어가 아닌 저장소로 효과적으로 변환했습니다. 전체 스크립트 내가 년 동안 사용하고는 단계를 포함한다 :

cd /path/to/current/worktree

# That creates a .git directly at the right place
git clone --bare /url/of/repo .git

# restore the link between the local repo and its upstream remote repo
git config --local --bool core.bare false
git config --local remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
git fetch origin
git branch -u origin/master master

# reset the index (not the working tree)
git reset HEAD -- .

하지만 난 정찰 할 허용 솔루션 합니다 (에 도움이 git reset추가 단계ADTC는 ) 간단합니다.


베어 리포지토리가 줄 끝이 다른 시스템에서 생성 된 경우 이러한 단계를 수행 한 후에도 수정 된 파일을 볼 수 있다는 점도 주목할 가치가 있습니다. 나는 그것이 정상이라고 믿습니다. 자식은 줄 바꿈을 수정하려고합니다. 이유가 확실하지 않습니다.
Juno Woods

그래서 기본적으로 GitHub 저장소를 맨손으로 복제하고 맨손이 아닌 것으로 전환하고 수동으로 "비 저장소"의 모든 파일을 넣고 인덱스를 재설정합니까? 처음에 맨손이 아닌 것으로 저장소를 복제하는 것과 어떻게 다릅니 까? 비 베어 클론 프로세스는 어쨌든 모든 파일을 체크 아웃합니다. 그리고 정말로 원한다면 체크 아웃 한 파일을 "non-repo"의 파일로 바꿀 수 있습니다.
ADTC

@ADTC의 목표는 .git처음에 아카이브 (비 자식)로 만든 작업 트리 (당신이 알고있는 저장소)에서 하위 폴더 를 가져 오는 것입니다. 체크 아웃을하고 있던 폴더가 비어 있지 않기 때문에 비 베어 리포지토리를 체크 아웃 할 수 없습니다. git clone --no-checkout하위 폴더에서 맨손이 아닌 작업을 수행하면 .git한 수준 위로 이동해야 했습니다. 베어 클론을 사용하면 .git원하는 위치 에 하위 폴더 를 직접 만들 수있었습니다 . 스크립트는 여기에서 볼 수 있습니다 : github.com/VonC/compileEverything/blob/…
VonC

"체크 아웃을하던 폴더가 비어 있지 않기 때문에 베어가 아닌 저장소를 체크 아웃 할 수 없었습니다." 아직 커밋되지 않은 변경 사항을 포함하는 비 git 작업 트리가 있으며 Git 지원 작업 트리로 변환 한 후 커밋하려고합니까? 예, 그런 사용 사례에서 작동합니다. 개인적으로 빈 폴더에 복제하고 먼저 두 개를 비교합니다 (외부 도구 사용). 하지만 그건 나뿐입니다.
ADTC

@ADTC 없음 : 나는 할 수 없습니다 "아직 커밋되지 않은 변경 사항이 포함되지 않은 자식 작업 트리"를 가지고있다. 나는 아무것도 저지르고 싶지 않습니다 . 내가 이 것은 환매 특약의 정확한 작업 트리입니다 : 모든없는 그이다 .git. 나는 .git베어 클론을 통해 그 .git폴더를 베어가 아닌 폴더로 변환하고 git resetgit이 작업 트리가 이미 거기에 있음을 깨닫도록 만듭니다. 이것이 바로 github.com/VonC/compileEverything/blob/…이하 는 일입니다.
VonC

11

답변의 정보를 단순화하고 결합하려면 :

베어 리포지토리를 일반 .git 폴더와 다른 세 가지 차이점이 있습니다.

  • core.bare는 구성 파일에서 true로 설정됩니다.
  • 인덱스 파일과 작업 트리가 존재하지 않습니다.
  • "원본"원격지에 대한 기본 참조 사양이 생성되지 않습니다.

따라서 베어 리포지토리를 새 폴더의 .git 하위 폴더로 간단히 이동할 수 있습니다.

mkdir clone
mv bare.git clone/.git

core.bare 변경 :

cd clone
git config --local --bool core.bare false

확인하기 위해 기본 원점 refspec을 추가 git fetch하고 git push평소와 같은 기본값을 선택합니다 :

git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'

그리고 인덱스 파일과 작업 트리를 생성합니다.

git checkout master

실수로 잘못된 위치에 입력 된 경우 파일을 생성하는 git checkout것보다 권장 git reset합니다.


9

원래 포스터의 질문은 간단한 방식으로 작업을 수행 할 공간이 부족하다는 것입니다. 충분한 공간이있는 경우 답은 훨씬 간단합니다.

git clone foo.git foo

내가 이것을 피하고 싶은 이유는 저장소가 커지면 git clone이 때때로 죽을 때입니다. 베어 리포지토리의 rsync를 수행 한 다음 변환하고 싶습니다.
Sridhar Sarnobat 19

@SridharSarnobat 후 허용 대답에 설명 된 작업 일을 고려 : stackoverflow.com/a/10637882/377270을 - 충분한 여유 공간을 가진 사람들이 사물에게 쉬운 방법을 할 수 있도록 내가 여기에 한 줄 답변을했습니다.
sarnold

6

디스크 공간이 부족한 경우 일반 저장소로 변환하여 작업 트리를 확장하는 것이 문제가 될 수 있지만 베어 저장소의 내용을 변환하지 않고 찾아 볼 수 있습니다. git cat-file -p <commit-sha>커밋에 사용 하여 참조하는 트리를 확인하십시오. git cat-file -p <blob-sha>Blob에서 참조하는 파일의 내용을 보려면 사용 합니다. 사용 git show <sha>:path샤 중 하나 인 커밋 또는 나무 경로에서 블롭의 내용을 볼 수 있습니다.


1
당신 말이 맞지만 더 편리하게 찾아 볼 필요가 있습니다 (ssh를 통한 파일 관리자에서). 따라서 나는 증가 된 디스크 공간을 가지고 살아야합니다.
nyi

1
사실 이것은 진짜 문제입니다 (+1). 작업 트리는 종종 디스크 공간의 절반을 차지합니다. 부분적으로는 git 히스토리가 공격적으로 압축되기 때문입니다.
jpaugh

3

cd 베어 레포로

  1. 어느 한 쪽:
git config core.bare false
git reset --hard
  1. 또는
git clone X.git X

(X라는 이름의 일반 git repo를 제공합니다)


이것이 가장 간단한 해결책이며 2019 년에 이것이 작동하는지 확인할 수 있습니다 (첫 번째 접근 방식).
Sridhar Sarnobat 19

내가 잊은 작은 메모 하나만 (모든 답변에 적용) 원격 URL을 설정하기 위해 처음 푸시 할 때 구성 파일을 편집해야합니다.
Sridhar Sarnobat 19

2

다른 작업 트리에서 작업해도 괜찮다면

git worktree add ../repo2
cd ..
git status # now works fine

이것은 클론이 아닙니다.


이것은이 목록 최대 높지 확실하지 왜, 중대하다
있는 Nickolai

0

배포 후 배포

베어 원격을 표준 리포지토리로 변환하는 대신 hooks 디렉터리의 수신 후 스크립트를 사용하여 리포지토리를 배포 디렉터리로 확장 할 수 있습니다.

다음은 Push-to-Deploy를 설정하는 좋은 예입니다.

참조의 편의를 위해 위 링크의 스크립트 내용 예제입니다. "master"분기에서 저장소의 상위 디렉토리와 동일한 레벨에있는 "deploy"라는 디렉토리로 푸시 만 배포합니다.

#!/usr/bin/env ruby
# post-receive

# 1. Read STDIN (Format: "from_commit to_commit branch_name")
from, to, branch = ARGF.read.split " "

# 2. Only deploy if master branch was pushed
if (branch =~ /master$/) == nil
    puts "Received branch #{branch}, not deploying."
    exit
end

# 3. Copy files to deploy directory
deploy_to_dir = File.expand_path('../deploy')
`GIT_WORK_TREE="#{deploy_to_dir}" git checkout -f master`
puts "DEPLOY: master(#{to}) copied to '#{deploy_to_dir}'"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.