Làm thế nào để sao chép tất cả các chi nhánh từ xa trong Git?


4129

Tôi có một mastervà một developmentchi nhánh, cả hai đều được đẩy lên GitHub . Tôi đã cloned, pulled và fetched, nhưng tôi vẫn không thể lấy lại được gì ngoài masterchi nhánh.

Tôi chắc chắn rằng tôi đang thiếu một cái gì đó rõ ràng, nhưng tôi đã đọc hướng dẫn và tôi không nhận được niềm vui nào cả.


133
Câu trả lời được chấp nhận ở đây ( git branch -a) hiển thị cho bạn các nhánh trong điều khiển từ xa, nhưng nếu bạn cố kiểm tra bất kỳ câu nào trong số đó, bạn sẽ ở trạng thái 'Tách rời'. Câu trả lời tiếp theo (phần lớn upvote thứ hai) trả lời một câu hỏi khác (để dí dỏm: làm thế nào để kéo tất cả các nhánh và, một lần nữa, điều này chỉ hoạt động cho những người bạn đang theo dõi cục bộ). Một số ý kiến ​​chỉ ra rằng bạn có thể phân tích git branch -akết quả bằng một tập lệnh shell sẽ theo dõi cục bộ tất cả các nhánh từ xa. Tóm tắt: Không có cách riêng nào để thực hiện những gì bạn muốn và dù sao thì đó cũng không phải là một ý tưởng tuyệt vời.
Ngày Davis Waterbury

5
Có lẽ chỉ cần sao chép toàn bộ thư mục theo cách cũ? scp some_user@example.com:/home/some_user/project_folder ~Không chắc chắn nếu giải pháp đó hoạt động cho github mặc dù ..
snapfractalpop

19
Thay vì nói "Tôi đã nhân bản, kéo và tìm nạp", tốt hơn nhiều là cho chúng tôi thấy các lệnh chính xác mà bạn đã thực hiện.
Bob Gilmore

57
Nó luôn làm tôi khó hiểu tại sao "bản sao" không có nghĩa là một bản sao chính xác. Nếu đó là một bản sao chính xác, tất cả các nhánh không phải là một phần của kho lưu trữ cục bộ? Tôi có nghĩa là không phải là một trong những điểm được phân phối? Vì vậy, khi một cái gì đó kho lưu trữ đã biến mất, bạn vẫn có một bản sao hoàn chỉnh của tất cả mọi thứ. Hay nó được gọi là "từ xa" thực sự là một phần của kho lưu trữ cục bộ?
huggie

21
Nhìn thấy tất cả các upvote, câu trả lời, nhận xét về câu trả lời và số lượt xem không đáng kể, tôi nghĩ rằng đã đến lúc git thêm một lệnh để làm điều này. Và đúng bạn là @huggie, suy nghĩ của tôi chính xác.
Sнаđошƒаӽ

Câu trả lời:


4557

Đầu tiên, sao chép một kho lưu trữ Git từ xa và cd vào nó:

$ git clone git://example.com/myproject
$ cd myproject

Tiếp theo, hãy xem các nhánh cục bộ trong kho lưu trữ của bạn:

$ git branch
* master

Nhưng có những nhánh khác ẩn trong kho của bạn! Bạn có thể thấy những điều này bằng cách sử dụng -acờ:

$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/master
  remotes/origin/v1.0-stable
  remotes/origin/experimental

Nếu bạn chỉ muốn xem nhanh tại một chi nhánh thượng nguồn, bạn có thể kiểm tra trực tiếp:

$ git checkout origin/experimental

Nhưng nếu bạn muốn làm việc trên nhánh đó, bạn sẽ cần tạo một nhánh theo dõi cục bộ được thực hiện tự động bằng cách:

$ git checkout experimental

và bạn sẽ thấy

Branch experimental set up to track remote branch experimental from origin.
Switched to a new branch 'experimental'

Dòng cuối cùng ném một số người: "Chi nhánh mới" - hả? Điều thực sự có nghĩa là chi nhánh được lấy từ chỉ mục và được tạo cục bộ cho bạn. Dòng trước thực sự có nhiều thông tin hơn vì nó cho bạn biết rằng nhánh đang được thiết lập để theo dõi nhánh từ xa, thường có nghĩa là nhánh origin / Branch_name

Bây giờ, nếu bạn nhìn vào các chi nhánh địa phương của bạn, đây là những gì bạn sẽ thấy:

$ git branch
* experimental
  master

Bạn thực sự có thể theo dõi nhiều hơn một kho lưu trữ từ xa bằng cách sử dụng git remote.

$ git remote add win32 git://example.com/users/joe/myproject-win32-port
$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/master
  remotes/origin/v1.0-stable
  remotes/origin/experimental
  remotes/win32/master
  remotes/win32/new-widgets

Tại thời điểm này, mọi thứ đang trở nên khá điên rồ, vì vậy hãy chạy gitkđể xem những gì đang diễn ra:

$ gitk --all &

119
Làm thế nào ai đó có thể tự động tạo tất cả các nhánh từ xa, ví dụ thử nghiệm cho nguồn gốc / thử nghiệm?
Cristian Ciupitu

54
Cristian: Tôi đã luôn tạo ra một nhánh 'foo' cho mỗi nhánh 'origin / foo', nhưng điều này dẫn đến hai vấn đề: (1) Tôi đã khắc phục rất nhiều nhánh theo dõi thực sự cũ mà nhiều cam kết đằng sau nhánh từ xa tương ứng và (2) trong các phiên bản cũ hơn của git, chạy 'git đẩy' sẽ cố gắng đẩy tất cả các nhánh địa phương của tôi đến một điều khiển từ xa, ngay cả khi các nhánh đó đã cũ. Vì vậy, bây giờ tôi chỉ giữ các chi nhánh địa phương cho những thứ mà tôi đang tích cực phát triển và truy cập trực tiếp vào các nhánh / * nếu tôi cần thông tin về chúng. (Điều đó nói rằng, bạn có thể sử dụng tập lệnh shell để phân tích 'git chi nhánh -a'.)
emk

