00:00:00반갑습니다. Git Butler를 모르시는 분들을 위해 간단한 데모를 준비했습니다. Git Butler는 새로운 버전 관리 도구입니다.
00:00:07우리는 몇 년 동안 이 프로젝트를 진행해 왔고, Jujutsu(JJ)에서 많은 영감을... 아니, 많은 걸 훔쳐왔죠.
00:00:10그러니 여러분 중에 Jujutsu를 사용하시는 분이 있다면, 저희가 여러분의 아이디어를 아주 많이 가져다 썼다고 보시면 됩니다.
00:00:16어쨌든 Git Butler를 처음 보시는 분들을 위해 설명하자면, 이건 버전 관리 도구입니다.
00:00:19보통은 GUI 형태로 사용하지만,
00:00:21현재 CLI 버전을 개발 중이라 그 결과물을 좀 보여드리고 싶었습니다. 여러분 모두 Git을 사용하시고,
00:00:26Git의 CLI가 꽤 흥미로운 구조를 가지고 있으니까요.
00:00:29저희는 Jujutsu에서 가져온 몇 가지 개념들을 적용했습니다.
00:00:33하지만 꽤 멋지다고 생각되는 새로운 기능들도 포함되어 있죠.
00:00:36그래서 여러분께 보여드리고 피드백을 받아 더 멋진 툴을 만들 아이디어를 얻고 싶습니다.
00:00:40자, 그럼 하나씩 살펴보겠습니다.
00:00:43먼저,
00:00:46이 명령줄 도구의 이름은 'but'입니다.
00:00:49제가 평소에 '아재 개그(Dad jokes)'를 즐겨 하다 보니 이 이름이 꽤 적절하다고 느껴지네요.
00:00:52'but status'를 실행하면, 일종의 요약 로그(short log)가 나옵니다.
00:00:57Sapling이나 Jujutsu를 사용하면서 로그를 확인해 보셨다면 익숙하실 텐데요,
00:01:00디스크에서 수정된 파일들을 보여줍니다.
00:01:05현재 작업 디렉토리와 타겟 브랜치의 차이점을 보여주는 방식이죠.
00:01:08동시에 현재 가지고 있는 커밋들도 함께 보여줍니다.
00:01:11'but status -f'를 실행하면 각 커밋에서 어떤 파일들이 수정되었는지도 확인할 수 있습니다.
00:01:18Git Butler GUI를 사용하고 계신다면 레인(Lane) 같은 요소들을 보실 수 있겠지만,
00:01:23CLI에서도 Git이 하지 못하는 멋진 기능들이 많습니다. 예를 들어 이런 깔끔한 요약 로그 기능이나,
00:01:29기타 여러 가지가 있죠.
00:01:30그리고...
00:01:32일반적인 로그를 통해 이 커밋들이 로컬인지 등을 확인할 수 있는데, 이건 다른 툴의 요약 로그와
00:01:39비슷한 방식입니다.
00:01:40새로운 브랜치를 생성할 수도 있습니다.
00:01:44다시 'status'를 보면, 여기서는 트위터 클론 프로젝트를 예시로 쓰고 있는데요.
00:01:50브랜치 몇 개가 서로 쌓여(stacked) 있는 것을 볼 수 있습니다.
00:01:52이건 Git에서도 'update-ref' 설정을 사용하면 가능한 기능이죠.
00:01:56리베이스 등을 할 때 참조(refs)를 다시 작성해 주는 기능 말입니다.
00:02:00하지만 저희는 이걸 훨씬 더 자연스럽게 처리합니다.
00:02:03참조를 자동으로 업데이트하고, 리베이스 과정에서 변경 사항을 자동으로 추적하죠.
00:02:09거기에 더해 저희는
00:02:11'병렬 브랜치' 기능을 지원합니다. 동시에 하나 이상의 브랜치를 적용할 수 있다는 뜻이죠. 여기서 한번
00:02:23새 브랜치를 생성해 보겠습니다.
00:02:26다시 실행해 보면, 작업 중인 다른 브랜치들과 병렬로 존재하는 새 브랜치가 보이죠?
00:02:33이제 해당 브랜치로 들어가서 파일을 할당하고 커밋하는 작업을 시작할 수 있습니다.
00:02:39그 과정을 이어서 보여드리죠.
00:02:41또 다른 멋진 기능은 여러 개의 스테이징 영역(staging areas)을 가질 수 있다는 점입니다.
00:02:45각 스택마다 별도의 스테이징 영역이 있어서, 예를 들어
00:02:51'rub' 명령어를 사용할 수 있습니다. 'rub KU'로 이 파일을 선택하고 'ZA'에 넣으라고 지정하면,
00:02:58해당 스테이징 영역으로 파일이 할당됩니다. 특정 위치에 파일을 할당하고 싶다면
00:03:04이런 짧은 코드들을 활용하면 됩니다. 자,
00:03:12이 파일은 여기에 할당하고, 저 파일은 저기에 할당했습니다.
00:03:15이 상태에서 커밋하면 각각의 브랜치에 동시에 커밋을 넣을 수 있습니다.
00:03:21결과를 보시죠. 파일이 여기에 할당된 것을 볼 수 있습니다. 이제 이렇게 입력하면,
00:03:27'but commit -o'
00:03:30여기에 바로 커밋됩니다.
00:03:40이제 이 파일은 해당 커밋에 포함되었습니다. 좋은 점은 이 모든 게 Git 기반이라는 겁니다. 그래서
00:03:48이렇게 하면,
00:03:50실제로 Git 커밋이 생성되고, 브랜치를 푸시하는 등의 작업이 모두 가능합니다.
00:03:57하지만...
00:03:59두 브랜치에 할당할 수도 있고, 그냥 'but commit'을 실행해 타겟 브랜치에 할당되지 않은 모든 변경 사항을
00:04:07커밋할 수도 있습니다. 어떤 브랜치에 새로운 작업을 커밋할지 선택할 수 있는 거죠.
00:04:11그래서 저희는 이걸 '러빙(rubbing)'이라고 부르기로 했습니다.
00:04:14밤새 술을 마시고 아직 안 나타난 케일럽에게도 이 용어를 말해줬는데요.
00:04:18만약 그가 들어오면 다 같이 일어나서 박수라도 쳐줍시다.
00:04:21어쨌든 그가 제안한 '러빙'이라는 용어는 본질적으로 두 요소를 비벼서 하나로 합치는 과정을 의미합니다.
00:04:28마인크래프트의 제작대(crafting table) 개념을 생각하시면
00:04:32이해하기 쉬울 겁니다.
00:04:34이것과 저것을 합쳐서 새롭고 더 흥미로운 것을 만들어내는 방식이죠.
00:04:38'but rub' 명령어를 통해 'but' CLI에서 할 수 있는 일은 정말 많습니다.
00:04:45몇 가지 보여드리죠. 방금 보여드린 것처럼 파일을 할당할 수도 있고,
00:04:52수정된 파일을 브랜치에 넣거나 반대로 할당을 해제할 수도 있습니다. 여기 '00'이라는 특수한 모드가 있는데,
00:05:01여기서 'but rub'을 사용해서
00:05:05예를 들어 이 커밋 전체를
00:05:07'00'으로 보내버리면
00:05:11커밋이 취소됩니다. 기본적으로 해당 커밋에 대해 'reset --soft'를 실행하는 것과 같죠.
00:05:17커밋 수정(amend)도 가능합니다. 'rub le r'...
00:05:24y...
00:05:27RV... 아, 이제 돋보기가 필요할 정도로 나이를 먹었나 보네요.
00:05:32SW... 아, 죄송합니다. 실제로는
00:05:351 1 W로 해보죠.
00:05:38IW인가요? 감사합니다.
00:05:41이런, 실수했네요.
00:05:44이게 I인가요?
00:05:48죄송합니다.
00:06:02그리고
00:06:04그대로 커밋에 반영됩니다. 이렇게
00:06:10Rub I...
00:06:14커밋을 취소할 수도 있고,
00:06:16커밋을 합칠(squash) 수도 있습니다. 이 커밋과 저 커밋을 합치고 싶다면 'but rub J e GE'를 하면 됩니다.
00:06:22J e GE
00:06:25그러면 두 커밋이 하나로 합쳐집니다. 커밋을 취소하거나 순서를 바꾸는 등
00:06:32두 요소를 결합했을 때 기대할 수 있는 모든 동작을 수행합니다.
00:06:37할당되지 않은 변경 사항과 결합하면 사실상 작업이 취소되는 식이죠.
00:06:42이 기능이 지금 제대로 작동하는지 가물가물한데...
00:06:48파일을 다른 곳으로 옮길 수도 있습니다.
00:06:53J 8 2
00:07:02그러면
00:07:03해당 커밋에서 파일을 가져와서
00:07:07그 커밋에서는 빼고, 바로 아래에 있는 커밋으로 옮겨줍니다.
00:07:11이게 흥미로운 점은 Git에서 불가능한 일이라서가 아니라, Git으로는 하기가 꽤 까다롭기 때문입니다.
00:07:19특정 커밋만 취소하거나, 커밋 간에 파일을 이동하거나, 세 단계 아래에 있는 커밋에 파일을 끼워 넣는 일 말이죠.
00:07:27Git에서도 할 수는 있습니다. 임시로
00:07:31fixup 커밋을 만들고 auto-squash를 하는 식의 방법이 있죠.
00:07:34하지만 이렇게 '비비는(rubbing)' 방식으로 원하는 위치에 콘텐츠를 툭툭 옮기고,
00:07:40동시에 여러 브랜치를 유지하는 편이 훨씬 쾌적합니다.
00:07:43커밋 분할도 아주 쉽습니다. 'but new'라는 명령어가 있는데요.
00:07:51이렇게 입력하면,
00:07:54'but new'
00:07:56H e... 그러면
00:07:59내용이 비어있는 새로운 빈 커밋이 생성됩니다.
00:08:03이건 Jujutsu 스타일이죠. 아무것도 들어있지 않은 빈 커밋을 먼저 만들고
00:08:08나중에 파일을 그 안으로 'rub'해서 넣을 수 있습니다. 예를 들어
00:08:12이 파일을 선택해서
00:08:150
00:08:23가져오면
00:08:29파일이 새 커밋으로 이동합니다. 그다음 'describe'로 설명을 추가할 수 있죠.
00:08:32뭐였더라... X y c
00:08:45어떻게 하더라...
00:08:56Status -f를 보면 각 커밋에 포함된 파일들을 보여줍니다. 그냥 'but st'나
00:09:02'but status'는 커밋 목록만 보여주지만,
00:09:04'but status -f'는 그 안의 파일까지 보여주므로 러빙 기능을 통해 자유롭게 옮길 수 있습니다.
00:09:11'new'와 'describe'가 있고, 마지막으로 'marking'이 있습니다. 이것도 아주 Jujutsu스러운 기능이죠.
00:09:16Jujutsu를 써보신 분은 알겠지만, 특정 커밋을 타겟으로 '마크(mark)'할 수 있습니다.
00:09:21그러면 이후 발생하는 모든 변경 사항이 해당 커밋으로 들어갑니다. 정말 흥미로운 기능이죠.
00:09:25자, 해보겠습니다.
00:09:29'but new -m'을 하거나 'but mark'를 써서
00:09:33ZA를 선택하면
00:09:35여기에 마크가 생깁니다. 보시다시피 할당되지 않았던 변경 사항이 자동으로 그 레인(Lane)으로
00:09:42들어갔습니다.
00:09:44이제 커밋을 하거나, 혹은 특정 커밋을
00:09:47직접 마크할 수도 있습니다.
00:09:56아, 이건 브랜치였네요. 죄송합니다.
00:09:58특정 커밋을 마크한 상태에서 새로운 내용을 'echo' 등으로 추가하면
00:10:07그 즉시 해당 커밋에 자동으로 반영됩니다.
00:10:15여러 커밋이 쌓인 스택 브랜치에서 작업 중일 때 특히 유용한데, 현재 하는 모든 작업이
00:10:21세 단계 아래에 있는 커밋에 자동으로 수정(amend)되어 들어가는 식입니다.
00:10:26Jujutsu에서 'jj new'를 실행하고 작업을 시작하는 방식과 비슷합니다.
00:10:31마지막 커밋을 자동으로 계속 수정해 나가는 거죠.
00:10:33차이점은 어떤 커밋이든 자유롭게 마크해서
00:10:36작업을 이어갈 수 있고, 원할 때 언제든 마크를 해제할 수 있다는 점입니다.
00:10:41그렇죠.
00:10:44어쨌든, 이것들이 저희가 작업 중인 재미있는 기능들 중 일부입니다.
00:10:48이런 방식으로 작업하는 게 정말 편하더라고요.
00:10:52또 하나 Jujutsu에서 가져온 건 작업 로그(oplog)입니다.
00:10:56이건 저희가 꽤 오래전부터 구현해 온 기능인데요.
00:10:59Git Butler 앱을 보시면 모든 작업 내역을 보여주는 탭이 있습니다.
00:11:03명령어를 실행할 때마다 작업 기록이 생성되는데,
00:11:06Git Butler가 수행한 모든 이력을 확인하고 어느 시점으로든 복구할 수 있습니다. 예를 들어
00:11:12이렇게
00:11:13'undo'
00:11:14철자만 제대로 쓰면, 'undo' 명령으로 방금 한 작업을 취소하고 작업 디렉토리와 상태를
00:11:20이전 상태로 되돌릴 수 있습니다. 아니면
00:11:22'restore'
00:11:24특정 해시값(SHA)을 지정해서 복구할 수도 있죠.
00:11:26이런...
00:11:29그리고
00:11:33작업 디렉토리와 브랜치 등 모든 것을 이전 상태로 리셋합니다.
00:11:38이 기능 덕분에 데모를 하기가 참 편합니다. 확실히 작동하는 시나리오를
00:11:44하나 만들어두고, 거기로 복구해서 시나리오를 처음부터 다시 시작할 수 있으니까요.
00:11:50물론 실제 작업 중에도 '아, 이건 좀 아닌데' 싶을 때나
00:11:54충돌이 복잡해졌을 때 그냥 취소하고 다시 작업을 이어갈 수 있어 매우 유용합니다.
00:11:58네, 여기까지입니다. 아, 한 가지 더! 모든 명령어는 JSON 출력을 지원합니다. '-j'
00:12:06혹은 '--json' 옵션을 붙여서 실행하면 동일한 데이터를 JSON 형식으로 받을 수 있습니다.
00:12:11스크립트를 짤 때 Git의 porcelain 출력보다 훨씬 깔끔하고 편리하죠.
00:12:15결과값을 그대로 가져오거나 jq를 써서 특정 항목을 찾는 등
00:12:21CLI를 활용한 스크립트 작업이 훨씬 수월해질 겁니다.
00:12:24준비한 내용은 여기까지입니다. 감사합니다!