공부블로그

Git 협업 본문

공부하기

Git 협업

떠어영 2022. 11. 25. 15:04

( pull, update, fetch가 헷갈리니까 정리 먼저 ~~~ )

 

1. git remote update

원격 저장소의 모든 브랜치에 대한 이력을 확인한다. 

2. git fetch

원격 저장소의 최신 이력을 확인. fetch로 확인한 최신 이력을 로컬 저장소로 병합할 때는 pull 또는 merge를 실행한다.

옵션 없이 사용하면 로컬 저장소에 존재하는 브랜치에 대해서만 업데이트한다. 모든 원격 브랜치 이력을 업데이트하고 싶다면 --all 옵션을 사용한다.

 

3. git pull

현재 위치하고 있는 원격 브랜치를 업데이트하고 로컬에서 변동 사항을 병합한다.

로컬 브랜치를 업데이트할 때 사용한다.

.

.

.

그런데 나를 헷갈리게 한 Webstorm의 update....는 pull처럼 원격의 업데이트를 현재 브랜치에 병합하는 거였고....

실제 공식 문서를 가보니 'if you need to sync a specific branch with its remote tracked branch' 즉 연결된 원격 저장소와 동기화하고 싶을 때 사용하는 거고 명령어 상으로는 fetch + git merge origin/main가 실행되었다. 

 

update project : fetch changes from all branches each time you sync with the remote repository 즉 update 모든 브랜치

 

두가지 옵션

pull은 어떤 원격브랜치에서 가져올건지 정할 수 있었다. 'If you need to get changes into the current branch from another branch instead of its remote tracked branch ' 그리고 가져온 브랜치가 로컬에 병합된다.

옵션도 짱많어

그래서 여기서 설명하는 기준은 그냥 Webstorm으로 하기로 했다! "업데이트된 = 원격저장소와 동기화된" 이렇게 보는 게 정확하겠다


 

협업 상황 1 ) dev브랜치에서 feature브랜치를 따서 내가 로컬에서 작업하는 도중에 반드시 반영해야 하는 dev브랜치의 변경사항이 생긴 경우!

 

모범답안 )

 

   1.  먼저 origin dev 와 local dev상태를 일치시키기

git checkout dev // local dev 가 되겠죠?
git pull origin dev // 다른 사람이 수정하여 새로 업데이트 된 dev 내용을 내 local dev 에도 받아옵니다.

   2. 새롭게 받아온 dev의 내용을 feature 브랜치에 합치기 위해 merge 또는 rebase를 사용

git checkout feature
git rebase dev

   3. 로컬 feature에서 이어서 작업 진행

 

가능한 답안 )

 

1 - 1 ) 업데이트된 dev를 내 로컬 feature에 병합하고 다시 내 작업을 진행한 뒤 push → PR을 통해 dev에 merge

  1. 업데이트된 dev브랜치를 feature브랜치로 merge하면 커밋 머지가 생기고 feature브랜치는 해당 커밋에 위치. 
  2. 이제 다시 내 작업을 진행하고 완료되면 dev브랜치에 merge하기 위해 내 로컬 feature를 원격에 push하면 PR생성
  3. PR을 통해 원격에 push한 feature브랜치에서 dev브랜치로 merge

 

- update branch해서 dev는 로컬과 원격 모두 업데이트 되어있는데, 내가 작업중인 feature는 업데이트 이전의 dev가 base

로컬 feature에 커밋 2개 작업중에 원격에서 dev브랜치에 충돌이 예상되는 업데이트를 함

- 로컬에서 미리 dev를 feature로 merge

역시 충돌남

- 수정해준 다음 commit하면 로컬 feature에 머지된 커밋이 생성

 

- 예상 충돌을 해결한, 내가 작업한 로컬 feature를 push하고 PR을 날리면 feature → dev로 merge

짱 복잡하지만 원하는 결과는 나온 히스토리 완성^^

- 결과물 : 원격 dev의 업데이트 내용이 반영된 내 로컬 feature를 push했고, 충돌을 미리 예방해서 성공적으로 merge했다 ~ 

 

 

1 - 2 ) 업데이트된 로컬의 dev브랜치에 내가 작업한 내용을 바로 병합할 수도 있는데 위험해 보인다^^

           ( dev를 건드릴 때는 PR을 만드는 게 좋다 )

 

- update하면 로컬의 dev는 원격의 기록을 가져오고 변동 내역을 병합한다. ( 원격과 로컬의 dev위치는 동일해진다. )

b7bdee83을 base로 하는 feature브랜치는 로컬에서 작업 중

 

- 이제 새로 업데이트된 dev에 내가 작업한 내용을 병합하고 싶어서 merge하면 → 충돌 → Resolve conflicts해서 merge commit

update된 dev브랜치에 작업한 feature브랜치가 병합된 모습, 아직 dev를 push하지 않았다. feature브랜치는 로컬에만 존재.

- 이렇게 내가 로컬에서 작업한 내용을 안전하게 잘 병합했다. feature브랜치는 이제 삭제하고 다음 작업 때는 또 새로운 feature을 생성

 

