[Git][GitHub 사용하기] push, pull

mutexlocking·2022년 7월 10일
0

[내 로컬의 커밋 내역 , 즉 프로젝트의 변화를 연결된 원격 저장소의 특정 브랜치에 업로드 하기]

(먼저 로컬 프로젝트에 변화를 준 후 , commit 완료 후)

  • git push
    -> 우리의 경우 앞서 git push -u origin main 을 통해 ,
    -> 로컬의 메인 브랜치를, 원격저장소 origin의 main브랜치와 연결 시켜놓았기 때문에
    -> 이후 push할 때는 , 그냥 git push 만 적어주어도
    -> 알아서 연결된 origin의 main 브랜치로 커밋이 업로드 된다.

[반대로 원격에 반영된 변화를 내 로컬에 적용하기]

  • git pull
  • 이 또한 앞선 git push -u origin main 에 의해 한번 연결된 origin의 main 브랜치의 커밋 중, 로컬에 반영되지 않은 커밋을 알아서 다운받게 된다.
  • 만약 push에 의해 원격저장소의 어느 브랜치와 연결될지 설정되지 않은 상태라면
    -> git pull origin main 등을 통해 , "어느 저장소의 어느 브랜치에서 pull 받을것인가" 를 pull 뒤에 명시적으로 설정하면
    -> 연결된 해당 저장소 (여기서는 origin) 에서 해당 브랜치의 내용이 pull 받아진다.
    -> EX ) (만약 upstream이라는 새로운 repo와 연결되어 있다면)
    -> git pull upstream main

이렇게 단순하게 내 로컬의 변화는 원격으로 push 하고, 원격의 변화는 로컬로 pull 하면 될 것 같지만, 협업은 그렇게 단순하지 않다.

예를 들어 나와 팀원이 함께 협업을 하면서,
내 로컬에도 변화가 생겼고 팀원의 로컬에도 변화가 생겼는데
팀원만 로컬의 변화를 원격에 push한 상황이라면
내 로컬 변화와 원격의 변화가 서로 다른데 무작정 내 변화만을 push 할 수 있을까?

답은 No 이다. 내 로컬과 원격의 변화가 다를 경우, Git은 반드시 원격의 변화를 먼저 내 로컬에 반영한 후 , 내 로컬의 변화를 원격에 반영하도록 교통정리를 하고 있기 때문이다

[정리하면 ,
내 로컬의 변화를 원격으로 push도 해야 하지만 && 동시에 원격의 변화를 로컬로 pull 해야하는 상황]

  • 이런상황에서 내 로컬의 변화 먼저 push 하면 -> 오류가 뜬다
  • 이는 원격 저장소와의 push , pull 매카니즘의 근본이 다음과 같기 때문이다
    : 로컬의 변화를 원격으로 push 할 수 있으려면, 반드시 먼저 원격의 변화를 pull한 이후여야 한다.

그런데 이때 원격의 변화를 받아서 내 로컬에 반영할 때,
원격의 변화(커밋 내역)와 - 내 로컬의 변화(커밋 내역)을
어떻게 합쳐서 반영 시킬것인가에 대해 2가지 전력이 존재한다

[전략 1. merge]

  • git pull --no-rebase
  • commit 메세지가 적힌 vim창이 나오면 -> :wq로 저장

-> 이 경우 아래와 같이 origin의 변화와 / 내로컬의 변화가
-> 각각의 브랜치로 분기된 후에 하나로 merge 되면서
-> 새 commit이 생기므로써
-> 원격의변화와 로컬의 변화가 합쳐진다.

[전략 2. rebase]

  • git pull --rebase
  • (vim 창이 나오지 않고 알아서 커밋 완료됨)

-> 이 경우 아래와 같이 origin의 변화와 / 로컬의 변화가 브랜치로 분기되지 않고
-> 기존의 하나의 브랜치 안에서
-> 원격의 변화가 먼저 적용된 후 (커밋) - 로컬의 변화가 적용된다 (커밋)

