git-worktree를 무엇에 사용합니까?


211

git-worktree에 대한 Github의 게시물을 읽었습니다 . 그들이 적다:

사용자가에서 feature긴급 버그를보고 할 때 이라는 지점의 Git 저장소에서 작업한다고 가정 해 보겠습니다 master. 먼저 새 브랜치를 사용하여 연결된 작업 트리를 만들고 hotfix[...] 마스터를 기준으로 체크 아웃합니다. 버그를 수정하고 핫픽스를 푸시하며 풀 요청을 만들 수 있습니다.

feature라는 지점에서 작업하고 마스터의 긴급 버그가보고되면 일반적으로 작업중인 모든 것을 숨기고 새 지점을 만듭니다. 완료되면 계속 작업 할 수 있습니다. 이것은 매우 간단한 모델입니다. 몇 년 동안 그런 식으로 일해 왔습니다.

반면에 git-worktree 사용에는 고유 한 제한이 있습니다.

예를 들어 하나의 작업 트리에서 커밋 된 변경 내용이 다른 작업 트리에서 커밋 된 변경 내용을 동기화 할 수 있기 때문에 동일한 분기가 연결된 두 개의 작업 트리에서 동시에 체크 아웃 할 수 없습니다.

이미 해결 된 문제에 대해 더 복잡한 워크 플로를 선택해야하는 이유는 무엇입니까?

git-worktree미리 할 수 ​​없었고이 완전히 새로운 복잡한 기능을 정당화 할 수 있는 어떤 것이 있습니까?


12
숨길 수없는 한 가지는 병합 또는 충돌로 리베이스 한 후 병합되지 않은 경로입니다.
chirlu

11
컴파일 된 언어로 작업하는 경우 스 태싱은 숨김 상태가 아닐 때 모든 것을 다시 컴파일해야 함을 의미합니다.
mb14

우리는 동일한 (300 MB) 소스 코드를 기반으로 한 여러 가지 다른 제품을 가지고 있으며, 하나의 큰 저장소로 결합하고 작업 트리를 사용하여 각 제품을 다른 폴더에서 체크 아웃하도록 유지하려고합니다. 동기화되지 않은 클론
endolith

답변:


196

저에게 git worktree는 오랜 시간 동안 가장 크게 개선되었습니다. 엔터프라이즈 소프트웨어 개발을하고 있습니다. 3 년 전에 출시 한 것과 같은 이전 버전을 유지 관리하는 것이 매우 일반적입니다. 물론 각 버전마다 지점이 있으므로 쉽게 전환하고 버그를 수정할 수 있습니다. 그러나 그 동안 저장소를 완전히 재구성하고 시스템을 구축 할 수 있기 때문에 전환 비용이 많이 듭니다. 전환하면 IDE가 프로젝트 설정을 조정하려고 열광합니다.

작업 트리를 사용하면 지속적인 재구성을 피할 수 있습니다. 작업 트리를 사용하여 이전 폴더를 별도의 폴더로 체크 아웃하십시오. 각 지점마다 독립적 인 IDE 프로젝트가 있습니다.

물론 이것은 과거에 저장소를 여러 번 복제하여 수행 할 수 있었으며 지금까지 나의 접근 방식이었습니다. 그러나 그것은 또한 hardrive 공간을 낭비하고 저장소에서 동일한 변경 사항을 여러 번 가져와야한다는 것을 의미했습니다.


4
리포지토리에서 동일한 변경 사항을 여러 번 가져올 필요가 없었습니다. 첫 번째 복제본의 .git 디렉토리를 간단히 복사했을 수 있습니다.
misiu_mp

1
@ jdk1.0 혼란을 드려 죄송합니다, 의견은 misiu_mp로 향했습니다
mxttie

2
2-3 개의 복제 된 저장소를 사용하여 다른 기능을 개발하는 동안 하나의 기능 분기를 구축 할 수있는 사람으로서, 각 로컬 저장소를 다른 원격 저장소로 사용했으며 Sebi의 단점에 대해 완전히 동의했습니다. ) 또한 작업 트리로 전환하면 더 이상 같은 이름의 로컬 분기 분기에 대해 걱정할 필요가 없습니다 (일일 동안 여러 번 중단되어 결국 6-10 개월마다 한 번씩 발생 함) 여러 저장소에서 동일한 기능 분기를 작업하지만 다시 동기화하는 것을 잊지
sage

