Git

[Git] git 개념 정리

sangchu 2022. 12. 17. 15:03

'팀 개발을 위한 Git GitHub 시작하기' 책을 참고하여 정리한 내용입니다.

정리한 개념 목록

  • branch
  • fork
  • clone
  • pull request
  • merge
  • rebase
  • amend
  • 브랜치 전략
  • cherry-pick
  • reset
  • revert
  • stash

둘 이상의 원격저장소로 협업하기

01 원본저장소를 복사해서 나의 원격저장소를 만든다(fork)

branch, fork

  • 원본 저장소에 커밋을 직접 푸시할 수 있는 사람은 본인(소유자) 뿐
    • 다른 사람이 푸시하려면 협력자(Collaborator)로 등록해야 함
  • 협력자가 5명정도면 걍 모두 협력자 등록하고 브랜치 나눠서 작업하는게 효율적
  • 직접 푸시하는게 부담 → pull request
    • fork한 원격저장소의 브랜치에서 원본저장소의 브랜치로 풀리퀘
  • fork
    • 브랜치를 포함한 원본저장소의 모든 커밋 이력을 새로운 원격저장소로 통째로 복사
    • 복제한 원격저장소는 새로운 주소로 독립 → 이곳의 이력을 보려면 추가적으로 원격저장소 주소 등록해야 함
  의의 편리한 점 불편한 점
브랜치 하나의 원본저장소에서 분기를 나눈다. 하나의 원본저장소에서 코드 커밋 이력을 편하게 볼 수 있다. 다수의 사용자가 다수의 브랜치를 만들면 관리하기 힘들다.
포크 여러 원격저장소를 만들어 분기를 나눈다. 원본저장소에 영향을 미치지 않으므로 원격저장소에서 마음껏 코드를 수정할 수 있다. 원본저장소의 이력을 보려면 따로 주소를 추가해야 한다.

남의 저장소를 내 계정에 통째로 복제하기(Fork)

repo명: 본주인아이디/iTshirt → 내아이디/iTshirt

  • fork하고 만든 내 원격저장소를 clone해옴

 

02 원격 저장소에서 원본저장소에 풀 리퀘스트 보내기

fork한 원격 저장소에서 원본저장소에 풀 리퀘스트 보내기

  • fork한 원격 저장소 A브랜치에서 원본저장소의 B브랜치로 코드를 합치기
  • 풀리퀘 보내고 승인(approve)과 병합(merge) 기다리면됨

풀 리퀘스트를 승인하고, 병합하기

  • 댓글만 달고싶으면 comment, 병합해도 될 것 같으면 Approve, 수정 요청하고 싶으면 request changes 선택 → summit review 버튼 클릭
  • 병합 하려면 Merge pull request 버튼 클릭 - 원본 저장소 주인만 할 수 있음
  • 이제 나도 컨트리뷰터에 포함 됨

 

03 묵은 커밋을 새 커밋으로 이력 조작하기(rebase)

  • 풀 리퀘를 보냈는데 코드 충돌 일어남
  • 내 브랜치로 먼저 병합하고 충돌을 해결한 다음 다시 풀 리퀘를 보내면 충돌이 나지 않을 거임
  • 하지만 그러면 풀 리퀘에 내가 추가한 코드 이외에 충돌을 해결하느라 생긴 병합 커밋이 생길 거임 → 이를 피하고 깔끔하게 변경한 부분만 풀 리퀘를 보내는 방법

원본저장소에 새로운 커밋이 있는데, 포크한 내 원격저장소에는 안 보여요!

  • 그래서 걍 모른체로 새로 만들어서 풀리퀘 보냈는데 원본꺼에서도 수정해서 충돌이 일어날 수 있음
  • 너무 예전 코드 기점으로 새 코드를 추가한 경우

