저번 시간에는 커밋을 잘 다룰 수 있는 방법 중, 커밋 히스토리와 커밋 메시지 작성법, 최신 커밋 수정하기 등에 대해 배웠습니다.
이번 시간에는 커맨드에 alias를 설정하고 두 커밋 간의 차이를 보며, HEAD의 의미를 알고, git reset에 대해 더 자세히 배워보겠습니다.
지금까지 커밋 히스토리를 보기 위해서 git log 커맨드를 사용했습니다. 그리고 커밋 하나당 한 줄씩 보기 위해서 pretty와 oneline 옵션을 줬죠. 그런데 옵션이 좀 길다고 느껴지지 않으신가요? 이렇게 긴 옵션을 매번 붙여서 사용하려니 좀 번거롭네요.
Git에는 이렇게 길이가 긴 경우, 커맨드 전체에 별명을 붙여 그 별명을 대신 사용할 수 있도록 해주는 기능이 있습니다. 이때, 별명을 alias라고 부르고, 별명을 붙이는 행위를 aliasing이라고 합니다. 한번 해볼까요?
우리는 앞으로 git log --pretty=oneline
에 git history
라는 별명을 붙여주겠습니다. 이때, config
라는 커맨드를 사용하면 되는데요. 그런데 이 커맨드가 좀 낯익습니다. 네, 맞습니다. 우리는 가장 첫번째 커밋을 하기 전 이 커맨드를 사용했습니다.
git config user.name 'tataki26'
와 같이 말이죠. 이 커맨드의 기능은 누가 커밋을 남기는지 그 사용자의 정보를 저장하는 것이었죠? alising도 이와 유사하게 설정할 수 있는데요.
git config alias.history 'log --pretty=oneline'
이렇게 적으면 이제 get history
를 입력해도 커밋 하나당 한 줄씩 볼 수 있습니다.
따라서, 이제부터는 get history를 대신 사용하겠습니다. history는 원래 git에 있던 커맨드가 아닌 임의로 만든 alias라는 것을 기억해두시길 바랍니다. 이렇게 별명을 사용하면 긴 커맨드를 간단히 사용할 수 있습니다.
커밋 히스토리를 보다 보면 커밋 A와 커밋 B 사이의 변경 사항을 확인하고 싶을 때가 있습니다. 예컨대, 어떤 코드가 추가되었는지 혹은 삭제되었는지를 알고 싶은 것이죠.
방금 지정한 별명이 잘 적용되었는지 확인할 겸, git history를 실행해보겠습니다.
잘 실행되네요. 출력 내용을 자세히 살펴보면 README 파일을 생성한 부분과 수정한 부분이 있는 것을 확인할 수 있는데요. 두 커밋 사이의 차이점을 살펴보겠습니다. 이럴 때 사용하는 커맨드는 git diff
입니다. diff는 difference의 줄임말로 '차이점'을 의미합니다.
이 뒤에 차이를 보고 싶은 두 커밋의 아이디를 적으면 되는데요. 순서는 좀 더 이전의 커밋 아이디부터 먼저 적어야 합니다.
git diff 309f 4ee6
그럼 두 커밋 간의 차이를 확인해볼 수 있습니다. 위 화면이 익숙하시죠? 앞서 봤던 git show와 유사한 결과를 보여주고 있습니다. git show와 마찬가지로 -
는 이전 커밋의 모습을, +
는 이후 커밋의 모습을 보여주고 있다고 해석하시면 됩니다.
맨 처음 README 파일에는 단 한 줄 밖에 없었지만 이후 커밋을 하면서 세 줄로 늘어나고 마크다운 기호들도 추가된 것을 확인할 수 있습니다.
커밋 히스토리를 다시 한 번 보면 HEAD
라는 부분이 보입니다. git에서 HEAD는 어떤 특정 커밋 하나를 가리키는 특별한 의미를 가지는데요. 그 커밋이 무엇일까요? 상황에 따라 다르지만 HEAD는 보통 가장 최근에 한 커밋을 가리킵니다. 이는 HEAD의 위치만 봐도 알 수 있습니다.
그런데 HEAD가 필요한 이유는 무엇일까요? 우리는 프로젝트 디렉토리의 다른 이름으로 working directory 혹은 working tree라는 것을 배웠습니다. 그리고 이 working directory는 HEAD가 가리키는 커밋에 따라 다르게 구성됩니다.
working directory의 내부를 보겠습니다.
지금까지 만들었던 파일과 디렉토리들이 잘 보이네요. 파일의 내용들도 하나씩 보겠습니다.
먼저, calculator.py 파일입니다.
다음으로 License 파일입니다.
마지막으로 README 파일을 보겠습니다.
세 파일 모두 최근에 커밋했을 때 상태 그대로 잘 있는 것을 확인할 수 있습니다. 이는 HEAD가 가장 최근에 한 커밋을 가리키고 있어서 가능한 일입니다. 하지만 HEAD가 다른 것을 가리키면 working directory에 있는 것들은 언제든지 다르게 바뀔 수 있습니다. 이 말은 즉, 만약 HEAD가 최신보다 이전의 커밋을 가리키게 되면 과거 커밋의 모습대로 working directory 안에 있는 파일이 변하게 됩니다.
현재 HEAD는 'Add function'이라는 커밋을 가리키고 있습니다. 이 커밋은 가장 최근에 한 활동이었죠? HEAD가 이 커밋보다 더 이전 커밋을 가리키도록 하려면 어떻게 해야 할까요? git reset
이라는 커맨드를 사용하면 됩니다. reset은 초기화한다는 뜻을 가지고 있죠?
이 커맨드 다음에는 --hard
라는 옵션과 가고 싶은 커밋의 아이디를 적어줘야 합니다. 'Add Function' 커밋에서 'Make README.md look nice' 커밋으로 이동하겠습니다.
git reset --hard 4ee6
그럼 HEAD가 'Make README.md'로 이동했다는 문구가 뜹니다. 다시 커밋 히스토리를 확인해보겠습니다.
이번에는 HEAD가 'Make README.md'를 가리키고 있습니다. 그 위에 있던 커밋의 내용은 사라졌네요.
앞서 HEAD가 가리키는 커밋에 따라 working directory의 구성이 바뀐다고 했습니다. 정말 working directory의 구성이 바뀌었는지 확인해 보겠습니다.
'Add Function' 커밋은 calculator.py 파일에 multiply 함수를 추가하는 작업을 반영한 것이었습니다. 그런데 HEAD가 그 이전 커밋을 가리키니 추가되었던 multiply 함수가 사라졌네요. 이는 HEAD가 'Make README.md' 커밋을 가리키게 되면서 그 이후 커밋의 내용이 반영되지 않았기 때문입니다.
이처럼 git reset을 사용하면 HEAD가 과거 커밋을 가리키게 할 수 있고 working directory의 내용도 과거 커밋의 모습으로 돌아가게 할 수 있습니다.
다시 한 번 정리하자면, git reset은 과거 커밋으로 아예 돌아가고 싶을 때 사용합니다. 개발을 하다보면 특정 커밋을 진행했는데 그 내용이 너무 마음에 들지 않아서 과거로 돌리고 싶은 순간이 있습니다. 바로 그때, git reset을 사용하여 돌아가고 싶은 커밋으로 복귀하고 그 커밋부터 새로 작업을 시작하면 됩니다.
git reset에는 --hard
외에도 다양한 옵션이 있는데요. 그 옵션들을 배우기 전에 알아둬야할 사항을 함께 보겠습니다.
먼저, git reset의 어떤 옵션이든 HEAD가 과거 커밋을 가리키게 되는 결과는 똑같이 나옵니다. 그러나 working directory의 내부도 커밋에 따라 바뀌는지의 여부는 옵션에 따라 다릅니다. 이는 hard 옵션에만 적용되는 결과인데요. 나머지 결과는 다음 챕터에서 확인해보도록 하겠습니다.
다음으로 staging area에 있던 파일들은 커밋 이후 어떻게 변하게 되는지에 대해 알아봅시다. 커밋의 절차는 프로젝트 디렉토리 안의 파일을 수정하고 git add를 한 후, staging area에 올리는 것으로 이루어집니다. 그런데 커밋을 하고 나면 staging area에 있던 파일들은 어떻게 될까요?
커밋을 했다고 해서 staging area가 초기화되지는 않습니다. 즉, staging area의 파일이 사라지지는 않는다는 거죠. 다만 계속 git add를 할 때마다 staging area에서는 새로운 파일이 추가되거나 원래 있던 파일이 더 새로운 버전으로 교체됩니다.
이 두 가지를 잘 기억해두어야 다음에 배울 git reset의 옵션에 관한 내용들을 잘 이해할 수 있습니다. staging area에 있던 파일들은 커밋을 하더라도 이와 상관없이 계속 남아있다는 점을 꼭 기억해주세요!
이번 시간에는 커맨드에 별칭을 지정하고 두 커밋 간의 차이를 보는 방법과 최신 커밋을 가리키는 HEAD, 그리고 과거 커밋으로 돌리는 git reset에 대해 함께 배웠습니다.
다음 시간에는 커밋을 다루는 마지막 시간입니다. git reset의 세 가지 옵션과 커밋에 tag를 다는 방법 등에 대해 배워보도록 하겠습니다.
* 이 자료는 CODEIT의 'Git으로 배우는 버전 관리' 강의를 기반으로 작성되었습니다.