3
@iheanyi — (1). IDE가 주어진 디렉토리와 관련된 외부 데이터 파일 (인덱싱 데이터베이스 등)을 유지 관리하는 것이 더 빠릅니다. 동일한 디렉토리 에서 컨텐츠를 스 래시하면 일반적으로 모든 IDE 데이터 캐시가 무효화되고 다시 색인화해야합니다.
Steve Hollasch

5
@iheanyi — (2) 시간이 지남에 따라 모든 기록이 특정 시점에서 작업 트리 파일보다 훨씬 커집니다. 모든 기록 == .git디렉토리. 업스트림의 로컬 복제본이 많으면 각 복제본마다 고유 한 .git데이터베이스 가 있으므로 동일한 데이터베이스의 로컬 복제본이 많이 있습니다. 많은 로컬 작업 트리가 있으므로 각 트리는 동일한 .git데이터베이스를 사용 합니다. 예, 로컬 작업 트리의 로컬 복제본이 있으면 Git은 많은 .git 내용을 하드 링크하지만 Windows는 아닙니다.
Steve Hollasch

70

나는 이것에 대한 몇 가지 용도를 볼 수 있습니다.

장시간 실행되는 테스트 스위트가있는 경우 시간을 상상해보십시오. 테스트 스위트가 시작되면 테스트가 완료 될 때까지 해당 작업 사본을 효과적으로 차단합니다. 테스트 중에 분기를 전환하면 이해하기 어려운 방식으로 분기됩니다.

그래서 git-worktree다른 지점에서 작업을 수행하기 위해 두 번째 아이디어를 시작할 수있었습니다.

또한 빠른 조사를 위해 다른 지점으로 전환하면 IDE에서 많은 파일이 갑자기 변경되었다고 생각하고 모든 변경 사항을 인덱싱합니다. 다시 전환 할 때 다시 인덱싱해야합니다.

세 번째 사용 사례는 두 가지가 아닌 경우 두 디렉토리 사이에서 git-diffnormal과 같은 다른 도구를 사용하여 파일을 비교하는 것 diff입니다.


6
이 모든 것들에 대해 잘 git clone작동 하지 않습니까?
jthill

12
원격에서 큰 저장소를 복제하는 데 시간이 오래 걸릴 수 있습니다. 복제하는 데 몇 분이 걸리는 하나의 저장소에 대해 작업하고 있습니다. 나는 당신이 그것을 할 수 있다고 생각합니다 git clone --reference. 또한 다른 모든 브랜치의 관리는 작업 디렉토리 당 한 번이 아니라 한 번만 수행됩니다.
Andreas Wederbrand

6
원격에서 복제하지 말고 로컬에서 복제하십시오. 지점 관리 문제를 이해하지 못합니다. 명확히 할 수 있습니까?
jthill

14
클론을 사용하려고했는데 실제로 관리 문제가 있습니다. 단일 브랜치 세트 대신 클론 세트가 있는데 단일 UI에서 모두를 볼 수는 없습니다. 내가 체리를 선택해야 할 경우 변경 사항을 가져 오거나 밀어야합니다. 모든 조치에 추가 단계를 추가합니다. 모든 것이 가능하지만 항상 약간의 마찰이 있습니다.
max630

2
백업을 설정하는 경우 단일 리포지토리가 훨씬 더 쉽습니다.
max630

64

하나의 명백한 용도는 행동 을 동시에 비교하는 것 입니다 다른 버전 (예 : 웹 사이트의 다른 버전 또는 웹 페이지)의 (소스가 아님) 입니다.

