IT story

Git을 사용하는 여러 작업 디렉토리?

hot-time 2020. 4. 13. 08:20
반응형

Git을 사용하는 여러 작업 디렉토리?


이것이 Git이 지원하는 것인지 확실하지 않지만 이론적으로는 그것이 나에게 효과가있는 것처럼 보입니다.

워크 플로에는 종종 여러 지점에서 동시에 파일을 편집하는 작업이 포함됩니다. 즉, 다른 브랜치에서 다른 파일의 내용을 편집하는 동안 한 브랜치에서 몇 개의 파일을 열고 싶습니다.

이것에 대한 나의 전형적인 해결책은 두 개의 체크 아웃을하는 것이지만, 지점과 참조를 공유 할 수 없다는 것은 부끄러운 일입니다. 내가 원하는 것은 동일한 .git 폴더로 두 개의 작업 디렉토리를 관리하는 것입니다.

로컬 git clone 솔루션 (공유 객체를 하드 링크하는 기본 설정 및 원래 저장소로 대체 ​​객체 저장소를 설정하는 --shared 옵션)에 대해 알고 있지만이 솔루션은 디스크 공간 사용량 만 줄입니다. , 특히 공유의 경우에는 위험에 처하게됩니다.

하나의 .git 폴더를 사용하고 두 개의 작업 디렉토리를 지원하는 방법이 있습니까? 아니면 Git은 언제든지 하나의 작업 디렉토리 만 체크 아웃하도록 하드 코딩되어 있습니까?


Git 2.5는 2015 년 7 월부터 다음을 대체 할 것을 제안합니다 contrib/workdir/git-new-workdir: git worktree

Junio ​​C Hamano ( gitster)의 commit 68a2e6a참조하십시오 .

릴리스 노트는 언급 :

이를 대체 contrib/workdir/git-new-workdir하는 것은 상징적 링크에 의존하지 않으며 차용자와 차용자가 서로를 인식하게하여 물건과 심판을 안전하게 공유합니다.

참조 799767cc9 커밋 (힘내 2.5rc2를)

수단은 지금 할 수 git worktree add <path> [<branch>]

작성 <path>하고 체크 아웃 <branch>하십시오. 새 작업 디렉토리는 현재 저장소에 링크되어 HEAD, 색인 등과 같은 작업 디렉토리 특정 파일을 제외한 모든 것을 공유 git worktree합니다.

git 저장소는 여러 작업 트리를 지원할 수 있으므로 한 번에 둘 이상의 브랜치를 체크 아웃 할 수 있습니다.
을 사용 git worktree add하면 새로운 작업 트리가 리포지토리와 연결됩니다.

이 새로운 작업 트리는 " git init"또는 " git clone"로 준비된 "주 작업 트리"와 달리 "링크 된 작업 트리 " 라고 합니다.
저장소에는 하나의 기본 작업 트리 (빈 저장소가 아닌 경우)와 0 개 이상의 연결된 작업 트리가 있습니다.

세부:

연결된 각 작업 트리에는 저장소 디렉토리에 개인용 하위 $GIT_DIR/worktrees디렉토리가 있습니다.
개인용 하위 디렉토리의 이름은 일반적으로 연결된 작업 트리 경로의 기본 이름이며 고유하게하기 위해 숫자가 추가 될 수 있습니다.
예를 들어, $GIT_DIR=/path/main/.git명령이 git worktree add /path/other/test-next next작성 될 때 :

  • 에 링크 된 작업 트리 /path/other/test-next
  • 또한 $GIT_DIR/worktrees/test-next디렉토리를 작성합니다 (또는 이미 사용중인 $GIT_DIR/worktrees/test-next1경우 test-next).

연결된 작업 트리 내에서 :

  • $GIT_DIR이 개인 디렉토리 (예 : /path/main/.git/worktrees/test-next예) 를 가리 키도록 설정되어 있으며
  • $GIT_COMMON_DIR는 메인 작업 트리를 다시 가리 키도록 설정됩니다 $GIT_DIR(예 :) /path/main/.git.

이러한 설정은 .git연결된 작업 트리의 최상위 디렉토리 에있는 파일 에서 이루어집니다 .

연결된 작업 트리가 완료되면 간단히 삭제할 수 있습니다.
저장소에서 작업 트리의 관리 파일은 결국 (참조 자동으로 제거됩니다 gc.pruneworktreesexpire에서 git config), 또는 당신이 실행할 수 git worktree prune있는 부실 관리 파일을 정리하기 위해 주 또는 링크 된 작업 트리에.


