모든 원격 자식 분기를 로컬 분기로 추적


175

단일 원격 지점을 로컬 지점으로 추적하는 것은 간단합니다.

$ git checkout --track -b ${branch_name} origin/${branch_name}

모든 로컬 브랜치를 원격으로 푸시하고 필요에 따라 새 원격 브랜치를 생성하는 것도 쉽습니다.

$ git push --all origin

나는 반대로하고 싶다. 단일 소스에 X 개의 원격 분기가있는 경우 :

$ git branch -r 
branch1
branch2
branch3
.
.
.

각 원격 지점을 수동으로 만들 필요없이 모든 원격 지점에 대해 로컬 추적 지점을 만들 수 있습니까? 다음과 같이 말하십시오 :

$ git checkout --track -b --all origin

나는 구글과 RTM을 봤지만 지금까지 이단했다.


3
단일 원격 지점을 로컬 지점으로 추적하는 훨씬 간단한 방법이 있습니다.git checkout --track origin/branchname
Cerran

이것은 당신이 무엇을 요구 정확히 아니지만, 나를 위해 작동 : 자식 완료를 얻을 : github.com/git/git/blob/master/contrib/completion/... . 그런 다음git pull origin 하고 눌러서 tab원격 분기 목록을 가져 오십시오. 그런 다음 계속 입력하고을 누르십시오 return.
Max Heiber

답변:


111

bash 사용 :