나는 이것을 로컬로 시도했다.

  • 디렉토리를 만듭니다 page1.

  • 내부에 디렉토리 src와 디렉토리를 작성하십시오 git init.

  • 에서 src생성 page1.html약간의 내용과 그것을 커밋합니다.

  • $ git branch ver0

  • $ git worktree add ../V0 ver0

  • src마스터 에서 더 많은 텍스트를 추가 page1.html하고 커밋하십시오.

  • $ git branch sty1

  • 브랜치 page1.html에서 편집 하고 sty1(특이한 CSS 스타일을 추가하십시오) 커밋을 추가하십시오.

  • $ git worktree add ../S1 sty1

이제 웹 브라우저를 사용하여이 3 가지 버전을 동시에 열고 볼 수 있습니다.

  • ..\page1\src\page1.html // 현재 자식이 무엇이든

  • ..\page1\V0\page1.html // 초기 버전

  • ..\page1\S1\page1.html // 실험적으로 스타일이 지정된 버전


2
이것이 복제본 보다이 목적으로 작업 트리를 사용하는 이점을 설명하는 방법을 모르겠습니다.
iheanyi

@iheanyi 같은 말을 할 수 있습니다 branch; 대답도 같습니다 : 더 가벼우 며 작업에 적합합니다.
OJFord

1
@OJFord 그게 요점입니다. 이 답변은 워크 트리가 다른 점을 설명하지 않습니다. 분명히 분기 또는 복제의 별명은 아니지만 여기에서 보는 효과는 동일한 것 같습니다. 나는 이것이 단지 분기 또는 복제를 사용하는 것보다 가벼운 무게를 보지 못합니다.
iheanyi

@iheanyi 분기를 사용하는 것과는 다릅니다. 분기를 사용하여 한 번에 여러 상태의 작업 트리를 가져올 수 없으며 두 번째 (.., nth) 복제본보다 가볍습니다. 내가 의미하는 것은 분기에 대해 '단순히 복제하고 변경하는 것이 아니라'라고 말할 수 있지만 단일 리포지토리의 여러 분기는 더 가볍고 쉽게 관리 할 수있는 방법입니다.
OJFord

@OJFord 나는 이것이 worktree와의 혼란을 해결한다고 생각하지 않습니다. 브랜치 또는 클론 또는 다른 것을 사용하든, 여기에 설명 된 프로세스의 최종 목표는 세 가지 버전의 것을 동시에 비교하는 것입니다. 답변에 무엇이 들어 있는지에 따라 왜 대안 대신 작업 트리를 사용하는지 이해할 수 없습니다. 대안은 그렇지 않은 워크 트리가 무엇을하고 있는지 설명하지 않습니다. 가볍거나 가벼운 것에 대해 주장하지만 워크 트리가 가지를 덜 "무겁게"하는 방법을 보지 못합니다.
iheanyi

29
  1. 파일 시스템에서 한 번에 여러 개의 작업 트리를 원하거나 필요로하는 합당한 이유가 있습니다.

    • 다른 곳에서 변경을 수행 하면서 체크 아웃 된 파일 조작 (예 : 컴파일 / 테스트)

    • 일반적인 diff 도구를 통해 파일을 diffing

    • 병합 충돌 중에 종종 파일의 충돌 해결 하면서 소스 측에서 소스 코드를 탐색하고 싶습니다 .

    • 많이 전환해야하는 경우 시간을 낭비하고 여러 워크 트리와 관련이 없는지 다시 확인하는 시간이 낭비됩니다.

    • git stashing을 통해 브랜치 사이의 정신 컨텍스트 전환의 정신 비용은 실제로 측정 할 수 없습니다. 어떤 사람들은 단순히 다른 디렉토리에서 파일을 열어서 존재하지 않는 정신적 비용이 있다는 것을 알고 있습니다.

  2. 어떤 사람들은 "여러 개의 로컬 클론을 사용하지 않는 이유"를 묻습니다. "--local"플래그를 사용하면 추가 디스크 공간 사용에 대해 걱정할 필요가 없습니다. 이것 (또는 유사한 아이디어)은 내가 지금까지 한 일입니다. 로컬 클론에 비해 연결된 작업 트리의 기능적 이점은 다음과 같습니다.

    1. 로컬 클론을 사용하면 추가 작업 트리 (로컬 클론에 있음)는 단순히 오리진 또는 업스트림 브랜치에 액세스 할 수 없습니다. 클론의 '원점'은 첫 번째 클론의 '원점'과 동일하지 않습니다.

      • 달리기 git log @{u}..또는 git diff origin/feature/other-feature매우 도움이 될 수 있으며 더 이상 불가능하거나 어렵습니다. 이러한 아이디어는 다양한 워 크라운을 통해 로컬 클론으로 기술적으로 가능하지만 연결된 워크 트리를 통해 수행 할 수있는 모든 해결 방법이 더 좋고 간단합니다.
    2. 작업 트리간에 참조를 공유 할 수 있습니다. 다른 지역 지점의 변경 사항을 비교하거나 빌리려면 지금 할 수 있습니다.


