본문 바로가기
코딩해보니/Git

[Git_43] 로컬 저장소의 커밋을 리셋(reset) 후 전송(push) 하기

by 위시랜 2023. 3. 30.

전송(push) 하기 오류 상황가 강제 전송
전송(push) 하기 오류 상황가 강제 전송

로컬 저장소의 커밋을 리셋(reset) 후 전송(push) 하기 - 강제 전송

제목 그대로 로컬 저장소에서 작업하면서 실행했던 커밋을 리셋한 이후에 서버(원격) 저장소로 전송(push)하면 어떻게 될까요?

이런 경우는 흔하진 않겠지만, 경험할 수 있는 경우이기에 언급하고자 합니다.

본 예를 통해 Push를 할 수 없는 상황과 서버 저장소를 이용할 경우 커밋에 대한 리셋(reset)과 리버트(revert)에 대해 한번쯤 생각해 보기 바랍니다.

 

실습을 통해 확인해 보겠습니다.

[상황 1]부터 [상황 4]까지 차근차근 따라 해 보기 바랍니다.

 

지금까지 상태는 서버(원격) 저장소(remoterepo)와 로컬 저장소(remoterepo)를 연결한 상태입니다.

똑같이 master라는 브랜치 하나만을 가지고 있는 상황입니다.


