Tools/Git&GitHub 2020. 6. 6. 15:40

 

오늘 다루어볼 내용은 평소에 조금 헷갈렸던 Git reset과 revert이다. 깃에서 되돌리기 위한 방법은 크게 2가지가 있다. 바로 reset과 revert이다. 그렇다면 둘의 차이점은 무엇일까?

 

  • reset : 시계를 마치 과거로 돌리는 듯한 행위
  • revert : 특정 사건을 없었던 일로 만드는 행위
git reset <--option> "돌아가고 싶은 커밋 hash"

먼저 reset을 알아보자. reset은 특정 커밋으로 돌아가는 행위다. 그말은 특정 커밋 이후의 커밋이력 모두 없어지게 되는 것이다.(물론 옵션마다 상태가 다르긴하다) reset에는 옵션이 3가지가 있다. hard, soft, mixed 각 옵션에 대한 설명은 아래와 같다.

 

  • hard : 돌아가려는 커밋 이후의 모든 내용을 다 지워버린다.
  • soft : 돌아가려는 커밋 이력으로 되돌아 갔고, 이후의 내용은 stage 상태로 남아있는다.(git add 상태) 즉, 커밋을 다시 할 수 있는 상태가 되는 것이다.
  • mixed : 돌아가려는 커밋 이력으로 되돌아 갔고, 이후 내용은 남아있지만, unstage된 상태로 남아있다.(git add 이전 상태, tracked file list)

이제 각 옵션에 대해 실습해보자. 우선 쓰레기 코드가 들어간 커밋이 마지막에 찍혀있는 것을 보자.

 

 

각 reset 옵션 적용 후 상태를 확인하자.

 

<hard>

 

이전 커밋이력으로 돌아갔다. 그리고 이전에 추가했던 trash_code.txt도 감쪽 같이 사라졌다.

 

 

<soft>

 

쓰레기코드가 추가된 커밋이 사라졌다. 하지만 Uncommitted changes 상태가 되었다.(git add)

 

 

<mixed>

 

이전 커밋으로 잘 돌아갔고, 파일은 untracked된 상태이다.

 

 

만약 현재 커밋으로부터 몇개 이전으로 커밋을 되돌리고 싶다면 아래 문법으로도 reset이 가능하다.

 

#현재 커밋 기준 6번째 전 커밋으로 되돌린다.
git reset HEAD~6

 

여기까지 reset에 대해 다루어보았다. 다음은 revert에 대해 다루어보자.

 

git revert "지우고 싶은 커밋 hash"

revert는 특정 커밋을 아예 날려버리는 행위이다. 하지만 reset과는 조금 다른 이력이 남는다. 바로 실습내용을 확인해보자.

 

 

나는 가장 마지막 커밋을 revert 할것이다. 과연 이력은 어떻게 남을 걸까?

 

 

reset과는 다르게 내가 특정 커밋을 revert했다라는 이력이 남아있다.(물론 trash_code.txt가 추가됬다는 것도 남아있다.) 이것이 reset과의 차이점이며, 또 하나는 reset은 특정 커밋 이후의 이력을 모두 지우지만, revert는 중간에 껴있는 특정 커밋 이력을 날려버릴 수 있다.

 

그렇다면 revert와 reset은 어떠한 상황에서 사용해야 할까?

보통 reset은 원격 레포지토리로 푸시하기 이전에만 사용한다. 만약 이미 원격 레포지토리에 푸시한 이후에 reset을 하고, push를 하면 아래와 같은 메시지가 보일 것이다. 그 이유는 로컬의 커밋이 원격 커밋보다 뒤에 있기 때문에.. 물론 git push --force 옵션을 사용하여 push할 수 있지만, 이미 다른 사람들이 작업한 커밋이 푸시되어있다면? 윽 생각도 하기 싫다. 

 

 

reset은 혼자만 사용하는 브랜치일 때와 다른 사람들이 해당 브랜치를 pull한 적이 없을 때 정도만 사용가능할 듯하다. 그 이유는 로컬에서만 작업한 내용에서 실수로 다른 커밋을 찍었고 아직 push하기 이전에 reset을 한다면 커밋이력이 훨씬 깔금해지기 때문이다. 하지만 push 이후에는 왠만하면 revert 옵션을 사용하자.

 

push 이후에 revert를 사용하면 내가 어떠한 커밋에 대해 revert를 했는지가 커밋 로그에 남기때문에 훨씬 이력관리에 좋고, 다른 사람이 제가 이력을 지운 커밋이후에 작업을 했더라고, 그 커밋들을 건드리지 않기때문에 크게 문제 없다. 여기까지 git reset, revert에 대해 다루어보았다.

 

<참고>

 

개발바보들 1화 - git "Back to the Future"

  이 내용에 대한 자세한 기술적인 설명이 듣고 싶나요? 연속되는 다음글을 참조하세요    

www.devpools.kr

posted by 여성게
:
Tools/Git&GitHub 2019. 2. 12. 13:48

GitHub - Git 사용법 2 (branch, checkout, reset 등)