49
"Git fetch <origin-name> <Branch-name>" mang chi nhánh xuống cho bạn.

137
Câu trả lời tốt, nhưng hơi nhớ câu hỏi. Tôi đang tìm kiếm một lớp lót để kiểm tra tất cả các chi nhánh từ xa.
cmcginty

32
Câu hỏi là về nhân bản tất cả các chi nhánh từ xa, không kiểm tra chúng. Và, như tôi đã lưu ý ở trên, bạn thực sự không muốn tạo ra nhiều nhánh theo dõi cục bộ hơn mức cần thiết, bởi vì khi chúng thực sự cũ, chúng có thể gây đau đầu.
emk

822

Nếu bạn có nhiều nhánh từ xa mà bạn muốn tìm nạp cùng một lúc, hãy làm:

$ git pull --all

Bây giờ bạn có thể kiểm tra bất kỳ chi nhánh nào bạn cần, mà không cần nhấn kho lưu trữ từ xa.


12
Nếu tôi làm git clone, tôi có nhánh chính cục bộ và 10 nhánh "từ xa". Vì vậy, câu trả lời NÀY của Gabe rất hữu ích và trả lời câu hỏi.
basZero

38
điều này chỉ tìm nạp các nhánh từ xa đã được thêm cục bộ chứ không phải bất kỳ nhánh từ xa nào
jujule

33
Lệnh đầu tiên là dự phòng. Đơn giản là git pull --allsẽ làm tương tự - nó sẽ không lấy hai lần. Và infosec812 đúng rằng điều này không trả lời câu hỏi nào. Tôi tự hỏi làm thế nào điều này có rất nhiều upvote.
Sven Marnach

6
Sau khi tôi làm git remote update, sau đó thử git branch, tôi chỉ thấy các chi nhánh địa phương. Nhưng nếu tôi làm git branch -abây giờ tôi có thể thấy các chi nhánh từ xa và tôi có thể làm một git pull <branchname>để có được chi nhánh tôi muốn. - Tôi đã trả lời câu hỏi này từ một tìm kiếm Google và câu trả lời này giải quyết vấn đề của tôi.
WNRosenberg

38
Điều này không hữu ích chút nào, không kéo bất kỳ chi nhánh từ xa nào khác ngoài điều đó hiện có.
Avinash R

446

Kịch bản Bash này đã giúp tôi hiểu:

#!/bin/bash
for branch in $(git branch --all | grep '^\s*remotes' | egrep --invert-match '(:?HEAD|master)$'); do
    git branch --track "${branch##*/}" "$branch"
done

Nó sẽ tạo các nhánh theo dõi cho tất cả các nhánh từ xa, ngoại trừ master (mà bạn có thể đã nhận được từ lệnh clone gốc). Tôi nghĩ rằng bạn có thể vẫn cần phải làm một

git fetch --all
git pull --all

để chắc chắn.

Một lớp lót : git branch -a | grep -v HEAD | perl -ne 'chomp($_); s|^\*?\s*||; if (m|(.+)/(.+)| && not $d{$2}) {print qq(git branch --track $2 $1/$2\n)} else {$d{$_}=1}' | csh -xfs
Như thường lệ: kiểm tra thiết lập của bạn trước khi sao chép vũ trụ rm -rf như chúng ta biết

Tín dụng cho một lớp lót cho người dùng cfi


19
Điều này thực sự gần như là một giải pháp hoàn hảo .. Điều duy nhất sẽ làm cho nó tốt hơn là nếu chức năng này được tích hợp như một tùy chọn trong git.
Deven Phillips

51
"Một lớp lót": git branch -a | grep -v HEAD | perl -ne 'chomp($_); s|^\*?\s*||; if (m|(.+)/(.+)| && not $d{$2}) {print qq(git branch --track $2 $1/$2\n)} else {$d{$_}=1}' | csh -xfs Như thường lệ: kiểm tra thiết lập của bạn trước khi sao chéprm -rf universe as we know it
cfi

4
Lệnh này tạo các nhánh tính năng từ xa như các nhánh thông thường (không phải các nhánh tính năng) - làm thế nào để khắc phục điều này?
Alex2php

4
nếu bạn gặp vấn đề với "/" trong tên nhánh, có một giải pháp bên dưới bằng cách sử dụng bí danh git. xem câu trả lời của "không ai" trên "đã trả lời ngày 15 tháng 5 năm 13 lúc 11:02"
wemu

8
Tôi cắt tỉa chỉ remotes/origin/để giữ nguyên không gian tên:for BRANCH in $(git branch -a | grep remotes | grep -v HEAD | grep -v master); do git branch --track "${BRANCH#remotes/origin/}" "${BRANCH}"; done
kgadek

348

Sử dụng --mirrortùy chọn dường như sao chép các remotenhánh theo dõi đúng cách. Tuy nhiên, nó thiết lập kho lưu trữ dưới dạng một kho lưu trữ trần, vì vậy bạn phải biến nó trở lại thành một kho lưu trữ bình thường sau đó.

git clone --mirror path/to/original path/to/dest/.git
cd path/to/dest
git config --bool core.bare false
git checkout anybranch

Tham khảo: Git FAQ: Làm cách nào để sao chép kho lưu trữ với tất cả các nhánh được theo dõi từ xa?


7
Bạn biết điều này thực sự có vẻ là một câu trả lời khá tốt mặc dù nó không có phiếu bầu. Có bất kỳ cạm bẫy để làm điều đó theo cách đó? Tôi đã phải kiểm tra rõ ràng một chi nhánh sau khi chạy các lệnh đó.
vòng