경고 : 여전히 git worktree"BUGS" 섹션을 알고 있어야합니다.

하위 모듈에 대한 지원 이 불완전 합니다.
수퍼 프로젝트를 여러 번 체크 아웃하지 않는 것이 좋습니다.


참고 : git 2.7rc1 (2015 년 11 월)을 사용하면 작업 트리를 나열 할 수 있습니다.
참조 bb9c03b 커밋 , 92718b7 커밋 , 5,193,490 커밋 , 1ceb7f9 커밋 , 1ceb7f9 커밋 , 5,193,490 커밋 , 1ceb7f9 커밋 , 1ceb7f9 커밋 (2015 08 시월) 92718b7 커밋 , 5,193,490 커밋 , 1ceb7f9 커밋 , 1ceb7f9 커밋 (2015 08 시월) 5193490 커밋 , 1ceb7f9 커밋 (2015 년 10 월 8 일), 1ceb7f9 커밋 (2015 년 10 월 8 일), ac6c561 커밋(2015 년 10 월 2 일) Michael Rappazzo ( rappazzo) .
(의해 병합 Junio C 하마노 - gitster-a46dcfb 커밋 26 시월 2015)

worktree: ' list'명령 추가

' git worktree list'는 작업 트리 목록을 반복하고 작업 트리 경로, 현재 체크 아웃 한 개정 및 분기 및 작업 트리가없는 경우를 포함하여 작업 트리의 세부 정보를 출력합니다.

$ git worktree list
/path/to/bare-source            (bare)
/path/to/linked-worktree        abcd1234 [master]
/path/to/other-linked-worktree  1234abc  (detached HEAD)

사용 가능한 도자기 형식 옵션도 있습니다.

도자기 형식에는 속성 당 한 줄이 있습니다.

  • 속성은 단일 공백으로 구분 된 레이블 및 값과 함께 나열됩니다.
  • 부울 속성 (예 : 'bare'및 'detached')은 레이블로만 나열되며 값이 true 인 경우에만 존재합니다.
  • 빈 줄은 작업 트리의 끝을 나타냅니다

예를 들어 :

$ git worktree list --porcelain

worktree /path/to/bare-source
bare

worktree /path/to/linked-worktree
HEAD abcd1234abcd1234abcd1234abcd1234abcd1234
branch refs/heads/master

worktree /path/to/other-linked-worktree
HEAD 1234abc1234abc1234abc1234abc1234abc1234a
detached

참고 : 작업 트리 폴더를 이동하는 경우 파일 수동으로 업데이트해야 gitdir합니다.

참조 618244e 커밋 (2016년 1월 22일을), 및 d4cddd6 커밋 (2016년 1월 18일)에 의해 응웬 타이 응옥 두이 ( pclouds) .
도움 : Eric Sunshine ( sunshineco) .
( Junio ​​C gitsterHamano의해 병합 -- 커밋 d0a1cbc , 2016 년 2 월 10 일)

git 2.8 (2016 년 3 월) 의 새로운 문서 는 다음과 같습니다.

연결된 작업 트리를 이동 gitdir하면 항목의 디렉토리에서 ' '파일 을 업데이트해야합니다 .
예를 들어, 연결된 작업 트리가로 이동 /newpath/test-next하고 .git파일이을 가리키는 경우 대신 참조 /path/main/.git/worktrees/test-next로 업데이트하십시오 ./path/main/.git/worktrees/test-next/gitdir/newpath/test-next


분기를 삭제할 때주의하십시오 : git 2.9 (2016 년 6 월) 전에 다른 작업 트리 에서 사용중인 분기를 삭제할 수 있습니다.

" git worktree"기능을 사용중인 경우 " git branch -d"는 다른 작업 트리에서 체크 아웃 된 분기를 삭제할 수 있습니다.

Kazuki Yamaguchi ( )의 커밋 f292244 (2016 년 3 월 29 일)를 참조하십시오 . 도움 : Eric Sunshine ( ) . ( Junio ​​C Hamano의해 합병 -- 커밋 4fca4e3 , 2016 년 4 월 13 일)rhenium
sunshineco
gitster

branch -d: 현재 체크 아웃 된 브랜치 삭제를 거부합니다.