어쨌든 두 전략중 한 전략을 써서, 로컬에서 원격의 변화와 로컬만의 변화를 모두 적용시킨후, 다시 push를 해줘야 원격의 변화와 로컬의 변화가 모두 반영된 로컬의 프로젝트가 원격에도 업로드 된다.

[다시 push]

  • git push 로 로컬에서 합쳐진 변화를 원격에 반영시켜주어야 ,
    로컬과 원격이 모두 최신 프로젝트가 된다.

이제는 나아가 내가 로컬에서 수정한 프로젝트와 ,
팀원이 로컬에서 수정한 프로젝트 사이에 충돌이 일어난 경우를 살펴보자.
팀원이 먼저 로컬에서 수정한 프로젝트를 원격에 올려서
내가 로컬에 먼저 pull 받은 후 - 내 로컬 변화까지 함께 push 하려고 하는데 ,
당연히 내 로컬에서 pull 받을 때 충돌이 일어난다!

일단 팀원이 push한 원격과 , 내 로컬 상황이 다른 것을 아래와 같이 확인할 수 있다.

[이때 merge 전략으로 pull 받을때 충돌이 발생한다면]

  • git pull --no-rebase
  • 충돌 발생
  • 충돌 해결
  • git add .
  • git commit
  • 커밋 메세지가 적힌 vim 창이 나오고 , 그대로 :wq로 저장하여 commit완료
    (충돌이 발생한 화면)

    (충돌 해결 후, commit 까지 완료한 화면)

[rebase 전략으로 pull 받을 때 충돌이 발생한다면]

  • git pull --rebase
  • 충돌 발생
  • 충돌 해결
  • git add .
  • git rebase --continue
  • 커밋 메세지가 적힌 vim 창이 나오고 , 그대로 :wq로 저장하여 commit완료

이 rebase 전략으로 충돌을 해결한 경우, 어떻게 해결하냐에 따라 내 로컬 변화에 의한 커밋이 추가가 안될 수도 있다.

  • ex 로컬 변화 : A 추가 / 원격 변화 : B 추가 인 경우
    -> rebase로 pull 받았을 때
    -> 충돌시 B추가만 하게 수정한다면
    -> 애초에 내 로컬에서의 A추가가 안된 것이니 - 로컬에서의 커밋도 사라진다

    -> 반면 충돌시 A추가만 하거나 A,B 둘다 추가할 경우
    -> 어쨌든 A가 남아있게 된 것이니 - 로컬에서의 A추가 커밋도 유지가 된다
    -> 이때의 커밋은 pull 한 원격 먼저 적용 후 - 내 커밋이 나중에 적용된다.

  • 앞에서, 협업 상황에서 rebase를 사용하지 말라고 했는데
  • 그건 이미 공유되는 상황에서 rebase로 합치지 말라는 의미였고
  • 이처럼 pull 받을 때 rebase로 합치는것은 협업시 써도 OK

[강제 push]

  • 언급한 것 처럼, 로컬 내역이 원격보다 뒤쳐진 경우는 push가 바로 안되고
  • 먼저 pull 받아서 로컬에서 합친 이후
  • push를 할 수 있었다.

그렇지 않고 서로 합의가 된 상황하에, 원격에 있는 프로젝트가 잘못되어서,
한 로컬에서 전부 수정한 걸로 원격껄 맞춰야 할때

  • git push --force로 강제 push 할 수 있고,
    -> 이 경우 원격은 로컬의 내용으로 전부 맞춰진다
    (단 원격의 일부가 날아갈 수 O)
  • 실제로 강제 push 할 경우 원격의 일부 커밋이 날아갈 수 있다는 점 주의
  • 그렇지만 그만큼 원격의 커밋이 로컬의 커밋에 깔끔하게 맞춰진다!!
profile
개발자가 되고자 try 하는중

0개의 댓글