11
또한 하나의 명령으로 모든 작업 트리를 나열 할 수 있으며 복제본을 사용하여 직접 추적해야합니다.
Ian Ringrose

흠. 자식 2.7.0부터는 그럴 것 같습니다. 알고 반갑습니다.
Alexander Bird

9

tl; dr : 어떤 이유로 든 두 개의 작업 트리를 동시에 체크 아웃하려는 git-worktree경우 신속하고 공간 효율적인 방법입니다.

다른 작업 트리를 만들면 리포지토리의 대부분의 부분 (예 :) .git이 공유됩니다. 즉 , 하나의 작업 트리에있는 동안 분기를 만들거나 데이터를 가져 오면 가지고있는 다른 작업 트리에서도 액세스 할 수 있습니다. 당신이 그것을 복제하기 위해 어딘가에 밀어 넣지 않고 foo 브랜치에서 테스트 스위트를 실행하고 싶다면 repo를 로컬로 복제하는 번거 로움을 피하고 싶다고 가정 해보십시오 git-worktree. 임시 또는 영구적으로 별도의 장소. 복제와 마찬가지로 복제가 완료되면 삭제하면됩니다. 복제본에 대한 참조는 시간이 지나면 가비지 수집됩니다.


2
문서에 따르면 두 작업 복사본 모두에 동일한 지점을 가질 수 없으며 이는 심각한 제한 사항입니다. Mercurial에서는 작은 문제 만 다루었습니다.
hypersw

물론 넌 할 수있어. 매뉴얼 페이지에 방법이 나와 있습니다. 를 찾으십시오 --force. 그러나 작업 트리가 업데이트되지 않기 때문에 한 곳에서 분기를 업데이트하고 다른 곳에서 작업 할 것으로 예상되는 경우 불편합니다.
jsageryd

그러나 Mercurial의 지점은이 측면에서보다 투명한 개념입니다. 한 작업 트리의 분기가 다른 작업 트리에 어떻게 나타 납니까? 여러 업 링크와 같은 방법으로 작업 트리를 사용한 첫 번째 실험은 둘 다에서 fetch를 실행하고 이름이 다른 두 개의 (!) 포인터로 끝났습니다 origin/master.
hypersw

워크 트리는 이름에서 알 수 있듯이 일부 추가 기능이있는 워크 트리입니다. 저장소는 모든 작업 트리 사이에서 공유됩니다. 두 작업 트리의 유일한 차이점은 체크 아웃 된 분기가 다르고 정상 워크 플로의 경우 다를 수 있다는 것입니다. 별도의 작업 트리에 커밋 할 수 있으므로 작업을 수행하기 위해 자체 인덱스 (일명 준비 영역)가 있습니다. .git별도의 파일 worktree 원래 저장소에있는 그 구성에 대한 경로를 포함하는 텍스트 파일이다.
jsageryd

2
@ WilsonF : git checkout --ignore-other-worktrees <branch> git-scm.com/docs/git-checkout/…
jsageryd

7

나는이 멋진 작업 트리가 무엇을 사용할 수 있는지 궁금해 한 후에이 질문에 걸려 들었습니다. 그 이후로 나는 그것들을 워크 플로에 통합했으며 초기 회의론에도 불구하고 그것들을 매우 유용하게 찾았습니다.

