회사 동기에게 깃 도움 요청을 받았다. 브랜치 switch를 못하고 있다고 한다. 궁금해서 다같이 구글밋에 모여서 해결방법을 찾았다.
현재 a브랜치에 있는데 b브랜치로 switch를 하고 싶지만 못하고 있었다.
git switch b
를 실행해서 에러를 확인해보았다. fatal: invalid reference: step3
브랜치가 로컬에 없는 것 같았다. --single-branch
로 받은 게 문제였다. a 브랜치만 받아서 b가 로컬에 없기 때문에 switch를 못하는 것 같다.git branch -r
을 확인해봤다. b 브랜치가 없었다...git checkout -t origin/b
를 실행했더니 fatal: 'origin/b' is not a commit and a branch 'b' cannot be created from it
에러가 떴다. git remote set-branches --add 'origin' 'newbranch'
git fetch 'origin'
git checkout --track 'origin/newbranch'
바로바로 찾아서 해결은 했지만 내가 부족한 부분은 있었다
--single-branch
로 받았을 때 왜 원격 브랜치 리스트를 못 봤을까??checkout -t
가 어떤 동작을 할까?저장소에 하나의 브랜치만 받을 경우 사용하는 옵션이다. 뒤에 브랜치 명을 적어주면 브랜치 하나만 받아온다.
그런데 이렇게 받아오면 왜 원격 브랜치 리스트는 못 보는지 모르겠다. git branch -r
은 로컬과 연결된 원격 브랜치의 리스트만 보여줘서 그런가?
찾아보니 -r
옵션은 Option -r causes the remote-tracking branches to be listed
remote에 있는 브렌치가 아니라 remote를 트레킹하는 (원격이랑 연결된 로컬 브랜치인듯) 브랜치의 리스트를 보여준다. 지금은 a브랜치만 원격이랑 연결돼서 안 보이는 것 같다.
그럼 origin에 있는 모든 브랜치의 리스트는 못 보는 걸까? - 찾아보니 없는 것 같다..
git clone
으로 바로 받아올 수 있는 방법은 없다.
git clone
은 여러 과정으로 되어 있는데, 크게 아래 과정으로 이루어진다. (실제로는 6단계)
1. git init
2. git remote add
3. git fetch
4. git checkout
여기서 git remote add
로 여러 브랜치를 받아올 수 있다.
또는 --single-branch
로 받아온 다음 git remote set-branches origin
으로 남은 브랜치를 받아올 수 있다. (우리가 해결한 방법)
--single-branch
를 찾아보다가 이 옵션을 해제하고 다시 전체 브렌치를 받아오고 싶다면 이 명령어를 치고 git config remote.origin.fetch refs/heads/*:refs/remotes/origin/*
다음으로 git fetch
를 하라고 한다. git config
는 잔디 설정이 안 될 때 이름이랑 이메일 설정하려고 건드린 적 있었는데 remote.origin.fetch
이 복잡한 설정은 무엇인가...! 너무 심연을 본 것 같지만 그래도 가보도록 하자. 이걸 참고해서 알아봤다.
git remote 설정은 Refspec이라 한다. 로컬 깃 저장소를 사용하다가 origin이라는 리모트 저장소를 지정하려면 이렇게 실행한다.
git remote add origin https://github.com/schacon/simplegit-progit
이 명령은 origin
이라는 저장소 이름, URL, Fetch할 Refspec을 .git/config
파일에 추가한다. 설정파일을 열어보면 이렇게 저장되어 있다.
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/*:refs/remotes/origin/*
이제 우리가 봤던 fetch 형식이 나온다. fetch는 +
와 <src>:<dest>
로 되어있다. <src>
는 리모트 저장소의 Refs 패턴이고 <dest>
는 로컬 저장소의 Refs 패턴이다.
--single-branch
로 클론받은 레포의 설정파일을 보면 이렇게 되어 있다.
전체 브랜치를 연결시키지 않고 딱 설정한 브랜치만 연결되었다. 이래서 이거 하나만 받아오는구나. 아 복잡하다!
git remote set-branches --add 'origin' 'newbranch'
git fetch 'origin'
git checkout --track 'origin/newbranch'
git remote set-branches
는 뭔지 아직 못 찾았다. 직접 해보니 Refspec이 바뀌는 건 아니고 config 파일에 [branch] 옵션이 새로 생겼다. 이걸로 브랜치 자체를 추가한 것 같다. (아니 그런데 Ref에는 왜 추가가 안 되지)
그 다음 fetch로 로컬에 없는 데이터 받아오고
git checkout --track origin/serverfix
으로 로컬 브랜치 이름을 자동으로 생성할 수 있다. origin 정보 받아온 다음 origin/브랜치로 바로 원격 브랜치랑 연결되는 로컬 브랜치를 만든 것 같다.
그래도 git HEAD 때서 분리하고 시간도 왔다갔다거리고 많이 알고있다 생각했는데 그래도 모르는 부분이 많다고 느꼈다. 특히 config 관련된 것들... 언젠가 공부해봐야지