티스토리 뷰

상태

어떤 프로젝트에 기생하는 폴더가 하나 있다. 여하한의 이유로 그 폴더가 분리되지 않은 채 있었고, 변경이력이 장기간 쌓여 왔다. 이젠 새로운 저장소로 해당 폴더만 이관하고 싶다.

아이디어

  • "git log" 명령으로 특정 파일들 또는 폴더만 지정하여 해당 경로에 영향을 준 커밋만 뽑을 수 있다.
  • "git log" 명령에는 커밋의 diff 를 출력해 볼 수 있는 "--patch" 옵션 (또는 줄여서 -p)이 있다.
  • "git log" 명령에는 binary의 변경 또한 출력할 수 있는 "--binary" 옵션이 있다.
  • "git rebase" 명령의 내부에서는 일련의 변경 이력을 replay하는 방법으로 구현된다.
  • "git am" 명령이 "git rebase" 내부에서 동작하는 방식이며, 포맷은 무려(!) 이메일 포맷이다.
  • "git log" 명령에는 이메일 형식으로 변경을 출력할 수 있는 "--format=email" 옵션이 있다.
  • "git am" 명령은 날짜가 오래된 커밋이 맨 앞에 나온다.
  • "git log" 의 결과로 날짜가 오래된 것을 먼저 보이려면 "--date-order", "--reverse" 로 가능하다.

예제

specific_dir 이라는 디렉토리의 변경 사항을 꺼내어 project2 를 만드는 예제이다. 

$ cd ~/work/project1
$ git log --date-order --reverse --binary --patch --format=email -- specfic_dir > 1.eml
$ cd ~/work
$ mkdir project2
$ cd project2
$ git init
$ git am ~/work/project1/1.eml

여기서의 제약이라면, "git log --graph -- specific_dir" 명령으로 확인했을 때, 단일 브랜치여야한다. 평소에 merge commit 을 쓰지 않고, fast forward 전략으로 브랜치를 관리하였다면, 어려움 없이 모든 커밋을 떼어 낼 수 있다.

가끔 1.eml 내부의 커밋이 비어 있는 경우도 있을 수 있고, "git am"은 그것에 대해 블평하며, 작업을 중단한다. 그때는 "git am --skip" 으로 넘기면 된다.

반응형
댓글
  • 프로필사진 skshin 안녕하세요, 멋진(!) 아이디어에 감탄하면서, merge를 자주하는 저로서는 비슷한 고민이 있지 않을까 검색해 봤습니다.
    아니나 다를까, "Splitting a subfolder"라는 주제로 Github Docs에 관련 내용이 떡하니 있네요.
    https://docs.github.com/en/get-started/using-git/splitting-a-subfolder-out-into-a-new-repository

    좋은 글 항상 잘 보고 있습니다 ^^;
    2021.07.26 19:20
댓글쓰기 폼