[Git] 9장 복귀

참조

되돌리기

  • 깃을 이용하여 버전을 관리하는 목적은 만일의 사태를 대비하기 위해서입니다.
  • 프로그래밍은 수많은 코드를 작성하고 테스트 하는 과정입니다.
  • 개발자는 코드를 단계별로 발전시키면서 실수를 최소화하고자 노력합니다.
  • 하지만 아무리 주의해서 프로그래밍해도 오류가 생깁니다.
  • 개발 도중에 심각할 정도로 오작동해서 더 이상 개선하기 어려울 때도 생기곤 합니다.
  • 이때는 문제를 억지로 해결하려고 노력하는 것보다 지금까지 한 작업을 포기하고 다시 시작하는 것이 좀 더 빠르게 해결할 수 있는 방법이 될 수도 있습니다.
  • 깃을 사용하면 언제든지 원하는 시점으로 전체 코드를 되돌릴 수 있습니다.
  • 마치 코드 복구 시스템과 같습니다.

다시 시작

  • 코드가 한두 줄 변경되었을 때는 언제든지 다시 시작할 수 있습니다.
  • 몇 줄만 암기하여 변경하면 됩니다. 하지만 몇 시간 혹은 며칠 동안 작업한 코드라면 이야기가 다릅니다.
  • 모든 수정 내역을 일일이 기억하여 과거 상태로 되돌아가는 것은 쉽지 않습니다.
  • 이때 깃을 사용하면 좀 더 손쉽게 되돌아 갈 수 있습니다.
  • 깃은 기록된 커밋을 기준으로 이전 상태로 되돌릴 수 있습니다.
  • 즉, 코드를 항상 안정적으로 유지하고 관리할 수 있게 해주는 도구입니다.
  • 깃에서 코드 작업을 되돌리는 방법은 크게 resetrevert 두 가지입니다.
  • 리셋(reset)리버트(revert) 동작을 동작을 좀 더 쉽게 이해할 수 있도록 실습으로 익혀보겠습니다.

리셋(reset)

  • 리셋(reset)은 커밋을 기준으로 이전 코드로 되돌리는 방법으로, 기록한 커밋을 취소합니다.
  • 커밋을 취소하는 만큼 리셋할 때는 항상 신중하게 작업해야 합니다.

복귀 시점

  • 복귀는 어떤 시점으로 돌아가는 것을 의미합니다. 따라서 이전 코드로 복귀하려면 복귀 시점을 알려 주어야 합니다.
  • 리셋은 이 시점을 커밋을 기준으로 정합니다.
  • 커밋은 log 명령어로 조회할 수 있습니다.
  • log 명령어를 실행하면 커밋의 해시 값과 메시지를 출력합니다. 따라서 복귀하고자 하는 특정 시점을 찾는 데 매우 유용합니다.
  • -oneline 옵션을 같이 사용하여 로그 기록을 확인합니다.

reset 명령어

  • reset 명령어를 사용하면 지정된 커밋 코드로 되돌아 갑니다.
  • 즉, 특정 커밋의 해시 값 상태로 모든 코드를 복구합니다.
$ git reset 옵션 커밋ID
  • reset 명령어는 옵션을 함께 사용해야 하며, 세 가지 옵션이 있습니다.

    • soft : 스테이지 영역을 포함한 상태로 복원합니다.
    • mixed : 기본 옵션 값은 mixed 입니다. reset 명령어를 사용할 때 옵션을 지정하지 않으면 기존 값인 mixed로 선택됩니다.
    • hard : 실제 파일이 삭제된 이전 상태로 복원합니다.
  • soft 옵션과 mixed 옵션 차이는 크게 스테이지 영역과 관련이 있습니다.

  • hard 옵션은 워킹 디렉터리와 관련이 있습니다.

soft 옵션

  • soft 옵션은 가장 낮은 단계의 리셋 동작입니다.
  • 먼저 soft 옵션의 동작은 reset --soft 명령어를 실행하여 이해해 봅시다.
  • 코드에서 HEAD~ 는 이전 커밋을 의미합니다.
$ git reset --soft HEAD~ ------- 이전 커밋으로 soft 옵션을 사용한 리셋
  • reset 전

  • reset 후

  • soft 옵션으로 reset 하니까 스테이지 영역을 포함한 상태로 복원되었습니다.