27
Điều này kết hợp với git đẩy --mirror chính xác là những gì tôi cần để tạo một bản sao chính xác của repo git từ xa khi chuyển từ github.com sang cài đặt doanh nghiệp github. Cảm ơn!
Jacob Fike

3
@Dave: Thêm một git checkoutlệnh cuối cùng là lệnh cuối cùng để kiểm tra phần đầu của nhánh hiện tại trên repo nhân bản. Đây là một câu trả lời tuyệt vời, cho đến nay là tốt nhất. Hãy dũng cảm, cuối cùng chúng ta sẽ đưa bạn lên đỉnh :-)
cfi

3
@Dave: Hừm. Tôi đang có suy nghĩ thứ hai: --mirror không chỉ thiết lập tất cả các chi nhánh theo dõi. Nó sao chép tất cả các ref từ nguồn gốc và tiếp theo git remote updatesẽ làm điều đó một lần nữa. Hành vi của kéo thay đổi. Tôi trở lại để tin rằng bản sao đầy đủ yêu cầu một tập lệnh một dòng.
cfi

5
git clone --mirrorlà rất tốt để sao lưu kho git của bạn ^ _ ^
TrinitronX

220

Bạn có thể dễ dàng chuyển sang một chi nhánh mà không cần sử dụng cú pháp "git checkout -b somebranch origin / somebranch". Bạn chỉ có thể làm:

git checkout somebranch

Git sẽ tự động làm điều đúng:

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

Git sẽ kiểm tra xem một nhánh có cùng tên có tồn tại trong chính xác một điều khiển không, và nếu có, nó sẽ theo dõi nó giống như cách bạn đã xác định rõ ràng rằng đó là một nhánh từ xa. Từ trang man git-checkout của Git 1.8.2.1:

Nếu không tìm thấy <nhánh> nhưng có tồn tại một nhánh theo dõi trong chính xác một điều khiển từ xa (gọi nó là <remote>) với tên phù hợp, hãy coi là tương đương với

$ git checkout -b <branch> --track <remote>/<branch>

1
Vì vậy, nếu tên của nhánh bạn checkoutgiống hệt với tên của nhánh từ xa, mọi thứ nằm sau "/", thì git sẽ tạo một nhánh có cùng tên, mọi thứ nằm sau "/", "theo dõi" từ xa đó ? Và bằng cách theo dõi, chúng tôi có nghĩa là: git push, git pull, vv sẽ được thực hiện trên xa đó? Nếu điều này là chính xác, thì hãy mở rộng câu trả lời của bạn với nhiều thông tin hơn, vì tôi đồng ý với @Daniel, câu trả lời này xứng đáng có nhiều đại diện hơn.
Gerard Roche

5
@BullfrogBlues, câu trả lời cho tất cả các câu hỏi của bạn dường như là có (Tôi đang sử dụng git v1.7.7.4). Tôi đồng ý hành vi này nên được biết đến nhiều hơn. (Nó không có trong hướng dẫn sử dụng cho phiên bản git này.) Tôi thực sự không thích hành vi này, tôi muốn nhận một lỗi và phải nói git checkout --track origin/somebranchrõ ràng.
dubiousjim

3
@dubiousjim: Thật ra, đây là trong hướng dẫn. git-checkout (1) nói: "Nếu không tìm thấy <chi nhánh> nhưng có tồn tại một nhánh theo dõi trong chính xác một điều khiển từ xa > --track <từ xa> / <chi nhánh> '"(Git V.1.8.1.1).
sleske

Cái chúng ta cần là $ git pull * <remote> / * - trong đó "*" là ký tự đại diện, do đó, nó kéo tất cả các nhánh, bao gồm cả các nhánh chưa có trên hệ thống cục bộ. làm như thế nào? Chúng tôi có thực sự phải kiểm tra / kéo mọi chi nhánh chỉ để lấy mã được kéo đến hệ thống cục bộ của chúng tôi không?
JosephK

98

Về,

$ git checkout -b nguồn gốc thử nghiệm / thử nghiệm

sử dụng

$ git checkout -t origin/experimental

hoặc dài dòng hơn nhưng dễ nhớ hơn

$ git checkout --track origin/experimental

có thể tốt hơn, về mặt theo dõi một kho lưu trữ từ xa.


Vì vậy, ý bạn là hình thức thứ hai chỉ dễ nhớ hơn và không có sự khác biệt nào khác?
aderchox

79

Việc tìm nạp mà bạn đang làm sẽ nhận được tất cả các nhánh từ xa, nhưng nó sẽ không tạo ra các nhánh cục bộ cho chúng. Nếu bạn sử dụng gitk, bạn sẽ thấy các nhánh từ xa được mô tả là "điều khiển từ xa / nguồn gốc / dev" hoặc một cái gì đó tương tự.

Để tạo một nhánh cục bộ dựa trên một nhánh từ xa, hãy làm một cái gì đó như:

kiểm tra git -b dev refs / điều khiển từ xa / nguồn gốc / dev

Mà sẽ trả lại một cái gì đó như:

Chi nhánh dev được thiết lập để theo dõi các ref / điều khiển từ xa / origin / dev.
Chuyển sang một nhánh mới "dev"

Bây giờ, khi bạn ở trên nhánh dev, "git pull" sẽ cập nhật dev cục bộ của bạn đến cùng điểm với nhánh dev từ xa. Lưu ý rằng nó sẽ tìm nạp tất cả các nhánh, nhưng chỉ kéo cái bạn đang ở trên ngọn cây.


14
Bạn không cần refs / điều khiển từ xa ở đây. git checkout -b dev origin / dev sẽ hoạt động tốt.
emk

