어제 올린 글 ( 2020/07/17 - Git에서 디렉토리 일부분만 가져오려면 어떻게 해야되요? )에서 sparse-checkout으로 특정 폴더만 받아올 수 있다는 것을 알았습니다. 그렇다면 그렇게 일부만 받아온 폴더를 실제 활용이 가능할까 궁금했습니다.
다시 말해, "SVN에서 처럼 특정 폴더만 받아왔을 때처럼, 이력관리를 할 수 있을까?" 가 궁금했습니다. 만약 가능하다고 하면, Git에서도 SVN처럼 하나의 리파지토리를 만들어두고, 업무별로 폴더를 나누어 사용할 수도 있을 테니, 수십개의 리파지토리를 사용하지 않아도 될것 같습니다.
가정
일단 제 생각은, "Git의 이력을 저장하는 방식은 스냅샷이나, SVN의 증분을 저장하는 방식 처럼 그렇게 하지 못할 것이다" 입니다만, 해보지 않으면 알 수가 없으니, 몇가지 상황을 만들어봤습니다.
실험
리파지토리는 구조는 다음과 같이 만들었습니다.
/
| - animal/
| - lion.txt
| - tiger.txt
| - dog.txt
| - fish /
| - salmon.txt
| - tuna.txt
| - shark.txt
| - tree /
| - pinetree.txt
| - baobab.txt
| - maple.txt
그리고 전체를 가지는 biology 리파지토리 하나, 그리고 각각 aninal과 fish 폴더만 가지는 리파지토리 두개, 모두 세 개의 리파지토리를 만들고, 전체를 가지고 있는 원격 리파지토리를 만듭니다.
# biology 리파지토리 생성 & push
$ mkdir biology
$ cd biology/
$ mkdir animal fish tree
$ cd animal/
$ touch lion.txt
$ touch tiger.txt
$ touch dog.txt
$ cd ../fish/
$ touch salmon.txt
$ touch tuna.txt
$ touch shark.txt
$ cd ../tree/
$ touch pinetree.txt
$ touch baobab.txt
$ touch maple.txt
$ cd ..
$ git init
$ git add .
$ git commit -m 'initial commit'
$ git remote add origin git@github.com:ikaruce/biology.git
$ git push origin master
# animal sparse-checkout
$ mkdir animal
$ cd animal/
$ git init
$ git sparse-checkout init
$ git sparse-checkout set animal
$ git remote add origin git@github.com:ikaruce/biology.git
$ git pull origin master
# fish sparse-checkout
$ cd ..
$ mkdir fish
$ cd fish/
$ git init
$ git sparse-checkout init
$ git sparse-checkout set fish
$ git remote add origin git@github.com:ikaruce/biology.git
$ git pull origin master
그리고 다음과 같은 경우에서 어떤 결과가 나오는지 알아봤습니다.
1. biology 리파지토리에서 tree 폴더 아래에 oak.txt를 추가하고 push
2. animal과 fish에서 pull
aninal에서 결과를 보면, 역시나 추측했던 대로 animal 폴더만 가지고 있지만, 전체 이력을 pull 합니다. fish도 동일합니다.
3. animal에 cat.txt를 추가하고 push.
animal은 기대했던 대로, 정상적으로 push가 되었습니다.
4. fish에서 cod.txt를 추가하고 push.
역시나, 여기서 문제가 생겼습니다. fish 가 가지고 있는 폴더에는 변경사항이 전혀 없는데도, 다른 폴더의 변경 때문에, PUSH를 할 수 없는 상황이 발생했습니다. 다른 git 리파지토리처럼 먼저 pull을 먼저 하고나서야 push를 할 수 있었습니다.
결론.
제가 추측했던 것이 맞았습니다. sparse-checkout을 하더라도, 보통의 Git리파지토리와 같이 모든 이력(스냅샷)을 가지고 있습니다. 다만, working dir에 전체 내용 중 제가 보기를 원하는 내용, 즉 전체 중 일부만 보여지고 있는 것입니다. 따라서 working dir에서의 수정과는 관계 없는 수정이 다른 폴더에서 발생한다면, 이력을 합치기 위해 pull을 진행해야 합니다. 이것은 Git의 workflow이며, SVN 사용자가 바라는 workflow와는 차이가 있습니다. 따라서 sparse-checkout을 사용하더라도 Git의 workflow를 버리는 것이 아니기에, 경우에 따라서는 사용자에게 혼란을 가져올 수 있을 것 같습니다. 1회성으로 다운받아서 무언가를 해야할 때는 유용하게 쓰이겠지만, 폴더별로 업무를 나눠서 사용하는 SVN의 workflow를 Git에 적용하는 것은 적합하지 않은 것 같습니다.