Warning
해당 문서를 정확하기 위해서는 Git의 상태 변화와 스테이지 영역에 대한 이해가 필요하니, 관련된 참고자료를 먼저 확인해주시면 좋겠습니다.
1. 기본 개념
git reset
은 특정 커밋으로 돌아가거나, 스테이징된변경 사항을 초기화하는데 사용하는 명령어 입니다. 즉 현재 상태에서 선택한 이전 커밋 상태로 변경사항을 되돌리는 것입니다.
Git을 사용하다 보면 다음과 같은 이유 등으로 HEAD의 위치를 옮겨서 과거 커밋 상태로 되돌리거나 작업 내용을 수정하고 싶을 때가 있습니다.
- 최근 커밋 메시지를 수정하고 싶거나,
- 테스트 되지 않은 코드를 실수로 커밋한 경우.
- 테스트 및 실험적인 변경 작업을 취소하고 싶을 때.
- 브랜치 내에서 과거 버전으로 되돌릴 때. (checkout은 특정 커밋으로 임시로 이동하는 것이 기 때문에 조금 다릅니다.)
- 병합충돌 후 되돌리고 싶을때
이를 위해 git reset
명령어를 사용합니다.
git reset
을 제대로 사용하려면, 함께 사용할 수 있는 다양한 옵션들을 정확히 이해해야 합니다.
2.예제 상황
상황
현재 우리는 feature
브랜치에서 작업 중이며, 두 개의 커밋을 만든 상태입니다. 그 상태를 먼저 확인해보겠습니다.
$> git log --oneline
a1b2c3d (HEAD -> feature) Second commit
f6g7h8i First commit
- 현재 상태
First commit
: 첫 번째 커밋으로,index.html
파일을 추가했습니다.
Second commit
: 두 번째 커밋으로,index.html
파일에 내용을 추가했습니다.- index.html 파일 내용 (Second commit 후)은 다음과 같습니다.
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Welcome to my page!</h1>
<p>This is the second version of my page.</p> <!-- 추가된 내용 -->
</body>
</html>
3. git reset
의 3가지 모드
--soft
옵션:
- 이 모드는 HEAD(현재 작업 위치)만 이동시키고, 스테이징된 변경사항과 작업 디렉토리의 파일 내용은 그대로 유지합니다.
- 커밋은 취소하지만, 변경된 파일들은 그대로 남아 있어 다음 커밋에 사용할 수 있습니다.
- 만약 아래와 같이 명령을 실행하면,,,
$> git reset --soft HEAD~1
Second commit
이 취소되었고, 이 커밋에 포함되었던 변경 사항이 스테이징 영역에 남아 있습니다.git status
명령어를 사용하면 스테이징된 파일을 확인하면 다음과 같습니다.
Changes to be committed:
modified: index.html
- index.html 파일 내용은 다음과 같이 변경됩니다.
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Welcome to my page!</h1>
<p>This is the second version of my page.</p> <!-- 추가된 내용 -->
</body>
</html>
- 이 상태에서는 두 번째 커밋이 취소되었지만, 파일의 변경 내용은 유지되며 다시 커밋할 수 있습니다.
--mixed
옵션:
- HEAD와 스테이징 영역 모두를 초기화하지만, 작업 디렉토리의 파일 내용은 그대로 유지합니다.
- 즉, 커밋을 취소하고 스테이징된 파일을 작업 디렉토리로 되돌립니다.
$> git reset --mixed HEAD~1
Second commit
이 취소되었고, 변경사항은 스테이징 영역에서도 제거되었습니다.- 이제 변경된 파일이 작업 디렉토리로 돌아왔고, 아직 커밋되지 않은 상태입니다.
$> git status
Changes not staged for commit:
modified: index.html
- index.html 파일 내용은 다음과 같이 변경됩니다.
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Welcome to my page!</h1>
<p>This is the second version of my page.</p> <!-- 추가된 내용 -->
</body>
</html>
- 여전히 파일의 변경 내용은 남아 있지만, 이번에는 스테이징 상태가 아니므로,
git add
를 다시 해야 커밋할 수 있습니다.
--hard
옵션:
- HEAD, 스테이징 영역, 작업 디렉토리의 모든 변경사항을 취소하고, 선택한 커밋 상태로 완전히 되돌립니다.
- 즉, 마지막 커밋을 취소하고, 파일의 변경사항도 모두 제거하기 때문에, 되돌린 후에는 변경사항을 복구할 수 없습니다. (사용상 주의 필요)
$> git reset --hard HEAD~1
Second commit
이 취소되었을 뿐만 아니라, 파일의 변경 내용도 완전히 제거되었습니다.- 다시
First commit
상태로 되돌아가며, 모든 변경사항이 사라집니다.
$> git status
nothing to commit, working tree clean
- 적용 결과는 다음과 같습니다.
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Welcome to my page!</h1>
</body>
</html>
- 파일에서 추가했던 내용이 모두 삭제되었고, 이제 원래의
First commit
상태로 완전히 돌아간 것을 확인할 수 있습니다.