Git 복귀

    1. 되돌리기

    • reset
    • revert

    Git에서 코드 작업을 되돌리는 위 두 가지가 존재한다.

    1.1 실습 코드 작성

    # menu.html 생성
    
    # <ul>
    # </ul>
    # comment : first
    
    # <ul>
    # 	<li><menu1/li>
    # </ul>
    # comment : menu1
    
    # <ul>
    # 	<li><menu1/li>
    # 	<li><menu2/li>
    # </ul>
    # comment : menu2
    
    # <ul>
    # 	<li><menu1/li>
    # 	<li><menu2/li>
    # 	<li><menu3/li>
    # </ul>
    # comment : menu3
    
    # <ul>
    # 	<li><menu1/li>
    # 	<li><menu2/li>
    # 	<li><menu3/li>
    # 	<li><menu4/li>
    # </ul>
    # comment : menu4
    
    # <ul>
    # 	<li><menu1/li>
    # 	<li><menu2/li>
    # 	<li><menu3/li>
    # 	<li><menu4/li>
    # 	<li><menu5/li>
    # </ul>
    # comment : menu5
    • 위 코드를 작성해서 총 6개의 커밋을 생성한다. 

     

     

    2. 리셋

    • 리셋은 커밋을 기준으로 이전 코드로 되돌리는 방법이다.
    • 기록한 커밋이 취소된다.

    2.1 복귀 시점

    • 리셋은 복귀 시점(커밋)을 기준으로 돌아간다. 
    • 커밋은 log 명령어로 조회할 수 있고, log 명령어로 해시 값을 볼 수 있다.
    $ git log --oneline
    • 위 명령어를 이용해서 현재 로그를 확인할 수 있다. 

    • 현재 commit 해시 값을 확인할 수 있다. 이 해시값을 알고 있으면, 해당 commit 시점으로 돌아갈 수 있다.

    2.2 Reset 명령어

    # soft : 스테이지 영역을 포함한 상태로 복원함.  (스테이지 영역 관련)
    # mixed : 기본 옵션 (스테이지 영역 관련)
    # hard : 실제 파일이 삭제된 이전 상태로 복원함. (워킹 디렉토리와 관련)
    
    $ git reset [옵션] [commit ID]

    위 명령어를 이용하면 지정된 커밋 시점으로 돌아간다. 옵션으로 soft / mixde / hard를 선택할 수 있다. 

     

    2.3 soft 옵션

    • soft 옵션은 가장 낮은 단계의 리셋 동작이다.
    • 실제로 동작하는 것을 살펴보자. 
    • soft 옵션은 커밋을 실행하기 바로 직전의 상태로 돌린다.
      • 따라서 커밋 직전의 스테이지에 모든 데이터가 올라가있는 상태로 돌려주는 것이다. 
      • 즉, add 명령어 없이도 바로 Commit이 가능하다. 
      • 변경한 지점까지의 모든 변경점은 Stage에 남아있다. (HEAD~2인 경우, 1,2의 변경점이 모두 스테이지에 남아있음)
    • reset 후 재커밋하면 커밋에 대한 해시 값은 바뀐다.
    $ git reset --soft HEAD~
    • 위 명령어로 HEAD 이전의 시점으로 Commit을 돌려본다. 

    • master 브랜치는 menu5의 변경사항을 가지고 있었는데, menu4를 HEAD가 가리키고 있게 된다. 
    • 또한 menu5는 없어지고, 커밋되지 않은 변경사항이 존재하는 것을 볼 수 있다. 

    • 이 때, menu.html을 살펴보면 menu5라는 값이 남아있는 것을 볼 수 있다. menu5의 커밋 내용은 사라졌는데, 그에 대한 내용이 파일에 남아있는 것이다. 
    $ git diff HEAD
    $ git status
    • 위 명령어를 이용해서 현재 HEAD 포인터와의 차이점, 그리고 Git 상태를 살펴볼 수 있다.

    • HEAD 파일과 <li>menu5</li>가 차이 있는 것을 볼 수 있다. 

    • git status에서도 menu.html이 modified 되어서 스테이지 영역에 등록되어있는 것을 볼 수 있다.
    • 즉, 이 상태에서 바로 Commit이 가능한 상태다. 

     

    2.4 Mixed 옵션

    • 변경점은 stage에 등록이 되어있지 않은 상태다.
    • 변경점은 워킹 디렉토리에 기록되어있는 상태다. 
    $ git reset --mixed HEAD~
    • 다음 명령어를 이용해서 커밋을 reset 한다. 
    $ git status
    $ cat menu.html
    $ git diff HEAD
    • 위 명령어를 이용해서 현재 상태를 살펴본다. 

    • 스테이지에는 파일이 올라가있지 않음.
    • 변경점은 워킹 디렉토리에 모두 기록되어있음
    • 따라서 commit이 필요한 경우 add를 한 후, 실행해야한다. 

    2.5 Hard 옵션

    • 리셋되는 복귀 시점의 커밋 상태 / 해당 커밋의 워킹 디렉터리까지 모두 되돌린다.
    • reset --hard 명령어를 사용한 커밋 이후의 모든 내용은 삭제된다. 
    $ git reset --hard HEAD~
    • 위 명령어를 이용하면 hard 상태로 reset 할 수 있게 된다. 
    $ git status
    $ git diff HEAD
    $ cat menu.html
    • 위 명령어를 이용해서 변경점을 확인해본다. 

    • 스테이지와 워킹 디렉토리는 모두 깨끗해졌고, HEAD와의 변경점도 존재하지 않는다. 그리고 실제 파일에 변경점(menu5)도 없어진다. 

     

    2.6. reset --soft 이용해서 커밋 합치기 <그림 추가>

    $ git reset --soft HEAD~2
    • 이 명령어를 이용하면,  HEAD 기준으로 2번째 이전 커밋으로 돌아간다. 
    • 이 때 스테이지 정보는 남아있다.
    $ git diff HEAD
    $ git status
    $ cat menu.html
    • 위 명령어를 사용하면 어떤 상태인지 알 수 있다.

    • 다음과 같이 2개 이전의 상태로 돌아가있고, 그 변경점이 모두 스테이지에 올라가있는 상태다.
    $ git commit -m "menu3/4"
    • 위 명령어를 이용해서 커밋을 한다. 

    • 커밋하면 다음과 같이 menu3 / menu4에 대한 커밋이 사라지고, 해당 커밋이 menu3/4로 병합된 것을 볼 수 있다.

     

    2.7 스테이지 리셋

    $ git reset 파일 이름
    $ git reset --mixed HEAD 파일이름
    • git reset 파일 이름을 사용하면, 해당 파일은 unstage 상태가 된다. 
    • 이 명령어는 몇 가지 옵션이 축약되어 있는데, 두번째 줄에 있는 명령어가 축약되어있는 것이다. 


    2.8 작업 취소

    $ git reset --hard HEAD
    • 코드를 수정하는 도중 오류가 생겨 현재 작업을 모두 취소하고 싶은 경우 사용한다.
    • 스테이지 영역 / 워킹 디렉토리 영역을 모두 제거하여야 한다. 
    • 위 명령어를 이용하면 된다. 왜냐하면 HEAD 포인터는 가장 마지막 커밋 시점을 가리키고 있기 때문이다. 따라서 가장 마지막 커밋의 상태로 돌아가는 것이기 때문에 수정 작업이 모두 사라진다.

    2.9 병합 취소

    리셋은 병합된 브랜치도 취소할 수 있다. 

    $ git checkout -b menu <menu2 브랜치 해쉬 ID>
    
    $ vim menu.html
    # <ul>
    # 	<li> menu1
    # 		<ul>
    #			<li> menu1-1</li>
    #        </ul>
    #    </li>
    #    <li>menu2</li>
    # </ul>
    # comment : "menu1-1"

    위 코드를 실행해서 새로 브랜치를 만들고 commit을 한다. 

    commit을 하면 다음과 같은 상태가 된다. 이 때 git merge menu를 해서 master에 menu 브랜치를 병합할 수 있다. 

    다음과 같이 merge가 될 수 있다. 그런데 이 때,  reset을 이용해서 merge 한 것을 취소할 수 있다. 

    # 이전 커밋 리셋 
    $ git reset --merge HEAD~

    위 명령어는 이전 커밋을 리셋하는 명령어다. 이 명령어를 이용해서 커밋을 바로 리셋할 수 있다. 

    다음과 같이 이전 커밋으로 바뀐 것을 볼 수 있다. 

     

     

    3. 리버트

    • 리셋을 하게 되면 커밋 값이 바뀌기 때문에 협업을 할 때는 리셋대신 리버트를 사용한다.
    • 리셋과 리버트의 차이점은 커밋 정보 삭제 여부다. 

    3.1 취소 커밋 <그림 추가>

    리버트는 기존 커밋을 남겨 두고 취소 커밋을 새롭게 생성한다.

    # 마스터 브랜치
    # 위 명령어 추가 
    
    <li> menu5 </li>
    # comment : menu5
    
    <li> menu6 </li>
    # comment : menu6
    
    <li> menu7 </li>
    # comment : menu7
    • 위 명령어를 이용해서 master 브랜치에 3개의 커밋을 추가한다. 

    • 소스트리에서는 다음과 같이 추가된 것을 확인할 수 있다. 
    # menu7 commit 삭제 → 취소하고자 하는 커밋을 rever 하면 됨.
    $ git revert HEAD (현재 커밋을 리버트)
    • 위 명령어를 통해 마지막 커밋을 리버트해본다.

    • 다음과 같이 menu7 커밋이 삭제되는 것이 아니라, menu7이 취소되었다는 취소 커밋이 생긴 것을 볼 수 있다. (Revert menu7)

     

    3.2 리버트 지정

    $ git revert 커밋ID
    $ git revert 커밋ID .. 커밋 ID
    • 리버트는 한 번에 커밋 하나만 취소할 수 있다. 따라서 여러 커밋을 리버트하려면 최신 커밋부터 순차적으로 취소해야한다. 
    • 깃의 범위 지정 연산자를 사용해서 여러 커밋을 리버트 할 수 있다. 

    3.3 병합 취소

    • 리버트를 이용해서 병합된 커밋을 취소할 수 있다.
    • 리셋은 방금 전 실행한 병합만 취소할 수 있다.
    • 리버트는 과거의 병합도 선택해서 취소할 수 있다.
    • 리베이스 된 병합을 리버트하기는 어렵다.
    • git revert --mainline
      • 병합은 두 브랜치가 결합된 형태다. 따라서 리버트로 병합이 취소 상태가 되면 둘 중 한 브랜치로 체크아웃 해야한다.
      • --mainline 옵션은 병합을 취소한 후 체크아웃되는 브랜치를 표시한다.
    # 메뉴를 병합한다.
    $ git merge menu
    
    # <li>menu7</li> 추가
    # comment : menu7
    • 위 명령어 대로 실행 한다.

    • 수행 결과 하나의 브랜치로 합쳐지고, master는 또 다른 Commit이 반영된 것을 볼 수 있다. 

    log를 확인해서 merge된 커밋 해시값을 확인하고, 해당 위치를 revert 한다. 

    $ git revert --mainline 1 9f85cb6

    위 명령어를 이용하면 된다. 

    실행 결과를 살펴보면, merge bracn "menu"를 리버트 한 것이 나온다. 

    그리고 menu7번은 살아있는 것이 보인다. 

     

     

     

     

     

    '기타 Tool > Git' 카테고리의 다른 글

    Git : Pull Request (PR)  (0) 2022.08.29
    Git 병합 / 충돌  (0) 2022.08.29
    Git Branch  (1) 2022.08.27
    Git Remote Repository  (0) 2022.08.27
    Git의 Commit  (0) 2022.08.26

    댓글

    Designed by JB FACTORY