Tại sao tôi cần phải đẩy một chi nhánh mới một cách rõ ràng?


180

Tôi mới vào gitvà tôi đang thực hành. Tôi đã tạo một chi nhánh địa phương nhưng tôi thấy rằng khi tôi làm git pushchi nhánh của tôi không được tải lên kho lưu trữ. Tôi đã phải thực sự làm : git push -u origin --all.
Tại sao lại thế này? Không phải là một nhánh thay đổi mới sẽ được đẩy theo mặc định? Tại sao tôi cần chạy lệnh thứ hai?


15
Lưu ý rằng đây là cấu hình (cài đặt push.default, xem man git-config). Nếu bạn làm như vậy git config --add push.default current, sau đó git pushsẽ tự động tạo chi nhánh trong repo từ xa nếu cần thiết. Tại sao điều này không phải là mặc định được giải thích trong các câu trả lời.
sleske

@sleske Tôi đồng ý. Đối với các chính sách khác ' current' và ' upstream', hãy xem câu trả lời cũ hơn của tôi stackoverflow.com/a/13751847/6309 .
VonC

Tại sao không chấp nhận một câu trả lời?
laike9m

Câu trả lời:


224

Lý do thực tế là, trong một repo mới (git init), không có nhánh nào (không master, không có nhánh nào cả, nhánh không)

Vì vậy, khi bạn lần đầu tiên đẩy một repo ngược dòng trống rỗng (nói chung là một trần trống ), repo ngược dòng đó không có chi nhánh cùng tên.

Và:

Trong cả hai trường hợp, vì repo trống ngược dòng không có nhánh:

  • chưa có chi nhánh phù hợp
  • hoàn toàn không có nhánh ngược dòng (có hoặc không có cùng tên! Theo dõi hay không)

Điều đó có nghĩa là lần đẩy đầu tiên tại địa phương của bạn không có ý tưởng:

  • đẩy ở đâu
  • cần đẩy cái gì (vì nó không thể tìm thấy bất kỳ nhánh ngược dòng nào được ghi là nhánh theo dõi từ xa và / hoặc có cùng tên)

Vì vậy, bạn cần ít nhất để làm một:

git push origin master

Nhưng nếu bạn chỉ làm điều đó, bạn:

  • sẽ tạo một masternhánh ngược dòng trên thượng nguồn (bây giờ là repo không trống): tốt.
  • sẽ không ghi lại rằng chi nhánh địa phương ' master' cần được đẩy lên thượng nguồn ( origin) ' master' (chi nhánh thượng nguồn): xấu.

Đó là lý do tại sao nó được khuyến nghị, cho lần đẩy đầu tiên, để thực hiện:

git push -u origin master

Điều đó sẽ ghi lại origin/masterdưới dạng một nhánh theo dõi từ xa và sẽ cho phép lần đẩy tiếp theo tự động đẩy mastertới origin/master.

git checkout master
git push

Và điều đó cũng sẽ hoạt động với các chính sách đẩy ' current' hoặc ' upstream'.
Trong mỗi trường hợp, sau lần khởi đầu git push -u origin master, một cú đẩy git đơn giản sẽ đủ để tiếp tục đẩy chủ sang nhánh ngược dòng bên phải.


2
Sau thời điểm này, tiếp theo git pushcũng mong chi nhánh đã tồn tại?
Cratylus

2
Đúng. Nó sẽ đẩy bất kỳ bản cập nhật nào đến chi nhánh đó lên kho lưu trữ ngược dòng.
RyPeck

@Cratylus có, vì chính sách đẩy mặc định mới ' simple': đẩy tới bất kỳ nhánh ngược dòng nào được ghi lại, nếu nhánh ngược dòng đó có cùng tên với chính sách cục bộ. Một đơn giản git pushsẽ là đủ.
VonC

1
@BriptButkus Cảm ơn bạn. Tôi đã khôi phục liên kết.
VonC

3
Đối với trường hợp tổng quát hơn của người hỏi về một chi nhánh mới 'new_branch', bạn sẽ sử dụng git push --set-upstream origin new_branchhoặc git push -u origin new_branchviết tắt. Người -allhỏi đã sử dụng bỏ qua việc đặt tên cho một nhánh mới cụ thể bằng cách bao gồm tất cả các nhánh. Điều này được bao phủ bởi + Klas Mellbourn trong câu trả lời của ông.
Paul Masri-Stone

106

Bạn không, xem bên dưới

Tôi thấy 'tính năng' này khá khó chịu vì tôi không cố phóng tên lửa lên mặt trăng, chỉ đẩy nhánh cây chết tiệt của mình. Bạn có thể làm quá nếu không bạn sẽ không ở đây!

Đây là cách khắc phục: nếu bạn muốn nó hoàn toàn thúc đẩy nhánh hiện tại bất kể nhánh đó có tồn tại nguồn gốc hay không, chỉ cần phát lệnh này một lần và bạn sẽ không bao giờ phải quay lại bất cứ nơi nào:

git config --global push.default current

Vì vậy, nếu bạn làm chi nhánh như thế này:

git checkout -b my-new-branch

và sau đó thực hiện một số cam kết và sau đó làm một

git push -u

để đưa chúng ra khỏi nguồn gốc (nằm trên nhánh đó) và nó sẽ tạo ra nhánh nói cho bạn nếu nó không tồn tại.

Lưu ý bit -u đảm bảo rằng chúng được liên kết nếu bạn muốn kéo về sau từ nhánh đã nói. Nếu bạn không có kế hoạch kéo chi nhánh sau (hoặc ổn với một lớp lót khác nếu bạn làm) -u là không cần thiết.


3
Khi tôi làm điều này, nếu tôi thực hiện thao tác git, ngay sau đó - hai nhánh không được liên kết. :(
Alisso

đây là câu trả lời duy nhất khắc phục vấn đề của tôi
Raymond Chenon

2
Để liên kết chúng, hãy sử dụnggit push -u
Ben Creasy

Cảm ơn! Câu trả lời này phải được chấp nhận là giải pháp nhanh chóng và nhanh chóng. Tôi khá chắc chắn rằng nó gần nhất với ý định của OP.
youngrrrr

3
> Tôi không cố phóng tên lửa lên mặt trăng. -- ĐÚNG.
VCavallo

39

Đầu ra git pushkhi đẩy một nhánh mới

> git checkout -b new_branch
Switched to a new branch 'new_branch'
> git push
fatal: The current branch new_branch has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin new_branch

Một git pushgiả định đơn giản rằng đã tồn tại một nhánh từ xa mà nhánh cục bộ hiện tại đang theo dõi. Nếu không có nhánh từ xa như vậy tồn tại và bạn muốn tạo nó, bạn phải chỉ định rằng sử dụng cờ -u(dạng ngắn --set-upstream).

Tại sao lại như vậy? Tôi đoán những người thực hiện cảm thấy rằng việc tạo một nhánh trên điều khiển từ xa là một hành động lớn đến mức khó có thể thực hiện nó do nhầm lẫn. git pushlà một cái gì đó bạn làm tất cả các thời gian.

"Không phải là một nhánh thay đổi mới sẽ được đẩy theo mặc định?" Tôi sẽ nói rằng "một sự thay đổi" trong Git là một cam kết. Một nhánh là một con trỏ đến một cam kết. Đối với tôi nó có ý nghĩa hơn khi nghĩ về một cú đẩy như một thứ gì đó đẩy cam kết sang các kho lưu trữ khác. Những cam kết nào được đẩy được xác định bởi bạn đang ở chi nhánh nào và mối quan hệ theo dõi của chi nhánh đó với các chi nhánh trên điều khiển từ xa.

Bạn có thể đọc thêm về theo dõi các nhánh trong chương Chi nhánh từ xa của sách Pro Git .


Tôi đã không nhận được fatalnhưng tôi đã thực hiện một cam kết trong chi nhánh. Vấn đề này là gì?
Cratylus

@Cratylus không có vấn đề gì. Cam kết an toàn trong kho lưu trữ của bạn và git push -u originsao chép nó vào kho lưu trữ từ xa.
Klas Mellbourn

Không, ý tôi là thực tế là tôi đã không nhận được một fataltin nhắn như câu mà bạn đề cập trong câu trả lời. Sự khác biệt này có phụ thuộc vào thực tế là tôi đã cam kết điều gì đó với chi nhánh không?
Cratylus

@Cratylus Tôi không biết tại sao bạn không nhận được fataltin nhắn. Tôi đoán rằng sự khác biệt phụ thuộc vào chính xác những gì bạn đang sử dụng git. Đầu ra của tôi là từ 1.8.1.msysgit.1 chạy trên Windows 8.
Klas Mellbourn

Tôi có cùng phiên bản nhưng trên Vista
Cratylus

4

Tôi không thể tìm thấy một lý do hợp lý bởi các nhà phát triển ban đầu này một cách nhanh chóng, nhưng tôi có thể đưa ra cho bạn một phỏng đoán có giáo dục dựa trên một vài năm kinh nghiệm của Git.

Không, không phải mọi chi nhánh đều là thứ bạn muốn đẩy ra thế giới bên ngoài. Nó có thể đại diện cho một thí nghiệm riêng tư.

Hơn nữa, nên git pushgửi tất cả các chi nhánh ở đâu? Git có thể hoạt động với nhiều điều khiển từ xa và bạn có thể muốn có các bộ nhánh khác nhau trên mỗi nhánh. Ví dụ, một dự án trung tâm GitHub repo có thể có các nhánh phát hành; một ngã ba GitHub có thể có các nhánh chủ đề để xem xét; và một máy chủ Git cục bộ có thể có các nhánh chứa cấu hình cục bộ. Nếu git pushsẽ đẩy tất cả các nhánh đến điều khiển từ xa mà nhánh hiện tại theo dõi, loại sơ đồ này sẽ dễ dàng bị hỏng.


1) It might represent a private experiment.Ok nhưng vấn đề lớn là gì? Chi nhánh "chính" mà mọi người đang làm việc tức masterlà không bị ảnh hưởng. Trừ khi bạn có ý định giấu mã nguồn 2) git push, without a remote, pushes to the current branch's remoteTôi đã mất bạn ở đây :(
Cratylus

@Cratylus: 1) trong một dự án với hàng tá nhà phát triển, tất cả các chi nhánh quảng cáo lib, bạn sẽ nhận được các repos rất lộn xộn. Tôi làm việc trong các dự án như vậy và tôi sẽ không muốn git fetchhàng trăm chi nhánh hoạt động nửa lần. 2) Tôi đang đề cập đến git pushhành vi mặc định của. Nó đẩy đến điều khiển từ xa mà chi nhánh hiện tại đang theo dõi, nếu có.
Fred Foo

3

HEAD là viết tắt của nhánh hiện tại vì vậy git đẩy -u nguồn gốc hoạt động. Bây giờ để tránh việc gõ này mỗi khi tôi sử dụng bí danh:

git config --global alias.pp 'push -u origin HEAD'

Sau này, mỗi khi tôi muốn đẩy nhánh được tạo thông qua nhánh git -b tôi có thể đẩy nó bằng cách sử dụng:

trang git

Hy vọng điều này tiết kiệm thời gian cho một ai đó!


2

Lúc đầu kiểm tra

Bước-1: git remote -v
// nếu tìm thấy git khởi tạo rồi xóa hoặc bỏ qua bước-2

Bước 2: git remote rm origin
// Sau đó định cấu hình địa chỉ email của bạn trên toàn cầu

Bước 3: git config --global user.email "youremail@example.com"

Bước 4: git initial

Bước-5: git commit -m "Initial Project"
// Nếu đã thêm repo dự án thì bỏ qua bước 6

Bước 6: git remote add origin %repo link from bitbucket.org%

Bước 7: git push -u origin master


1

Tôi vừa trải qua một hoán vị hơn nữa của vấn đề này.

Tôi có một chi nhánh được đặt tên feat/XYZ-1234-some-descriptionbởi vì tôi đang làm việc về vấn đề Jira 1234. Trong quá trình làm việc, tôi đã tạo ra một vấn đề Jira mới để theo dõi một công việc nhỏ hơn và khi tôi đến để thúc đẩy tôi đã quyết định chuyển sang một tên chi nhánh với số vấn đề mới này trong:

git push -u origin feat/XYZ-5678-a-different-description # failed

Điều này đã cho tôi lỗi được thảo luận trong chủ đề SO này. Nhưng vì tôi đã cố gắng chuyển sang một tên chi nhánh khác từ chi nhánh hiện tại của mình, vấn đề của tôi khác với tên được mô tả ở đây. Tôi đã kết thúc việc đổi tên chi nhánh địa phương của mình trước khi tôi có thể đẩy nó:

git branch -m feat/XYZ-1234-some-description feat/XYZ-5678-a-different-description
git push -u origin feat/XYZ-5678-a-different-description # now works

Sau hơn một chút đọc xung quanh tôi nhận ra rằng tôi có thể thiết lập một srctrên git push, một trong hai tên chi nhánh hiện tại, hoặc chỉ HEADnếu thích hợp:

git push -u origin feat/XYZ-1234-some-description:feat/XYZ-5678-a-different-description # also works

-1

Nếu bạn kích hoạt để đẩy những thay đổi mới từ chi nhánh mới của bạn lần đầu tiên. Và nhận được lỗi dưới đây:

*git push -f
fatal: The current branch Coding_Preparation has no upstream branch.

Để đẩy nhánh hiện tại và đặt điều khiển từ xa là ngược dòng, hãy sử dụng

git push -u origin new_branch_name


** Successful Result:** 
 git push -u origin Coding_Preparation
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 599 bytes | 599.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'Coding_Preparation' on GitHub by visiting: ...
 * [new branch]      Coding_Preparation -> Coding_Preparation
Branch 'Coding_Preparation' set up to track remote branch 'Coding_Preparation' from 'origin'.
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.