+ merge말고 rebase해도 된다.

  1. feature브랜치에서 업데이트된 dev로 rebase
  2. 충돌해결
  3. $ git add ~
  4. $ git rebase -- continue

 + 내가 작업한 내용을 dev에 반영하는 경우 :  4번까지 완료하면 feature브랜치가 하나 앞으로 가있기 때문에 dev브랜치에서 feature를 병합 : $ git merge feature ( fast-forward merge ) 

한줄로 이쁘게 히스토리 정리, 마치 가장 최근의 dev에서 feature를 따온 것처럼

 

 

2 ) dev에서 feature를 따서 내가 로컬에서 작업, 근데 이거말고 새로운 기능을 먼저 개발해야 해서 hotfix라는 브랜치로 작업하는 경우!

우선 dev에서 feature를 따서 내가 작업ing, 그런데 또 새로운 작업을 받았을 때

  1. 작업하던 feature브랜치 commit or stash
  2. dev에서 새로운 hotfix브랜치 생성
  3. hotfix에서 급한 작업 & 커밋 진행
  4. 완성된 기능을 dev에 merge (Fast-forward)
  5. 다시 원래 하던 작업인 feature로 돌아감
  6. 이제 내가 작업한 내용을 dev에 merge하면 브랜치가 가리키는 커밋 두 개와 공통 조상 하나를 사용하여 3-way Merge를 한다.
  7. 이 과정에서 새로운 merge commit은 3-way Merge 의 결과를 별도의 커밋으로 만들고 나서 해당 브랜치가 그 커밋을 가리키도록 이동시킨 것

 

3 ) Cherry-pick 사용해서 원하는 commit만 적용하기 

dev의 하위 feature브랜치, 각각 두개씩 커밋, feature의 마지막 commit (6a7c1e81) 만 dev에 적용하고 싶은 경우!

항상 기준은 받는 브랜치에서 ~ 가져오고 싶은 커밋/브랜치를 ~ 입력해야 한다.

그래서 dev에 적용하고 싶으니까 dev브랜치에서!! 원하는 커밋을!! 

 

(+ 툴을 사용하면 더 쉽다. Webstorm에서 dev브랜치로 checkout하고, 원하는 커밋 우클릭하면 cherrypick버튼으로 바로 가능 )

충돌나면 고쳐서 add, --continue
feature에만 있었던 add text feature and dev feature branch가 dev브랜치에도 똑같이 생김(적용)

 

+ ) dev브랜치의 하위 feature브랜치에서 개발을 진행하고 특정 커밋만 cherry-pick하면 dev브랜치에 feature브랜치와 커밋 메세지는 같지만 hash는 다른 커밋이 생성, 그 다음 feaure브랜치가 cherry-pick된 dev브랜치에 rebase하면 cherry-pick 커밋 뒤로 붙는다.

 

4 ) Stash 가 필요한 상황

feature브랜치에서 작업하던 일이 있고 다른 요청이 들어와서 잠시 브랜치를 변경해야 할 일이 생겼다고 치자. 그런데 이런 상황에서 아직 완료하지 않은 일을 커밋하는 것이 껄끄럽다는 것이 문제다. 커밋하지 않고 나중에 다시 돌아와서 작업을 다시 하고 싶을 것이다. 이 문제는 git stash 라는 명령으로 해결할 수 있다. 

 

Stash 명령을 사용하면 워킹 디렉토리에서 수정한 파일들만 저장한다. Stash는 Modified이면서 Tracked 상태인 파일과 Staging Area에 있는 파일들을 보관해두는 장소다. 아직 끝내지 않은 수정사항을 스택에 잠시 저장했다가 나중에 다시 적용할 수 있다(브랜치가 달라져도 말이다).

 

1. 하던 일을 stash → 스택에 저장됨

2. 다른 브랜치로 체크아웃 가능해져서 다른 요청 해결

3. 다시 작업하던 브랜치로 돌아와서 스택에 저장되어 있던 수정했던 파일들을 복원 

 

ex ) feature브랜치에서 작업하다가 요청을 받고 dev브랜치로 이동하여 요청을 해결하고 다시 feature브랜치로 돌아와 수정했던 파일들을 복원하기

 

feature브랜치에서 작업하던 일을 stash

git stash

dev브랜치로 체크아웃해서 요청 해결~

git checkout dev

다시 feature로 돌아와서 저장해놨던 수정된 파일들을 복원

git checkout feature
git stash apply //가장 최근의 stash 적용

 

+ 추가 명령어 

 git stash list : stash 목록 조회

$ git stash list
stash@{0}: WIP on feature-meritz: 629732d update css

git stash apply : stash에 저장된 내용을 다른 브랜치에 적용

$ git stash apply stash@{1}

 

 

추가적으로 아래의 GitBook을 참고하는 것도 도움이 될 것 같다. 나는 아직 소규모 팀 협업까지만 이해한 것 같다...

 

Git - 프로젝트에 기여하기

책 처럼 하지말고, 시키는 대로 하기. 시간 관계상, 이 책에서 설명하는 예제의 커밋 메시지는 위와 같이 아주 멋지게 쓰지 않았다. git commit 명령에서 -m 옵션을 사용하여 간단하게 적는다. 하지

git-scm.com