branch를 합치는 방법에는 크게 두 가지가 있습니다.
merge
, rebase
merge
: 합칠 branch들의 맨 위 HEAD를 병합합니다.
merge
는 어느 branch를 기점으로 두고 합칠 것인지가 중요하게 작용합니다.
기점이 될 branch를 바라보고 있는 상태에서 merge
를 진행합시다.
또한 merge
작업시에는 별도의 commit 메시지를 적을 필요가 없습니다.
merge
작업 때 사용할 문법은 다음과 같습니다.
git switch [기점이 될 branch명] // 기점이 될 branch를 선택합니다.
git merge [병합할 branch명] // branch를 병합합니다.
git branch -d [병합된 branch명] // 병합된 branch를 삭제합니다.
병합시 CONFLICT 에러가 발생한다면...
git merge --abort
명령어로 병합을 취소할 수 있습니다.
충돌이 일어나는 코드를 수정 및 선택합니다.
(VSCode를 이용해서 작업하면 위 이미지처럼 충돌이 일어나는 코드 중에서
병합할 때 사용할 코드를 탭 클릭으로 선택할 수 있습니다.)
CONFLICT 에러 발생을 되도록 피하기 위해 팀원들의 파일명을
각각 달리 하는 것을 추천합니다.
merge hell?
rebase
: 합쳐질 branch들이 기점이 되는 branch의 라인에 붙여집니다.
rebase
는 merge
와 달리 병합이 한 줄로 처리됩니다.
branch 라인 자체가 이동하기에, 병합할 가지가 많아졌을 때
병합 후 merge
보다 깔끔하게 보인다는 장점이 있습니다.
단 병합 전후의 히스토리를 추적하기 어려워진다는 단점도 존재합니다.
rebase
작업을 할 때 주의할 점은 합칠 가지를 먼저 선택해야 한다는 것입니다.
(rebase
는 보내는 것, merge
는 가져오는 것으로 이해하면 쉽습니다)
사용 문법은 다음과 같습니다.
git switch [옮길 branch명]
git rebase [옮겨질 branch명]
//충돌 작업 완료 후
git rebase --continue
+) rebase가 완료된 것처럼 보여도 위 이미지처럼
병합된 branch의 히스토리가 아래에 깔려 있습니다.
이 때는 merge를 통해서 가지를 위로 당겨줘야 합니다.
(*main branch와 develop branch의 코드가
이 시점까지는 동일했다는 것을 의미합니다)
+) main branch는 프로젝트 작업의 기준이 되는 가지인 만큼
항상 완성 코드를 싣고 맨 위로 끌어올려야 합니다.
git switch main
git merge develop
(이것으로 rebase 작업 끝!)
Github는 전 세계에서 가장 대표적이며 동시에
가장 널리 쓰이는 무료 Git 저장소입니다.
Github는 주로 본인이 만든 코드를 공유하기 위해,
그리고 협업 프로젝트의 Git 커밋 내역을 저장하는 용도로 사용됩니다.
오늘은 Github를 이용해서 어떻게 협업 프로젝트를 진행할 수 있을지
Github를 이용하는 방법에 대해 알아보겠습니다
(*초점은 Github가 아닌 Git에 두어야 합니다
Git의 기능을 제대로 이해하고 능숙하게 다룰 수 있는 사람만이
Github 사이트도 그만큼 잘 이용할 수 있습니다)
사이트 좌측 상단의 Create repository 혹은 New 버튼을 클릭합니다.
원격 저장소의 이름을 기입하고 사이트의 안내에 따라 원격 저장소를 생성합니다.
(*add a README flie은 체크를 해제하는 것을 추천합니다.
이걸 만드는 순간 커밋이 저장되는데 병합과정에서 번거로움이 생기기 때문에
팀 프로젝트 작업을 할 때 오류의 원인이 될 수도 있습니다.)
VSCode의 내장기능을 활용하여 연결작업을 진행해보겠습니다.
(모든 작업은 하단의 터미널을 통해 진행합니다)
git remote add "원격저장소 이름" "원격저장소 주소"
// 원격저장소명은 실제 Github상의 이름(git_sample)과 달라도 괜찮습니다.
// 여기서 저장소 이름은 보통 'origin'을 사용합니다 (기본 세팅)
git remote add origin "원격저장소 주소".git
// https://github.com/"github 유저명"/"원격 저장소 이름"
// https://github.com/nazzzo/git_sample.git
git remote -v
// 원격저장소에 잘 저장되었는지를 확인합니다.
git push origin main
// 작업이 끝난 main branch의 코드를 origin에 업로드합니다.
위 과정을 거치고 나면 .git
폴더 안에 있던 커밋 내역이
github에 성공적으로 업로드되는 것을 확인할 수 있습니다~
+) 원격 저장소와의 연결을 끊어야 할 때는 다음 명령어를 사용합니다.
git remote remove [원격저장소 이름]
//git remote remove origin
// 원격저장소(origin)와의 연결을 차단합니다.
전체 가져오기 (
clone
) : 프로젝트(main branch)의 모든 코드를 지정한 폴더에 가져옵니다.git clone "원격저장소 주소" "폴더명" //https://github.com/nazzzo/git_sample.git project
보내기 (
push
) : 새로운 작업내역을 원격저장소에 업로드합니다.git push "원격저장소 이름" main //git push origin main
가져오기 (
pull
) : 업데이트된 작업내역을 로컬 저장소에 내려받습니다.git pull "원격저장소 이름" main // git pull origin main // 원격저장소(origin)의 main branch를 가져옵니다.
(전체 코드를 내려받는clone
과 달리
push
, pull
명령어는 원격저장소에서 허가된 사용자만 사용할 수 있습니다.)
clone
으로 main branch를 받아와서 작업을 진행한 뒤
커밋을 실행하면 main branch가 2개로 분리(main
과 main/origin
)되는 이유는 뭘까요?
이것은 로컬에 있는 소스코드(main
)을 고쳐서 커밋을 진행해도
원격 저장소의 main branch(origin
)에는 반영되지 않기 때문입니다.
(Github는 인터넷 상의 데이터베이스일 뿐,
Git처럼 작업 진행도(로그)를 실시간으로 추적하고 있는 것이 아닙니다)
이 때 작업을 마친 커밋 내역을 헤드에 두고 git push origin main
을 입력하면
사용자가 업데이트한 만큼의 커밋 리스트가 원격 저장소에 업로드 됩니다.
그리고 푸시와 동시에 main/origin
과 main
branch가 병합되며 헤드로 올라옵니다.
push & pull 주의사항
로컬 저장소와 github의 원격저장소는 연결되어있는 상태가 아닙니다.
원격저장소에서 수정한 내용 또한 로컬 저장소의main/origin branch
에 반영되지 않습니다.
원격 저장소의 커밋 내역이 업데이트 되면 그때는 pull
명령어로 받아와야 합니다.
(Github에 업데이트 내역이 없다면 명령어가 실행되지 않습니다.)
pull
명령어는 로컬 저장소의 working directory의 변경사항은 인지하지 못합니다.
(그래서 이때는 pull
로 원격저장소의 업데이트 코드를 받아올 수 있습니다.)
단, 로컬 저장소에서 커밋을 실행, 원격저장소에서도 커밋내역이 업데이트 되었을 때는
pull
명령어 실행시 오류가 생기게 됩니다.
이런 상황을 막기 위해 협업 작업을 할 때는 main branch를 이용해서
작업하는 것을 피해야 합니다. 작업용 branch를 새로 생성해서
작업 및 병합과정을 거친 뒤 마지막으로 main branch과의 병합을 거치도록 합니다.
main branch
는 원격저장소와의 소통(pull & push)을 하는 데에만 이용합시다.
+) 윈도우 환경에서 커밋 에디터를 다룰 때
vi 에디터로 켜지길 원한다면 다음 코드를 입력해주세요
git config --global core.editor "vi -c 'set colorcolumn=72'"
팀 프로젝트를 진행하는 도중 피치못하게
커밋 히스토리를 수정해야 하는 상황이 닥칠 수가 있습니다.
이럴 때는 git rebase
명령어와 옵션인 -i
(interactive)를 사용해야 합니다.
git rebase -i "수정할 커밋의 해시값"
// 커밋 해시를 이용하는 방법입니다
git rebase -i 9d9cde8
// HEAD를 이용할 수도 있습니다.
// 숫자 1은 가장 최근의 커밋 코드를 의미합니다
git rebase -i HEAD~1
수정하고자 하는 커밋 내역을 불러오면 에디터가 열리는데,
여기서는 다음과 같은 명령어를 입력할 수가 있습니다.
- p(or pick) : 커밋 그대로 두기
- r(or reword) : 커밋 메시지 변경
- e(or edit) : 수정을 위해 정지
- d(or drop) : 커밋 삭제
- s(or squash) : 이전 커밋에 합치기
*(따로 외우지 않아도 --help
를 통해 명령어를 확인할 수 있습니다.)
*만약 메시지 변경을 위해 r을 입력했다면
wq로 저장하고 빠져나오려는 순간 또 다른 에디터가 열릴 텐데
이 에디터는 커밋메시지를 수정하는 에디터입니다.
문제 발생...?
수정 후 커밋까지 완료하고 나면 원격 저장소에서 받아온 main branch와
수정을 마친 커밋이 분리되게 됩니다
그 이유는 rebase
를 통한 수정은 기존의 커밋 내역을 재사용하는 것이 아닌,
내용이 같은 커밋을 새로 만들어서(Copy & Paste) 진행되는 방식이기 때문입니다
그래서 팀 프로젝트로 협업하는 과정에서 이미 원격 저장소에 업로드된 커밋 히스토리를
로컬 저장소에서 rebase
로 수정하여 다시 푸시하는 일은 일어나지 않도록 해야 합니다
이 때문에 원격 저장소의 브랜치를 베이스로 작업하고 있던 동료들의 커밋 히스토리가
와장창 깨질 수도 있거든요...
그러니 커밋 히스토리를 수정할 경우가 생기면 협업을 진행하는 팀원과
반드시 상의를 거치고 진행하시길 바랍니다
(모든 팀원이 작업의 싱크를 맞춰야 합니다)
마지막으로 팀 프로젝트에서 Github의 사용법을 요약하자면 다음과 같습니다.
main branch
)을 Github에 업로드합니다.clone
)main branch
에 병합해서 Github에 업로드합니다. (push
)main branch
)을 받아와서 작업 진행을 이어갑니다.main
코드와 작업중인 코드간에 충돌이 일어난다면 여기서 해결해야 합니다.)Github에서 가져온 코드는 의심하지 맙시다...