나는 다소 큰 코드베이스에서 작업하는데 컴파일하는 데 꽤 시간이 걸립니다. 일반적으로 현재 작업중인 기능 분기와 함께 현재 시스템에 현재 개발 분기가 있고 마스터 분기는 라이브 시스템의 현재 상태를 나타냅니다.

나에게 가장 큰 이점 중 하나는 분명히 분기를 전환 할 때마다 (즉, 작업 트리) 전체를 다시 컴파일 할 필요가 없다는 것입니다. 좋은 부작용은 개발 작업 트리로 가서 거기에서 작업을 수행하고 디렉토리를 현재 기능 분기의 작업 트리로 변경 한 다음 먼저 가져 오지 않고도 리베이스 할 수 있다는 것입니다.


4

나는 다소 특이한 것을 가지고있다 : 나는 같은 머신 에서 Windows와 Linux 개발을하고있다 . Windows 상자 안에 Linux를 실행하는 VirtualBox가 있습니다. VirtualBox는 일부 Windows 디렉토리를 마운트하고 Linux 시스템 내에서 직접 사용합니다. 이를 통해 Windows를 사용하여 파일을 관리하지만 Linux 내에서 빌드 할 수 있습니다. 이것은 크로스 플랫폼 프로젝트이므로 동일한 디렉토리 구조에서 Windows와 Linux 모두에서 빌드됩니다.

문제는 Linux와 Windows 빌드 시스템이 동일한 디렉토리에서 사용될 때 서로 충돌한다는 것입니다. 동일한 디렉토리 이름을 사용하는 라이브러리 등을 다운로드하기위한 복잡한 빌드 단계가 있습니다. 빌드 시스템의 Windows 버전은 Windows 특정 라이브러리를 다운로드하고 Linux 버전의 빌드 시스템은 Linux 특정 라이브러리를 다운로드합니다.

이상적인 세계에서, 빌드 시스템은 Windows와 Linux가 디렉토리 내에 공존 할 수 있도록 수정 될 것이지만, 현재는 문제가 워크 트리와 함께 해결되고 있습니다. "Linux"폴더는 Linux 특정 빌드 아티팩트를 생성 할 수 있고 "Windows"폴더는 Windows 특정 빌드 아티팩트를 생성 할 수 있습니다. 이것은 이상적인 솔루션은 아니지만 빌드 시스템 버그가 해결되기를 기다리는 동안 좋은 스톱 갭을 만듭니다.

분명히, worktree는 이것을 위해 설계되지 않았습니다. Windows 버전과 Linux 버전을 동일한 지점에 두는 것을 선호하지만 별도의 지점에 보관해야합니다. 아직도, 그것은 일을하고 있으며, 하루를 절약하는 다소 관습적인 작업 트리의 경우입니다.


+1 이는 구성 별 빌드 출력 디렉토리를 기본적으로 수행하지 않는 매우 효과적인 해결 방법 인 것 같습니다. Ubuntu 및 macOS 게스트와 유사한 VMware Workstation 설정이 있습니다.
Tanz87

1

나를 위해 새 프로젝트에서 기능을 만들었습니다. 그러나 일부 사양은 실패했습니다. 결과를 비교하기 master위해 work-treerepo를 만들었습니다 . 무엇이 잘못되었는지 이해할 때까지 실행 코드에서 단계별로 결과를 비교했습니다.


그러나 작업 트리는 어떻게 이것을 복제본보다 쉽게 ​​만들 수 있습니까? 이 질문은 개인적인 취향을 요구하는 것이 아니라 구체적인 차이점을 요구합니다.
IInspectable

1

git worktree기계 학습 개발에 사용 하고 있습니다.

주요 기능 코드가 있고 다른 실험 (다른 알고리즘과 다른 하이퍼 매개 변수)의 분기를 나누고 싶습니다. 다른 알고리즘에 특화된 다른 버전의 코드와 함께 dvcgit worktree 를 통합 할 수 있습니다 . 모든 교육 작업을 실행 한 후 최종 메트릭을 평가하고 병합하여 최상의 지점 / 모델을 마스터합니다.

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