mixed 옵션

  • reset 명령어의 기본값은 mixed 옵션입니다.
  • mixed 옵션은 soft 옵션과 달리 리셋한 후 스테이지 상태까지 복원하지 않습니다.
  • 즉, unStaged 상태로 변경이 됩니다.
$ git reset -mixed 커밋ID
$ git reset 커밋ID ------- 생략 가능
  • reset 전

  • reset 후

hard 옵션

  • 이번에는 가장 강력한 옵션인 hard 옵션 을 알아봅니다.
  • soft 옵션과 mixed 옵션은 이전 커밋으로 되돌리는 과정에서 실제로 삭제되는 내용은 없습니다.
  • 모든 작업 내용이 워킹 디렉터리에 그대로 유지됩니다.
  • 정확히 말하면 이전 상태로 되돌아 가는 것이 아닙니다.
  • 복귀 커밋 이후의 작업들은 워킹 디렉터리 영역에 남겨 두어 다시 수정하거나 커밋할 수 있도록 상태만 변경하는 것입니다.
  • 이에 반해 hard 옵션 은 리셋되는 복귀 시점의 커밋 상태와 해당 커밋의 워킹 디렉터리까지 모두 되돌립니다.
  • 즉, reset --hard 명령어 를 사용한 커밋 이후의 모든 내용은 삭제됩니다.
  • 따라서 hard 옵션은 주의해서 사용해야 합니다.
$ git reset -hard HEAD~ ---------- 완전 삭제
  • reset 전

  • reset 후

커밋 합치기

  • 앞에서는 리베이스 병합의 -i 옵션을 사용하면 여러 커밋을 하나로 합치는 동작을 수행할 수 있었습니다.
  • 단일 커밋은 커밋 명령어의 -amend 옵션으로 커밋을 수정할 수 있었습니다.
  • 리셋의 동작 원리를 이해하고 있다면, 커밋도 수정할 수 있습니다.
  • 리셋의 soft 옵션은 HEAD 를 커밋으로 이동합니다.
  • 그리고 원본 내용은 그대로 워킹 디렉터리에 남겨 둡니다.
$ git log --oneline
$ git reset --sort HEAD~2
$ git log --oneline

스테이지 리셋

  • 스테이지 영역은 커밋을 하려고 임시로 결과물을 보관해 두는 공간입니다.
  • 커밋을 하려면 워킹 디렉터리에서 작업한 내용을 스테이지 영역에 등록해야 합니다.
  • 스테이지 영역에 등록을 할 때는 add 명령어를 사용합니다.
$ git add 파일이름
  • 또 add 명령어로 등록된 스테이지 영역의 파일을 다시 unstage 상태가 되도록 스테이징을 취소할 수도 있습니다.
  • 스테이지 영역에서 등록된 파일을 다시 unstage 상태로 만들때는 reset 명령어를 사용합니다.
$ git reset 파일이름
  • reset 명령어 다음에 커밋 ID 대신 파일 이름을 사용하면 됩니다.
  • 파일 이름을 지정하여 리셋하면 해당 파일은 unstage 상태가 됩니다.
  • 하지만 이 명령어는 몇 가지 옵션이 축약되어 있습니다.
  • 내부적으로 다음과 같이 여러 단계로 처리하여 파일은 unstage 상태로 변경합니다.
$ git reset --mixed HEAD 파일이름
  • 원래는 중간에 -mixed HEAD 가 생략된 형태입니다.
  • 최신 커밋에서 지정 파일을 리셋하고 mixed 옵션으로 스테이지 영역도 같이 제거합니다.
  • 다음과 같이 HEAD 대신 다른 커밋 ID를 사용할 수도 있습니다.
$ git reset 커밋 ID 파일이름

작업 취소

  • 코드를 수정하는 도중 오류가 생겨 현재 작업을 모두 취소하고 싶을 수 있습니다.
  • 보통은 다음과 같이 워킹 디렉터리에서 코드를 수정하고, 수정한 코드는 다시 스테이지 영역에 등록합니다.
  • 수정 작업을 완전히 취소하려면 워킹 디렉터리와 스테이지 상태를 모두 제거하여 마지막 커밋 상태로 되돌려 놓아야 합니다.
  • 그림을 보면 HEAD 포인터는 가장 마지막의 커밋 위치를 가리킵니다.
  • 그리고 수정 작업들은 모두 워킹 디렉터리 안에 남아있습니다.
  • 리셋할 때의 시점을 현재 HEAD를 기준으로 하면 해당 시점의 수정 작업을 모두 삭제할 수 있습니다.
