Git(2)

Lee Jooam·2022년 4월 14일
0

Git에 대한 두 번째 포스팅이다. 오늘로 Git에 대한 강의가 모두 끝났는데 사전에 알았던 지식들 외에도 몰랐던 부분들이 많았다.

그만큼 얕게 Git을 알고 사용했었나 보다.

checkout, switch, restore

이전 버전에서는 checkout 명령 밖에 없었지만 버전이 업그레이되면서 checkout은 switch와 restore 명령어로 나뉘었다.
checkout 명령어가 브랜치를 옮기는 것 외에도 특정 지점으로 복구할 수 있는 기능도 있었기 때문이라는데, 처음 안 사실이었다.

git checkout -- [filename]

다음과 같이 파일을 수정 전으로 되돌릴 수 있다.

git restore [filename]

restore도 같은 기능을 제공한다.

git switch -c [branch_name]

switch는 기존에 브랜치를 옮길 때 사용했던 checkout과 사용법이 동일하다.

다만 브랜치를 생성과 동시에 옮길 때 -b 옵션을 사용했지만 switch는 -c 옵션을 사용한다.

Merge Conflict

서로 다른 브랜치에서 작업 중 같은 파일에서 충돌이 발생한다면?

가장 좋은 해답은 애초에 그러한 상황을 만들지 않는 것이다. 하지만 부득이하게 발생할 경우 개발자는 3가지 방안 중 하나를 선택해야한다.

모두 지우거나, 둘 중 하나를 선택하거나, 둘을 병합하거나.

Git은 파일을 line by line으로 추적하기 때문에 한 파일이 다른 브랜치에서 수정되었다면 필히 충돌이 발생한다.

다음은 두 브랜치 test와 test2에서 각각 같은 파일을 수정했을 때 생긴 충돌 상황이다. status 명령을 통해 확인하면 다음과 같이 충돌을 감지해 어떤 파일에서 충돌이 발생했는지 나타내준다.

HEAD는 현재 브랜치(해당 브랜치의 가장 최신 커밋), 구분선 밑의 내용은충돌이 생긴 부분이다.

해당 충돌을 해결하고 add, commit 명령을 내리면 다음과 같이 커밋 메시지가 자동 생성된다. commit시 -m 옵션을 자제해야 하는 이유가 드러났다.

-m 옵션을 저 메시지를 덮어씌워버리기 때문이다.

UNDO

현재 작업 중인 working directory, 이미 staging된 변경사항, 혹은 commit 해버린 내용들을 되돌리려면 어떻게 해야할까?
이것도 마찬가지로 애초에 이런 상황이 발생하지 않도록 하는 게 최선이지만, 사람이 완벽할 수는 없다.

restore, checkout

git checkout -- [filename]
git restore [filename]

위에 설명한대로 working directory에서 수정은 간단하다. 위의 명령으로 수정 전 상황으로 돌아올 수 있다.

commit --amend, reset, revert

git commit --amend

commit 내용이 아닌 메시지만 수정하고 싶다면 다음과 같은 명령어를 통해 가능하다.

revert와 reset은 둘 다 commit을 되돌리는 명령어지만 revert의 경우 이전의 commit들이 그대로 내역에 남고 reset은 내역까지 초기화해버린다.

무엇때문에 commit을 되돌렸는지 분명하게 알 수 없기 때문에 reset은 지양하고 revert를 하는 게 바람직하다고 한다.

revert와 reset에 사용될 옵션 플래그는 다양하다. 해당 명령어를 사용하게 될 때 적절한 옵션을 설정해 사용할 수 있다.

참고

  • 파일 이름 변경
    -> 파일 이름을 변경할 때 깃은 rename이 아닌 하나의 파일이 삭제되고 다른 파일이 생성되었다고 인식한다.
git mv [name] [rename]

이 명령어를 사용한다면 rename으로 수정내역을 남길 수 있다.

  • HEAD
    위에서 HEAD는 현재 브랜치의 가장 최신 커밋이라고 했지만 commit의 해시값을 이용해 이전 commit으로 HEAD를 옮길 수 있다.

이때 HEAD는 detached HEAD라고 하는데 브랜치를 통하지 않고 직접 commit을 가리키는 상황이다.

생각해보면 HEAD가 꼭 브랜치를 가리킬 필요는 없는 것 같다. 브랜치는 결국 commit을 가리키는 포인터고 HEAD->Branch->Commit이니 당연한 결과였다.

profile
프론트엔드 개발자로 걸어가는 중입니다.

0개의 댓글