본문 바로가기
[Useful tech]/[GIT]

Git - 원하는 시점으로 프로젝트 되돌리기

by hi_kmin6 2020. 5. 7.

# 문제의 발견

 

제가 최근에 <Node.js - Express로 서버 개발 시 초기 설정> 을 작성하면서 ES6로 서버를 설정한다고는 했지만, 모듈 관리는 Node.js에서 기본으로 사용하고 있는 CommonJS 기반으로 놔두었기에 마음에 걸렸습니다.

초기 설정을 수정해 올리고, 본 프로젝트에 적용을 해보고자 진행 중인 프로젝트의 커밋을 확인했습니다.

 

https://github.com/dorakang612/chatPrac/commits/master

 

dorakang612/chatPrac

Node.js를 기반으로하는 채팅어플 학습 프로젝트입니다. Contribute to dorakang612/chatPrac development by creating an account on GitHub.

github.com

 

처음 세팅을 하고서 바로 커밋을 했었습니다. 간단하게 생각하여 이때의 프로젝트 파일을 클론 하면 되겠지 하는 생각으로, 해당 커밋의 repository로 이동하였습니다.

 

초기 설정의 commit

그리곤 clone을 하기 위해 주소를 복사했습니다.

 

해당 커밋의 repository

 

이후 빈 디렉토리로 와서 clone을 진행했으나,

가장 마지막 commit 한 시점의 repository로 clone이 진행되었습니다.

 

생각처럼 간단히 되지 않음을 깨닫고 구글을 통해 검색한 결과 다음과 같은 명령어의 존재를 알 수 있었습니다.

 

"git reset"

 


# git reset

 

아래는 git 공식 사이트의 문서 링크입니다.

 

git reset을 알기 위해서 깃의 파일 관리 체계를 설명해주고, 이를 바탕으로 git reset이 하는 역할을 설명하고 있습니다.

 

깃을 처음 다루시는 분이라면 꼭 한번 읽어 보시기를 추천드립니다. 저도 필요할 때마다 이렇게 찾아보면서 공부하고 있기에 git을 다루기 시작한 지 얼마 되지 않았는데, 이 글을 읽고서는 git에 대한 개념을 잡는데 큰 도움이 되었습니다.

 

https://git-scm.com/book/ko/v2/Git-%EB%8F%84%EA%B5%AC-Reset-%EB%AA%85%ED%99%95%ED%9E%88-%EC%95%8C%EA%B3%A0-%EA%B0%80%EA%B8%B0

 

Git - Reset 명확히 알고 가기

지금까지 reset 명령을 실행하는 기본 형태와 사용 방법을 살펴봤다. reset 명령을 실행할 때 경로를 지정하면 1단계를 건너뛰고 정해진 경로의 파일에만 나머지 reset 단계를 적용한다. 이는 당연한 이야기다. HEAD는 포인터인데 경로에 따라 파일별로 기준이 되는 커밋을 부분적으로 적용하는 건 불가능하다. 하지만, Index나 워킹 디렉토리는 일부분만 갱신할 수 있다. 따라서 2, 3단계는 가능하다. 이 명령을 실행한 것과 같은 결과를 만들려면 워

git-scm.com

 

제가 간단히 위의 글을 정리해보겠습니다.

 

Git 상태 3단계와 git reset

 

Git은 3가지의 상태로 파일을 관리합니다. Working Directory, Staging Area, Repository가 그 3단계입니다. 맨 왼쪽의 Past Working Directory는 제가, git reset을 설명하기 위해 임의로 넣은 것입니다.

 

git의 커밋들은 로컬 데이터베이스에 안전하게 저장된 상태를 나타내는 것으로 각각의 커밋들은 그 당시의 파일들의 변화에 대한 스냅샷입니다. 따라서 해당 커밋 이전의 커밋이 부모 커밋이 되어 모두 꼬리를 물고 있습니다. 그렇기 때문에 특정 시점의 프로젝트 상태를 효율적으로 관리할 수 있습니다.

 

