Study Programming/Git

Git Remote 연동하기1 - Refs, Tracking branch

네모메모 2021. 8. 15. 16:04
반응형

 


 

 

리모트 Refs (Remote References)


일단, "Refs"란??


- Git은 모든 'history'를 'Key-Value format'으로 관리한다.
   ㄴ> 'Key'는 'SHA-1로 만들어진 40자리 해시값'이나 이를 기억하기 어렵기 때문에 "쉬운 이름의 파일"에 해시값이 저장한다.
      이런 파일들을 "References"라고 하며, 약자로 "Refs"라고한다.

- Git에서 "Refs"는 '.git/refs'에 저장된다.
   ㄴ>  '.git/refs/heads' 디렉토리 내에는 main와 branch파일들이 있다.

 

- Git에서 "어떤 특정한 작업을 가르키는 Refs"를 "branch"라고 한다.

 

 


 

 

리모트 Refs (Remote references) 란?

 : 리모트 저장소에 있는 포인터인 레퍼런스.  리모트 저장소에 있는 브랜치, 태그, 등등을 의미한다. 
 


<리모트 Refs 정보 조회 명령어들>

1. $ git ls-remote [remote]  : 모든 리모트 Refs를 조회

- 원격 저장소의 refs/heads 와 refs/tags 목록을 표시해준다.

- ex) 커니코들린 github의 리모트 Refs 조회 시

$ git ls-remote https://github.com/kunny/kunny-kotlin-book.git
724da71f0afd8e9beb37e0acf7d60216c1a33e75        HEAD
ece20d7730ff73bdcd422906c360982a8be57107        refs/heads/arch-components-lifecycle
dcc096e0afa44af8dd78ecf8a8da137d5f715ddb        refs/heads/arch-components-room
680f7b8dc0bee2b63d66c38f1801e4e09c1c2c0c        refs/heads/arch-components-viewmodel
6dec6be7abcce7e0c4f877da438218b7c6b238ec        refs/heads/dagger-step-1
a6bbe93de516b42ec57df5f2915447c2cf283db5        refs/heads/dagger-step-2
080897e00b236874f29051fc9054f3e1c286975d        refs/heads/java
e09876c9a663b61fe1e920971523170f47e389e9        refs/heads/kotlin-step-1
d8f2dae007086272adabe4a7a53681974e25b630        refs/heads/kotlin-step-2
fa165cb2ca67012693707b8268457bacaa93116a        refs/heads/kotlin-step-2_cache-on-viewholder
724da71f0afd8e9beb37e0acf7d60216c1a33e75        refs/heads/master
b562d48c40e4620de3cc97acc91afd68a2db6a34        refs/heads/rxjava
aea3c173a796f218fa6856577475ec6aa5565508        refs/heads/rxjava-rxbinding
467185d0c280332775669180ac64bf88878f4d8f        refs/pull/2/head

 

 

2. $ git remote show [원격저장소명] : 모든 리모트 브랜치와 그 정보 출력

- '리모트 저장소의 URL'과 '추적하는 브랜치'들을 출력

- $ git pull 명령을 실행할 때, main 브랜치와 Merge할 브랜치가 무엇인지 보여 준다.

 

- ex) fork해 온 커니코들린 github의 리모트 정보 조회

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/sykim-ivy/kunny-kotlin-book.git
  Push  URL: https://github.com/sykim-ivy/kunny-kotlin-book.git
  HEAD branch: master
  Remote branches:
    arch-components-lifecycle         tracked
    arch-components-room              tracked
    arch-components-viewmodel         tracked
    dagger-step-1                     tracked
    dagger-step-2                     tracked
    java                              tracked
    kotlin-step-1                     tracked
    kotlin-step-2                     tracked
    kotlin-step-2_cache-on-viewholder tracked
    master                            tracked
    rxjava                            tracked
    rxjava-rxbinding                  tracked
  Local branches configured for 'git pull':
    java   merges with remote java
    master merges with remote master
  Local refs configured for 'git push':
    java   pushes to java   (up to date)
    master pushes to master (up to date)

 

 


 

 

 

사실, 리모트 Refs가 있지만 보통은 "리모트 트래킹 브랜치(Remote-tracking branch)"를 사용한다.

리모트 트래킹 브랜치(Remote-tracking branch)

 

