두 상황은 아주 다르지만 모두 worktree명령어로 해결할 수 있습니다.
git worktree는 말 그대로 브랜치가 아니라 새로운 '작업 트리'를 만들고 관리하는 명령입니다. 기존의 트리와 새 트리는 HEAD, index를 별도로 사용하기 때문에 파일의 변경상황에 서로 관여하지 않으며 디렉토리도 다릅니다.
말로만 설명하면 이해하기 어려우니 직접 코드를 살펴봅시다.
clone이나 init이후 별도로 worktree명령을 사용하지 않았다면, 기존의 로컬 레포지터리에서는 단 하나의 워크트리만 확인할 수 있을 겁니다.
git worktree list
/Users/Username/Git-practice 4973dc8 [branchname]
이런 상황이 실제로 생길지는 모르겠지만, 당신이 작업하고 있는 도중에 버그를 발견했다고 가정해봅시다. hotfix하려면 의존하고 있는 라이브러리의 버전을 업데이트해야 하는데, 지금 개발중인 버전에서는 당장 바꾸기 어렵습니다.
이럴 때 worktree명령 없이 작업하려면 상당히 복잡하고 귀찮은 과정을 거쳐야 할 겁니다.
이런 상황에서 worktree명령어가 있다면 흐름을 상당히 단순화할 수 있습니다. 먼저 새 worktree를 생성해봅시다.
git worktree add <path>
Preparing worktree (checking out '<path>')
HEAD is now at 496dca8 TEST convert reduxTK
이제 주어진 path에 같은 이름을 가진 폴더가 생성되었습니다. git worktree list 명령을 사용해보면 git 역시 추가된 worktree를 인지하고 있습니다.
git worktree list
/Users/Username/Git-practice 496dca8 [rebase]
/Users/Username/Git-practice/tempwt 496dca8 [tempwt]
/Users/Username/Git-practice/worktree 496dca8 [worktree]
git branch 명령을 사용해보면 다른 브랜치와는 다르게 표시됩니다.
checkout을 시도하면 이미 다른 워크트리에서 체크아웃중이라는 표시가 뜰 겁니다.
'temptree' is already checked out at '/Users/User/Git-practice/temptree'
새로운 워크트리를 이용하려면 실제로 디렉토리를 이동해야 합니다. cd명령이나 직접 폴더로 이동해 사용합시다.
!주의: 만일 편집기에서 파일을 연 상태로 worktree를 추가했다면 현재 편집창이 마지막으로 생성한 워크트리 내의 파일로 경로가 변경되어 있을 수 있습니다.
터미널에서 보고 있는 경로와 편집기에서 보이는 파일의 경로가 다를 수 있으니 잘 확인하고 작업합시다.
만일 worktree add의 path를 현재 편집기(vscode 등)의 디렉토리 내부로 지정했다면, git status명령을 했을 때 untracked files에 생성한 워크트리들이 나타날 겁니다.
git add한 순간 git이 경고해주기는 하지만, push할 때 실수로라도 포함되지 않도록 .gitignore에 추가해두는게 좀 더 안전한 사용법입니다.
// .ignore 파일 내부
# worktree
tempwt/
worktree/
거꾸로, 기존에 .gitignore에 추가되어있던 파일(node_modules등등)은 새로 생성한 worktree에 나타나지 않습니다. 필요하다면 새로운 worktree에 별도로 추가해주어야 합니다.
먼저 제가 처음에 쓰던 worktree에서 README.md파일을 변경했습니다. 이제 git status명령을 사용하면 당연히 modified된 파일이 표시될 겁니다.
만일 브랜치를 이용했다면, 다른 브랜치로 checkout을 시도할 때 git은 변경사항을 저장하지 않았다고 commit이나 stash를 요구할겁니다.
그러나 이미 언급했지만 worktree간에는 index와 HEAD를 별도로 사용하기 때문에 다른 worktree의 변경사항은 신경쓰지 않습니다.
워크트리를 변경할 때는 물리적으로 파일 디렉토리를 이동하면 됩니다.
cd tempwt
git status
이제 tempwt에서 커밋한 내용은 원본 worktree의 히스토리에서 확인할 수 있지만, 의존성이 다른 worktree를 넘나들며 작업해도 아무런 문제가 생기지 않습니다.
갑작스러운 작업 중 다른 브랜치로 이동해야 한다면 현재 작업하던 내용을 보존하는 방법은 여러가지가 있습니다.
여기에서도 이제 worktree add라는 선택지가 추가되었습니다.
워크트리를 삭제하는 명령은 git worktree remove <treename>입니다.