3
Điều này sẽ luôn luôn làm việc : git checkout -b newlocaldev --track origin/dev. Nếu bạn muốn chi nhánh địa phương có cùng tên với điều khiển từ xa và chi nhánh từ xa không có tên khó, bạn có thể bỏ qua -b newlocaldev. Với branch.autosetupmergecài đặt cấu hình mặc định và giả sử bạn không có nhánh cục bộ có tên dev, hai lệnh này có thể thực hiện cùng một điều: git checkout -b dev origin/devvà chỉ đơn giản git checkout dev. Cuối cùng, git checkout origin/devkhông tạo ra một nhánh mới, mà chỉ đưa bạn vào trạng thái CHÍNH tách rời.
dubiousjim

Điều gì xảy ra khi điều khiển từ xa không còn tồn tại nhưng Git quá ngu ngốc khi thừa nhận nó đã bị xóa? Điều này giả định rằng bạn đã cập nhật và git branch -atiếp tục liệt kê nó như một nhánh từ xa.
22:00

Và chúng tôi làm điều này cho hàng chục chi nhánh?
JosephK

59

Khi bạn thực hiện "git clone git: // location", tất cả các nhánh và thẻ được tìm nạp.

Để hoạt động trên một nhánh từ xa cụ thể, giả sử đó là điều khiển từ xa gốc:

git checkout -b branch origin/branchname

2
Tôi đánh giá cao ghi chú của bạn "tất cả các chi nhánh và thẻ được tìm nạp". Tôi sẽ nhận xét về câu trả lời của bạn là sai, nhưng sau đó tôi đã kiểm tra nó và thấy rằng, bạn hoàn toàn đúng. Vì vậy, theo một cách nào đó, bạn đã cung cấp câu trả lời ngắn nhất - nếu bạn nhân bản, bạn đã có nó. Đẹp. Người ta có thể thử thêm: cố gắng $ git branch -ahọc, những nhánh từ xa nào đã có sẵn.
Jan Vlcinsky

Có một cái nhìn vào câu trả lời tôi đăng là tốt. Điều này có thể hữu ích nếu bạn biết bạn sẽ muốn làm việc tại nhiều chi nhánh từ xa và không phải kiểm tra từng cái một.
lacostenycoder

Bạn có thể giải thích cho tôi sự khác biệt giữa git checkout -b master origin/mastergit checkout --track origin/masterxin vui lòng?
aderchox

1
@aderchox Ngày nay, tôi nghĩ không có.
elmarco

58

Sử dụng bí danh. Mặc dù không có bất kỳ lớp lót Git riêng nào, bạn có thể định nghĩa riêng của mình là

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'

và sau đó sử dụng nó như là

git clone-branches

Cảm ơn. Điều này thực sự nhân bản tất cả các nhánh từ xa không giống như một số câu trả lời khác
FearlessHyena

50

Tại sao bạn chỉ thấy "chủ"

git clonetải xuống tất cả các chi nhánh từ xa nhưng vẫn coi chúng là "từ xa", mặc dù các tệp được đặt trong kho lưu trữ mới của bạn. Có một ngoại lệ cho điều này, đó là quá trình nhân bản tạo ra một nhánh cục bộ gọi là "master" từ nhánh từ xa gọi là "master". Theo mặc định, git branchchỉ hiển thị các nhánh cục bộ, đó là lý do tại sao bạn chỉ nhìn thấy "chủ".

git branch -acho thấy tất cả các chi nhánh, bao gồm các chi nhánh từ xa .


Làm thế nào để có được chi nhánh địa phương

Nếu bạn thực sự muốn làm việc trên một chi nhánh, có lẽ bạn sẽ muốn có một phiên bản "cục bộ" của nó. Để chỉ cần tạo các nhánh cục bộ từ các nhánh từ xa (mà không cần kiểm tra chúng và do đó thay đổi nội dung của thư mục làm việc của bạn) , bạn có thể làm như thế này:

git branch branchone origin/branchone
git branch branchtwo origin/branchtwo
git branch branchthree origin/branchthree

Trong ví dụ này, branchonelà tên của một chi nhánh địa phương bạn đang tạo dựa trên origin/branchone; thay vào đó, nếu bạn muốn tạo các nhánh cục bộ với các tên khác nhau, bạn có thể làm điều này:

git branch localbranchname origin/branchone

Khi bạn đã tạo một chi nhánh địa phương, bạn có thể thấy nó với git branch(nhớ rằng, bạn không cần -aphải xem các chi nhánh địa phương).


Nếu origin/branchonetồn tại, bạn cũng có thể chỉ cần sử dụng git checkout branchoneđể tạo một nhánh cục bộ có cùng tên và đặt nó để theo dõi từ xa.
Evan

47

Điều này không quá phức tạp, các bước rất đơn giản và đơn giản như sau;

git fetch origin Điều này sẽ mang tất cả các chi nhánh từ xa đến địa phương của bạn.

git branch -a Điều này sẽ cho bạn thấy tất cả các chi nhánh từ xa.

git checkout --track origin/<branch you want to checkout>

Xác minh xem bạn có ở trong nhánh mong muốn bằng lệnh sau không;

git branch

Đầu ra sẽ như thế này;

*your current branch 
some branch2
some branch3 

Lưu ý dấu * biểu thị nhánh hiện tại.


1
Cảm ơn suraj. Lý do vì nó không được bình chọn nhiều. Và ans không được người hỏi chấp nhận.
Sam

"Nguồn gốc git fetch" không mang bất kỳ chi nhánh từ xa nào đến địa phương của tôi - hoặc chúng được giấu ở đâu đó? Đọc tất cả các câu trả lời ở trên làm tôi đau đầu. Chúng tôi đang tìm kiếm "git lấy tất cả các chi nhánh cho địa phương". Phải có một cách ngoài bash-scripts để làm điều này.
JosephK

