[Git] 4장 커밋

참조

코드의 변화

  • 깃은 개발 중인 코드의 이력을 만들 수 있습니다. 깃이 코드 변화를 기록하는 것을 커밋(commit) 이라고 합니다.
  • 개발 과정에서 소스 코드는 수없이 수정됩니다.
  • 일반적으로는 새로운 기능을 추가하는 코드를 삽입합니다. 또 버그를 수정하려고 많은 코드를 이동하거나 대체합니다.
  • 이러한 코드 수정은 개발 목적을 달성하는 작업들입니다.

파일 관리 방법

  • 깃이 없던 시절, 전통적인 파일의 이력 관리 방법을 알아봅시다.
  • 보통 우리는 의미 있는 변경을 할 때 파일을 복사합니다. 그리고 복사한 새 파일에는 추가하거나 변경하고 싶은 내용을 적용합니다.
  • 하지만 이렇게 파일을 복사하는 형태는 파일의 변경 내역을 기록하는 것보다 더 많은 파일을 생성하고 관리해야 하는 부작용이 있습니다.
  • 반면, 깃의 커밋은 새로 변경된 부분만 추출하여 저장합니다.
  • 그것도 파일 이름을 변경하지 않고도 동일한 파일 이름으로 하나로 관리가 가능합니다.
  • 즉, 시간에 따라 변화되는 내용만 관리하고, 코드가 변화된 사간 순서에 따라서 영구적으로 저장합니다.
  • 이를 커밋(commit) 이라고 합니다.
  • 개발자 입장에서는 복잡한 구조의 파일을 관리하지 않아도 되고, 여러개의 파일보다는 파일 하나로 모든 이력을 처리하기 때문에 유용합니다.

새 파일 생성

  • 실습을 위해 파일 하나를 간단히 작성합니다.
<!DOCTYPE html>
<html>
<head>
    <meta charset=“utf-8” />
    <meta name=“viewport” content=“width=device-width, initial-scale=1”>
    <title>Page Title</title>
</head>
<body>

</body>
</html>

소스트리에서 새 파일 감지

  • 소스트리를 사용하여 깃의 status 명령어와 동일한 상태를 확인할 수 있습니다.
  • 저장소에 새 파일이 추가 되면, Unstaged Files 영역에 새파일이 표시됩니다.

깃에 새 파일 등록

  • 깃의 워킹 디렉터리에 새 파일이 생성되었습니다.
  • 워킹 디렉터리에 있는 파일은 깃이 자동으로 추적 관리하지 않습니다. 커밋을 하려면 파일의 사태가 추적 가능해야 합니다.
  • 워킹 디렉터리에 새로 추가된 untracked 상태의 파일을 추적 가능 상태로 변경하는 것을 등록이라고 합니다.
  • 또 파일을 등록하면 워킹 디렉터리의 파일이 스테이지 영역에 추가됩니다.
  • 스테이지 영역의 관리 목록에 추가된 파일만 깃에서 이력을 추적할 수 있습니다.

스테이지에 등록

  • 깃에서 등록이란 워킹 디렉터리에 있는 파일을 스테이지(stage) 영역으로 복사하는 것을 의미 합니다.
  • 여기서 '복사' 는 실제 파일을 복사하는 것을 의미하지는 않습니다.
  • 깃 내부에서 논리적인 기록을 변경하는 과정일 뿐입니다. 복사라고 표현한 것은 이해하기 쉽게 풀어쓴 의미입니다.
  • 워킹 디렉터리에 추가된 모든 파일을 커밋할 때는 반드시 이 과정을 거쳐야 합니다.
  • 그래야 깃에서 버전 이력을 관리할 수 있습니다.
  • 스테이지에 등록되지 않은 unstage 상태의 파일들은 커밋할 수 없습니다.
  • 깃은 커밋하기 전에 파일들이 stage 상태인지 unstage 상태인지를 판단합니다.
  • 스테이지 영역으로 등록된 파일들은 tracked 상태로 자동 변경됩니다.

파일의 추적 상태 확인

  • 워킹 디렉터리에 있는 새로운 파일이 스테이지 영역에 등록되었습니다.
  • 콘솔창에서 status 명령어를 사용하여 등록 상태를 다시 한번 확인합니다.

파일 등록 취소

  • tracked 상태의 파일은 untracked 상태로 변경할 수도 있습니다.
  • 스테이지에 등록하는 것과 반대 과정입니다.
  • 등록 취소는 워킹 디렉터리와 스테이지 영역을 서로 왔다 갔다 할 수 있는 방법입니다.
  • unstage 상태로 변경하려면 삭제(rm) 나 리셋(reset) 명령어를 사용합니다.
$ git rm - cached index.html ---- 스테이지 삭제
rm 'index.html'