여러 원격저장소 히스토리를 한 눈에 보기: 리모트 추가(Add remote)

  • 포크한 시점까지의 모든 히스토리는 내가 알 수 있지만, 그 다음에 원본저장소에서 무슨 일이 있어났는지 모름
    • 포크한 원격저장소는 이미 주소까지 바뀌어서 서로 다른 원격저장소가 됐기 때문 → 원본저장소와 원격저장소를 동시에 추적하도록 만들면 됨 → 원본저장소 주소 remote
    • 원본저장소를 지칭하는 관용적 닉네임 : upstream
  • fetch
    • upsteam 원본저장소에 있는 커밋 히스토리 받아오는 것
    • ‘새로고침’ 기능, 원본저장소 이력 업데이트 → 이력만 가져오는 거니까 내 코드에는 아무 영향 없음 최신 코드를 내 코드에 반영하는 pull과는 다름
    • 소스트리에서는 10분에 한번씩 자동으로 패치해서 따로 하지 않아도 새로운 이력이 보인 거임

묵은 커밋을 방금 한 커밋처럼: 리베이스(Rebase)

  1. 현재 커밋과 병합하고 싶은 커밋을 미리 내 브랜치에 병합해서 병합 커밋을 만들고 이를 풀 리퀘스트 보내는 방법
  • 불필요한 병합 커밋 이력이 남음, 충돌을 해결하느라 쓸데없는 코드가 더 들어가게 된 거임 → 묵은 커밋을 방금 한 커밋(햇 커밋)처럼 이력을 조작하는 것

  • 0번 커밋(옛날커밋)이 아니라 3번 커밋으로 베이스로 만들었으면 아무 문제 없이 빨리감기 merge가 되는 상태일 것임.
  • rebase: 이렇게 커밋의 베이스를 똑 떼서 다른 곳으로 붙이는 것 (리 베이스 - 베이스를 다시 잡다)
  • 깔끔하게 풀리퀘 보낼 수 있고, 내 브랜치에 내 변경사항만 남길 수 있음

실습

  • 소스트리 보면 ‘찜하기 기능 추가’의 베이스 커밋이 ‘좋아요 기능 추가’임
  • 이제 베이스 커밋을 upstream/master의 최신 커밋인 ‘개발자 목록에 너구리 추가’인 것처럼 이력 조작할거임
  • 리베이스는 반드시 혼자만 쓰는 브랜치에서 수행해야함, 보통 기능 구현 하는 브랜치는 혼자만 쓰니까 편하게 리베이스
    • 히스토리를 강제로 조작하기 때문에 다른 사람이 만약 이 히스토리를 보고 있다면 완전히 꼬임
  • 리베이스 명령어를 하고 충돌 고치고 리베이스 계속을클릭해서 리베이스 계속진행
    • 리베이스는 커밋을 하나씩 비교하면서 충돌이 있나 확인하기 때문에 계속 같은 곳을 수정했다면 ‘재배치 계속’을 누를때마다 충돌이 여러번 날 수도 있음
  • 모든 충돌이 해결하고 리베이스가 성공되면 베이스 커밋이 바뀐걸 확인 가능
  • 원격저장소에 푸시해서 로컬저장소의 이력을 반영해야 함
  • 리베이스는 다른 개발자가 이 변경사항을 사용하고 있지 않아야 한다고 했음
  • 강제 푸시로 해야함

 

실무 사례와 함께 Git 다루기

01 실습을 위한 사전 준비: 새로운 저장소 만들기

  • MIT License : 재배포 가능

 

02 amend: 수정 못한 파일이 있어요, 방금 만든 커밋에 추가하고 싶어요

커밋 하나 만들었는데, 추가할 파일이 있다는 것을 뒤늦게 알았을 때, 커밋을 더 추가하고 싶지 않을 때

amend로 마지막 커밋 수정하기

  • 수정할 코드를 수정하고, 변경사항을 stage에 올림 → amend하면 지금 stage에 올린 변경사항이 기존 커밋에 추가되면서 기존 커밋이 덮어 씌워짐
  • 커밋 메세지 수정 해도되고 안해도 됨

amend로 마지막 커밋 메세지를 수정하고 원격저장소 브랜치에 강제 푸시하기

  • 위는 로컬저장소에만 올린 커밋을 수정하는 거임
  • 이번에는 원격저장소에 푸시한 커밋을 amend로 수정하고 원격저장소에 다시 반영하는 실습
  • amend로 커밋 메세지 바꾸고 강제푸시하면 됨
  • 강제푸시는 나혼자만 쓰는 브랜치에서만 해야 함 - 다른 사람의 커밋 히스토리가 엉망으로 꼬이게 되므로

 