1
Ngay sau khi bạn thực hiện "git fetch origin", nó sẽ hiển thị đầu ra như thế này trong thiết bị đầu cuối của bạn - "* [nhánh mới] Branch_name -> origin / Branch_name", nhưng khi bạn chạy "git Branch", nó sẽ chỉ hiển thị cho bạn cục bộ thay vào đó, để xem tất cả các nhánh bạn có thể thực hiện "git chi nhánh -a" và sau đó để chuyển sang chi nhánh từ xa, bạn cần chạy "git checkout --track origin / <chi nhánh bạn muốn thanh toán>". Hi vọng điêu nay co ich. :-)
Sam

4
Suraj, bởi vì câu hỏi là, làm thế nào để "nhân bản tất cả các nhánh từ xa" - chứ không phải làm thế nào để cập nhật thủ công một lần. Dường như không có câu trả lời cho câu hỏi thực tế - chỉ là cách để thực hiện toàn bộ việc gõ nếu bạn có nhiều nhánh.
JosephK

47

Muộn còn hơn không, nhưng đây là cách tốt nhất để làm điều này:

mkdir repo
cd repo
git clone --bare path/to/repo.git .git
git config --unset core.bare
git reset --hard

Tại thời điểm này, bạn có một bản sao hoàn chỉnh của repo từ xa với tất cả các chi nhánh của nó (xác minh với git branch). Bạn có thể sử dụng --mirrorthay vì --barenếu repo từ xa của bạn có điều khiển từ xa.


Đã xảy ra lỗi trong quá trình chỉnh sửa ở đây. Bây giờ câu trả lời này không có ý nghĩa. " --bare" Được đề cập trong câu cuối không tồn tại trong danh sách lệnh đã cho.
Cerran

lấy từ câu trả lời của Dave dưới đây. Sử dụng 'git config --bool core.bare false' thay vì 'git config unset core.bare' dường như thực hiện công việc.
Vorlon bối rối

Tôi có error: key does not contain a section: unset. Các câu trả lời của Dave hoạt động tốt hơn.
olibre

git config --unset core.barethực sự ... Đối với tôi, đây có vẻ là giải pháp sạch nhất trong tất cả các câu trả lời ở đây. Thật đáng tiếc vì nó có quá ít sự
ủng hộ

1
Cảm ơn @ChrisSim tôi đồng ý git config --bool core.bare false. Đây là lý do tại sao tôi đề nghị thay vì câu trả lời của Dave . Bạn nghĩ gì về câu trả lời của Dave ? Chúc mừng
olibre

39

Chỉ cần làm điều này:

$ git clone git://example.com/myproject
$ cd myproject
$ git checkout branchxyz
Branch branchxyz set up to track remote branch branchxyz from origin.
Switched to a new branch 'branchxyz'
$ git pull
Already up-to-date.
$ git branch
* branchxyz
  master
$ git branch -a
* branchxyz
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/branchxyz
  remotes/origin/branch123

Bạn thấy, 'git clone git: //example.com/myprojectt' tìm nạp mọi thứ, ngay cả các nhánh, bạn chỉ cần kiểm tra chúng, sau đó chi nhánh địa phương của bạn sẽ được tạo.


25

Bạn chỉ cần sử dụng "git clone" để có được tất cả các chi nhánh.

git clone <your_http_url>

Mặc dù bạn chỉ nhìn thấy nhánh chính, bạn có thể sử dụng "nhánh git -a" để xem tất cả các nhánh.

git branch -a

Và bạn có thể chuyển sang bất kỳ chi nhánh nào bạn đã có.

git checkout <your_branch_name>

Đừng lo lắng rằng sau khi bạn "git clone", bạn không cần kết nối với repo từ xa, "git Branch -a" và "git checkout" có thể chạy thành công khi bạn đóng wifi. Vì vậy, nó đã được chứng minh rằng khi bạn thực hiện "git clone", nó đã sao chép tất cả các nhánh từ repo từ xa. Sau đó, bạn không cần repo từ xa, địa phương của bạn đã có tất cả các mã của chi nhánh.


Phản ứng rất rõ ràng ở đây. Rất nhiều người nhầm lẫn về chủ đề này.
Xman

Tôi muốn tán thành câu nói của bạn "có thể chạy thành công khi bạn đóng wifi". "Git clone" thực sự dẫn đến một repo chứa tất cả các nhánh.
bvgheluwe

Một câu trả lời rõ ràng đơn giản tuyệt vời.
Amr

24

A git cloneđược cho là sao chép toàn bộ kho lưu trữ. Hãy thử nhân bản nó, và sau đó chạy git branch -a. Nó nên liệt kê tất cả các chi nhánh. Nếu sau đó bạn muốn chuyển sang nhánh "foo" thay vì "master", hãy sử dụng git checkout foo.


1
Bạn có thể chạy các lệnh git có hoặc không có dấu gạch nối. Cả "nhánh git" và "nhánh git" sẽ hoạt động.
Peter Boughton

21
Có thể câu trả lời này đã được đưa ra từ lâu khi git hoạt động khác đi, nhưng tôi nghĩ nó đã gây hiểu lầm ngày hôm nay. git clonekhông tải xuống tất cả các nhánh từ xa, nhưng nó chỉ tạo ra một nhánh chính của địa phương. Vì git branchchỉ hiển thị các nhánh cục bộ, bạn cũng cần git branch -aphải xem các nhánh từ xa.
Cerran

Cảm ơn bạn. Đây là loại hành vi mặc định kỳ lạ IMO. Tôi sẽ chỉ viết nó lên nhân chứng khó hiểu hơn. Nếu nó tải xuống các nhánh, tại sao nó lại ẩn chúng khi gọi nhánh git?
Adam Hughes

1
@ Địa Trung Hải, cảm ơn; Tôi đã cập nhật câu trả lời của mình cho phù hợp.
MattoxBeckman