HEAD

  • 커밋을 학습하기 전에 HEAD 개념을 하나 더 알아봅시다.
  • 깃에는 HEAD 라는 포인터 개념이 있습니다. HEAD는 커밋을 가리키는 묵시적 참조 포인터입니다.
  • HEAD는 최종적인 커밋 작업의 위치를 가리킵니다.
  • 앞에서 새로운 커밋은 이전 부모 커밋을 기반으로 새로운 커밋을 만든다고 했습니다. HEAD는 바로 부모 커밋 을 가리킵니다.
  • 단 깃을 설치하고 처음 커밋할 때는 HEAD의 포인터가 없습니다. 최소한 한 번 이상 커밋을 해야만 HEAD가 존재합니다.
  • HEAD는 커밋될 때마다 한 단계씩 이동합니다. 그리고 마지막 커밋 위치를 가리킵니다.
  • HEAD는 커밋이 변화한 최종 시점을 의미합니다.

스냅샷

  • 커밋은 파일 변화를 깃 저장소에 영구적으로 기록합니다. 이러한 커밋은 이전에 파일을 복사하여 관리하던 방식과는 큰 차이가 없습니다.
  • 깃이 다른 버전 관리 도구와 다른 점은 스냅샷(snapshot) 방식을 이용한다는 것입니다.
  • 파일을 복사하는 방식으로 수정본을 관리하면 같은 내용을 반복해서 저장하기에 많은 용량을 차지합니다.
  • 또 수정된 부분들을 일일이 찾아야 하기 때문에 검색할 때도 매우 불편합니다.
  • 깃은 이러한 시스템적인 단점을 해결하려고 변경된 파일 전체를 저장하지 않고, 파일에서 변경된 부분을 찾아 수정된 내용만 저장합니다.
  • 마치 변화된 부분만 찾아 사진을 찍는 것과 같다고 하여 스냅샷 방식 이라고 합니다.
  • 깃의 스냅샷은 HEAD가 가리키는 커밋을 기반으로 사진을 찍습니다.
  • 그리고 이를 스테이지 영역과 비교하여 새로운 커밋으로 기록합니다.
  • 이처럼 깃은 스냅샷 방식을 이용하여 빠르게 버전의 차이점을 처리하고, 용량을 적게 사용합니다.

파일 상태와 커밋

  • 커밋은 변화된 내용을 영구적으로 깃 저장소에 기록합니다.
  • 새롭게 생성된 파일을 커밋하려면 반드시 tracked 상태로 변경해 주어야 합니다. tracked 상태로 파일이 변경됨과 동시에 스테이지 영역에 등록합니다.
  • tracked 상태인 파일을 수정하면 다시 modified 상태로 변경됩니다. modified는 untracked 상태입니다.
  • untracked 상태의 파일은 반드시 등록 명령으로 다시 스테이지 상태로 재등록해야 합니다. 재등록 하면 다시 tracked 상태로 변경됩니다.
  • 커밋을 하려면 스테이지 영역에 새로운 변경 내용이 있어야 합니다.
  • 수정된 내용이 스테이지 영역으로 등록되지 않으면 커밋을 할 수 없습니다. 커밋은 수정된 내용을 한 번만 등록합니다.
  • 스테이지 영역의 파일이 변경되지 않았다면 커밋을 두 번 실행할 수 없습니다.
  • 깃은 스테이지 영역의 변경된 내용을 기준으로 스냅샷을 만들어 커밋하기 때문입니다.

스테이지 초기화

  • 먼저 터미널에서 status 명령어를 실행해서 상태를 확인합니다.

로그 기록 확인

  • 깃은 커밋 목록을 확인할 수 있는 log 명령어를 별도로 제공합니다.
  • log 명령어는 시간 순으로 기록을 출력하는데, 최신 커밋 기록부터 내림차순으로 나열합니다.
$ git log

파일 수정

  • index.html 파일의 내용을 수정합니다.
<!DOCTYPE html>
<html>
<head>
    <meta charset=“utf-8” />
    <meta name=“viewport” content=“width=device-width, initial-scale=1”>
    <title>Page Title</title>
</head>
<body>
   <h1>hello GIT world!</h1>
</body>
</html>

파일 변경 사항 확인

  • 파일을 수정 후, 터미널에서 status 명령어를 다시 한번 실행합니다.
  • 이전과 다른 새로운 메시지를 확인할 수 있습니다.
  • 처음 우리가 파일을 생성했을 때는 new file:index.html 메시지를 보았습니다.
  • 파일을 수정한 후에는 modified:index.html 메시지가 출력됩니다.