"트래킹 브랜치(Tracking branch)"란??

 :  원격 브랜치를 로컬로 가져올 때 자동으로 생성되는 '원격 브랜치와 연결된 로컬 브랜치'

  - 리모트 브랜치와 직접적인 연결고리가 있는 '로컬 브랜치'이다.

 

  - Repository를 clone하면, 일반적으로 'origin/main'를 추적하는 'main' 브랜치가 자동으로 생성됩니다.

    그렇기 때문에 '$ git push'와 '$ git pull'은 별다른 매개변수 없이 바로 사용 가능함

 

 

 - 트래킹 브랜치에서 $ git push 명령 시 자동으로 원격 저장소와 브랜치를 알고 연결됨

 - 트래킹 브랜치에서 $ git pull 명령 시 자동으로 모든 원격 저장소가 업데이트되고 병합(merge)된다.

 

 +) 'Upstream 브랜치'

       : 트래킹하는 대상 브랜치 (=로컬 저장소와 연결된 원격 저장소) -> Q. 리모트 트래킹 브랜치가 upstream브랜치랑 같은 거 아닌가??

 

 


 


clone 시, 트래킹 브랜치를 직접 설정하기 

 : $ git clone -b <remote>/<RemoteTrackingBranchName> <RemoteURL>

(리모트를 origin 이 아닌 다른 리모트로 할 수도 있고, 브랜치도 master 가 아닌 다른 브랜치로 추적하게 할 수 있다.)

 

 


 

<RemoteTrackingBranchName>에 해당하는 'Upstream 브랜치'로 이동

 : $ git checkout <remote>/<RemoteTrackingBranchName> 

 cf) $ git checkout <LocalBranchName> : 브랜치 이동 (※생성 안함!)

 


'트래킹(Tracking) 브랜치' 생성과 이동 

  : $ git checkout -b <LocalTrackingBranchName> <remote>/<RemoteTrackingBranchName> 

- 생성된 로컬 브랜치의 'Upstream 브랜치'는 <RemoteTrackingBranchName>이다.
ㄴ> cf1) $ git branch <LocalBranchName> : 로컬 브랜치 생성 (※ 이동 안함!)

ㄴ> cf2) $ git push <remote> <AddingRemoteBranchName> : 원격 브랜치 생성

 

1) 리모트 브랜치와 다른 이름으로 로컬 브랜치를 만들려면 

 : $ git checkout -b <다르게 사용할 branch명> <remote>/<RemoteTrackingBranchName> 

: 리모트 브랜치와 다른 이름으로 브랜치를 만들려면 로컬 브랜치의 이름을 아래와 같이 다르게 지정한다. (ex2)
ㄴ> eX) $ git checkout -b <LocalNewBranchName> master : 원격 master를 기준으로 local에 새로운 branch 만들기

 

2) 브랜치 이름을 짓지 않고 remote 저장소의 브랜치 이름을 그대로 로컬 브랜치로 생성
: $ git checkout --t <remote>/<RemoteTrackingBranchName>

 - [-t 또는 --track 옵션]을 사용하면 된다. (ex1)

 


 

 

이미 로컬에 존재하는 브랜치가 리모트의 특정 브랜치를 추적하게 할 때 = upstream branch설정

: $ git branch -u <remote>/<RemoteTrackingBranchName>

  또는 $ git branch --set-upstream-to <remote>/<RemoteTrackingBranchName>

 

- $ git branch -u 나 --set-upstream-to 옵션 사용 (ex3)

- ★ remote repository로 push할 경우 처음에는 --set-upstream 옵션이 필요하다. 

  그냥 push할 경우, 로컬 저장소의 브랜치와 연결된 원격 저장소의 브랜치가 없어서 아래와 같이 오류가 발생함

>> fatal: The current branch master has no upstream branch. To push the current branch and set the remote as upstream, use git push --set-upstream origin master

 


 

'트래킹(Tracking) 브랜치' 현재 설정 확인 : $ git branch -vv


※ 중요) 명령을 실행했을 때 나타나는 결과는 모두 "마지막으로 서버에서 데이터를 가져온(fetch) 시점을 바탕으로 계산한다"는 점이다. 
           단순히 이 명령만으로는 서버의 최신 데이터를 반영하지는 않으며 로컬에 저장된 서버의 캐시 데이터를 사용한다. 
           최신 데이터로 추적 상황을 알아보려면 먼저 서버로부터 최신 데이터를 받아온 후에 추적 상황을 확인해야 한다. 

           그러므로 아래처럼 두 명령을 이어서 사용하는 것이 적당하다

$ git fetch --all
$ git branch -vv

 

- (ex4)

 


 

리모트 서버로부터 로컬 저장소 정보를 동기화

  : $ git fetch <Remote저장소명>