"không tải xuống tất cả các nhánh từ xa, nhưng nó chỉ tạo ra một nhánh chính của địa phương". Tôi cần giúp đỡ để hiểu điều này. Dường như git clone KHÔNG nhân bản bất kỳ nhánh nào ngoại trừ master, vì khi bạn thực hiện "git Branch -a", nó cho thấy nhánh "phát triển" chỉ ở "điều khiển từ xa / nguồn gốc / phát triển". Điều này phải nói rằng bạn không có chi nhánh này ở bất cứ đâu tại địa phương, nó chỉ tồn tại trên nguồn gốc phải không?
John Little

19

Sử dụng công cụ của tôi git_remote_branch (bạn cần cài đặt Ruby trên máy của bạn). Nó được xây dựng đặc biệt để làm cho các thao tác chi nhánh từ xa trở nên dễ dàng.

Mỗi lần nó thực hiện một thao tác thay cho bạn, nó sẽ in nó màu đỏ tại bàn điều khiển. Theo thời gian, cuối cùng chúng dính vào não bạn :-)

Nếu bạn không muốn grb chạy các lệnh thay mặt bạn, chỉ cần sử dụng tính năng 'giải thích'. Các lệnh sẽ được in ra bàn điều khiển của bạn thay vì thực thi cho bạn.

Cuối cùng, tất cả các lệnh đều có bí danh, để làm cho việc ghi nhớ dễ dàng hơn.

Lưu ý rằng đây là phần mềm alpha ;-)

Đây là sự giúp đỡ khi bạn chạy grb help:

git_remote_branch phiên bản 0.2.6

  Sử dụng:

  grb tạo Branch_name [origin_server] 

  grb xuất bản Branch_name [origin_server] 

  grb đổi tên Branch_name [origin_server] 

  grb xóa Branch_name [origin_server] 

  grb theo dõi nhánh_name [origin_server] 



  Ghi chú:
  - Nếu origin_server không được chỉ định, tên 'origin' được giả sử 
    (mặc định của git)
  - Chức năng đổi tên đổi tên chi nhánh hiện tại

  Lệnh meta giải thích: bạn cũng có thể thêm bất kỳ lệnh nào với 
từ khóa 'giải thích'. Thay vì thực thi lệnh, git_remote_branch
sẽ chỉ xuất ra danh sách các lệnh bạn cần chạy để thực hiện 
mục tiêu đó

  Thí dụ: 
    grb giải thích tạo
    grb giải thích tạo my_branch github

  Tất cả các lệnh cũng có bí danh:
  tạo: tạo, mới
  xóa: xóa, hủy, hủy, xóa, rm
  xuất bản: xuất bản, từ xa
  đổi tên: đổi tên, rn, mv, di chuyển
  theo dõi: theo dõi, theo dõi, lấy, lấy

6
Lời cho người khôn ngoan: Có vẻ như dự án này đã bị bỏ rơi trong khoảng thời gian câu trả lời này được đăng. Tôi không thể tìm thấy bất kỳ cập nhật nào sau năm 2008. Caveat emptor và tất cả những thứ đó. Nếu tôi sai, tôi hy vọng ai đó sẽ chỉnh sửa và cung cấp một con trỏ hiện tại, vì tôi thích có một công cụ tiện dụng như thế này.
bradheintz

@bradheintz kiểm tra câu trả lời này, nó thiết lập một bí danh git: stackoverflow.com/a/16563327/151841
user151841

19

tất cả các câu trả lời tôi thấy ở đây là hợp lệ nhưng có một cách sạch hơn nhiều để sao chép một kho lưu trữ và kéo tất cả các nhánh cùng một lúc.

Khi bạn sao chép một kho lưu trữ, tất cả thông tin của các nhánh thực sự được tải xuống nhưng các nhánh bị ẩn đi. Với lệnh

$ git branch -a

bạn có thể hiển thị tất cả các nhánh của kho lưu trữ và với lệnh

$ git checkout -b branchname origin/branchname

sau đó bạn có thể "tải xuống" chúng theo cách thủ công một lần.


Tuy nhiên, khi bạn muốn sao chép một repo với rất nhiều nhánh, tất cả các cách minh họa ở trên đều dài và tẻ nhạt đối với một cách nhanh hơn và nhanh hơn mà tôi sẽ trình bày, mặc dù nó hơi phức tạp. Bạn cần ba bước để thực hiện điều này:

  1. Bước đầu tiên

tạo một thư mục trống mới trên máy của bạn và sao chép một bản sao nhân bản của thư mục .git từ kho lưu trữ:

$ cd ~/Desktop && mkdir my_repo_folder && cd my_repo_folder
$ git clone --mirror https://github.com/planetoftheweb/responsivebootstrap.git .git

kho lưu trữ cục bộ bên trong thư mục my numpo_folder vẫn trống, hiện tại chỉ có một thư mục .git ẩn mà bạn có thể thấy bằng lệnh "ls -alt" từ thiết bị đầu cuối.

  1. Bước thứ hai

chuyển kho lưu trữ này từ kho lưu trữ trống (trống) sang kho lưu trữ thông thường bằng cách chuyển giá trị boolean "trần" của cấu hình git thành false:

$ git config --bool core.bare false
  1. Bước thứ ba

Lấy tất cả mọi thứ trong thư mục hiện tại và tạo tất cả các nhánh trên máy cục bộ, do đó làm cho nó trở thành một repo bình thường.

$ git reset --hard

Vì vậy, bây giờ bạn có thể chỉ cần gõ lệnh "git Branch" và bạn có thể thấy rằng tất cả các nhánh được tải xuống.

Đây là cách nhanh chóng để bạn có thể sao chép một kho lưu trữ git với tất cả các nhánh cùng một lúc, nhưng đó không phải là điều bạn muốn làm cho mỗi dự án theo cách này.