수정된 파일 되돌리기

  • 파일을 수정하면 modified 상태로 변경됩니다. 하지만 수정하는 과정에서 파일을 잘못 수정할 수도 있습니다.
  • 깃을 이용하면 수정한 파일을 커밋 전 마지막 내용으로 쉽게 되돌릴 수 있습니다.
  • 수정 파일을 되돌리면 이전 커밋 이후에 작업한 수정 내역은 모두 삭제합니다.
$ git checkout - 수정파일이름

스테이지에 등록

  • 변경된 소스 코드를 커밋하는 것은 처음 파일을 생성하고 등록하는 과정과 매우 유사합니다.
  • ➊. 기존 파일을 수정하면 해당 파일은 modified 상태로 변경됩니다. 그리고 다시 워킹 디렉터리로 이동합니다.
  • ➋. 파일이 수정되면 반드시 add 명령어로 스테이지 영역에 재등록해야 합니다. 즉, 파일을 수정할 때마다 등록 작업을 반복해야 한다는 것입니다.
$ git add 수정파일이름

두 번째 커밋

  • 수정된 파일을 커밋할 수 있는 사전 준비 작업을 마쳤습니다.
  • 커밋과 동시에 간단하게 한 줄까지 커밋 메시지도 작성할 수 있습니다.
  • 커밋할 때는 --m 옵션을 사용합니다.
  • --m 옵션 옆에 간단히 입력한 내용을 바로 커밋 메시지로 처리합니다.
$ git commit --m "커밋메시지"

두 번째 커밋 확인

  • 두번째 커밋을 마쳤다면, 다시 한번 로그 확인을 해보겠습니다.
  • 로그 메시지가 새롭게 추가된 것을 보실 수 있습니다.

메시지가 없는 빈 커밋

  • 커밋을 할 때는 반드시 커밋 메시지를 같이 작성해야 합니다.
  • 하지만 의미 없는 커밋이라 커밋 메시지를 생략하고 싶을 때도 있습니다.
  • 이러한 특별한 상황에 대비하여 깃은 메시지가 없는 커밋 작성도 허용합니다.
  • 이를 간단히 '빈 커밋' 이라고 합니다.
  • 빈 커밋 작성 방법은 지금까지 살펴본 메시지 작성 방법과 약간 다릅니다.

세 번째 커밋

  • 실습을 위해 index.html 파일을 다시 수정하고 커밋하도록 하겠습니다.
<!DOCTYPE html>
<html>
<head>
    <meta charset=“utf-8” />
    <meta name=“viewport” content=“width=device-width, initial-scale=1”>
    <title> BeomHeeJo</title>
</head>
<body>
   <h1>헤더 추가</h1>
</body>
</html>

소스트리에서 빈 커밋

  • 소스트리에서는 메시지가 없는 빈 커밋을 하기가 더 쉽습니다.
  • 예를 들어 파일 상태 탭을 선택한 후 아래쪽의 커밋 메시지 입력란을 비워 두고 커밋을 누르면 됩니다.
  • 그러면 다음과 같은 화인 메시지가 표시됩니다.

빈 커밋 확인

  • 빈 커밋 메시지를 확인할 수 있습니다.
  • 터미널에서 log 명령어를 입력합니다.
  • 소스트리에서 자동적으로 빈 커밋을 하게 되면, no message 라는 문구를 입력하여 커밋합니다.

커밋 아이디

  • 각 커밋에는 aa92947d350db27b604d1351930d4f809f96886e 와 같은 이상한 영문과 숫자가 있습니다.
  • 이를 커밋 아이디 라고 합니다.
  • 커밋 아이디는 특정 커밋을 가리키는 절대적인 이름이고, 명시적 참조 값입니다.
  • 커밋 아이디는 다수의 커밋을 구분할 수 있는 키이며, 브랜치나 태그 등에도 많이 사용됩니다.

SHA1

  • 커밋 아이디가 이렇게 복잡한 영어와 숫자로 된 이유는 SHA1 이라는 해시알고리즘을 사용하기 때문입니다.
  • SHA1 해시키 값은 40 자리의 복잡한 hexa 값으로 되어 있습니다.
  • 깃은 스테이지 영역의 변경된 내용을 기반으로 SHA1 해시키를 생성합니다.
  • 따라서 SHA1 해시는 중복되지 않은 고유의 키를 생성할 수 있는 장점이 있습니다.
  • 깃이 SHA1 해시를 이용하는 것은 콘텐츠 추적과 분산형 저장 관리를 운영하면서 충돌을 방지하기 위해서입니다.

단축키

  • SHA1 해시키는 매우 복잡한 모양의 영어와 숫자로 되어 있습니다.
  • 해시는 40자리의 16진수로 입력하다 실수로 잘못 입력할 가능성이 높습니다.
  • SHA1 해시키는 매우 큰 숫자이기 때문에 고유 접두사로 간략하게 사용할 수 있는데, 해시의 앞쪽 7자만으로도 중복을 방지하면서 전체 키 갑을 사용할 수 있습니다.
  • 해시는 매우 큰 값으로 웬만해서는 앞쪽 숫자 값이 변경되는 경우가 드뭅니다.