03 cherry-pick: 저 커밋 하나만 떼서 지금 브랜치에 붙이고 싶어요

브랜치 전략은 회사, 팀마다 다름

브랜치명 특징

브랜치명 특징
feat/기능이름 각 개발자가 개발 중인 브랜치
직접 커밋을 올린다.
master [feat/기능이름] 브랜치에서 개발 완료된 코드가 합쳐진 브랜치
출시 전인 베타 버전이라고 볼 수 있다.
직접 커밋을 올리지 않는다(병합을 통해서만 코드를 업데이트)
test.itshirt.com에 배포되어 항상 최신 개발 버전을 볼 수 있음
latest 실제 출시할 코드(대중에게 보여줄 완벽한 코드)를 올리는 브랜치
[master] 브랜치에서 굵직한 개발이 끝나면 출시 시점[latest] 브랜치로 코드를 병합한다
실제 서버인 itshirt.com에 배포

  • 출시한 코드가 담긴 [latest] 브랜치에 당장 고쳐야하는 버그 발견
  • [master] 브랜치에서 [fix/text-bug] 브랜치를 따서 고치고 이를 [master] 브랜치에 병합 함
  • 이제 이를 [latest] 브랜치에 반영해야 하는데, [master]에 있는 다른 변경사항 말고 딱 그 버그를 고칫 커밋만 반영하고 싶음. 다른 기능들은 출시할 시점이 아니어서
  • cherry-pick : 내가 따길 원하는 체리(커밋)을 선택
    • 커밋을 복사해 왔지만 서로 같은 커밋은 아님(커밋 아이디 다름)

 

04 reset: 옛날 커밋으로 브랜치를 되돌리고 싶어요

Soft/Mixed reset: 모든 기억을 남기면서 브랜치를 되돌리기

  • Hard 모드 : 깔끔하게 히스토리를 돌리겠다
  • Soft, Mixed 모드: 원하는 커밋 이력으로 되돌리긴 하지만, 이 다음에 추가했던 모든 변경사항을 작업 공간으로 뽑아 줌
    • Mixed: 변경사항이 stage 아래로 튕겨나감(커밋하기 전 상태로 남겨짐), stage위로 올리려면 Add해야 함
    • Soft: 변경사항이 stage 위에 둬서 다시 당장 커밋할 수 있음

Hard reset: 모든 기억을 지우며 브랜치를 되돌리기

  • 히스토리를 수정하는 푸시이기에 강제 푸시로 해야 함

 

05 revert: 이 커밋의 변경사항을 되돌리고 싶어요

  • reset과 달리, 모두가 함께 쓰는 브랜치라 이력 관리가 중요할 때, → 되돌리는 새로운 커밋을 만듦

revert: 커밋의 변경사항을 되돌리는 새로운 커밋 만들기

  • 잘못된 커밋이 있으면 언제든 되돌릴 수 있음

 

06 stash: 변경사항을 잠시 다른 곳에 저장하고 싶어요, 커밋은 안 만들래요

  • 한 브랜치에서 개발을 하다가 급하게 고쳐야 하는 버그가 생김, 다른 브랜치로 이동하려는데 현재 브랜치에 앚기 커밋하지 않은 변경사항 파일이 10개 있음 하지만 아직 커밋으로 만들기는 애매한 파일들
  • stash(넣어두다) : 이 변경사항을 잠깐 서랍속에 넣어뒀다가 이따 다시 꺼내 쓰는 방법

stash: 커밋하지 않은 변경 사항을 서랍 속에 넣어두기

  • stash 및 그에 대한 설명을 적고(나중에 까먹지 않고 찾아서 꺼내 쓰기 위해), 현재 변경사항을 임시 저장하고 작업 중인 사항을 비움
  • 이제 변경된 파일에 신경 쓰지 않고 자유롭게 Pull이나 브랜치 이동같은 다른 작업 가능
  • stash는 tracked 상태(추적중 - 한번이라도 Git에 올렸던 상태)인 파일들만 들어감