Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

Git의 sparse checkout 기능 사용 실패기

Git 1.7부터 추가된 sparse checkout기능에 대한 얘기인데 기능설명이라기 보다 사용실패에 대한 내용입니다. 결과적으로 보면 제가 생각했던 것과 sparse checkout의 동작이 달랐고(곰곰히 생각해 보면 git의 동작방식상 제가 잘못된 기능을 기대했다는 생각이 듭니다.) 결국 sparse checkout기능을 사용하지 않기로 했습니다. 사실 어떤 상황에서 써야 하는 것인지 잘 감이 안오고 있습니다.

일단 sparse checkout기능을 먼저 보겠습니다. sparse checkout은 저장소에서 특정 디렉토리나 파일만 보이도록 체크아웃하는 기능입니다. 예를 들어 다음과 같이 스프링 프레임워크의 저장소를 내려받습니다.


$ git clone https://github.com/SpringSource/spring-framework.git 
Cloning into spring-framework...
remote: Counting objects: 100954, done.
remote: Compressing objects: 100% (31757/31757), done.
remote: Total 100954 (delta 54965), reused 100662 (delta 54808)
Receiving objects: 100% (100954/100954), 23.36 MiB | 179 KiB/s, done.
Resolving deltas: 100% (54965/54965), done.
$ cd spring-framework/
spring-framework (git:3.1.x)$ ls -l
total 240
-rw-r--r--   1 outsider  staff   3241  1 20 19:22 README.md
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 build-spring-framework
-rw-r--r--   1 outsider  staff    834  1 20 19:22 build.properties
-rw-r--r--   1 outsider  staff    101  1 20 19:22 build.versions
-rw-r--r--   1 outsider  staff    326  1 20 19:22 ci-build.properties
-rw-r--r--   1 outsider  staff  28524  1 20 19:22 eclipse-code-formatter.xml
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.aop
drwxr-xr-x  10 outsider  staff    340  1 20 19:22 org.springframework.asm
drwxr-xr-x  10 outsider  staff    340  1 20 19:22 org.springframework.aspects
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.beans
drwxr-xr-x  12 outsider  staff    408  1 20 19:22 org.springframework.context
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.context.support
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.core
drwxr-xr-x  12 outsider  staff    408  1 20 19:22 org.springframework.expression
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.instrument
drwxr-xr-x  10 outsider  staff    340  1 20 19:22 org.springframework.instrument.tomcat
drwxr-xr-x  12 outsider  staff    408  1 20 19:22 org.springframework.integration-tests
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.jdbc
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.jms
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.orm
drwxr-xr-x  12 outsider  staff    408  1 20 19:22 org.springframework.oxm
drwxr-xr-x   7 outsider  staff    238  1 20 19:22 org.springframework.spring-library
drwxr-xr-x   6 outsider  staff    204  1 20 19:22 org.springframework.spring-parent
drwxr-xr-x  12 outsider  staff    408  1 20 19:22 org.springframework.test
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.transaction
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.web
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.web.portlet
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.web.servlet
drwxr-xr-x  11 outsider  staff    374  1 20 19:22 org.springframework.web.struts
drwxr-xr-x  14 outsider  staff    476  1 20 19:22 spring-build
drwxr-xr-x   9 outsider  staff    306  1 20 19:22 spring-framework-reference
-rw-r--r--   1 outsider  staff  72074  1 20 19:22 spring-framework.ipr
-rw-r--r--   1 outsider  staff   2627  1 20 19:22 spring-framework.psf

저같은 경우는 origin 저장소를 따로두고 스프링 프레임워크를 따로 패치받아왔지만 설명과는 관계없으므로 그냥 클론받았습니다. 제가 원했던 기능은 스프링 프레임워크에는 수많은 라이브러리에 관련된 폴더들이 있는데 최근에 시작한 레퍼런스 문서의 번역을 하기 위해서 받아온 것이기 때문에 라이브러리 폴더들은 필요가 없었습니다. 레퍼런스 문서가 들어있는 spring-framework-reference 폴더를 포함해서 빌드와 관련된 몇가지 디렉토리와 폴더만 필요할 뿐이었습니다. 사용하지 않는 라이브러리 파일까지 가지고 있는 것은 저장소가 너무 무거워지기 때문에 원하는 파일만 가져와서 제 저장소와 합치고 싶었고 추후에 레퍼런스 문서가 업데이트되었을 때 변경내역을 비교하기 위해서 히스토리를 유지하고 싶었습니다. 그래서 일부만 체크아웃 받을 수 있나 하고 검색하다가 알게 된 것이 sparse checkout 입니다.