$ git reset --hard HEAD

주의할 점

  • 리셋 기능을 이용하면 독립된 개인 프로젝트를 관리할 때 쉽게 이전 상태로 복귀할 수 있습니다.
  • 하지만 저장소를 외부에 공개했거나 공유하고 있다면 주의해서 리셋을 사용해야 합니다.
  • 작성된 커밋이 리셋으로 삭제되면 함께 작업하는 개발자에게 혼란을 줄 수 있습니다.
  • 일반적으로 협업하거나 소스 코드를 공유한 후에는 리셋 작업을 하지 않습니다.

리버트(revert)

  • 공개된 커밋은 보통 리셋 작업을 하지 않는다고 했습니다.
  • 그러면 공개한 저장소에서는 이전 상태로 되돌리려면 어떻게 해야 할까요?
  • 깃은 커밋의 버전을 되돌릴 수 있는 도 다른 방법인 리버트를 제공합니다.
  • 리버트와 리셋의 차이점은 커밋 정보 삭제 여부입니다.

취소 커밋

  • 리셋은 기존 커밋 정보를 삭제하는 반면, 리버트는 기존 커밋을 남겨 두고 취소에 대한 새로운 커밋을 생성합니다.
  • 취소 커밋을 생성할 때는 revert 명령어를 사용합니다.
  • 취소 커밋은 지정한 커밋을 삭제하지 않습니다.
  • 그 대신 삭제를 위한 새로운 커밋을 생성합니다.

리버트 지정

  • 직전의 커밋은 간단하게 HEAD 포인터를 이용하여 리버트 했습니다.
  • 한 번에 여러 커밋을 리버트해야 한다면 어떻게 해야 할까요?
  • 리버트는 한 번에 커밋 하나만 취소할 수 있습니다. 따라서 여러 커밋을 리버트하려면 최신 커밋부터 순차적으로 취소해야합니다.
$ git revert 커밋 ID
$ git revert 커밋 ID ... 커밋 ID

소스트리에서 리버트 실습

  • 소스트리에서 리버트 하는 방법은 간단합니다.
  • 해당 커밋을 선택한 후 마우스 오른쪽 버튼을 누릅니다.
  • 그리고 커밋 되돌리기 메뉴를 선택합니다.

revert(리버트) 히스토리

  • 리버트를 실행하면 새 커밋이 추가되기 때문에 커밋 이력이 복잡합니다.
  • 어떻게 보면 리셋으로 간단하게 이전 상태로 되돌리는 것이 간편해 보일 수도 있습니다.
  • 하지만 저장소를 공개했다면 리셋으로 커밋을 삭제하는 것은 협업 차원에서 위험합니다.
  • 이떄는 revert(리버트) 가 유용합니다.

정리

  • 리셋과 리버트는 버전 관리의 특성을 그대로 보여 주는 기능입니다.
  • 리셋과 리버트는 동작을 취소하고 과거로 돌아간다는 면에서는 유사합니다.
  • 코드 변경 이력을 저장하고 필요한 시점에 해당 코드 상태로 쉽게 이동할 수 있습니다.
  • 하지만 이렇게 두 명령어로 분리하여 사용하는 것은 저장소를 원격 저장소로 공유했는지 여부와 관련이 있습니다.
  • 자신의 저장소를 외부로 공유했다면 특정 커밋을 삭제하는 것은 위험합니다.
  • 다수의 사용자와 공유하는 저장소의 커밋 기록이 깨질 수 있기 때문입니다.
  • 외부로 공개한 저장소라면 리버트를 사용하는 것이 좋습니다.
  • 자신의 저장소가 컴퓨터에만 있다면 리셋을 사용해도 됩니다.
728x90

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

[Git] 11장 서브모듈  (0) 2022.06.25
[Git] 10장 배포 관리와 태그  (0) 2022.06.24
[Git] 8장 병합과 충돌  (0) 2022.06.20
[Git] 7장 임시 처리  (0) 2022.06.20
[Git] 6장 브랜치  (0) 2022.06.19

이 글을 공유하기

댓글

Designed by JB FACTORY