커밋 로그

  • 깃은 터미널 기반의 응용 프로그램입니다.
  • 깃의 로그는 저장소 커밋 기록들을 확인할 수 있습니다.
  • 또 커밋 메시지, 아이디도 확인할 수 있고, 브랜치 경로 등을 분석할 수 있는 옵션들도 제공합니다.

간략 로그

  • 커밋 메시지를 여러 줄 작성했다면 일반적인 로그 정보를 복잡하게 느낄 수 있습니다.
  • 로그 옵션 중에서 --pretty-short 를 사용하면 로그를 출력할 때 첫 번째 줄의 커밋 메시지만 출력합니다.
  • 특정 커밋의 상세 정보도 확인할 수 있습니다. 특정 커밋의 상ㅅ 정보를 확인하고 싶다면 show 명령어를 사용합니다.
$ git show 커밋ID

특정 파일의 로그

  • 전체 커밋과 달리 특정 파일의 로그 기록만 볼 수도 있습니다.
  • 이때는 log 명령어 뒤에 파일 이름을 적어 주면 됩니다.

  • log 명령어의 옵션은 매우 다양합니다.
--p 옵션 : diff 기능(수정한 라인 비교)을 같이 포함하여 출력할 수 있습니다.
--stat 옵션 : 히스토리를 출력합니다.
--pretty=oneline 옵션 : 각 커밋을 한 줄로 표시합니다.

diff 명령어

  • diff 명령어는 커밋 간 차이를 확인합니다.
  • 보통 리눅스나 macOS 같은 유닉스 계열의 운영체제에는 유용한 diff 명령어가 있습니다.
  • 깃 또한 초기 시작은 리눅스 커널을 개발하려는 것이었기 때문에 유사한 기능을 하는 diff 명령어를 제공합니다.

파일 간 차이

  • 깃의 장점은 파일들의 수정 이력을 커밋이라는 형태로 구분할 수 있다는 것입니다.
  • 앞에서 살펴보았듯이, 깃은 커밋으로 파일들의 수정 내역을 추적합니다.
  • 파일 수정이란 파일 내용 일부가 수정, 추가, 삭제되는 것을 의미합니다. 개발하면서 수많은 소스 코드가 수정, 추가, 삭제되곤 합니다.
  • 깃은 커밋을 기준으로 이러한 파일들의 수정 이력을 비교해 볼 수 있는 diff 기능을 제공합니다.
  • diff 기능으로 파일의 수정 및 변경 내역을 쉽게 파악할 수 있습니다.

워킹 디렉터리 vs 스테이지 영역

  • 아직 add 명령어로 파일을 추가하지 않은 경우, 워킹 디렉터리와 스테이지 영역 간 변경사항을 비교할 수 있습니다.
  • index.html 파일을 수정합니다.
<!DOCTYPE html>
<html>
<head>
    <meta charset=“utf-8” />
    <meta name=“viewport” content=“width=device-width, initial-scale=1”>
    <title> BeomHeeJo</title>
</head>
<body>
   <h1>헤더 추가</h1>
   <h2>깃을 이용하면 소스의 버전 관리를 쉽게 할 수 있습니다.</h2>
</body>
</html>

커밋 간 차이

  • 스테이지 영역에 있는 수정된 파일을 아직 커밋하지 않았다면, 최신 커밋과 변경 내용을 비교하여 볼 수 있습니다.
  • HEAD 는 마지막 커밋을 가지고 있는 포인터입니다.
  • HEAD는 최근의 커밋 중 가장 마지막 커밋의 위치를 가리키는 값입니다. HEAD를 이용하면 최신 커밋과 이전 커밋을 비교하여 출력할 수 있습니다.

정리

  • 커밋 작업은 깃에서 소스 코드를 관리하는 첫 단추입니다.
  • 너무 많은 코드를 수정한 후 커밋하는 것보다는 작은 단위로 코드를 수정한 후 커밋하는 것을 추천합니다.
  • 커밋의 수정 부분이 적을수록 검토하기 쉽고, 오류도 쉽게 찾을 수 있습니다.
728x90

'버전관리' 카테고리의 다른 글

[Git] 6장 브랜치  (0) 2022.06.19
[Git] 5장 서버  (0) 2022.06.19
[Git] 3장 깃 개념 잡기  (0) 2022.06.18
[Git] 2장 깃과 소스트리 설치 및 환경 설정  (0) 2022.06.18
[Git] 1장 깃과 버전관리  (0) 2022.06.18

이 글을 공유하기

댓글

Designed by JB FACTORY