Devlog

잊어버리기 쉬운 깃 명령어 정리 본문

기타

잊어버리기 쉬운 깃 명령어 정리

ehdrb92 2023. 2. 27. 23:23

깃(Git)과 깃헙(Github)을 사용하면서 add, commit, push, pull 등의 자주 쓰이는 명령들은 사실 따로 정리를 하지 않아도 몸에 배어있다. 하지만 stash, rebase, reset 등 자주 사용하지는 않지만 가끔씩 쓰려고 하면 사용방법을 잊어버리는 명령어들이 많이 있다. 물론 사용할 때 구글링을 통해 알아보면 되지만 한 곳에 정리해 두면 좋겠다는 생각이 들어 정리해 보았다.

switch

기본적으로 브랜치를 이동하는 명령어로 사실 자주 사용되는 명령어이다. 하지만 대부분의 사람들이 checkout 명령어를 브랜치를 이동하기 위해 사용하기도 한다. 새로 등장한 switch는 많은 기능을 담고 있는 checkout에 비해 브랜치 이동이라는 좀 더 하나에 충실한 명령어이다. 그래서 공식적으로도 switch의 사용이 권장된다고 한다.

> git switch {브랜치명}

기본적인 사용은 위와 같고, 자주 사용되는 옵션은 다음과 같다.

  • -c, --create: 새로운 브랜치를 생성하고 이동한다.
  • -f, --force: 새로운 브랜치를 생성하여 이동하기 전 현재 브랜치에서 커밋되지 않은 변경사항을 버린다.
  • -m, --merge: 새로운 브랜치를 생성하여 이동하기 전 현재 브랜치에서 커밋되지 않은 변경사항을 새로운 브랜치에 병합한다.
  • --detach: "detached HEAD"상태로 이전 커밋의 내용을 확인할 수 있다.

restore

기본적으로 파일의 상태를 이전으로 되돌리는 명령어이다. 자주 사용될 법하지만 VScode에서 버튼을 클릭하여 되돌리는 게 편해 잘 사용하지 않았다. 예를 들어 작업 디렉터리에서 어떤 파일을 작업 중인데 이를 가장 최근 커밋되었던 상태로 다시 되돌리고 싶다면 사용하는 명령어이다. 해당 명령어 또한 checkout으로 부터 쪼개어진 명령어이다.

> git restore {파일명}

자주 사용되는 옵션은 다음과 같다.

  • --source: 특정 커밋 또는 브랜치에서 파일을 복원한다. "git restore --source={커밋} {파일명}"으로 사용하면 해당 커밋에서의 파일 상태로 작업 디렉토리에 가져온다.
  • --staged: 스테이지에 올라가 있는 파일을 다시 작업 디렉터리로 가져온다.

stash

현재 브랜치에서 커밋되지 않은 변경사항들을 별도의 목록에 잠시 숨겨둔다. 이 명령어는 우리가 특정 브랜치에서 작업을 하다가 잠시 다른 브랜치에 이동하여할 일이 생겼는데, 작업하던 변경사항들을 커밋하기에는 애매할 때 따로 저장해 두는 것이다. 그리고 기억해두어야 할 것은 stash 저장목록은 스택 자료구조와 같이 작동한다. 후입선출 방식으로 작동하기 때문에 이를 염두에 두고 사용해야 한다.

> git stash

위와 같이 간단한 명령어를 입력하면 변경사항들이 모두 따로 저장된다.

  • list: 저장 목록을 조회한다.
  • apply: 저장 목록에 있는 데이터 중 가장 최근에 저장된 사항을 현재 브랜치에 적용한다.
  • pop: 저장 목록에 있는 데이터 중 가장 최근에 저장된 사항을 목록에서 삭제하고 현재 브랜치에 적용한다.
  • drop: 저장 목록에 있는 데이터 중 특정 데이터를 삭제한다. "git stash drop stash@{인덱스}"로 특정 인덱스를 삭제한다.
  • clear: 저장 목록의 모든 데이터를 삭제한다.

reset

레포지토리의 변경 사항을 과거로 되돌리는 명령어이다. 다르게 말하면 몇몇의 커밋된 사항들을 지우고 과거로 돌아가는 것이다.

> git reset --hard {커밋}

# 또 다른 사용법
> git reset --hard HEAD~1

reset의 경우 두 가지 방법으로 사용이 가능하다. 첫 번째는 커밋해시로 되돌리는 것이다. 두 번째는 HEAD로부터 몇 번째 전 커밋으로 돌아갈 것인지를 정하는 것이다. 위의 예시에서는 HEAD에서 하나의 커밋 뒤로 이동하는 것이다.

  • --hard: HEAD를 지정된 커밋으로 이동하면서 해당 커밋 뒤에 존재하던 변경 사항을 완전히 버린다.
  • --soft: HEAD를 지정된 커밋으로 이동하면서 해당 커밋 뒤에 존재하던 변경 사항들을 자신의 작업 디렉터리로 가져온다.

revert

레포지토리의 변경 사항을 과거로 되돌리는 것은 reset과 같지만 조금 다르다. reset은 특정 과거로 돌아가면 돌아간 커밋 이후의 커밋은 다 지워버린다. 하지만 revert는 어떻게 보면 돌아간다는 표현보다는 가져온다는 표현도 가능하다. 특정 과거의 커밋을 현재 커밋으로 가져오는 것이다.

 

예를 들면 브랜치에 커밋 "A -> B -> C"가 있다. 만약 여기서 A로 reset을 한다면 A만 남게 된다. 하지만 revert 한다면 "A -> B -> C -> A*"가 되는 것이다. 과거 커밋들은 그대로 남아 있지만 현재 커밋의 과거 A 상태가 되는 것이다. 사용법은 reset과 동일하다.

> git revert --hard {커밋}

# 또 다른 사용법
> git revert --hard HEAD~1

rebase

브랜치가 뻗어 나기 시작한 base를 이동시켜 기록을 다시 쓰는 명령어이다. 보통 어떤 때 사용하냐 하면, 우리가 main 브랜치로부터 특정 기능 브랜치를 만들어 작업 중이라고 하자. 그런데 main 브랜치에 다른 사람의 커밋이 병합되면 main 브랜치에 변경사항이 생기게 되고 우리가 이를 현재 작업 중인 브랜치에 적용해서 작업을 이어나가기 위해 병합을 해야 한다. 한두 번이면 상관없지만 이것이 많아지면, 무의미한 병합 커밋이 내 작업 브랜치에 생성되어 어지럽게 된다.

 

이때 rebase를 사용하면 나의 작업 브랜치의 base를 가지를 뻗어 나왔던 커밋이 아닌 main 브랜치의 HEAD로 옮길 수 있다. 그리고 덤으로 rebase를 하면 병합 커밋이 사라진다. 이를 통해 작업 브랜치를 깔끔하게 관리하는 것이다.

git rebase {브랜치명}

브랜치명 부분에 자신이 뻗어 나온 브랜치의 이름을 넣어주면, 해당 브랜치의 HEAD로 base를 이동한다. 단 커밋 날짜, 시간 등의 메타데이터는 변경되지 않는다. 날짜 상으로는 더 이전의 커밋이라도 rebase에 의해 이후 단계의 커밋으로 갈 수 있다.

 

rebase는 다양한 기능을 포함한 interactive 옵션을 가지고 있는데 이는 따로 정리하도록 하겠다.