현재 작업 트리에서 분기를 체크 아웃하면 분기 삭제가 금지됩니다.
그러나 다른 작업 트리에서만 분기를 체크 아웃하면 잘못 삭제됩니다. 현재 작업 트리의 HEAD와 비교하지 않고 분기가
사용 find_shared_symref()중인지 확인하는 데 사용 합니다.


마찬가지로 git 2.9 (2016 년 6 월) 이전에 다른 작업 트리에서 체크 아웃 된 지점의 이름을 바꾸면 다른 작업 트리의 기호 HEAD가 조정되지 않았습니다.

참조 18eb3a9 커밋 (2016 4월 8일을), 및 70999e9 커밋 , 2,233,066 커밋 에 의해 (2016년 3월 27일) 카즈키 야마구치을 ( rhenium) .
( Junio ​​C gitsterHamano의해 합병 - 커밋 741a694 , 2016 년 4 월 18 일)

branch -m: 모든 작업 트리 당 HEAD 업데이트

분기 이름을 바꾸면 현재 작업 트리의 HEAD 만 업데이트되지만 이전 분기를 가리키는 모든 작업 트리의 HEAD를 업데이트해야합니다.

이것은 현재 동작이며 / path / to / wt의 HEAD는 업데이트되지 않습니다.

  % git worktree list
  /path/to     2c3c5f2 [master]
  /path/to/wt  2c3c5f2 [oldname]
  % git branch -m master master2
  % git worktree list
  /path/to     2c3c5f2 [master2]
  /path/to/wt  2c3c5f2 [oldname]
  % git branch -m oldname newname
  % git worktree list
  /path/to     2c3c5f2 [master2]
  /path/to/wt  0000000 [oldname]

이 패치는 브랜치 이름을 바꿀 때 모든 관련 작업 트리 HEAD를 업데이트하여이 문제를 해결합니다.


잠금 메커니즘은 공식적으로 git 2.10 (Q3 2016)에서 지원됩니다

참조 080739b 커밋 , 6d30862 커밋 , 58142c0 커밋 , 346ef53 커밋 , 346ef53 커밋 , 58142c0 커밋 , 346ef53 커밋 , 346ef53 커밋 (2016 6월 13일), 및 984ad9e 커밋 , 6,835,314 커밋 에 의해 (2016 6월 3일를) 응웬 타이 응옥 두이 ( pclouds) .
제안 : Eric Sunshine ( sunshineco) .
( Junio ​​C gitsterHamano의해 병합 -- 커밋 2c608e0 , 2016 년 7 월 28 일)

git worktree lock [--reason <string>] <worktree>
git worktree unlock <worktree>

연결된 작업 트리가 항상 탑재되지 않은 휴대용 장치 또는 네트워크 공유에 저장되어 있으면 git worktree lock명령 을 실행하여 관리 파일이 정리되지 않도록 할 수 있습니다 ( 선택적으로 --reason작업 트리가 잠긴 이유를 설명하도록 지정) .

<worktree>: 작업 트리 경로의 마지막 경로 구성 요소가 작업 트리 중에서 고유 한 경우 작업 트리를 식별하는 데 사용할 수 있습니다.
예를 들어 " /abc/def/ghi"및 " /abc/def/ggg" 에서 트리를 작업해야하는 경우 " ghi"또는 " def/ghi"로 이전 작업 트리를 가리 키기에 충분합니다.


Git 2.13 (Q2 2017 )은 Nguyễn Thái Ngọc Duy ( )의 commit 507e6e9 (2017 년 4 월 12 일) lock옵션추가합니다 . 제안 : David Taylor ( ) . 도움 : Jeff King ( ) . ( Junio ​​C Hamano의해 합병 - 커밋 e311597 , 2017 년 4 월 26 일)pclouds
dt
peff
gitster

작업 트리를 만든 직후에 잠글 수 있습니다.
이렇게하면 " git worktree add; git worktree lock"와 " git worktree prune" 간의 경쟁을 방지 할 수 있습니다.

따라서 after git worktree add' --lock와 동일 하지만 경쟁 조건이 없습니다.git worktree lockgit worktree add


Git 2.17+ (2018 년 2 분기) 추가 git worktree move/ git worktree remove: 이 답변을 참조하십시오 .


Git 2.19 (Q3 2018)에 " --quiet"옵션을 추가하여 " git worktree add"을 덜 장황하게 만듭니다.

