Git을 활용하여 소프트웨어를 개발하다 보면, 다양한 기능 브랜치에서 작업하던 도중 긴급한 버그가 생기거나, 원격 저장소에서 새로운 변경 사항을 받아와야 하는 상황이 자주 발생합니다. 이때 작업 중인 변경 사항이 완성되지 않았는데도 불구하고 다른 작업으로 전환해야 한다면, 단순히 바로 커밋하기도 꺼려지고, 그렇다고 현재 상태를 무시하고 새 브랜치로 이동하기도 부담스럽습니다. 이런 상황에서 “Git stash”는 작업 디렉토리의 변경 사항을 임시로 저장할 수 있는 강력한 도구입니다. 또한, 개발을 진행하다가 여러 갈래로 나뉜 커밋 기록을 깔끔하게 정리하고자 할 때는 “Git rebase”가 큰 도움이 됩니다.
────────────────────────────────────────────────────
1. Git Stash
────────────────────────────────────────────────────
“Git stash”는 커밋하지 않은 변경 사항을 임시로 저장하는 데 사용됩니다. 작업 디렉토리와 인덱스의 상태를 따로 보관해 두었다가, 다시 필요할 때 언제든지 쉽게 꺼내 쓸 수 있게 해주는 기능입니다. 예를 들어 기능 구현 도중 긴급 버그가 발견되었을 때, 버그 수정 브랜치로 넘어가야 하면서도 현재 작업을 그대로 놔두기는 어려운 상황이라면, stash를 활용하면 변경 사항들을 안전하게 임시 보관할 수 있습니다. 수정이 끝난 후에는 stash에 보관해 둔 내용을 다시 적용해 원래 하던 일을 마저 진행하면 됩니다.
실제로 stash를 사용할 때는 다음과 같은 절차가 자주 활용됩니다. 현재 변경 사항이 있는 상태에서 “git stash” 명령을 입력하면, 변경 사항이 “stash@{0}” 형태로 저장됩니다. stash가 여러 개 쌓이면 “stash@{1}”, “stash@{2}”와 같은 식으로 인덱스가 늘어납니다. 저장된 stash 목록은 “git stash list”로 확인할 수 있고, 어느 stash에 어떤 내용이 들어 있는지는 “git stash show”로 확인하거나, 더 자세히 보려면 “git stash show -p”를 사용할 수도 있습니다. 나중에 임시 저장해 둔 내용을 적용하려면 “git stash pop” 또는 “git stash apply”를 사용하면 됩니다. “pop”은 stash를 적용하면서 목록에서 제거해버리는 반면, “apply”는 내용을 적용하더라도 stash 목록에서 제거하지 않습니다.
예시로, 기능 구현 중 마무리하지 않은 작업이 있고, 원격 저장소에서 최신 코드를 받으려면 깨끗한 상태여야 하는 상황을 가정해 봅시다.
이때 “git stash”로 변경 사항을 보관한 뒤, “git pull”로 최신 코드를 받아옵니다. 그런 다음에 다시 “git stash pop”을 해서 이전 변경 사항을 되돌려받을 수 있습니다. 이렇게 stash를 쓰면 작업 흐름을 끊지 않고도 다른 작업이나 다른 브랜치로 넘어갔다 돌아올 수 있어서 매우 유용합니다.
Stack Overflow에서도 “git stash”의 용도를 설명하면서 부분적으로만 완료된 작업을 임시로 보관할 수 있기 때문에, 병합(merge)이나 푸시(push), 페치(fetch), 풀(pull) 같은 브랜치와 관련된 작업을 수월하게 할 수 있다는 점을 강조합니다. Atlassian Git Tutorial - git stash 문서에서는 stash가 여러 개 쌓였을 때 특정 stash를 선택하여 적용하거나 삭제하는 방법도 자세히 다루고 있으므로, 여러 작업을 병렬로 진행하는 상황이라면 참고해 두면 좋습니다.
■ 매우 쉬운 예시
예시1) “책을 읽다가 잠깐 나갔다 돌아오기”
내가 읽던 책에 책갈피(=stash)를 꽂아두고 책상 위에서 치 웁니다.
급한 볼일(=긴급 버그 수정)을 보고 돌아옵니다.
책갈피가 꽂힌 부분(=stash)에 다시 손을 대서, 읽던 부분부터 이어서 읽습니다(=stash pop).
예시2) “편집 중인 문서 잠깐 저장”
문서를 편집하다가 아직 완성되지 않았지만, 잠깐 다른 업무가 생겨서 문서를 닫고 자리에서 일어나야 함.
문서 편집기는 “임시 저장” 버튼이 있어서, 현재까지 작성한 문서를 임시 저장해 둠(=git stash).
다른 업무 끝낸 뒤 문서 편집기를 열어서, 임시 저장했던 부분을 다시 불러와서 이어서 작성(=git stash pop).
■ 실제 Git에서의 예시 시나리오
예를 들어, 기능 구현 도중에 아직 마무리 못 한 수정 사항이 다음과 같이 있다고 해봅시다.
(작업 디렉토리 상태)
$ git status
modified: index.html
modified: style.css
이때, 갑자기 “버그 수정 브랜치로 가서 아주 급한 문제를 해결해야 한다”는 요청이 들어왔다면, 변경 사항을 커밋하기엔 애매하고 그냥 날려버리긴 아깝습니다. 이럴 때:
$ git stash
이 명령을 실행하면 현재 변경 사항들이 stash@{0}라는 이름으로 임시 저장됩니다. 이제 작업 디렉토리는 깨끗해졌으니 버그 수정 브랜치로 마음 편히 전환이 가능합니다.
(버그 수정 작업 완료 후)
git checkout feature-branch
이제 다시 원래 기능 브랜치로 돌아와서 수정하던 코드 상태로 복원하려면:
$ git stash pop
위 명령으로 임시저장했던 stash@{0}을 꺼내와 변경 사항을 적용합니다. 이처럼 stash를 사용하면 “작업 도중 다른 일을 해야 할 때, 임시로 코드를 안전하게 보관”하는 데 큰 도움이 됩니다.
────────────────────────────────────────────────────
2) Git Rebase
────────────────────────────────────────────────────
“Git rebase”는 이미 커밋된 변경 사항을 새로운 기반 위에 재적용하여, 커밋 기록을 한 줄로 ‘선형화’하는 데 큰 도움을 줍니다. 이는 “git merge”와는 달리, 별도의 “merge commit”을 만들지 않고도 한 브랜치의 기록을 다른 브랜치 위로 깔끔하게 덮어쓰는 방식이기 때문에, 최종적으로 역사(히스토리)가 단순하고 보기 쉽게 정리됩니다.
예를 들어, 메인 브랜치(master나 main)에 새로운 커밋들이 생겼는데, 내가 작업 중인 기능 브랜치가 상당히 뒤쳐져 있는 상황이라고 해봅시다. “git merge master”를 통해 기능 브랜치를 업데이트할 수도 있지만, 이 경우 병합 커밋이 추가로 생깁니다. 반면 “git rebase master”를 사용하면, 기능 브랜치의 모든 커밋이 순서가 바뀌지 않은 채로 master 뒤에 이어져서 마치 처음부터 master의 최신 커밋들 위에서 작업한 것처럼 정렬됩니다. 이 과정에서 충돌이 발생하면 “git rebase --continue”로 각 충돌에 대한 수동 해결을 진행하면 되고, 만약 재정렬 도중에 무언가 심각하게 꼬였다면 “git rebase --abort”로 이전 상태로 돌아갈 수도 있습니다.
또한 “git rebase -i” 또는 “git rebase --interactive”를 사용하면, 특정 커밋을 편집하거나 순서를 바꾸거나 병합(squash)할 수도 있습니다. 이렇게 대화형 모드를 활용하면, 사내 협업이나 오픈소스 프로젝트에 기여할 때 불필요한 커밋을 정리하여 코드 검토와 디버깅을 보다 수월하게 만들 수 있습니다. 단, 공유 브랜치에서 rebase를 하는 것은 주의가 필요한데, 이미 다른 사람이 기반 삼고 작업하고 있는 커밋 기록을 재작성해버리면 충돌이나 혼동을 일으킬 수 있기 때문입니다. Git Book - Rebasing에서는 이런 점을 강조하며, 반드시 팀원들과 협의 후에 rebase를 사용하라고 권장합니다.
정리하자면, rebase를 통해 얻을 수 있는 대표적인 이점은 다음과 같습니다.
• 병렬로 나타나던 커밋 기록을 한 줄로 정리하여 코드 리뷰와 히스토리 파악이 쉬워집니다.
• 최신 메인 브랜치 위에서 작업함으로써, 코드가 충돌할 가능성을 미리 해소할 수 있습니다.
• 패치를 제출할 때, 나의 커밋이 깔끔하게 하나의 흐름으로 정리되어 있어서 유지보수자나 팀원의 리뷰 시간이 단축됩니다.
■ 매우 쉬운 예시
예시1) “책 챕터의 순서 재배치하기”
원고 작업을 하면서 챕터1, 챕터2, 챕터3… 이런 식으로 글을 쓰던 중, 중간에 보충 자료(=추가 커밋)들이 삽입되어 챕터 순서가 뒤죽박죽이 됨.
나중에 최종적으로는 독자들이 직관적으로 읽기 쉽도록, 원고 챕터 순서를 재배치(rebase)해서 다시 한 줄로 만들고 싶음.
rebase를 통해 “챕터1 → 챕터2 → 보충자료 → 챕터3”처럼 원하는 순서로 정돈 가능.
예시2) “놀이공원 줄 세우기”
놀이공원에 두 줄(브랜치 A, 브랜치 B)로 사람들이 쭉 서 있음.
나중에 한 줄로 합치고 싶을 때, B 줄에 서 있던 사람들을 A 줄 맨 뒤로 한 명씩 순서 그대로 옮겨 세움(=rebase).
결과적으로 한 줄로 쭉 이어지는 깔끔한 대기 줄이 완성됨.
■ 실제 Git에서의 예시 시나리오
예를 들어, 내가 작업 중인 기능 브랜치(feature-branch)가 메인 브랜치(main)와 달라지기 시작한 지 꽤 오래돼서, 쌓여온 변경 사항이 많다고 가정해 봅시다.
최신 메인 브랜치 코드를 기반으로 작업하고 싶으면 다음과 같이 할 수 있습니다:
git checkout feature - branch git rebase main
위 명령을 실행하면, feature-branch에서 쌓인 커밋들을 최신 main 뒤로 순서대로 ‘재적용’하게 됩니다. 충돌이 발생하면 해결 후 “git add”로 수정 사항을 반영하고, “git rebase --continue” 명령으로 rebase를 이어나갈 수 있습니다.
만약, 커밋 기록을 편집하고 싶다면, “git rebase -i main” 명령(대화형 모드)을 실행합니다. 그러면 편집기 창이 열리는데, 이 안에서 커밋을 합치거나(squash), 순서를 바꾸거나(reorder), 특정 커밋을 아예 삭제(drop)할 수도 있습니다. 최종 결과물은 훨씬 깔끔해진 커밋 이력이 됩니다.
────────────────────────────────────────────────────
3) Git Stash vs. Git Rebase
────────────────────────────────────────────────────
“Git stash”와 “Git rebase”는 각각 목적이 다릅니다. stash는 “현재 커밋되지 않은 변경 사항을 임시로 저장”하는 것에 초점이 맞춰져 있습니다. 작업을 하다가 다른 브랜치나 다른 긴급 작업으로 전환해야 할 때, 현재의 진행 상태를 안전하게 보관할 수 있게 해주지요. 반면에 rebase는 “이미 커밋된 변경 사항을 재정렬”하여 깔끔한 커밋 기록을 유지하는 것이 핵심입니다.
개발 실무 환경에서도 두 가지 기능은 함께 사용되는 경우가 많습니다. 예를 들어, 기능 브랜치에서 작업을 하던 중 수많은 변경 사항이 아직 커밋되지 않은 상태인데, 메인 브랜치에서 중요한 변경이 있어서 최신 상태를 받아와야 한다면 다음과 같은 단계를 거칠 수 있습니다.
“git stash”로 현재 변경 사항을 임시로 저장합니다(이 때 stash@{0} 같은 식으로 쌓임).
“git pull”이나 “git fetch && git merge” 혹은 “git rebase” 등을 이용하여 메인 브랜치의 최신 변경 사항을 가져옵니다.
다시 “git stash pop”으로 stash에 저장해 두었던 변경 사항을 꺼내 적용합니다.
이후 필요하다면 기능 브랜치를 메인 브랜치에 rebase하여(“git rebase main”) 커밋 기록을 깔끔하게 맞춥니다.
이렇게 하면 작업 중인 부분도 잃지 않고, 최신 상태에 맞춰 작업을 계속 진행할 수 있으며, 최종적으로는 커밋 기록도 선형적으로 유지할 수 있습니다.
────────────────────────────────────────────────────
4) 결론
────────────────────────────────────────────────────
결론적으로, Git stash와 Git rebase는 서로 보완적인 기능입니다.
stash는 “아직 완성되지 않은 작업을 잃지 않고 잠시 보관”할 수 있으며, rebase는 “이미 커밋된 작업을 깔끔한 기록으로 재정렬”해서 협업과 코드 리뷰를 쉽게 만듭니다. 개발 현장에서 긴급하게 버그를 고쳐야 하거나, 여러 팀원들이 동시에 작업하여 브랜치 기록이 복잡해지는 상황일수록, 이 두 가지 도구를 적절히 활용하면 훨씬 효율적이고 체계적인 워크플로우를 구축할 수 있습니다.
• Git stash 정리:
“git stash” 명령으로 변경 사항 임시 저장.
“git stash list”, “git stash show”로 stash 목록 및 내용을 확인.
“git stash pop” 또는 “git stash apply”로 임시 저장된 변경 사항 복원.
• Git rebase 정리:
“git rebase”로 한 브랜치의 커밋을 다른 브랜치 위에 재적용.
기록이 선형으로 정리되어 히스토리가 깔끔해짐.
“git rebase -i” 대화형 모드로 커밋 편집, 재정렬, 병합 가능.
충돌 시 “git rebase --continue” / “git rebase --skip” / “git rebase --abort”로 대응.
공유 브랜치에서 사용하는 경우에는 팀원들과 상의 필수.
이 두 도구에 대한 이해와 숙련도는 개발 효율을 높일 뿐 아니라 협업 과정에서도 큰 이점을 제공합니다. 버전 관리 시스템인 Git은 팀 프로젝트나 오픈소스 기여에서 사실상 표준처럼 사용되고 있으므로, stash와 rebase를 잘 활용하면 다양한 상황에서 속도감 있고 안정적인 개발을 진행할 수 있을 것입니다.
'Data Analysis > Computer Science' 카테고리의 다른 글
jar 파일 (0) | 2024.08.07 |
---|---|
JWT (JSON Web Token)란? (0) | 2024.08.06 |
동적으로 쿼리를 생성한다는 것 / 동적할당 정적할당 (0) | 2024.04.23 |
GIT 명령어 정리 (1) | 2023.05.09 |
FTP / SFTP(SSH파일전송프로토콜)/ FTPS / SMTP / TCP/IP & FileZilla (0) | 2023.05.09 |
댓글