- Remote저장소 서버 주소 정보를 찾아서,

  로컬의 저장소가 갖고 있지 않은 새로운 정보가 있으면 모두 내려받고 받은 데이터를 로컬 저장소에 업데이트 후, 
  '<RemoteName>/<RemoteBranchName>'위치를 최신 커밋으로 이동시킨다.

 

 - ※주의★★)

   $git fetch 명령으로 "리모트 트래킹 브랜치를 내려받는다고 해서 로컬 저장소에 수정할 수 있는 브랜치가 새로 생기는 것이 아니다. "

 

 

▼ 위 주의사항을 꺽고 로컬 저장소에 수정할 수 있는 브랜치를 만들고 싶을 때


리모트 트래킹 브랜치에서 시작하는 로컬 브랜치 생성

  : $ git checkout -b <LocalTrackingBranchName> <Remote저장소명>/<Remote브랜치명>

- Merge 하지 않고 리모트 트래킹 브랜치에서 시작하는 로컬 브랜치 생성를 만들려면 아래와 같은 명령을 사용한다.

$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

 

ㄴ> 그러면 origin/serverfix 에서 시작하고 수정할 수 있는 serverfix 라는 로컬 브랜치가 만들어진다.

 

 



$git merge  : 현재 브랜치와 다른 브랜치를 병합할 때
$git rebase : 현재 브랜치의 commit을 다른 브랜치에 재배치

 

 


Ex) 트래킹 브랜치 사용하기 

 

ex1) 리모트 브랜치를 로컬에 가져오기 (checkout)
$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'


▼ 이 명령은 매우 자주 쓰여서 더 생략할 수 있다. 
입력한 브랜치가 있는 (a) 리모트가 딱 하나 있고 (b) 로컬에는 없으면 Git은 트래킹 브랜치를 만들어 준다.


$ git checkout serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'


ex2) 리모트 브랜치를 가져올 때 다른 이름으로 로컬 브랜치를 만들려면 
$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'

 

ㄴ> 이제 sf 브랜치에서 Push 나 Pull 하면 자동으로 origin/serverfix 로 데이터를 보내거나 가져온다.

 


ex3) 로컬에 존재하는 브랜치가 리모트의 특정 브랜치를 추적
$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.


ex4) 추적 브랜치가 현재 어떻게 설정되어 있는지 확인 
$ git branch -vv
  iss53     7e424c3 [origin/iss53: ahead 2] forgot the brackets
  master    1ae2a45 [origin/master] deploying index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
  testing   5ea463a trying something new