Elia Pinto ( )의 commit 371979c (2018 년 8 월 15 일)를 참조하십시오 . 도움 : Martin Ågren, Duy Nguyen ( )Eric Sunshine ( ) . ( Junio ​​C Hamano의해 병합 -- 커밋 a988ce9 , 2018 년 8 월 27 일)devzero2000
pcloudssunshineco
gitster

worktree: --quiet옵션 추가

다른 명령 과 마찬가지로 ' --quiet'옵션을에 추가하십시오 . ' '을 (를) 제외한 다른 모든 명령 은 현재 기본적으로 자동 이므로 ' '는 영향을받는 유일한 명령 입니다.git worktreegit
addlist


" git worktree add"는 "stat로 가능한 이름을 찾은 다음 mkdir", 경쟁하기 쉬운 "을 찾는 데 사용되었습니다 .
이것은 루프에서 사용 mkdir하고 반응 하여 Git 2.22 (Q2 2019)로 수정되었습니다 EEXIST.

Michal Suchanek ( )의 commit 7af01f2 (2019 년 2 월 20 일)를 참조하십시오 . (의해 병합 - Junio C 하마노 -20fe798 커밋 2,019 09 사월)hramrach
gitster

worktree: worktree add레이스 수정

Git은 stat 루프를 실행하여 사용 가능한 작업 트리 이름을 mkdir찾은 다음 찾은 이름에서 수행합니다. worktree add의 다른 호출이 동일한 무료 이름을 찾고 디렉토리를 먼저 작성하지 않도록
하려면 mkdir루프로 돌리십시오 .


Git 2.22 (Q2 2019)는 Git 리포지토리에 작업 트리 git branch -D가 있는지 확인하여 현재 실수로 체크 아웃 된 분기를 " "에서 제거하지 못하도록 보호하는 논리를 수정합니다 .
이 논리의 구현은 특이한 이름을 가진 리포지토리에 대해 깨졌습니다. 불행히도 요즘 하위 모듈의 표준입니다.

Jonathan Tan ( )의 commit f3534c9 (2019 년 4 월 19 일)를 참조하십시오 . ( Junio ​​C Hamano의해 병합 - 커밋 ec2642a , 2019 년 5 월 08 일)jhowtan
gitster

코드 풀 요청 178 통찰력

worktree: is_bare휴리스틱 업데이트

" git branch -D <name>"가 실행될 , Git은 일반적으로 해당 분기가 현재 체크 아웃되어 있는지 먼저 확인합니다.
그러나 해당 리포지토리의 Git 디렉터리가 " <repo>/.git" 이 아닌 경우이 검사가 수행되지 않습니다 super/.git/modules/<repo>. 예를 들어 해당 리포지토리가 Git 디렉터리가 " " 로 저장된 하위 모듈 인 경우입니다 .
체크 아웃 된 경우에도 분기가 삭제됩니다.

그 이유 get_main_worktree()worktree.c세트 is_bare에만 worktree의 경로 "로 끝나지 않는 경우 환매 특약이 벌거 벗은 것을 발견 적 사용 worktree에 /.git"그렇지 베어 없음.
is_bare코드는 휴리스틱 에 따라 92718b7 ( " worktree: 작업 트리 구조에 세부 정보 추가", 2015-10-08, Git v2.7.0-rc0) 에 도입되었습니다 pre-core.bare.

이 패치는 다음 두 가지를 수행합니다.

  • 티치가 get_main_worktree()사용하는 is_bare_repository()대신에 도입 7d1864c ( "(is_bare_repository 소개) 및 core.bare 구성 변수", 2007-01-07, 힘내 v1.5.0-RC1)을하고 업데이트 e90fdc3 2007 년 ( "청소 작업 트리 처리까지" -08-01, 힘내 v1.5.3-rc4).
    이렇게하면 git branch -D <name>위에서 설명한 " "문제가 해결 됩니다.

그러나 ... 리포지토리에 보조 작업 트리 중 하나에서 core.bare=1" git"명령을 실행 하고 있지만 is_bare_repository()사용 가능한 작업 트리가 있으므로 false를 반환합니다.

또한 기본 작업 트리가 맨손이 아닌 경우 비 작업으로 처리하면 문제가 발생합니다.

예를 들어, 기본 작업 트리가 비어있는 경우에도 기본 작업 트리의 HEAD가 참조하는 보조 작업 트리에서 분기를 삭제하지 못했습니다.