이전 포스팅에서는 간단한 Git 사용법에 대하여 다루어봤습니다. 이번에는 조금 더 나아가서 branch, tag, 잘못 반영된 작업을 되돌리는 작업 등 조금 더 진화된 예제를 다루어보려고합니다. 혹시 이전 포스팅을 보시지 못하셨다면 이전 포스팅을 참고하시고 오시면 좋을 듯 싶습니다. 혹시라도 대부분의 기본 명령어들이 숙지 되어있으시다면 굳이 보시지 않으셔도 됩니다.


▶︎▶︎▶︎GitHub - 간단한 Git사용법(로컬 레포지토리,원격 레포지토리)









로컬 저장소는 git이 관리하는 세그루의 나무로 구성되어 있습니다.

첫번째 나무인 작업 디렉토리(Working Directory)는 이전 포스팅에서 생성한 git 위한 로컬디렉토리입니다.

두번째 Index는 staging 역할을 합니다.("add 명령어로 파일을 관리하에 추가")

마지막 세번째 HEAD는 commit된 스냅샷, 즉 최종 확정본을 나타냅니다.




Branch 만들기 (일명 가지치기)

master라는 최종본의 형상이 있고, 무엇인가를 변경해야하는 작업이 생겨났습니다.

만약 master branch에 직접 수정을 하면? 큰일 날 수도 있겠죠.... 그렇기 때문에

새로운 Branch를 하나 따서 원하는 작업을 진행 할 수 있게 됩니다.

이제 새로운 작업을 새로운 Branch에서 진행하고 개발이 완료된다면

master 가지로 돌아와 병합을 하면 됩니다.










"git checkout -b yeoseong_branch" 라는 명령어로 새로운 Branch 하나를 생성함과 동시에
그 Branch로 스위칭 해줍니다.
"git status" 명령으로 현재 어떠한 Branch에 있는지 확인할 수 있습니다.
만약 다시 Master Branch로 돌아가고 싶다면 "git checkout master"로 돌아가시면 됩니다.
다른 Branch 역시 동일합니다.

만약 Branch를 삭제하고 싶다면 "git branch -d yeoseong_branch"로 삭제해줍니다.







이제 작업을 진행하기 위하여 수정할 소스를 다른 Branch에서 pull 해옵니다.
"git pull origin master"






새로운 파일도 생성했습니다.
이전 포스팅과 똑같은 과정입니다. "git add yeoseong_yoon.txt" 로 
git이 관리할 수 있는 파일로 만들어주고 commit 하여 HEAD에 최종본을
반영합니다.





이제는 변경하려고 pull 했던 파일을 수정합니다.

"add" 하지않은 파일은 "git status" 명령에 수정되었으니 

"add" 해라라는 상태를 보여줍니다.





만약 파일을 add 하지 않고 commit 한다면 이러한 예외문구를 만날 수 있을 겁니다.









파일을 모두 변경하고 commit까지 해놓은 상태입니다. 이제 commit된 모든 변경사항을

원격 레포지토리에 push합니다.




깃허브에 접속해보니 yeoseong_branch에 변경사항들이 모두 잘 적용이 되었습니다.




변경사항을 master Branch에 merge

이제는 변경사항이 모두 yeoseong_branch로 적용되었으니(개발완료) 

master branch에 병합하는 작업입니다.





현재 branch를 master로 스위치 해줍니다. 그리고 yeoseong_branch에 있는 변경내용과
master의 내용을 병합해줍니다.
"git merge yeoseong_branch" 명령어는 현재 Branch와 target Branch를
병합해라 라는 명령어입니다.







master에 추가된 파일과 변경된 파일이 잘 들어온것이 보입니다.
이제는 이것을 원격 레포지토리에 push 해줍니다!



와우... 깃허브에 master Branch를 보면 변경 사항이 잘 merge 된것을 볼 수 있습니다.!!!



로컬 레포지토리에서 잘못 반영되어 되돌리고싶을때(Checkout OR Reset,Fetch)



만약 commit하지 않았다면 "git checkout -- filename"으로 변경내용을 변경 전 상태(HEAD)로 되돌려줍니다.

다만, 이미 인덱스에 추가된 변경 내용과 새로 생성한 파일은 그대로 남습니다.

but add 하지않아서 index에 들어가지도 않았다면 완벽한 reset입니다.






만약 위와 같이 이미 인덱싱했고 commit까지 했다고 가정하면 



"git fetch origin" 명령어를 치고,

"git reset --hard orgin/master" 명령어로 리셋을 합니다. 그렇다면

결과를 보듯이 commit된 것이 없어졌습니다.



그렇다면 여기서

Pull & Fetch의 차이점이란 무엇인가?

Fetch : 중앙 저장소의 소스를 로컬 저장소로 가져온다!  그러나 현재 작업중인 소스들을 변경하는 Merge 작업을 하지는 않는다

즉, 변경된 소스는 버려지고 원격저장소의 소스로 업데이트가 된다.

Pull : 중앙 저장소의 소스를 로컬 저장소로 가져온다! 또한 현재 작업중인 소스들의 Merge 작업까지 통합하여 수행한다

변경된 소스 + 원격저장소 소스가 merge된다.


posted by 여성게
: