Tại sao tôi cần phải thực hiện `--set-upstream` mọi lúc?


1468

Tôi tạo một chi nhánh mới trong Git:

git branch my_branch

Đẩy nó:

git push origin my_branch

Bây giờ nói ai đó đã thực hiện một số thay đổi trên máy chủ và tôi muốn lấy từ đó origin/my_branch. Tôi làm:

git pull

Nhưng tôi nhận được:

You asked me to pull without telling me which branch you
want to merge with, and 'branch.my_branch.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.

If you often merge with the same branch, you may want to
use something like the following in your configuration file:

    [branch "my_branch"]
    remote = <nickname>
    merge = <remote-ref>

    [remote "<nickname>"]
    url = <url>
    fetch = <refspec>

See git-config(1) for details.

Tôi đã học được rằng tôi có thể làm cho nó hoạt động với:

git branch --set-upstream my_branch origin/my_branch

Nhưng tại sao tôi cần phải làm điều này cho mọi chi nhánh tôi tạo ra? Không phải là rõ ràng rằng nếu tôi đẩy my_branchvào origin/my_branch, sau đó tôi sẽ muốn kéo origin/my_branchvào my_branch? Làm thế nào tôi có thể làm cho hành vi này mặc định?


21
Mặc định cho branch.autosetupmergecó nghĩa là cấu hình ngược dòng cho một nhánh mới chỉ được đặt tự động khi tạo một nhánh từ nhánh theo dõi từ xa (ví dụ <remote-name>/<branch-name>) (xem git-config (1) ). Bạn có thể đang tạo các chi nhánh của bạn từ các chi nhánh địa phương hiện có. Nếu bạn đang phân nhánh hiệu quả trực tiếp từ đầu của một nhánh từ xa (mặc dù nằm trên một nhánh cục bộ), thì bạn có thể sử dụng git branch my_branch <remote-name>/<branch-name>để tự động thiết lập cấu hình ngược dòng.
Chris Johnsen

20
FYI, --set-upstreamtùy chọn bị phản đối. Bạn nên sử dụng --trackhoặc --set-upstream-tothay thế.
Sean the Bean

139
Nếu --set-upstreamkhông được dùng nữa, thì có lẽ các nhà phát triển git nên xóa nó khỏi thông báo trợ giúp được hiển thị khi bạn chạy git pushkhông có tùy chọn và không có dòng ngược nào được đặt?
Christopher Hunter

17
@ChristopherHunter Đã hơn một năm kể từ bình luận của bạn và nó vẫn nói lên điều đó. Có phải đó chỉ là một phản hồi cẩu thả hoặc có lẽ có một lý do khôn ngoan về mặt kỹ thuật để giữ nó xung quanh mà chúng ta không biết gì về nó?
Konrad Viltersten

15
@ChristopherHunter git branch --set-upstreamkhông được dùng nữa. git push --set-upstreamkhông phải.
Brian Gordon

Câu trả lời:


1538

Một phím tắt, không phụ thuộc vào việc nhớ cú pháp cho git branch --set-upstream 1 là phải làm:

git push -u origin my_branch

... Lần đầu tiên bạn đẩy chi nhánh đó. Hoặc, để đẩy đến nhánh hiện tại đến một nhánh cùng tên (tiện dụng cho bí danh):

git push -u origin HEAD

Bạn chỉ cần sử dụng -umột lần và thiết lập liên kết giữa chi nhánh của bạn và chi nhánh origintheo cùng một cách như git branch --set-upstreamvậy.

Cá nhân, tôi nghĩ rằng đó là một điều tốt để thiết lập sự liên kết giữa chi nhánh của bạn và một chi nhánh từ xa một cách rõ ràng. Thật là xấu hổ khi các quy tắc khác nhau cho git pushgit pull .


1 Nghe có vẻ ngớ ngẩn, nhưng tôi rất hay quên chỉ định nhánh hiện tại, giả sử đó là mặc định - không phải vậy, và kết quả là khó hiểu nhất :)

Cập nhật 2012-10-11 : Rõ ràng tôi không phải là người duy nhất thấy dễ mắc sai lầm! Cảm ơn VonC đã chỉ ra rằng git 1.8.0 giới thiệu rõ ràng hơn git branch --set-upstream-to, có thể được sử dụng như sau, nếu bạn ở trên nhánh my_branch:

git branch --set-upstream-to origin/my_branch

... hoặc với tùy chọn ngắn:

git branch -u origin/my_branch

Thay đổi này và lý do của nó, được mô tả trong ghi chú phát hành cho git 1.8.0, ứng viên phát hành 1 :

Thật hấp dẫn để nói git branch --set-upstream origin/master, nhưng điều đó nói với Git để sắp xếp chi nhánh địa phương origin/masterđể tích hợp với chi nhánh hiện đang được kiểm tra, điều này rất khó xảy ra với ý nghĩa của người dùng. Tùy chọn không được chấp nhận; thay vào đó, hãy sử dụng tùy chọn mới --set-upstream-to(với -utùy chọn ngắn và ngọt ).


95
Cũng lưu ý rằng ngay cả khi bạn quên -ulần đầu tiên đẩy, bạn có thể chạy lại lần đẩy với cờ đó và nó sẽ bắt đầu theo dõi.
Henrik N

70
Không ai trong số này thỏa mãn trường hợp sử dụng sử dụng git đẩy mà không có đối số. Vẫn còn đó là tôi vẫn phải nhớ 'git push -u origin my-Branch' khi lần đầu tiên chuyển nhánh mới của mình sang điều khiển từ xa.
Karl the Pagan

19
Tôi ghét việc nhớ cú pháp đó, vì vậy tôi đã tạo ra bí danh sau:alias gpo="git push --set-upstream origin $(git branch | awk '/^\* / { print $2 }')"
lillialexis

99
Điều này hoàn toàn tốt, nhưng tôi vẫn nghĩ rằng khiếu nại của OP là hợp lệ. Bạn bắt đầu một chi nhánh địa phương, làm việc trên nó, đẩy nó về nguồn gốc để chia sẻ (không có đối số); Tại sao không nên thiết lập ngược dòng? Có thực sự mong muốn vì một số lý do KHÔNG thiết lập ngược dòng khi đẩy một nhánh mới vào một điều khiển không?
GaryO

23
Hoàn toàn không có giá trị thời gian dev. Tại sao nó không tự động làm điều đó?
sudo

1346

Bạn có thể làm điều này xảy ra với ít gõ hơn. Đầu tiên, thay đổi cách đẩy của bạn hoạt động:

git config --global push.default current

Điều này sẽ suy ra origin my_branchmột phần, do đó bạn có thể làm:

git push -u

Cả hai sẽ tạo ra nhánh từ xa có cùng tên và theo dõi nó.


4
Làm thế nào đến git có thể suy ra originkhi chạy git push -ucho nhánh mới được tạo trong kho lưu trữ mới được tạo? Có phải giả định rằng kho lưu trữ đã được nhân bản, do đó chi nhánh hiện tại có cài đặt từ xa originkhông?
Piotr Dobrogost

73
Điều này nên được mặc định. Vì vậy, nhiều thứ trong git có thể thân thiện với người dùng hơn nếu nó được vận chuyển với mặc định tốt hơn.
phreakhead

13
Xin lưu ý rằng 'hiện tại' hơi không an toàn hơn so với sử dụng 'đơn giản' để thực hiện điều tương tự, xem stackoverflow.com/questions/23918062/
Air

30
Có, nhưng sau đó khi bạn cố gắng, pullbạn sẽ phải xác định từ đâu. Việc -uthiết lập theo dõi chi nhánh giữa nguồn gốc và repo địa phương của bạn.
Zamith

7
Mặc dù thuận tiện một chút, nhưng điều này vẫn bắt buộc phải chạy một lệnh khác cho lần đầu tiên và duy nhất push- đánh bại toàn bộ điểm của câu hỏi này. Tóm lại, không có câu trả lời tốt. Việc các nhà phát triển Git khăng khăng giữ lại Người dùng eXperience (AUX) vụng về này trước sự bất đồng quan điểm rộng rãi của cộng đồng là ... khai sáng. Và nản lòng. (Chủ yếu là không khuyến khích.)
Cecil Curry

87

Bạn có thể đơn giản

git checkout -b my-branch origin/whatever

ở nơi đầu tiên Nếu bạn đặt branch.autosetupmergehoặc branch.autosetuprebase(yêu thích của tôi) thành always(mặc định là true), my-branchsẽ tự động theo dõi origin/whatever.

Xem git help config.


5
Điều này tạo ra "fatal: Không thể cập nhật đường dẫn và chuyển sang nhánh 'my-Branch' cùng một lúc."
Karl the Pagan

12
Nhân tiện, tôi thường chỉ git checkout -t origin/whatever, cũng chọn whatevertên chi nhánh mới. Rât thuận tiện!
cdunn2001

2
@cdunn Cái này là lý tưởng, nhưng hầu như không nhất quán. Cờ nên được gọi là -u/ --set-upstream.
Tobu

1
git checkout -t origin/whateverkhông hoạt động với tôi khi cố gắng tạo một chi nhánh mới:fatal: Cannot update paths and switch to branch 'whatever' at the same time.
wvducky

1
git checkout -b my-branch origin/whatevercũng có lỗi tương tự (Tôi đang cố gắng tạo một nhánh mới không tồn tại trên địa phương hoặc từ xa): fatal: Cannot update paths and switch to branch 'whatever' at the same time.
wvducky

81

Đây là cách sử dụng phổ biến nhất của tôi cho The Fuck .

$ git 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

$ fuck
git push --set-upstream origin master [enter/↑/↓/ctrl+c]
Counting objects: 9, done.
...

Ngoài ra, thật thú vị khi gõ từ chửi thề trong thiết bị đầu cuối của bạn.


Điều này vì vậy cần phải được chuyển sang Windows (hoặc ít nhất là git-bash).
BrianHVB

1
khám phá nhỏ này chỉ làm cho ngày của tôi. cảm ơn bạn
Ivan Durst

Công cụ tuyệt vời, cảm ơn!
Yurii

81

Bạn có thể thiết lập đơn giản ngược dòng theo hai cách. Đầu tiên khi bạn tạo chi nhánh:

git branch -u origin/my-branch

hoặc sau khi bạn đã tạo một nhánh, bạn có thể sử dụng lệnh này.

git push -u origin my-branch

Bạn cũng có thể phân nhánh, kiểm tra và thiết lập dòng trong một lệnh duy nhất:

git checkout -b my-branch -t origin/my-branch

Sở thích cá nhân của tôi là làm điều này trong một lệnh hai bước:

git checkout -b my-branch
git push -u origin my-branch

1
Câu trả lời chính xác! Địa chỉ cả hai trường hợp sử dụng phổ biến. Sau khi chạy git branch -u origin/my-branchtôi có thể chạy git pullđể kéo xuống những thay đổi của mình.
Benjamin Atkin

2
"git checkout -b my-Branch -t origin / my-Branch" điều này không hoạt động nếu 'origin / my-Branch' chưa tồn tại.
Spongman

1
Bạn thực sự có thể làm git checkout -t origin/my-branchmà không cần -b my-branch, nó sẽ tự động suy ra my-branchtên chi nhánh địa phương. Tuy nhiên, như @Spongman đã đề cập, lệnh này không hoạt động nếu origin/my-branchkhông tồn tại trước.
wvducky

Có, sẽ hoạt động @wvducky, -t hoạt động tốt. Cá nhân, mặc dù hai năm sau khi tôi viết câu trả lời đó, tôi vẫn thích chia thành hai dòng với thanh toán -b và đẩy -u. Rõ ràng hơn và không có lỗi khi thanh toán -b khi tôi không có điều khiển từ xa - điều này xảy ra khá thường xuyên khi thử nghiệm :)
Tzen

2
git push -u origin/my-branchthất bại cho tôi với fatal: 'origin/my-branch' does not appear to be a git repository. Công việc này:git push -u origin my-branch
stason

48

Bạn có thể dùng:

git config --global Branch.autosetupmerge luôn

sẽ liên kết nhánh ngược dòng mỗi khi bạn tạo hoặc kiểm tra một nhánh mới.

Xem https://felipec.wordpress.com/2013/09/01/advified-git-con accept-the-upstream-trans-branch /

Điều này cũng hoạt động với branch.autosetuprebase, nếu bạn theo một quy trình làm việc tập trung vào rebase nhiều hơn, nhưng không sử dụng điều này trừ khi bạn biết bạn đang làm gì, vì nó sẽ mặc định hành vi kéo của bạn để rebase, điều này có thể gây ra kết quả kỳ lạ.


8
Không hoạt động, tôi vẫn nhận được --set-upstreamtin nhắn
Dorian

2
@Dorian, Bạn phải đặt cái này trước khi tạo chi nhánh. Xem stackoverflow.com/a/9753268/263998
cdunn2001

8
nhưng điều này không đặt nhánh theo dõi là điều khiển từ xa có cùng nhánh, nhưng với nhánh cục bộ hiện tại .. vì vậy khi bạn đẩy nó sẽ cố gắng đẩy sang nhánh ĐỊA PHƯƠNG mà bạn đã tạo trước khi tạo nhánh mới ..
Arnold Roa

1
Điều này thậm chí còn có hành vi kỳ lạ hơn mặc định. Nếu bạn làm việc ngoài một chi nhánh, nó hoạt động thực sự kỳ lạ.
Beefster

1
Hãy cẩn thận với cài đặt này !! Sau khi thiết lập nó, bạn có được hành vi này. 1. Chuyển sang master. 2. Chạy git checkout -b new_branch. 3. Thêm một cam kết cho chi nhánh đó. 4 git push origin new_branch.. Điều này đẩy cam kết với masterchi nhánh về nguồn gốc (chứ không phải là một chi nhánh mới về nguồn gốc được gọi new_branch).
stwr667

38

Nhân tiện, phím tắt để đẩy nhánh hiện tại đến một điều khiển từ xa có cùng tên:

$ git push -u origin HEAD

22

Cá nhân tôi sử dụng những bí danh sau đây trong bash

trong tập tin ~ / .gitconfig

[alias]
    pushup = "!git push --set-upstream origin $(git symbolic-ref --short HEAD)"

và trong tệp ~ / .bashrc hoặc ~ / .zshrc

alias gpo="git pushup"
alias gpof="gpo -f"
alias gf="git fetch"
alias gp="git pull"

1
Tôi chỉ cần hcange .gitconfig, sau đó tôi có thể sử dụng lệnh git pushupluôn đẩy nhánh hiện tại về gốc. Tôi luôn có thể chỉ cần sử dụng git pushupthay vì git push👍
thespacecamel

18

Nếu cách dưới đây không hoạt động:

git config --global push.default current

Bạn cũng nên cập nhật cấu hình cục bộ của dự án, vì có thể dự án của bạn có cấu hình git cục bộ:

git config --local push.default current

2
Nhiều lời giải thích sẽ là tuyệt vời. Dòng đầu tiên làm gì?
papillon

3
Câu trả lời này là một trong những cảm thấy hợp pháp. Tất cả những người đề xuất bí danh là cách giải quyết ngu ngốc. Và những cái khác biện minh cho việc ghi nhớ các chuỗi lệnh dài là phạm vi.
MarkHu

10

Bạn cũng có thể nói rõ ràng với git pull nhánh từ xa nào sẽ kéo (vì nó đề cập đến trong thông báo lỗi):

git pull <remote-name> <remote-branch>

Tuy nhiên, hãy cẩn thận với điều này: nếu bạn ở một nhánh khác và thực hiện thao tác kéo rõ ràng, thì refspec bạn kéo sẽ được hợp nhất vào nhánh bạn đang ở!


10

Đối với giá trị của nó, nếu bạn đang cố gắng theo dõi một nhánh đã tồn tại trên điều khiển từ xa (ví dụ: origin / somebranch) nhưng chưa kiểm tra nó tại địa phương, bạn có thể làm:

$ git checkout --track origin/somebranch

Lưu ý: '-t' là phiên bản rút gọn của tùy chọn '--track'.

Điều này thiết lập cùng một hiệp hội ngay lập tức.


5
Bạn thực sự có thể chỉ cần kiểm tra chi nhánh. Như vậy git checkout somebranchlà tương đương.
Zamith

2
@Zamith Không phải nó chỉ hoạt động sau khi đã gọi git fetchngay trước đó sao?
Walter Roman

1
Không phải ngay lập tức, nhưng có, bạn cần phải có một tham chiếu đến chi nhánh đó trên repo địa phương của bạn, điều này xảy ra bất cứ khi nào bạn gọi git fetchhoặc git pull. Tôi chưa bao giờ thấy đó là một vấn đề.
Zamith

10
git branch --set-upstream-to=origin/master<branch_name>

9

Tôi sử dụng bí danh Git này thay vì sao chép / dán đề xuất từ ​​Git mỗi lần: https://gist.github.com/ekilah/88a880c84a50b73bd306

Nguồn được sao chép bên dưới (thêm phần này vào ~/.gitconfigtệp của bạn ):

[alias]
  pushup = "!gitbranchname() { git symbolic-ref --short HEAD; }; gitpushupstream() { git push --set-upstream origin `gitbranchname`; }; gitpushupstream"

7

Bạn có thể thiết lập một bí danh thực sự tốt có thể xử lý việc này mà không cần cú pháp quá dài.

Tôi có bí danh sau ~/.gitconfig:

po = "!git push -u origin \"$(git rev-parse --abbrev-ref HEAD)\""

Sau khi thực hiện một cam kết trên một nhánh mới, bạn có thể đẩy chi nhánh mới của mình bằng cách gõ lệnh:

git po

tại sao po? push origin? Điều gì xảy ra nếu điều này được chạy nhiều lần?
Arnold Roa

Vâng, như trong nguồn gốc đẩy. Không có gì xảy ra nếu nó chạy nhiều lần. Tôi cũng có một git push -fbí danh được thiết lập git pf, vì vậy tôi sử dụng nó khi nguồn gốc đã được đẩy.
123

xem bình luận của djanowski , bạn có thể trực tiếp sử dụngHEAD
arhak

3

Đối với những người tìm kiếm một bí danh làm việc với git pull, đây là những gì tôi sử dụng:

alias up="git branch | awk '/^\\* / { print \$2 }' | xargs -I {} git branch --set-upstream-to=origin/{} {}"

Bây giờ bất cứ khi nào bạn nhận được:

$ git pull
There is no tracking information for the current branch.
...

Chỉ cần chạy:

$ up
Branch my_branch set up to track remote branch my_branch from origin.
$ git pull

Và bạn tốt để đi


2

Bởi vì git có khả năng tuyệt vời để đẩy / kéo các nhánh khác nhau đến các kho "ngược dòng" khác nhau. Bạn thậm chí có thể sử dụng các kho riêng biệt để đẩy và kéo - trên cùng một nhánh. Điều này có thể tạo ra một luồng phân tán, đa cấp, tôi có thể thấy điều này hữu ích trong dự án như nhân Linux. Git ban đầu được xây dựng để sử dụng cho dự án đó.

Kết quả là, nó không đưa ra giả định về việc repo chi nhánh của bạn nên theo dõi.

Mặt khác, hầu hết mọi người không sử dụng git theo cách này, vì vậy nó có thể tạo ra một trường hợp tốt cho một tùy chọn mặc định.

Git thường ở mức độ khá thấp và nó có thể gây nản lòng. Tuy nhiên, có GUI và thật dễ dàng để viết các tập lệnh trợ giúp nếu bạn vẫn muốn sử dụng nó từ trình bao.



0

Tôi sắp xếp lại legitvì vấn đề này (chỉ dành cho OS X). Bây giờ tất cả những gì tôi sử dụng khi phân nhánh là hai lệnh này:

legit publish [<branch>] Xuất bản chi nhánh được chỉ định vào điều khiển từ xa. (bí danh pub:)

legit unpublish <branch> Loại bỏ chi nhánh được chỉ định từ xa. (bí danh unp:)

SublimeGit đi kèm với legitsự hỗ trợ theo mặc định, điều này làm cho toàn bộ thói quen phân nhánh dễ dàng như nhấn Ctrl-b.


0

Chúng tôi sử dụng máy dệt và không đẩy bằng git. Tôi đã phải tạo bí danh bash hoạt động trên Linux / mac

vim ~/.bash_aliases

new_branch() {
    git checkout -b "$1"
    git branch --set-upstream-to=origin/master "$1"
}

tiết kiệm

source ~/.bash_aliases
new_branch test #instead of git checkout -b test
git pull

0

Dưới đây là một bí danh bash cho git đẩy an toàn để chạy cho mỗi lần đẩy và sẽ tự động chuyển đổi giữa việc thiết lập ngược dòng cho lần đẩy đầu tiên và sau đó thực hiện các cú đẩy bình thường sau đó.

alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push'

Bài gốc

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.