[상황 #1] 파일 생성 및 두 번째 커밋 실행

로컬에서 index.html 파일을 만들고 커밋하겠습니다.

그 과정을 다음 화면에서 확인할 수 있습니다.

로컬 저장소 master 브랜치에서 index.html 파일을 생성 후 커밋하기
로컬 저장소 master 브랜치에서 index.html 파일을 생성 후 커밋하기

커밋 후 소스트리에서 커밋 이력을 확인한 결과는 다음과 같습니다.

소스트리(Sourcetree)에서 확인한 커밋 이력
소스트리(Sourcetree)에서 확인한 커밋 이력

로컬의 master HAED와 서버의 master HEAD의 위치가 달라짐을 알 수 있습니다.


[상황 #2] 서버로 전송하기

이제 서버(원격) 저장소(remoterepo)와 동기화를 위해 $ git push를 실행해 서버 저장소로 로컬 저장소의 내용을 전송합니다.

이번에는 소스트리에서 push 해 보겠습니다.

 

다음 화면과 같이 Push가 필요한 상황이 되면 소스트리에서는 해당 버튼에 차이나는 커밋 개수만큼 숫자로 표시해 주고 있습니다.

소스트리(Sourcetree)에서 Push 실행하기
소스트리(Sourcetree)에서 Push 실행하기

[Push] 메뉴를 클릭합니다.

다음과 같이 Push를 위한 설정 창이 나타납니다.

소스트리(Sourcetree)에서 Push를 위한 설정 화면
소스트리(Sourcetree)에서 Push를 위한 설정 화면

현재는 등록된 서버(원격) 저장소가 origin 만 있고, 브랜치가 master 하나뿐이어서 특별히 변경할 사항은 없습니다.

아래 [Push] 버튼을 클릭합니다.

 

다음과 같이 Push가 진행 중임을 잠시 표시가 됩니다.

소스트리(Sourcetree)에서 Push 실행 중 화면
소스트리(Sourcetree)에서 Push 실행 중 화면

진행 간 문제가 발생한다면 이 진행 화면에 오류가 표시됩니다.

 

별다른 문제없이 완료되면 다음과 같이 커밋 이력이 변경됨을 알 수 있습니다.

소스트리(Sourcetree)에서 Push 완료 후 커밋 이력 확인
소스트리(Sourcetree)에서 Push 완료 후 커밋 이력 확인

master와 origin/master의 HEAD가 같아진 것을 볼 수 있으며,

동기화가 되면 상단의 Push 버튼의 숫자 표시도 없어짐을 알 수 있습니다.

 

GitHub(서버 저장소)도 확인해 봅니다.

다음과 같이 정상적으로 index.html 파일이 올라와 있음을 알 수 있습니다.

GitHub의 master 브랜치 상태 확인
GitHub의 master 브랜치 상태 확인


[상황 #3] 로컬 저장소의 커밋을 취소하기

이제 로컬 저장소의 커밋을 되돌려보겠습니다.

이번에도 소스트리를 사용하겠습니다.

 

다음 화면과 같이 되돌리고자 하는 지점의 커밋 이력에 마우스를 가져가 오른쪽 버튼을 클릭합니다.

소스트리(Sourcetree)에서 커밋 되돌리기
소스트리(Sourcetree)에서 커밋 되돌리기

클릭 후 나타나는 팝업 메뉴에서 [이 커밋까지 현재 브랜치를 초기화] 메뉴를 클릭합니다.

 

다음과 같이 “커밋 초기화...” 설정 창에서 모드를 Hard로 선택하고 [확인] 버튼을 클릭합니다.

커밋 초기화(reset) 옵션 선택
커밋 초기화(reset) 옵션 선택

 

그러면 다음과 같이 정말로 진행할 거냐는 확인창이 나오는데 [예]를 클릭하고 진행하겠습니다.

커밋 초기화를 실행할 것인지 확인 메시지 창
커밋 초기화를 실행할 것인지 확인 메시지 창

 

실제 업무에서는 이러한 커밋 취소는 매우 신중하게 진행하기 바랍니다.

 

지금은 실습이기에 과감하게 진행하도록 하겠습니다.

실행 후 다음과 같이 커밋 이력이 변경되었습니다.

커밋 초기화(reset) 실행 후 커밋 이력 확인
커밋 초기화(reset) 실행 후 커밋 이력 확인

이제 서버(원격) 저장소의 HEAD 로컬 저장소의 HEAD보다 앞서 있습니다.

그래서 소스트리(Sourcetree)는 서버가 업데이트되었다고 판단하고 Pull 버튼에 앞선 만큼의 숫자를 표시하고 있습니다.

Pull(내려받기)에 대해서는 다음에 학습하겠습니다만,

보통은 서버(원격) 저장소가 로컬 저장소보다 HEAD가 앞서 있는 상황에서는 서버(원격) 저장소의 내용을 로컬로 내려받아 최신화해야 합니다. 그래서 소스트리도 그러한 상황이라 판단해 Pull 버튼에 변화를 표시해 주고 있습니다.


[상황 #4] 로컬 저장소의 커밋을 취소 후 전송(push) 하기

그런데, 저는 서버(원격) 저장소의 커밋까지 되돌리고 싶습니다. 그래서 Pull이 아닌 Push를 실행합니다.

[상황 #2] 서버로 전송하기”와 같이 Push를 실행합니다.

 

그러면, 다음과 같은 오류 메시지를 만나게 됩니다.

로컬 저장소의 커밋을 되돌린 후 전송(push)한 결과
로컬 저장소의 커밋을 되돌린 후 전송(push)한 결과

이와 같이 로컬 저장소의 커밋 HEAD 서버 저장소의 커밋 HEAD보다 뒤에 있으면 Push를 할 수 없습니다.

만약, 그럼에도 불구하고 로컬 저장소와 같이 서버(원격) 저장소를 동기화해야 하는 상황이라면 강제로 push를 해줘야 합니다.

하지만 소스트리(Sourcetree)에서는 강제로 push를 할 수 없었습니다.

 

다음과 같은 명령으로 터미널에서 실행해 강제로 push 할 수 있습니다.

# 로컬 저장소의 커밋을 서버(원격) 저장소로 강제 전송(push)하기
$ git push <서버 저장소 이름> +<브랜치 이름>

일반적인 전송하기(push)와 비슷한데, 마지막 <브랜치 이름> 앞에 + 를 붙여줍니다.

 

다음과 같이 전송이 진행됨을 알 수 있습니다.

강제로 전송하기(push)
강제로 전송하기(push)

 

리셋(reset)과 리버트(revert)를 통해 커밋을 되돌리는 것을 학습할 때도 언급했습니다만, reset으로 커밋 이력을 되돌리는 방법은 서버(원격) 저장소를 사용해 협업을 하는 경우 이러한 문제가 발생하기 때문에 revert를 사용하는 것이 낫습니다.

 

감사합니다.

댓글