들어가며
협업을 하기 위해서는 Git을 잘 알아야만 합니다. 하지만 Git을 모두 공부하기란 쉬운 일은 아닙니다. 정말 깊게 공부해본다면 끝없이 공부해야하는 경우도 있습니다. 일단 먼저 협업할 때 Git을 어떻게 사용해야할지 정리해본다면, 처음 협업을 진행하는 개발자분들에게 도움이 될 수 있지 않을까 생각했습니다. 이 글은 협업을 위해 가볍게 Git에 대해 공부하고 싶은 분들을 위한 글입니다.
주요 Git 명령어들
새로운 기능을 위해 branch를 생성하는 방법
이 글에서 저희는 브랜치 생성법에 대해 배웠습니다. 하지만 아주 짧게 배웠기 때문에, 브랜치를 생성하고, 다루는 방법에 대해 조금 더 깊게 배워보겠습니다.
우리는 브랜치를 활용해서 개발을 진행하고 개발이 완료가 되면 나중에 master로 돌아와 merge 할 수 있습니다. 그렇다면, 새로운 branch를 생성하는 방법부터 다시 배워보겠습니다.
git branch 브랜치 이름 (해당 브랜치가 존재하지 않는다면 브랜치를 새로 만듭니다.)
ex) git branch feature/#1
git checkout -b 브랜치 이름 (해당 브랜치가 존재하지 않는다면 브랜치를 새로 만들면서 바로 그 브랜치로 이동합니다.)
ex) git checkout -b feature/#1
git checkout 브랜치 이름 (존재하는 브랜치가 있다면 그 브랜치로 이동합니다.)
ex) git checkout feature/#1
이와 같이, 브랜치를 생성하고, 브랜치로 이동할 수 있습니다. 하지만 이는 아직 로컬 환경에서만 브랜치를 추가한 것이기 때문에 원격 저장소에도 브랜치를 저장해줘야 합니다. 어떻게 하면 원격 저장소에 브랜치를 등록할 수 있을까요?
원격 저장소에 브랜치 생성하는 방법
로컬에만 존재하는 브랜치를 원격에 저장하는 명령어는 다음과 같습니다.
$ git push origin(원격 저장소 이름) feature/#1 ->
명령어를 해석해보자면, origin이라는 원격 저장소에 feature/#1이라는 브랜치를 추가하겠다! 정도로 해석할 수 있습니다. 이렇게 원격 저장소에도 브랜치를 등록시켰다면, 이런 경우를 상상해봅시다. 협업을 하는 상황에서 누군가 브랜치에 커밋을 push 해서 원격 저장소가 변경이 됐는데, 저는 그것을 모르고, 제 작업만 하고 커밋하고 push를 했는데, 충돌로 인해 push가 되지 않는 상황이라면, 어떻게 이 문제를 해결해야 할까요? 이를 어떻게 활용하는지 알아보겠습니다.
로컬 저장소에서 원격 저장소의 변화된 브랜치 정보를 가져오는 방법
정보를 최신화 하는 방법은 git pull 명령어를 사용하면 됩니다. 이때 놓치지 말아야 할 것이 있습니다. 만약 master(혹은 main) 브랜치에서 git pull 명령어를 사용하면 원격 저장소와 브랜치 이름을 작성하지 않아도 성공적으로 명령어대로 실행이 될까요?
$ git pull <master 브랜치에 있는 상황>
-> 성공
git pull 명령어만 작성해도 원격 저장소의 master 브랜치에 있는 변화된 정보를 로컬 저장소에 저장시켜줍니다. 원래는 git pull origin master까지 적어야 하지만, origin master는 디폴트 값이기 때문에 넣지 않아도 괜찮습니다. 하지만 feature/#1 브랜치에서 git pull 명령어를 사용하면 조금 문제가 생기게 됩니다.
$ git pull <feature/#1 브랜치에 있는 상황>
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details
git pull <remote> <branch>
If you wish to set tracking information for this branch you can do so with:
git branch --set-upstream-to=origin/<branch> feature/#1
터미널에서 나오는 정보를 해석해보면, 현재 브랜치를 위해 추적하는 정보가 없으니, 구체적으로 머지하기 원하는 정보를 지정하라고 나왔습니다. 즉 원격 저장소 이름과 브랜치 이름까지 명시해줘야 최신 정보를 가져올 수 있습니다. 하지만 origin master처럼 디폴트 값을 지정해줄 수 있습니다. 즉 로컬 저장소의 브랜치와 원격 저장소의 브랜치를 연동시켜줄 수 있다는 것입니다. 이러한 명령어는 --set-upstream-to로 지정해줄 수 있습니다.
$ git branch --set-upstream-to origin/feature/#1
이 명령어를 작성한다면, 로컬과 원격 저장소의 브랜치가 연동되어 git pull만 작성해도 자동으로 정보를 가져올 수 있게 됩니다. 그렇다면, 브랜치를 모두 사용해서 머지를 했다면, 필요 없는 브랜치는 어떻게 삭제할 수 있을까요? 이에 대해 알아보겠습니다.
원격 저장소, 로컬 저장소 브랜치 삭제하는 방법
작업을 끝내고 pull request 한 후, merge까지 완료했다면, 브랜치는 필요 없어지게 되는데, 이때 브랜치를 어떻게 삭제할 수 있는지 알아보겠습니다. 만약 develop 브랜치에서 feature/#1 브랜치를 생성했다고 가정해보겠습니다. 그렇다면, merge 작업이 끝난 local의 feature/#1 branch를 삭제하기 위해서는, 다른 branch로 checkout 한 후, feature/#1 브랜치를 삭제해줘야 합니다. 여기서 develop 브랜치로 이동해서 feature/#1 브랜치를 삭제해보겠습니다.
$ git checkout develop
$ git branch -d feature/#1
이 명령어는 develop 브랜치로 이동한 후, feature/#1 브랜치를 삭제하겠다는 뜻입니다. 그러나 작업된 사항이나 commit 한 이력이 남아있는 경우, 해당 command로 branch가 삭제되지 않는 경우가 있습니다. 이러한 경우에는 branch를 강제로 삭제할 수 있습니다.
$ git branch -D feature/#1
-D(대문자) option을 통해 local 브랜치를 강제로 삭제할 수 있습니다. 지금까지는 로컬 저장소의 브랜치만을 삭제했는데, 아직 원격 저장소의 브랜치를 삭제하지 않았습니다. 그렇다면, 원격 저장소의 브랜치를 삭제하기 위해서는 어떻게 해야 할까요? 다음 커맨드를 수행합니다.
$ git push origin :feature/#1
:을 붙인다면, 원격 저장소의 브랜치를 삭제할 수 있습니다.
개발 내역을 브랜치에 Push, Merge 하는 방법
만약 브랜치를 생성하고, 그 내용을 원격 저장소에 넣는 방법은 이 글을 통해 배울 수 있었습니다. 그렇다면, 작업한 내용을 develop 브랜치에 병합하려면 어떻게 해야 하는지 알아보겠습니다.
$ git checkout develop
$ git merge feature/#1
일단 먼저, 정보를 합치고 싶은 브랜치로 이동하고, 합쳐야 할 브랜치를 merge 해야 합니다. 이 순서에 대해 헷갈리지 않아야 합니다. 하지만 일단 merge 하기 전에 원격 저장소의 변경 내용이 있을 수 있으니, git pull을 통해 최신 정보로 갱신한 다음 merge 하는 것을 추천드립니다. 하지만 가끔 merge 하는 과정에서 conflict가 나는 상황이 발생합니다.
CONFLICT (content): Merge conflict in test.js Automatic merge failed; fix conflicts and then commit the result.
let test = "test";
<<<<<<< HEAD // conflict 가 발생한 범위의 시작
let testMerge = "test for merge";
=======
let testMerge = "test for push";
>>>>>>> 551231568980535642123214215675835737e // 모든 commit은 유일한 커밋 ID를 가진다
이때 conflict 부분을 직접 수정해줘야 합니다.
let test = "test";
let testMerge = "test for merge";
이렇게 <<< 또는 >>> , 그리고 === 까지 제거하고 다시 commit을 하면 conflict를 해결할 수 있습니다.
최종 버전 릴리즈하기
애플리케이션의 빌드 및 테스트가 완료되어 새 버전을 릴리즈한다면 읽기 전용 상태의 tag 버전을 생성하는 것이 좋습니다.
$ git tag 1.0.0
$ git log
만약 git log를 작성해보면, 커밋에 tag가 생성된 것을 볼 수 있습니다. 그리고 생성한 tag 버전은 아래와 같이 remote 서버에 최종적으로 반영합니다.
$ git push origin 1.0.0
remote branch 업데이트
만약 remote 서버를 변경해야 할 때 어떻게 하면 서버를 바꿀 수 있을까요? 아래의 명령을 통해 알아보겠습니다.
$ git remote -v
origin https://github.com/sopt12-hackathon/backend_server.git (fetch)
origin https://github.com/sopt12-hackathon/backend_server.git (push)
$ git remote set-url origin https://github.com/sopt12-hackathon/backend_server.git/awesome-wiki
$ git remote -v
origin https://github.com/sopt12-hackathon/backend_server.git/awesome-wiki (fetch)
origin https://github.com/sopt12-hackathon/backend_server.git/awesome-wiki (push)
이 git remote set-url을 통해 원격 저장소의 위치를 변경할 수 있었습니다. 다음에는, 만약 원격 저장소에서 머지하고 필요 없는 브랜치를 삭제했는데, 로컬 저장소에는 브랜치가 남아있을 때, 로컬 저장소에 남아있는 브랜치를 효과적으로 제거할 수 있는 방법에 대해 알아보겠습니다.
git prune을 활용한 브랜치 참조 제거하기
origin으로 추가한 원격 저장소에 있는 브랜치가 삭제됐을 때, 로컬에서도 해당 정보를 업데이트받아서 원격 저장소에서 삭제한 브랜치가 로컬에서도 자동으로 삭제되도록 하는 방법에 대해 알아보겠습니다. 즉, 로컬 저장소를 원격 저장소와 동기화하고, 자동적으로 더 이상 유효하지 않은 branch 참조를 제거하는 명령어는 다음과 같습니다.
$ git fetch origin --prune
$ git remote prune origin
git prune은 원격 저장소에 있는 것을 지우는 것이 아니라, local에서 참조하는 것 중 유효하지 않은 것을 제거하는 작업입니다.
git stash를 활용한 임시보관하기
현재 작업중인 브랜치에서 다른 브랜치로 checkout 해야 할 경우 커밋하지 않은 작업 때문에 checkout이 안될 수 있습니다. 이럴 때 커밋하지 않은 작업을 stash 명령어로 임시 보관하고 다른 브랜치로 checkout할 수 있습니다. 스택에 임시 보관한 작업들은 나중에 다시 꺼내와 마무리할 수 있습니다.
$ git add .
$ git stash
$ git checkout develop
stash 목록 확인하기
$ git stash list
git stash list를 하면, stash한 목록들이 나오게 됩니다.
stash 적용하기 (작업했던 것을 다시 가져오기)
$ git stash apply // 가장 최근의 stash를 가져와 적용한다.
$ git stash apply stash@{0} // stash@{0}은 하나의 예시. stash@{0} 에 해당하는 stash를 적용한다
git list를 통해 살펴본 stash@{0)가 저장되어 있는 것을 살펴볼 수 있고, 임시저장한 코드를 다시 불러오는 코드는 apply를 통해 구현할 수 있습니다.
마치며
지금까지 협업에 필요한 기본적인 Git 명령어에 대해서 알아봤습니다. 기본적인 Git 명령어를 모르고 작업을 진행하면서, Git 때문에 많은 불편함을 느낀 적이 많았습니다. 이 글에 이어, 기본적인 Git 명령어를 공부하고 정리하고자 합니다.
협업을 잘할 수 있는 개발자가 되고 싶습니다. 기본이 쌓이다 보면, 어느 순간 성장도 빠르게 할 수 있지 않을까 하는 마음이 있습니다. 비록 꿈을 향해 느리게 걷는 것지만, 느리게 걷는 길이 틀린 길을 의미하지 않는다는 친구의 위로를 기억하며 이 글을 마칩니다.
참고
'Project > 개발 협업' 카테고리의 다른 글
[협업] 협업을 위한 swagger 설정하기 (feat node.js) (0) | 2021.04.18 |
---|---|
[협업] 협업을 위한 VScode 설정하기 (0) | 2021.02.21 |
[협업] 협업을 위한 Git Flow 설정하기 (2) | 2020.12.19 |
[협업] 협업을 위한 git 커밋컨벤션 설정하기 (12) | 2020.12.18 |
[협업] 협업을 위한 코드컨벤션 설정하기 (0) | 2020.12.17 |