sparse checkout은 다음과 같이 사용합니다. 저장소 폴더에서 다음 명령어를 실행합니다.

git config core.sparsecheckout true

이 명령어는 현재 저장소의 sparse checkout기능을 킨 것입니다. 기본은 꺼져있습니다. 그리고 .git/info/sparse-checkout파일을 만들어서 다음과 같은 내용을 추가합니다.(원래는 없는 파일이므로 만들어야 합니다.)


build-spring-framework/
spring-build/
spring-framework-reference/
build.properties

sparse-checkout파일에 현재 저장소에서 필요한 파일이나 디렉토리를 적어줍니다. 위 폴더와 파일들은 스프링 레퍼런스 문서와 빌드에 필요한 파일과 디렉토리입니다. 이제 설정은 끝났습니다. git read-tree -m -u HEAD 명령어를 실행해서 spase checkout이 적용되도록 저장소 트리를 다시 읽어옵니다.


spring-framework (git:3.1.x)$ git read-tree -m -u HEAD
spring-framework (git:3.1.x)$ ls -l
total 8
drwxr-xr-x  11 outsider  staff  374  1 20 19:22 build-spring-framework
-rw-r--r--   1 outsider  staff  834  1 20 19:22 build.properties
drwxr-xr-x  14 outsider  staff  476  1 20 19:22 spring-build
drwxr-xr-x   9 outsider  staff  306  1 20 19:22 spring-framework-reference
outsider@Outsider-MBP:spring-framework (git:3.1.x)$ cat .git/info/sparse-checkout

이 기능을 사용하면 저장소에서 원하는 폴더나 파일만 남길 수 있습니다. 더 필요한 파일이나 목록의 수정이 필요하면 sparse-checkout파일을 수정하고 다시 git read-tree -m -u HEAD를 실행하면 변경할 수 있습니다.

이 때까지만 해도 제가 원하는 기능이 제대로 된줄 알았씁니다. 하지만 sparse checkout은 해당 폴더와 파일만 체크아웃해온다기 보다는 해당 파일만 보이도록 하는 기능처럼 보입니다. 그래서 숨겨진 파일도 실제로 존재합니다.(존재한다기 보다는 관리대상에 여전히 포함되어 있다는 표현이 맞을 듯 합니다.) 예를 들어 README.md파일이 원래 있기 때문에 새로 README.md파일을 만들어도 파일은 생성되지만 커밋해야할 리스트에 나타나지 않습니다.(원래는 있는 파일이기 때문이죠.)  그러므로 실제 스프링 저장소의 모든 파일과 히스토리도 모두 가지고 있습니다.(Git의 특성상 당연한 얘기죠.) 이 저장소를 이 상태로 수정한 뒤에 Github에 push를 하면 Github에는 sparse checkou이 설정되어 있지 않으므로 모든 폴더와 파일이 다 나타나고 제가 만들다가 원래있던 파일과 겹친 파일들은 오히려 제대로 나타나지 않습니다.(정확히 어떤 용도에 사용하는지 잘 모르겠지만 제가 의도했던 기능해서는 오히려 문제의 소지가 커보입니다.)

원하는 동작은 하지 못했지만 처음 알게된 기능이므로 사용방법이라도 기록하기 위해서 남겨봅니다. 결국 이 문제는 스프링 프레임워크 저장소를 내려받아서 필요없는 파일은 모두 삭제한 다음에 제 저장소에 머지했습니다. 스프링 저장소의 모든 히스토리가 필요한건 아니고 제가 받은 파일 기준으로 이후 변경내역만 비교할 수 있으면 되기 때문에 이렇게 한 다음에 이후 변경사항을 내려받아서 비교하면 될 것 같습니다.
2012/01/21 19:12 2012/01/21 19:12