Tôi không thích cách bạn sử dụng từ "tải xuống" trong ... "tải xuống" chúng theo cách thủ công một lần . Trên thực tế, tất cả thông tin đã được tải xuống sau khi nhân bản repo. Điều duy nhất người ta cần làm là tạo các nhánh theo dõi cục bộ (điều này cũng có thể xảy ra khi ngoại tuyến, điều này chứng tỏ rằng tất cả thông tin đều có trong repo).
bvgheluwe

@bvgheluwe đó là lý do tại sao nó được trích dẫn.
FedericoCapaldo

15

Nhân bản từ một repo cục bộ sẽ không hoạt động với git clone & git fetch: rất nhiều nhánh / thẻ sẽ vẫn không được tải.

Để có được một bản sao với tất cả các chi nhánh và thẻ.

git clone --mirror git://example.com/myproject myproject-local-bare-repo.git

Để có được một bản sao với tất cả các chi nhánh và thẻ nhưng cũng có một bản sao hoạt động:

git clone --mirror git://example.com/myproject myproject/.git
cd myproject
git config --unset core.bare
git config receive.denyCurrentBranch updateInstead
git checkout master

13

OK, khi bạn sao chép repo của bạn, bạn có tất cả các chi nhánh ở đó ...

Nếu bạn chỉ làm git branch, họ là loại ...

Vì vậy, nếu bạn muốn xem tất cả tên chi nhánh, chỉ cần thêm --allcờ như thế này:

git branch --all hoặc là git branch -a

Nếu bạn chỉ kiểm tra chi nhánh, bạn sẽ có được tất cả những gì bạn cần.

Nhưng làm thế nào nếu nhánh được tạo bởi người khác sau khi bạn nhân bản?

Trong trường hợp này, chỉ cần làm:

git fetch

và kiểm tra lại tất cả các chi nhánh ...

Nếu bạn muốn tìm nạp và kiểm tra cùng một lúc, bạn có thể làm:

git fetch && git checkout your_branch_name

Cũng tạo ra hình ảnh dưới đây để bạn đơn giản hóa những gì tôi đã nói:

chi nhánh git - tất cả để có được tất cả các chi nhánh


3
Có một sự khác biệt giữa "bạn có nó" và "bạn thấy nó". nhánh git -all sẽ KHÔNG liệt kê các nhánh từ xa nữa khi bạn xóa kho lưu trữ từ xa.
Gustave

12

Nhìn vào một trong những câu trả lời cho câu hỏi tôi nhận thấy rằng có thể rút ngắn nó:

for branch in  `git branch -r | grep -v 'HEAD\|master'`; do  
 git branch --track ${branch##*/} $branch;
done

Nhưng hãy cẩn thận, nếu một trong những nhánh từ xa được đặt tên là admin_master thì nó sẽ không được tải xuống!

Cảm ơn bigfish cho ý tưởng ban đầu


Bạn có thể cải thiện regex hoặc có thể sử dụng Awk thay vì grepđể cải thiện bộ lọc để tránh các kết quả dương tính giả.
tripleee

tất cả các nhánh là 'origin \ my_branch_name', đây không phải là điều tôi muốn.
Sнаđошƒаӽ

Tôi chưa từng thấy cấu trúc $ {chi nhánh ## * /} trước đây - trông thực sự hữu ích - có ý tưởng nào tôi có thể tìm hiểu thêm về điều đó không? dường như không thể tìm thấy dưới bash bất cứ nơi nào. Cám ơn.
SaminOz


10

Để sao chép-dán vào dòng lệnh:

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

Để dễ đọc hơn:

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


Điều này sẽ:

  1. kiểm tra chủ (để chúng tôi có thể xóa chi nhánh chúng tôi đang ở trên)
  2. chọn từ xa để kiểm tra (thay đổi nó thành bất kỳ điều khiển từ xa nào bạn có)
  3. vòng qua tất cả các chi nhánh của điều khiển từ xa trừ master và HEAD
    1. xóa bỏ chi nhánh địa phương (để chúng tôi có thể kiểm tra các chi nhánh được cập nhật lực lượng)
    2. kiểm tra chi nhánh từ xa
  4. kiểm tra chủ (vì lợi ích của nó)

Dựa trên câu trả lời của VonC .


10

Tôi đã viết các hàm Powershell nhỏ này để có thể kiểm tra tất cả các nhánh git của tôi, có nguồn gốc từ xa.

Function git-GetAllRemoteBranches {
     iex "git branch -r"                       <# get all remote branches #> `
     | % { $_ -Match "origin\/(?'name'\S+)" }  <# select only names of the branches #> `
     | % { Out-Null; $matches['name'] }        <# write does names #>
}


Function git-CheckoutAllBranches {
    git-GetAllRemoteBranches `
        | % { iex "git checkout $_" }          <# execute ' git checkout <branch>' #>
}

Nhiều chức năng git có thể được tìm thấy trên repo cài đặt git của tôi


9

Đây là một câu trả lời sử dụng awk. Phương pháp này sẽ đủ nếu được sử dụng trên một repo mới.

git branch -r | awk -F/ '{ system("git checkout " $NF) }'

Các nhánh hiện có sẽ chỉ được kiểm tra hoặc khai báo như đã có trong đó, nhưng các bộ lọc có thể được thêm vào để tránh xung đột.

Nó cũng có thể được sửa đổi để nó gọi một git checkout -b <branch> -t <remote>/<branch>lệnh rõ ràng .

Câu trả lời này sau Nikos C. 's ý tưởng .


Thay vào đó, chúng ta có thể chỉ định các chi nhánh từ xa thay thế. Điều này dựa trên câu trả lời của murphytalk .

git branch -r | awk '{ system("git checkout -t " $NF) }'

Nó ném các thông báo lỗi nghiêm trọng về xung đột nhưng tôi thấy chúng vô hại.


Cả hai lệnh có thể được đặt bí danh.

Sử dụng câu trả lời của không ai làm tham chiếu, chúng ta có thể có các lệnh sau để tạo bí danh:

git config --global alias.clone-branches '! git branch -r | awk -F/ "{ system(\"git checkout \" \$NF) }"'
git config --global alias.clone-branches '! git branch -r | awk "{ system(\"git checkout -t \" \$NF) }"'

Cá nhân tôi sẽ sử dụng track-allhoặc track-all-branches.


Chỉ muốn cảm ơn bạn. Điều này hoạt động hoàn hảo và nó không gặp phải các vấn đề khác nhau liên quan đến việc nhân bản một repo trần như một số thay đổi hành vi kéo, v.v.
mahonya 16/12/19

8

Tôi cần phải làm chính xác như vậy. Đây là kịch bản Ruby của tôi .

#!/usr/bin/env ruby

local = []
remote = {}

# Prepare
%x[git reset --hard HEAD]
%x[git checkout master] # Makes sure that * is on master.
%x[git branch -a].each_line do |line|
  line.strip!
  if /origin\//.match(line)
     remote[line.gsub(/origin\//, '')] = line
   else
     local << line
   end
end
# Update 
remote.each_pair do |loc, rem|
  next if local.include?(loc)
  %x[git checkout --track -b #{loc} #{rem}]
end
%x[git fetch]

Xem câu trả lời tôi đã đăng thêm xuống để tránh phải chạy tập lệnh này.
lacostenycoder

8

Không có câu trả lời nào trong số này cắt giảm, ngoại trừ người dùng không ai đi đúng hướng.

Tôi gặp rắc rối với việc chuyển repo từ máy chủ / hệ thống này sang máy chủ khác. Khi tôi nhân bản repo, nó chỉ tạo một nhánh cục bộ cho master nên khi tôi đẩy sang remote mới, chỉ có nhánh master được đẩy.

Vì vậy, tôi thấy hai phương pháp RẤT hữu ích. Hy vọng họ giúp đỡ người khác.

Cách 1:

git clone --mirror OLD_REPO_URL
cd new-cloned-project
mkdir .git
mv * .git
git config --local --bool core.bare false
git reset --hard HEAD
git remote add newrepo NEW_REPO_URL
git push --all newrepo
git push --tags newrepo

Cách 2:

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'
git clone OLD_REPO_URL
cd new-cloned-project
git clone-branches
git remote add newrepo NEW_REPO_URL
git push --all newrepo
git push --tags newrepo

8

git clone --mirror trên repo ban đầu hoạt động tốt cho việc này.

git clone --mirror /path/to/original.git
git remote set-url origin /path/to/new-repo.git
git push -u origin

7

Git thường (khi không được chỉ định) tìm nạp tất cả các nhánh và / hoặc thẻ (refs, xem git ls-refs:) từ một hoặc nhiều kho lưu trữ khác cùng với các đối tượng cần thiết để hoàn thành lịch sử của chúng. Nói cách khác, nó tìm nạp các đối tượng có thể truy cập được bởi các đối tượng đã được tải xuống. Xem: Điều gì git fetchthực sự làm gì?

Đôi khi bạn có thể có các nhánh / thẻ không được kết nối trực tiếp với thẻ hiện tại, vì vậy git pull --all/ git fetch --allsẽ không giúp đỡ trong trường hợp đó, nhưng bạn có thể liệt kê chúng theo:

git ls-remote -h -t origin

và lấy chúng bằng tay bằng cách biết tên ref.

Vì vậy, để lấy tất cả chúng , hãy thử:

git fetch origin --depth=10000 $(git ls-remote -h -t origin)

Các --depth=10000thông số có thể giúp đỡ nếu bạn đã shallowed kho.

Sau đó kiểm tra lại tất cả các chi nhánh của bạn:

git branch -avv

Nếu ở trên không giúp được gì, bạn cần thêm các nhánh bị thiếu theo cách thủ công vào danh sách được theo dõi (vì chúng bị mất bằng cách nào đó):

$ git remote -v show origin
...
  Remote branches:
    master      tracked

bằng cách git remote set-branchesthích:

git remote set-branches --add origin missing_branch

vì vậy nó có thể xuất hiện dưới remotes/originsau khi tìm nạp:

$ git remote -v show origin
...
  Remote branches:
    missing_branch new (next fetch will store in remotes/origin)
$ git fetch
From github.com:Foo/Bar
 * [new branch]      missing_branch -> origin/missing_branch

Xử lý sự cố

Nếu bạn vẫn không thể nhận được bất cứ thứ gì ngoài nhánh chính, hãy kiểm tra các mục sau:

  • Kiểm tra kỹ từ xa của bạn ( git remote -v), vd
    • Xác thực đó git config branch.master.remoteorigin.
    • Kiểm tra nếu origintrỏ đến đúng URL thông qua: git remote show origin(xem bài đăng này ).

7

Kể từ đầu năm 2017, câu trả lời trong bình luận này hoạt động:

git fetch <origin-name> <branch-name>mang chi nhánh xuống cho bạn. Trong khi điều này không kéo tất cả các nhánh cùng một lúc, bạn có thể thực hiện đơn lẻ trên mỗi nhánh này.


Điều này đòi hỏi bạn phải tìm nạp từng nhánh một. Không tốt lắm nếu bạn có nhiều chi nhánh.
lacostenycoder

6

Đây là một lệnh one-liner ngắn khác tạo các nhánh cục bộ cho tất cả các nhánh từ xa:

(git branch -r | sed -n '/->/!s#^  origin/##p' && echo master) | xargs -L1 git checkout

Nó cũng hoạt động đúng nếu theo dõi các chi nhánh địa phương đã được tạo. Bạn có thể gọi nó sau lần đầu tiên git clonehoặc bất cứ lúc nào sau đó.

Nếu bạn không cần phải masterkiểm tra chi nhánh sau khi nhân bản, hãy sử dụng

git branch -r | sed -n '/->/!s#^  origin/##p'| xargs -L1 git checkout
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.