자식 1.9.1 이후
for i in `git branch -a | grep remote | grep -v HEAD | grep -v master`; do git branch --track ${i#remotes/origin/} $i; done

크레딧 : Val Blant, elias 및 Hugo

자식 1.9.1 이전

참고 : 이후 버전의 git (> v1.9.1) 버전에서 사용되는 경우 다음 코드는

  1. (버그) 마스터를 추적하기 위해 생성 된 모든 브랜치
  2. (불쾌) 접두사가 붙일 모든 작성된 로컬 브랜치 이름 origin/
for remote in `git branch -r `; do git branch --track $remote; done

로컬 추적 분기에 변경 사항이 없다고 가정하고 분기를 업데이트하십시오.

for remote in `git branch -r `; do git checkout $remote ; git pull; done

모호한 참조 이름 경고를 무시하십시오 .git은 로컬 브랜치를 선호하는 것처럼 보입니다.


2
refname 경고에 대한 의견을 보내 주셔서 감사합니다. 도움이되었습니다.
Paul

1
고마워 오토, 나는 스크립팅이 유일한 해결책이라고 생각했다. 당신은 매우 간단한 것을 제공했습니다.
Janson

1
@Jason은 여전히 ​​오늘날 유일한 솔루션을 스크립팅합니까?
cregox

1
@Cawas : 추적 분기를 수동으로 만들어야하지만 모든 추적 분기를 가져오고 병합 git pull하는 --all스위치가 있습니다.
naught101

13
이것은 Git 1.9.1에서 작동하지 않았습니다. "git branch --track <banch_name>"은 원하는 원격 브랜치 대신 로컬 브랜치 마스터를 추적하는 새로운 브랜치 <branch_name>을 만듭니다. 따라서이 스크립트는 로컬 마스터를 가리키는 많은 로컬 브랜치를 만들었습니다. 아래에 솔루션을 게시하겠습니다.
발 블런트

183

오토 (Otto)의 답변은 훌륭하지만, 생성 된 모든 브랜치는 이름의 시작으로 "origin /"을 갖습니다. 마지막 부분 (마지막 / 뒤)을 결과 분기 이름으로 사용하려면 다음을 사용하십시오.

for remote in `git branch -r | grep -v /HEAD`; do git checkout --track $remote ; done

또한 모호한 참조에 대해 경고하지 않는 이점이 있습니다.


힘내 로컬 추적 지점 이름에 "원산지"를 추가하지 않습니다.
Adam Dymitruk

14
@adymitruk : 실제로 그것은 git 1.7.2.2 (이 주석의 최신 안정)를 사용하여 OSX 10.6.4에서 나에게 말한대로 정확하게 작동합니다. 오토 (Otto)는 모호한 참조 이름 경고를 언급하기도합니다. "origin /"이 각 로컬 브랜치 이름의 일부가 아닌 경우 경고가 존재하지 않아도됩니다. 다음은 오토 명령을 실행 한 후의 'git branch'출력입니다 : [master, origin / HEAD, origin / charts, origin / master, origin / production, origin / staging]. 그리고 내 명령 : [차트, 마스터, 생산, 준비].
tjmcewan


8
동의합니다. 이것은 현재 "허용 된"답변보다 더 나은 솔루션입니다.
tobias.mcnulty

2
대신 grep -v mastergrep -v /HEAD어떻습니까? 이것은 커스터마이즈없이 기본 브랜치를 걸러내는 것 같습니다
dashrb

22

여기에 대한 답변의 대부분은의 출력 구문 분석을 복잡하게 만듭니다 git branch -r. 다음을 사용할 수 있습니다for 루프를 사용하여 리모컨의 모든 분기에 대해 추적 분기를 만들 .

이 원격 지점이 있다고 가정 해보십시오.

$ git branch -r
  origin/HEAD -> origin/master
  origin/development
  origin/integration
  origin/master
  origin/production
  origin/staging

로컬에서 이미 마스터 이외의 것을 추적하고 있지 않은지 확인하십시오.

$ git branch -l    # or using just git branch
* master

이 하나의 라이너를 사용하여 추적 분기를 만들 수 있습니다.

$ for i in $(git branch -r | grep -vE "HEAD|master"); do 
    git branch --track ${i#*/} $i; done
Branch development set up to track remote branch development from origin.
Branch integration set up to track remote branch integration from origin.
Branch production set up to track remote branch production from origin.
Branch staging set up to track remote branch staging from origin.

이제 확인하십시오 :

$ git branch
  development
  integration
* master
  production
  staging

삭제하려면 :

$ git br -D production development integration staging 
Deleted branch production (was xxxxx).
Deleted branch development (was xxxxx).
Deleted branch integration (was xxxxx).
Deleted branch staging (was xxxxx).

-vv스위치를 사용하면 git branch다음을 확인할 수 있습니다.

$ git br -vv
  development xxxxx [origin/development] commit log msg ....
  integration xxxxx [origin/integration] commit log msg ....
* master      xxxxx [origin/master] commit log msg ....
  production  xxxxx [origin/production] commit log msg ....
  staging     xxxxx [origin/staging] commit log msg ....

for 루프 분석

루프는 기본적으로 명령을 호출 git branch -r하여를 사용하여 출력에서 ​​HEAD 또는 마스터 분기를 필터링합니다 grep -vE "HEAD|master". 분기의 이름에서 origin/하위 문자열을 뺀 값을 얻으려면 Bash의 문자열 조작을 사용하십시오 ${var#stringtoremove}. 변수 "stringtoremove"문자열이 제거됩니다 $var. 이 경우 origin/변수 에서 문자열 을 제거합니다 $i.

참고 : 또는 git checkout --track ...이 작업을 수행 할 수도 있습니다 .

$ for i in $(git branch -r | grep -vE "HEAD|master" | sed 's/^[ ]\+//'); do 
    git checkout --track $i; done

그러나 나는이 방법에 관심이 없습니다. 체크 아웃을 수행 할 때 지점 사이를 전환하기 때문입니다. 완료되면 마지막으로 생성 한 지점으로 이동합니다.

참고 문헌


1
git 버전 2.3.2 (Apple Git-55)와 완벽하게 작동
AndrewD

22

2020 년 1 분기 업데이트 : Mohsen Abasi 는 2014 년 slm답변을 기반으로 한 간단한 대안으로 의견을 제안합니다 .

for i in $(git branch -r | grep -vE "HEAD|master" | sed 's/^[ ]\+//'); 

그리고 사용 $()되지 않는 역 따옴표 대신 합니다.

다른 오래된 대답 에서 언급했듯이 사용 속도git for-each-ref더 빠를 것 입니다.
그리고 새로운 (Git 2.23+) git switch명령 을 사용하여 혼란git checkout 을 대체합니다 .

for i in $(git for-each-ref --format=%(refname:short) \
  --no-merged=origin/HEAD refs/remotes/origin); do \
    git switch --track $i; \
done

그렇게하지 grep않아도됩니다.


Old (2011) 원래 답변 :

다음은 내가 사용하는 하나의 라이너입니다 (bash 쉘에서 msysgit1.7.4로 테스트 됨).

복사 붙여 넣기의 경우 :

remote=origin ; for brname in `git branch -r | grep $remote | grep -v master | grep -v HEAD | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do git branch --set-upstream-to $remote/$brname $brname; done

가독성을 높이려면 :

remote=origin ; // put here the name of the remote you want
for brname in `
    git branch -r | grep $remote | grep -v master | grep -v HEAD 
    | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'
`; do 
    git branch --set-upstream-to $remote/$brname $brname; 
done
  • remote변수에 지정한 리모콘에서 업스트림 분기 만 선택 합니다 ( 'origin '또는 현재 Git 저장소의 리모콘 중 하나에 설정 한 이름이 ).
  • 지점의 이름을 추출합니다 origin/a/Branch/Name => a/Branch/Name.awk표현식을 .
  • 그것은 업스트림 지점을 통해 설정합니다--set-upstream-to (또는 -u) 하지 --track:
    장점은 즉, 지점이 이미 존재하는 경우, 그것은 실패하지 않습니다하고 해당 분기 원점을 변경되지 않습니다, 그것은 단지 구성하는 것입니다 branch.xxx.(remote|merge)설정을.

    branch.aBranchName.remote=origin
    branch.aBranchName.merge=refs/heads/a/Branch/Name
    

이 명령은 모든 원격 업스트림 브랜치에 대한 로컬 브랜치를 만들고 원격 및 병합 설정을 해당 원격 브랜치로 설정합니다.


5
이것은 원격에만 존재하고 해당 로컬 분기가없는 모든 분기에 대해 "치명적인 : '무엇이'존재하지 않는 분기"를 제공합니다.
Chris Dodd

지점 이름에 /가 포함되어 있다고 생각합니다 : feature / rc-41-bckend,이 솔루션은 작동하지 않습니다!
Mohsen Abasi

@VonC "slm"의 답을 기반으로 함 : $ (git branch -r | grep -vE "HEAD | master"| sed 's / ^ [] \ + //'); git checkout --track $ i; 수행
모흐센 Abasi

@MohsenAbasi 좋아 보인다. 내 대답에서는 그래도 --set-upstream-to대신 사용 을 언급했습니다 --track.
VonC

@MohsenAbasi 나는 더 많은 가시성을 위해 당신의 대안을 대답에 포함시켰다. 원격 브랜치를 나열하는 다른 가능한 방법을 추가하고 git switch대신 사용하십시오 git checkout. 그러나 (아주 좋은) 아이디어는 남아 있습니다.
VonC

14

충분히 쉽게 스크립트를 작성할 수는 있지만 언제 가치가 있는지 모르겠습니다. 그 지점은 꽤 빨리 뒤쳐져 서 항상 업데이트해야합니다.

원격 지점은 자동으로 최신 상태로 유지되므로 실제로 작업하려는 지점에서 로컬 지점을 만드는 것이 가장 쉽습니다.


2
그건 좋은 지적이야. 내가 생각하는 주요 유스 케이스는 원격 자식 저장소를 기반으로 로컬 개발 환경을 설정하는 것입니다. 따라서 초기 복제를 수행 할 때 모든 원격 브랜치를 해당 시점에 추적하고 싶습니다.
Janson

1
편리한 git up모든 로컬 지점을 업데이트합니다.
휴고


9
for i in `git branch -a | grep remote`; do git branch --track ${i#remotes/origin/} $i; done

4
| grep -v HEAD제대로 작동하려면 파이프 라인에을 추가 해야했습니다.
Elias Dorneles 2016 년

9

스크립팅없이 (빈 디렉토리에) :

$ git clone --bare repo_url .git
$ git config core.bare false
$ git checkout

그 후에는 모든 원격 지점이 로컬로 표시됩니다.


원본 (러시아어) .


이것은 지금까지 가장 간단한 솔루션이며 2.21.0.windows.1에서 작동했습니다.
Rotsiser Mho

7

Powershell을 사용하고 리모컨을 원점이라고합니다. 그런 다음 작동합니다.

git fetch    
git branch -r  | %{$_ -replace "  origin/"} | %{git branch --track $_ "origin/$_"}

이것은 매우 도움이되었고, 약간의 변형을 사용하여 내 git svn clone'd저장소 와 작동하게되었습니다 .git branch -r | %{$_ -replace " origin/"} | %{git checkout -b $_ "origin/$_"}
Nate

지역 지사가 이미 존재하기 때문에 약간의 변형을했습니다.git branch -r | %{$_ -replace " origin/"} | %{git branch -u "origin/$_" $_}
ch271828n

3
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do  git branch --track ${branch##*/} $branch; done

이것을 사용하면 다음과 같은 경고가 표시되지 않습니다. refname 'origin / dev'is ​​ambiguous


3

@tjmcewan이 참조하는 BASH 명령의 솔루션은 다음과 같습니다.

for remote in `git branch -r | grep -v /HEAD `; do git branch --track ${remote/"origin/"/""}; done

내 목표는 $ remote 변수에 여전히 "origin /"이 포함되어 있는지 테스트했기 때문에 작성된 모든 브랜치의 이름 시작 부분에 "origin /"이라는 문제를 해결하는 것입니다.

for remote in `git branch -r | grep -v /HEAD`; do echo $remote ; done

@tjmcewan의 BASH를 테스트 한 후 현지에서 'origin /'이없는 모든 추적 된 지점 이름을 찾았습니다. 왜 그런지 모르겠습니다.
Nick Tsai

1
첫 번째 명령은 "마스터"를 추적하는 brance를 생성합니다. 그것은 대부분의 사람들이 원하는 것이 아닙니다.
Alexei Osipov

트윗 담아 가기
Nick Tsai

2

tjmcewan의 답변 과 동일 하지만 Windows에서는 다음을 배치 파일 에서 호출 하십시오 .

for /f "delims=" %%r in ('git branch -r ^| grep -v master') do git checkout --track %%r

또는 명령 줄에서 :

for /f "delims=" %r in ('git branch -r ^| grep -v master') do git checkout --track %r

1

자식 2.23부터 :

for branch in `git branch -r | grep origin/`; do git switch -t -C ${branch#origin/} $branch; git pull; done

-C에 대한 플래그를 git switch만들거나 재설정이 이미 존재하는 경우.

자식 스위치 설명서


0

이미 일부 지점을 체크 아웃하고 싶어하는 경우

  • 리모컨에서 남은 가지를 모두 확인하십시오
  • 모든 지역 지점이 원격 지점을 추적하는지 확인하십시오

다음 bash 및 zsh 호환 스크립트를 사용할 수 있습니다.

git branch -r | while read b; do if git branch | grep -q " ${b##*/}$"; then git branch --set-upstream ${b##*/} $b; else git branch --track ${b##*/} $b; fi; done

0
for rembranch in `git remote update 2>&1 > /dev/null ; git branch -r|egrep -wv "HEAD|master"`
do 
    git checkout --track -b `echo $rembranch|awk -F\/ '{print $2}'` $rembranch; 
done

설명:

1 행 : 'git branch -r'(원격 변경에 대한 정보를 업데이트하기 위해 'git remote update'가 뒤 따름)은 모든 원격 브랜치를 나열합니다. 'egrep -vw'는 결과에 HEAD 및 마스터가있는 항목을 노크하는 데 사용됩니다.

3 행 : 명명 된 원격 지점을 로컬로 체크 아웃하면서 추적합니다. 간단한 awk는 'origin /'이 지역 브랜치의 접미사임을 피하기 위해 사용됩니다.


0

모든 분기를 체크 아웃하려면 bash를 사용하십시오.

for remote in `git branch -r`; do git checkout $(echo $remote | cut -d'/' -f 2); done

새로운 원격 추적 분기를 가져 오는 가져 오기를 수행 할 때 로컬에서 편집 가능한 로컬 사본이 자동으로 생성되지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.