ㄴ> line2 :  iss53 브랜치는 origin/iss53 리모트 브랜치를 추적하고 있다.
'ahead' 표시를 통해 로컬 브랜치가 커밋 2개 앞서 있다(리모트 브랜치에는 없는 커밋이 로컬에는 존재)는 것을 알 수 있다. 
ㄴ> line3 :  `master 브랜치는 origin/master 브랜치를 추적하고 있으며 두 브랜치가 가리키는 커밋 내용이 같은 상태이다. 
ㄴ> line4 :  로컬 브랜치 중 serverfix 브랜치는 server-fix-good 이라는 teamone 리모트 서버의 브랜치를 추적하고 있으며 커밋 3개 앞서 있으며 동시에 커밋 1개로 뒤쳐져 있다. 
 이 말은 serverfix 브랜치에 서버로 보내지 않은 커밋이 3개, 서버의 브랜치에서 아직 로컬 브랜치로 머지하지 않은 커밋이 1개 있다는 말이다.
ㄴ> line5 : testing 브랜치는 추적하는 브랜치가 없는 상태이다.

 


 

 

리모트 트래킹 브랜치(Remote-tracking branch)

  : 로컬에 존재하는 리모트 브랜치를 추적하는 레퍼런스이며 브랜치.

    (영어 뜻 그대로 'Remote-tracking branch'로 일종의 북마크)

 

- 리모트 저장소에 마지막으로 연결했던 순간에 브랜치가 무슨 커밋을 가리키고 있었는지를 나타낸다.

 

- 로컬에 있지만 임의로 움직일 수 없다. 
  리모트 서버에 연결할 때마다 리모트의 브랜치 업데이트 내용에 따라서 자동으로 갱신될 뿐이다. 

 

- 브랜치의 이름 형식 

<RemoteName>/<RemoteBranchName>

ㄴ> ex1) 리모트 저장소 origin 의 master 브랜치를 보고 싶다면?

∴ origin/master 라는 이름으로 브랜치를 확인


ㄴ> ex2) 다른 팀원과 함께 어떤 이슈를 구현할 때 그 팀원이 iss53 브랜치를 서버로 Push 했고 당신도 로컬에 iss53 브랜치가 있다고 가정하자. 이때 서버의 iss53 브랜치가 가리키는 커밋은 로컬에서의 명칭은??

origin/iss53

 



- Ex3) GitPro의 리모트 Ref 예제  

 

ⓐ git.ourcompany.com 이라는 Git 서버가 있고, 이 서버의 저장소를 하나 Clone 하면 Git은 자동으로 'origin' 이라는 이름을 붙인다.

    'origin' 으로부터 저장소 데이터를 모두 내려받고 'master' 브랜치를 가리키는 포인터를 만든다. 
    이 포인터는 origin/master 라고 부르고 멋대로 조종할 수 없다. 

    그리고 Git은 로컬의 master 브랜치가 origin/master 를 가리키게 한다. 

그림 30. Clone 이후 서버와 로컬의 master 브랜치
 


ⓑ 로컬 저장소에서 어떤 작업을 하고 있는데 동시에 다른 팀원이 git.ourcompany.com 서버에 Push 하고 master 브랜치를 업데이트한다. 
    그러면 이제 팀원 간의 히스토리는 서로 달라진다. 

    서버 저장소로부터 어떤 데이터도 주고받지 않아서 origin/master 포인터는 그대로다.


그림 31. 로컬과 서버의 커밋 히스토리는 독립적임

$ git fetch origin 명령을 사용하여 원격 저장소 반영사항을 로컬에 가져온다.

그림 32. git fetch 명령은 리모트 브랜치 정보를 업데이트

ⓓ 로컬에 리모트 저장소를 하나 더 추가.

리모트 저장소를 여러 개 운영하는 상황을 이해할 수 있도록 개발용으로 사용할 Git 저장소를 팀 내부에 하나 추가해 보자. 

이 저장소의 주소가 git.team1.ourcompany.com 이며 'ch2.1 Git의 기초'에서 살펴본 

$ git remote add <이름> <원격 URL> 명령으로 현재 작업 중인 프로젝트에 팀의 저장소를 추가
이름을 teamone 으로 짓고 긴 서버 주소 대신 사용한다.

 

그림 33. 서버를 리모트 저장소로 추가 https://git-scm.com/book/en/v2/images/remote-branches-4.png


$ git fetch teamone 명령으로 teamone 서버의 데이터를 내려받는다. 
※ 이 예제의 경우, 명령을 실행해도 teamone 서버의 데이터는 모두 origin 서버에도 있는 것들이라서 아무것도 내려받지 않는다.

     (teamone브랜치가 master 브랜치의 이전 커밋을 가리키므로) 
    하지만, 이 명령은 리모트 트래킹 브랜치 teamone/master 가 teamone 서버의 master 브랜치가 가리키는 커밋을 가리키게 한다.

 

그림 34. teamone/master 의 리모트 트래킹 브랜치 https://git-scm.com/book/en/v2/images/remote-branches-5.png

 

 

 

 

 

 



 

 


 

END!

 

 


스터디 도움 참조 블로그 (References)

- Refs
http://ghcksdk.com/git-master%EC%97%90%EC%84%9C-branch%EB%A1%9C-pull-%ED%95%98%EA%B8%B0-git-refs/

- git ls-remote
https://runebook.dev/ko/docs/git/git-ls-remote
https://nochoco-lee.tistory.com/30

- git Remote 저장소 관련
https://thisblogbusy.tistory.com/entry/Git-Basics-Working-with-Remotes

- 3.5 Git 브랜치 
https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%A6%AC%EB%AA%A8%ED%8A%B8-%EB%B8%8C%EB%9E%9C%EC%B9%98

- What is a tracking branch?
https://stackoverflow.com/questions/4693588/what-is-a-tracking-branch
https://stackoverflow.com/a/4693780

- tracking branch
 https://jw910911.tistory.com/16


- What is a tracking branch?
https://stackoverflow.com/a/4693780


- Git Remote Tracking Branch and Upstream Branch are different ?
https://stackoverflow.com/questions/62137200/git-remote-tracking-branch-and-upstream-branch-are-different


- [Git] branch 관련 명령어 모음(생성, 관리, 삭제)
https://developerntraveler.tistory.com/62



- git--distributed-even-if-your-workflow-isnt (Pro Git Book)
https://git-scm.com/book/en/v2

 

 

 

반응형