Git에서 내 기록 작업하기
학습 목표
이 유닛을 완료하면 다음을 수행할 수 있습니다.
- Git이 어떻게 데이터를 저장하는지 설명하고 관련 지식의 실질적인 적용에 대해 설명할 수 있습니다.
- Git으로 프로젝트 내역 및 변경 사항을 볼 수 있습니다.
- 이전 변경 사항을 실행 취소할 수 있는 Git 명령을 사용할 수 있습니다.
- 리베이스와 일반적인 병합 전략의 연관성을 요약할 수 있습니다.
Git에서 데이터를 저장하는 방법
이전에 커밋에 대해 다루었을 때 커밋을 프로젝트의 스냅샷이라고 하였습니다. 각 스냅샷에는 많은 정보가 포함되어 있습니다. 스냅샷에서 압축된 파일은 각각 블랍이라고 하는 고유의 SHA-1 해시가 주어집니다. 트리는 이 블랍을 참조하고, 커밋은 해당 트리를 참조합니다.
파일을 변경하고 새 커밋을 만들 경우 Git은 변경된 파일을 식별하고 파일에 새로운 SHA-1 해시를 적용하지만 변경되지 않은 파일은 기존 SHA-1 해시를 유지합니다. 파일에 대한 SHA-1 해시가 변경됨에 따라 이전 SHA-1 해시를 상위 항목으로 참조합니다. GitHub에서는 SHA-1 해시(A)의 첫 일곱 문자를 모든 커밋에서 볼 수 있습니다.
이는 커밋 내력이 작동하는 방식과 매우 유사합니다. 새 커밋을 만들 경우 이전 커밋을 상위 커밋으로 참조합니다. 이 기준점은 매우 중요합니다. 이러한 선형, 상위/하위 관계는 일관된 내역을 만들고 Git이 브랜치를 함께 병합할 수 있게 합니다.
Git을 사용한 내역 탐색
프로젝트를 진행하는 동안 커밋 내역을 검토하는 것이 도움이 될 수 있습니다. GitHub.com에서는 프로젝트의 코드 탭에서 커밋 버튼을 선택하여 프로젝트 기록에 액세스할 수 있습니다. 로컬에서는 git log
를 사용할 수 있습니다.
git log
명령을 사용하면 현재 브랜치에 있는 모든 커밋의 목록을 표시할 수 있습니다. 기본적으로 git log
명령은 많은 정보를 한꺼번에 제공합니다.
git log
수정자 중 일부를 사용하여 몇 가지 주요 정보를 제공하는 읽기 쉬운 목록을 생성합니다.
-
git log -10
은 가장 최근의 10개의 커밋만 표시합니다.
-
git log --oneline
은 SHA-1 해시의 처음 7개의 문자와 현재 브랜치에 커밋의 커밋 메시지를 표시하여 커밋 이력을 볼 수 있는 좋은 방법입니다.
-
git log --oneline --graph
는 저장소에 있는 서로 다른 브랜치와 해당 커밋을 표시하는 ASCII 그래프의 커밋 내역을 제시합니다.
-
git log --oneline --graph --decorate --graph
수정자를 사용하여 표시되는 것과 동일한 ASCII 그래프를 표시하지만 표시되는 다른 커밋에 대한 브랜치 이름도 포함됩니다.
파일 버전 비교하기
완벽한 커밋을 만들기 위해 준비하는 동안 현재 작업 디렉터리에 있는 항목과 스테이징 영역 간의 차이를 확인하면 커밋에 git add
로 적절한 파일을 추가할 수 있습니다.
기본적으로 git diff
명령을 통해 프로젝트의 마지막 커밋과 파일의 다양한 상태(예: 작업 디렉터리 또는 스테이징 영역) 간의 변경 사항을 검토할 수 있습니다.
git diff
를 사용하여 저장소에 있는 두 개의 커밋, 브랜치 또는 태그를 비교할 수도 있습니다. 예를 들어, 두 개의 커밋을 SHA-1 해시 참조 4e3dc9b
및 0cd75d4
와 비교하려면 git diff 4e3dc9b 0cd75d4
명령을 입력합니다.
마지막으로 이전 커밋에서 적용된 변경 사항을 보려면 git show <SHA-1>
명령을 사용하여 특정 커밋의 세부 정보를 표시할 수 있습니다. 여기에는 커밋 작성자, 커밋의 시간 및 날짜, 저장소 내의 다양한 자산에 대한 변경 사항 목록이 포함됩니다.
이전 변경 사항 실행 취소하기
경우에 따라 작은 실수(또는 큰 실수)를 저지르기도 합니다. 다행히도 Git에는 실수를 고칠 수 있는 명령이 있습니다. 하지만 실수를 수정하는 데 도움이 되는 몇 가지 명령은 커밋 ID를 손상시키는 방식으로 수정합니다. 이러한 커밋 ID는 변경할 수 없으므로 다른 공동 작업자에게 문제를 초래할 수 있습니다. 일반적으로 커밋이 원격으로 푸시된 경우에만 git revert
를 사용해야 합니다.
변경 실행 취소
git revert
는 '실행 취소'하는 커밋과 반대되는 변경 사항으로 새 커밋을 만듭니다.
예를 들어, 저장소의 커밋 기록 내에서 모든 제목 3을 제목 5로 변경하는 커밋이 있었다고 가정해 보겠습니다. git revert
를 사용하면 제목 5의 모든 항목을 하나씩 제목 3으로 변경하는 대신 한번에 제목 3으로 다시 변경할 수 있습니다.
git revert
는 다른 작업에 영향을 주지 않고 저장소 내역의 어느 시점에서든 커밋에 사용할 수 있습니다.
git revert
를 사용하면 프로젝트의 커밋 내역을 변경할 경우 발생하는 일반적인 문제를 방지하여 안전하게 특정 변경 사항을 취소할 수 있습니다.
커밋 수정하기
앞서서 git commit
에 대해 논의하고 커밋 메시지가 세부 프로젝트 내역을 작성하는 데 중요한 측면임을 확인했습니다.
경우에 따라 커밋을 만드는 과정에서 커밋 메시지 내에 오타가 발생할 수 있습니다. git commit --amend
를 사용하여 마지막 커밋을 수정할 수 있습니다. 이렇게 하면 프로젝트의 커밋 내역이 변경되므로 커밋을 이미 원격으로 푸시한 경우 git commit --amend
를 사용하지 않는 것이 좋습니다.
git commit --amend
를 사용하여 스테이징 영역에 파일을 포함할 가장 최근의 커밋을 다시 작성할 수도 있습니다.
내역의 초기 시점으로 되돌리기
Salesforce는 프로그래머들이 새로운 것을 실험하고 시도하는 것을 좋아한다는 것을 알고 있습니다. 그러나 경우에 따라 실험하는 동안 잘못된 길로 들어섰다거나 만들고 있는 커밋이 생각했던 것만큼 유용하지 않다는 것을 깨달을 수도 있습니다.
Git에는 프로젝트의 내역을 되돌리는 데 도움이 되는 git reset
명령이 있지만, 앞서 언급한 대로 변경하는 경우 다른 공동 작업자에게 문제가 생길 수 있습니다. 원격 분기에 커밋을 푸시하지 않은 경우에만 git reset
을 사용하는 것이 훨씬 좋습니다.. git reset
은 --soft
, --mixed
및 --hard
세 가지가 있습니다.
-
git reset --soft
는 식별된 커밋을 가져오고 스테이징 영역에 모든 변경 사항을 배치합니다. 커밋 그룹을 가져와서 하나의 큰 커밋으로 나누는 경우에 활용할 수 있습니다.
-
git reset --mixed
는git reset
의 기본 모드로, 식별된 커밋을 가져오고 모든 변경 사항을 작업 디렉터리에 배치합니다.--soft
와 마찬가지로 작은 커밋 그룹을 가져오고 변경 사항 중 일부를 결합하여 더 큰 커밋을 만들려는 경우 이 방법을 활용할 수 있습니다. 또한 파일을 추가로 변경한 다음 커밋 내역을 다시 만드는 데 사용할 수도 있습니다.
-
git reset --hard
는 식별된 커밋을 가져와서 파기시킵니다. 해당 명령으로 파기된 파일은 휴지통으로 들어가지 않으므로 신중하게 사용합니다. 파일은 실질적으로 존재하지 않게 되면 저장소에서 완전히 제거됩니다. 현재 작업 디렉터리 또는 스테이징 영역에 있는 파일에 대한 커밋되지 않은 변경 사항도 삭제됩니다. git reset--hard
로 작업을 잃을 수 있습니다.
다음과 같은 상황에서 reset을 사용할 수 있습니다.
git reset --soft HEAD ~ 2
는 현재 있는 브랜치를 두 개의 커밋으로 되돌립니다. head는 브랜치의 첫 부분에 대한 포인터입니다. 지난 두 번의 커밋에서 적용된 변경 사항이 스테이징 영역에 반영됩니다.
Git 병합 전략
병합에 관해서는 Git이 메인 브랜치(또는 병합할 브랜치)에 변경 사항을 적용하는 데 사용하는 재귀 병합 및 빠른 전달 병합과 같은 두 가지 기본 방법이 있습니다.
합병 전략에 대한 정답은 없지만 각 전략이 내역 플로에 어떤 영향을 미치는지 아는 것이 중요합니다. 언뜻 보기에 병합 전략이라기보다 git이 병합을 처리하는 방식에 더 가깝지만, 두 가지 병합에 대해 논의한 후에 이를 통해 설명합니다.
재귀 병합
재귀 병합은 기능 분기가 병합할 분기에 최신 버전의 코드가 없을 경우 발생합니다(항상 메인이 아닌 경우도 있음).
기능 브랜치를 만들 경우 현재 상태에서 원래 브랜치를 기본으로 합니다. 브랜치를 변경하면 다른 공동 작업자가 자신의 변경 사항을 원래 브랜치로 병합할 수 있습니다.
풀 요청을 생성하고 변경 사항을 병합하면 병합 커밋이 생성됩니다. 이렇게 하면 브랜치에 대한 변경 사항과 병합할 브랜치의 현재 상태를 가져오고 이러한 변경 사항을 결합한 새 커밋이 생성됩니다.
빨리감기 병합
빠른감기 병합은 기능 분기를 만든 이후 원래 분기에서 병합할 커밋을 제외한 새 커밋이 없을 때 발생합니다.
원래 브랜치에는 변경 사항이 없기 때문에 브랜치의 첫 부분은 변경 사항을 브랜치에 포함하기 위해 빠르게 전달됩니다. 빠른 전달 병합을 사용하면 Git은 새 병합 커밋을 만들지 않습니다.
재귀 병합을 빨리 감기 병합으로 전환하기
git rebase
명령은 강력하고 저장소에서 많은 멋진 일을 할 수 있습니다(모두 내역을 다시 작성할 수 있으므로 주의해서 사용합니다). git rebase
의 가장 일반적인 용도 중 하나는 Git이 기본적으로 재귀 병합으로 설정되었을 때 빠른 전달 병합을 만드는 것입니다.
재귀 병합은 병합할 브랜치가 브랜치를 만든 이후 새로운 변경 사항이 있을 때 발생합니다. 리베이스는 브랜치에서 수행한 커밋을 픽업하고 선택한 브랜치의 마지막 커밋 이후에 다시 적용합니다. git rebase
를 사용하여 커밋 내역의 표시 방식을 수정할 수도 있습니다. 리베이스와 함께 대화형 수정자 -i
를 사용하면 이전 커밋 메시지를 편집하고 커밋을 더 큰 커밋으로 묶어 커밋 내역을 다시 정렬할 수 있습니다.