이를 피하려면 core.bare설정시 확인하십시오 is_bare.
이면 core.bare=1신뢰하고 그렇지 않으면을 사용하십시오 is_bare_repository().


git분포되어 기여 스크립트 라고합니다 git-new-workdir. 다음과 같이 사용하십시오.

git-new-workdir project-dir new-workdir branch

여기서 project-dir은 .git저장소를 포함하는 디렉토리의 이름입니다 . 이 스크립트 .git는 현재 분기와 같이 공유 할 수없는 파일을 제외하고 원본과 많은 심볼릭 링크가있는 다른 디렉토리를 만들어 두 개의 다른 분기에서 작업 할 수 있도록합니다.

약간 허약 한 것처럼 들리지만 옵션입니다.


나는 여기서 찾지 못한 해결책을 기대 하면서이 질문을 보았습니다. 이제 필요한 것을 찾았 으므로 다른 사람들을 위해 여기에 게시하기로 결정했습니다.

주의 사항 : OP 상태와 같이 여러 분기를 동시에 편집 해야하는 경우에는 좋은 해결책이 아닐 수 있습니다 . 편집 하지 않으려 는 여러 분기 동시에 체크 아웃 하기위한 것 입니다. (하나의 .git 폴더가 지원하는 여러 작업 디렉토리)

이 질문에 처음 왔을 때 배운 것들이 몇 가지있었습니다.

  1. " 보통 저장소 " 란 무엇입니까? 기본적 .git으로 작업 트리에 위치하지 않고 디렉토리 의 내용입니다 .

  2. 옵션 .git을 사용하여 명령 행에서 사용중인 리포지토리 위치 ( 디렉토리 위치)를 지정할 수 있다는 사실git--git-dir=

  3. 작업 사본의 위치를 ​​지정할 수 있다는 사실 --work-tree=

  4. "거울 저장소"는 무엇입니까?

이 마지막은 매우 중요한 차이점입니다. 실제로 리포지토리에서 작업 하고 싶지 않고 다른 지점 및 / 또는 태그의 사본을 동시에 체크 아웃하면됩니다. 실제로, 지점 리모컨의 지점과 다르지 않도록 해야합니다 . 그래서 거울은 나에게 완벽합니다.

그래서에 대한 사용 사례, 나는 일을 필요로 무엇을 가지고 :

git clone --mirror <remoteurl> <localgitdir> # Where localgitdir doesn't exist yet
mkdir firstcopy
mkdir secondcopy
git --git-dir=<localgitdir> --work-tree=firstcopy checkout -f branch1
git --git-dir=<localgitdir> --work-tree=secondcopy checkout -f branch2

이것에 대한 큰 경고는 두 사본에 대해 별도의 HEAD가 없다는 것입니다. 따라서 git --git-dir=<localgitdir> --work-tree=firstcopy statusHEAD가 branch2를 가리키고 있기 때문에 running은 branch2에서 branch1까지의 모든 차이점을 커밋되지 않은 변경 사항으로 표시합니다. (따라서 실제로 로컬로 변경을 계획하지 않기 때문에에 -f옵션을 사용하는 이유입니다. 옵션을 사용하는 checkout한 작업 트리의 태그 또는 분기를 체크 아웃 할 수 있습니다 -f.)

여러 대의 체크 아웃 을 편집 할 필요 없이 동일한 컴퓨터에 공존 하는 유스 케이스의 경우 완벽하게 작동합니다. 다른 답변에서 다루는 것과 같은 스크립트없이 여러 작업 트리에 대해 여러 HEAD를 가질 수있는 방법이 있는지 모르겠지만 다른 사람에게 도움이되기를 바랍니다.


내가 생각할 수있는 유일한 해결책은 두 디렉토리를 복제하고 서로의 원격 저장소로 추가하는 것입니다. 그런 다음 실제로 원격 저장소에 아무것도 푸시하지 않고도 변경된 항목에서 다른 항목으로 항목을 계속 가져올 수 있습니다.

일부 분기를 원격으로 푸시하고 싶지 않기 때문에 두 개의 작업 디렉토리가 있고 두 개의 원격 복제본이 아닌 것으로 가정합니다. 그렇지 않으면 리모컨의 두 클론이 잘 작동합니다. 세 번의 동기화를 유지하려면 약간의 밀기 및 당기기를 수행하면됩니다.

참고 URL : https://stackoverflow.com/questions/6270193/multiple-working-directories-with-git

반응형