git reset을 알기 위해선 HEAD, INDEX, Working Directory라는 3가지의 트리를 알아야한다고 공식 문서에서는 말하고 있습니다. 

 

HEAD

현재 브랜치를 가리키는 포인터로, 브랜치는 해당 브랜치에 담긴 커밋 중 가장 마지막 커밋을 가리키고 있습니다. 즉, HEAD는 가장 마지막 커밋을 가리키고 있습니다.

 

git cat-file -p HEAD // 트리 상태와 작성자, 승인자를 확인합니다.
git ls-tree -r HEAD // 현재 HEAD가 가리키는 tree의 파일리스트를 출력합니다.

 

위의 두 git 명령들은 저수준 명령어로 평소에 잘 사용되지 않지만, Git이 무슨일을 하고 있는지 볼 때 유용한 명령어들입니다. 저러한 저수준 명령어들을 plumbing이라고 합니다.

 

 

INDEX

 

워킹 디렉토리에서 마지막으로 checkout 한 브랜치의 파일 목록과 내용으로 채워지는 것으로, 파일을 변경한 후에 변경한 내용들로 INDEX는 채워지게 됩니다. 저희가 commit을 하기 전에 먼저 add를 해주는데, INDEX는 이 add 된 파일들을 가리킵니다. 업데이트 후 git commit 명령을 실행하게 되면, INDEX는 새로운 커밋으로 변환됩니다.

 

git ls-files -s

 

마찬가지로 저수준 명령어입니다. 현재 INDEX가 어떤 상태인지를 확인 할 수 있습니다.

 

 

Working Directory

HEAD와 INDEX는 내용을 효율적으로 .git 디렉터리에 저장합니다. 하지만 이는 사람이 알아보기 힘들고, 수정하기 불편하다는 단점이 존재합니다. 워킹 디렉터리는 실제 파일이 존재하는 곳입니다. 눈에 보이기 때문에 쉽게 편집할 수 있으며, 커밋을 하기 전에는 INDEX에 올려두고 얼마든지 변경할 수 있습니다.

 

 

 

git -reset --[option] [HEAD의 부모 커밋]

 

git reset 명령어에는 3가지 옵션이 있습니다. soft, mixed, hard가 그것들 입니다.

 

git -reset --soft [HEAD의 부모 커밋]  INDEX나 Working Directory는 그대로 두고 HEAD가 가리키는 브랜치가 부모 커밋을 가리키게합니다.
즉, git commit을 취소합니다.
git -reset --mixed [HEAD의 부모 커밋] INDEX를 HEAD가 가리키는 커밋으로 이동시킵니다.
즉, git commit과 git add를 취소합니다.
기본적으로 mixed는 옵션 부분을 생략해도됩니다. git reset의 기본 옵션이 mixed이기 때문입니다.
git -reset --hard [HEAD의 부모 커밋] git commit과 git add의 취소 뿐만 아니라, Working Directory의 내용도 되돌립니다.

 

 


# 문제 해결

 

위의 git reset을 활용하기 위해서 git clone을 진행하고, 제가 원하는 바는 Working Directory가 첫 커밋 상태로 돌아가는 것이었기 때문에 옵션을 hard로 진행했습니다.

 

부모 커밋의 코드

부모 커밋의 코드는 위의 사진에서 표시한 곳을 누르시면 복사를 하거나, 해당 커밋의 변경 내용을 보실 수 있습니다.

 

진행 결과 첫 커밋 상태의 프로젝트 파일을 볼 수 있었습니다.

'[Useful tech] > [GIT]' 카테고리의 다른 글

GitHub - 보안성 취약 해결 및 gitignore  (0) 2020.03.31
GitHub - Branch 생성 및 관리  (0) 2020.03.03
GitHub - GitHub Desktop 설치 및 알아보기  (0) 2020.02.27
GitHub - 계정 및 저장소 생성  (0) 2020.02.26
Git 이란?  (0) 2020.02.24