Tại sao gọi nhánh git --unset-upflow để sửa lỗi?


160

Tôi không chỉ là người mới khi nói đến các hoạt động nâng cao trong git. Tôi duy trì blog của mình bằng cách sử dụng Octopress khung blog . Mặc dù Octopress không được phát triển kể từ năm 2011, nhưng nó phục vụ mục đích của tôi rất tốt và vì vậy tôi chưa nghĩ đến việc thay đổi bất cứ điều gì cho đến nay.

FYI, blog của tôi được lưu trữ trên Github Pages.

Hôm nay, trong khi làm việc trên một bài đăng mới, git statusđã hiển thị thông báo sau:

On branch source
Your branch is based on 'origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

Thông báo tương tự lặp lại cho tất cả các lệnh tiếp theo như git add ., git commit -m 'message'git push origin source.

  • Tin nhắn có ý nghĩa gì?
  • Là một cái gì đó bị hỏng?
  • Nếu có?
  • Tôi có cần sửa nó không?

Nếu có thể, xin vui lòng chỉ cho tôi một bài viết pdf / web nơi tôi có thể đọc về điều này và hiểu nó cho tương lai.

Thêm chi tiết:

bash-3.2$ git branch -a
* source
  remotes/octopress/2.1
  remotes/octopress/HEAD -> octopress/master
  remotes/octopress/gh-pages
  remotes/octopress/linklog
  remotes/octopress/master
  remotes/octopress/refactor_with_tests
  remotes/octopress/rubygemcli
  remotes/octopress/site
  remotes/origin/source

Xin vui lòng cho tôi biết nếu cần thêm thông tin. Cảm ơn.

Câu trả lời:


196

Phiên bản TL; DR: chi nhánh theo dõi từ xa đã origin/mastertừng tồn tại, nhưng hiện tại không có, vì vậy chi nhánh địa phương sourceđang theo dõi thứ gì đó không tồn tại, điều đáng nghi ngờ nhất là điều đó có nghĩa là một tính năng Git khác không thể làm gì cho bạn. Git đang cảnh báo bạn về nó. Bạn đã hòa thuận tốt mà không có tính năng "theo dõi ngược dòng" hoạt động như dự định, do đó, tùy thuộc vào việc bạn có nên thay đổi bất cứ điều gì hay không.

Đối với một cài đặt ngược dòng khác, hãy xem Tại sao tôi phải "git đẩy --set-upstream origin <Branch>"?


Cảnh báo này là một điều mới trong Git, xuất hiện đầu tiên trong Git 1.8.5. Các ghi chú phát hành chỉ chứa một mục đạn ngắn về nó:

  • "Git chi nhánh -v -v" (và "trạng thái git") không phân biệt giữa một nhánh không dựa trên bất kỳ nhánh nào khác, một nhánh được đồng bộ hóa với nhánh ngược dòng của nó và một nhánh được cấu hình với một luồng ngược dòng nhánh không còn tồn tại.

Để mô tả ý nghĩa của nó, trước tiên bạn cần biết về "điều khiển từ xa", "các nhánh theo dõi từ xa" và cách Git xử lý "theo dõi ngược dòng". ( Chi nhánh theo dõi từ xa là một thuật ngữ thiếu sót khủng khiếp Tôi đã bắt đầu sử dụng tên từ xa theo dõi thay vào đó, mà tôi nghĩ là một sự cải thiện nhẹ. Dưới đây, tuy nhiên, tôi sẽ sử dụng "từ xa theo dõi chi nhánh" cho phù hợp với tài liệu Git. )

Mỗi "remote" chỉ đơn giản là một tên, như originhoặc octopresstrong trường hợp này. Mục đích của họ là ghi lại những thứ như URL đầy đủ của những nơi mà bạn git fetchhoặc git pullcập nhật. Khi bạn sử dụng 1 Git, hãy chuyển đến điều khiển từ xa đó (sử dụng URL đã lưu) và mang đến bộ cập nhật thích hợp. Nó cũng ghi lại các bản cập nhật, sử dụng "các nhánh theo dõi từ xa".git fetch remote,

"Chi nhánh theo dõi từ xa" (hoặc tên theo dõi từ xa) chỉ đơn giản là bản ghi tên chi nhánh như được nhìn thấy lần cuối trên một số "từ xa". Mỗi điều khiển từ xa là một kho lưu trữ Git, vì vậy nó có các nhánh. Các nhánh trên "nguồn gốc" từ xa được ghi lại trong kho lưu trữ cục bộ của bạn bên dưới remotes/origin/. Các văn bản mà bạn thấy nói rằng có một chi nhánh tên sourcetrên origin, và các chi nhánh đặt tên 2.1, linklogvà vân vân trên octopress.

(Tất nhiên, một nhánh "bình thường" hoặc "cục bộ" chỉ là một tên nhánh mà bạn đã tạo trong kho lưu trữ của riêng bạn.)

Cuối cùng, bạn có thể thiết lập một nhánh (cục bộ) để "theo dõi" một "nhánh theo dõi từ xa". Khi nhánh cục bộ Lđược đặt để theo dõi nhánh theo dõi từ xa R, Git sẽ gọi R"nhánh ngược" của nó và cho bạn biết liệu bạn có "đi trước" và / hoặc "phía sau" ngược dòng hay không (về mặt cam kết). Đó là bình thường (thậm chí khuyên-thể) cho các chi nhánh địa phương và từ xa theo dõi các chi nhánh để sử dụng cùng tên (trừ phần tiền tố từ xa), giống như sourceorigin/source, nhưng đó không phải là thực sự cần thiết.

Và trong trường hợp này, điều đó không xảy ra. Bạn có một chi nhánh địa phương sourcetheo dõi một chi nhánh theo dõi từ xa origin/master.

Bạn không cần phải biết cơ chế chính xác về cách thức Git thiết lập một chi nhánh địa phương để theo dõi một điều khiển từ xa, nhưng chúng có liên quan dưới đây, vì vậy tôi sẽ trình bày cách thức hoạt động của nó. Chúng tôi bắt đầu với tên chi nhánh địa phương của bạn , source. Có hai mục cấu hình sử dụng tên này, đánh vần branch.source.remotebranch.source.merge. Từ đầu ra mà bạn đã hiển thị, rõ ràng cả hai đều được đặt, do đó bạn sẽ thấy những điều sau nếu bạn chạy các lệnh đã cho:

$ git config --get branch.source.remote
origin
$ git config --get branch.source.merge
refs/heads/master

Đặt những thứ này lại với nhau, 2 cái này cho Git biết rằng chi nhánh sourcecủa bạn theo dõi "chi nhánh theo dõi từ xa" của bạn , origin/master.

Nhưng bây giờ hãy nhìn vào đầu ra của git branch -a , trong đó hiển thị tất cả các tên nhánh theo dõi cục bộ và từ xa trong kho lưu trữ của bạn. Các tên theo dõi từ xa được liệt kê dưới remotes/... và không córemotes/origin/master . Có lẽ đã có lúc, nhưng giờ nó đã biến mất.

Git đang nói với bạn rằng bạn có thể loại bỏ thông tin theo dõi --unset-upstream. Điều này sẽ xóa cả hai branch.source.originbranch.source.merge, và dừng cảnh báo.

Dường như khá có khả năng những gì bạn muốn, mặc dù, là để chuyển đổi từ theo dõi origin/master, sang theo dõi một thứ khác: có thể origin/source, nhưng có thể là một trong nhữngoctopress/ cái tên.

Bạn có thể làm điều này với git branch --set-upstream-to, 3 vd:

$ git branch --set-upstream-to=origin/source

(giả sử bạn vẫn ở trên "nguồn" chi nhánh và điều đó origin/source là thượng nguồn mà bạn muốn, không có cách nào để tôi nói cái nào, nếu có, dù bạn thực sự muốn gì).

(Xem thêm Làm thế nào để bạn tạo một nhánh Git hiện có theo dõi một nhánh từ xa? )

Tôi nghĩ rằng cách bạn đến đây là khi bạn mới làm một thứ git clone, thứ bạn nhân bản từ một nhánh master. Bạn cũng có một nhánh master, được đặt để theo dõi origin/master(đây là một thiết lập tiêu chuẩn, bình thường cho git). Điều này có nghĩa là bạn đã có branch.master.remotebranch.master.mergethiết lập, đến originrefs/heads/master. Nhưng sau đó originremote của bạn đổi tên từ masterthành source. Để phù hợp, tôi tin rằng bạn cũng đã thay đổi tên địa phương của bạn từ masterthành source. Đây đã thay đổi tên của các thiết lập của bạn, từ branch.master.remoteđến branch.source.remotevà đi từ branch.master.mergeđể branch.source.merge... nhưng nó bỏ cái cũ giá trị , vì vậy branch.source.mergebây giờ đã sai.

Chính tại thời điểm này, liên kết "ngược dòng" đã bị hỏng, nhưng trong các phiên bản Git cũ hơn 1.8.5, Git không bao giờ nhận thấy cài đặt bị hỏng. Bây giờ bạn có 1.8.5, nó chỉ ra điều này.


Điều đó bao gồm hầu hết các câu hỏi, nhưng không phải là câu hỏi "tôi có cần sửa nó không". Có khả năng là bạn đã làm việc xung quanh tình trạng hỏng hóc trong nhiều năm nay, bằng cách thực hiện (ví dụ :). Nếu bạn tiếp tục làm điều đó, nó sẽ tiếp tục giải quyết vấn đề, vì vậy, không, bạn không cần phải sửa nó. Nếu bạn thích, bạn có thể sử dụng để loại bỏ ngược dòng và dừng các khiếu nại, và không có chi nhánh địa phương được đánh dấu là cógit pull remote branchgit pull origin source--unset-upstreamsource bất kỳ thượng nguồn nào cả.

Điểm có một thượng nguồn là làm cho các hoạt động khác nhau thuận tiện hơn. Chẳng hạn, git fetchtheo sau git mergethường sẽ "làm điều đúng" nếu dòng ngược được đặt chính xác và git statussau đó git fetchsẽ cho bạn biết liệu repo của bạn có khớp với dòng ngược dòng, cho nhánh đó không.

Nếu bạn muốn sự thuận tiện, hãy thiết lập lại ngược dòng.


1 lầngit pull sử dụng git fetchvà kể từ Git 1.8.4, điều này (cuối cùng!) Cũng cập nhật thông tin "chi nhánh theo dõi từ xa". Trong các phiên bản cũ hơn của Git, các bản cập nhật không được ghi lại trong các nhánh theo dõi từ xa git pull, chỉ với git fetch. Vì Git của bạn phải có ít nhất phiên bản 1.8.5, đây không phải là vấn đề đối với bạn.

2 Vâng, điều này cộng với một dòng cấu hình tôi cố tình bỏ qua được tìm thấy bên dưới remote.origin.fetch. Git phải ánh xạ tên "hợp nhất" để tìm ra rằng tên địa phương đầy đủ cho nhánh từ xa là refs/remotes/origin/master. Ánh xạ hầu như luôn luôn hoạt động giống như thế này, tuy nhiên, do đó, nó có thể dự đoán rằng masterđi vào origin/master.

3 Hoặc, với git config. Nếu bạn chỉ muốn đặt ngược dòng thành origin/sourcephần duy nhất phải thay đổi là branch.source.merge, và git config branch.source.merge refs/heads/source sẽ làm điều đó. Nhưng --set-upstream-tonói những gì bạn muốn làm, thay vì bắt bạn tự làm bằng tay, vì vậy đó là "cách tốt hơn".


3
+1 cho "Nếu bạn thích, bạn có thể sử dụng --unset-up để có nhánh cục bộ được đánh dấu là không có bất kỳ ngược dòng nào cả."
BeatriceThalo

157

Câu trả lời của torek có lẽ là hoàn hảo, nhưng tôi chỉ muốn bản ghi đề cập đến một trường hợp khác khác với câu hỏi được mô tả trong câu hỏi ban đầu nhưng cùng một lỗi có thể xuất hiện (vì nó có thể giúp những người khác gặp vấn đề tương tự):

Tôi đã tạo một repo trống (mới) bằng cách sử dụng git init --baretrên một trong các máy chủ của mình. Sau đó tôi cógit clone nó vào một không gian làm việc cục bộ trên PC của tôi.

Sau khi cam kết một phiên bản duy nhất trên repo cục bộ, tôi đã gặp lỗi đó sau khi gọi git status .

Theo câu trả lời của torek, tôi hiểu rằng những gì đã xảy ra là cam kết đầu tiên trên thư mục làm việc cục bộ repo đã tạo ra nhánh "chính". Nhưng trên repo từ xa (trên máy chủ) không bao giờ có bất cứ thứ gì, vì vậy thậm chí không có một nhánh "chính" (từ xa / nguồn gốc / chủ).

Sau khi chạy git push origin mastertừ repo cục bộ, repo từ xa cuối cùng đã có một nhánh chính. Điều này đã ngăn lỗi xuất hiện.

Vì vậy, để kết luận - người ta có thể nhận được một lỗi như vậy cho một repo từ xa mới với cam kết bằng không vì nó không có chi nhánh, bao gồm cả "chủ".


6
Đây hiện là kết quả thứ 1 cho thông báo lỗi này On branch source Your branch is based on 'origin/master', but the upstream is gone. (use "git branch --unset-upstream" to fixup)và, trong khi chủ quan, nhiều khả năng nguyên nhân là do nhân bản một kho lưu trữ trống rất tuyệt vời để có câu trả lời thay thế ở đây.
Bella

2
Tôi nghĩ đó là lý do tại sao nên khởi tạo kho lưu trữ mới của bạn với tệp README.md, ngay cả khi đó là một tệp trống
Ahmed Hussein

8

Điều này có thể giải quyết vấn đề của bạn.

Sau khi thực hiện các thay đổi, bạn có thể cam kết và sau đó

git remote add origin https://(address of your repo) it can be https or ssh
then
git push -u origin master

Hi vọng nó sẽ giúp ích cho bạn.

cảm ơn


1
Điều này thực sự có ích - lý do được nêu chi tiết trong câu trả lời của tôi (Tóm lại - điều này tạo ra nhánh chủ bị thiếu trong repo từ xa).
ElazarR

7

Đối với tôi, .git/refs/origin/masterđã có tham nhũng.

Tôi đã làm như sau, trong đó khắc phục vấn đề cho tôi.

rm .git/refs/remotes/origin/master
git fetch
git branch --set-upstream-to=origin/master

0

Trên thực tế, torek đã nói với bạn cách sử dụng các công cụ tốt hơn nhiều so với khả năng của tôi. Tuy nhiên, trong trường hợp này tôi nghĩ điều quan trọng là chỉ ra điều gì đó đặc biệt nếu bạn làm theo hướng dẫn tại http://octopress.org/docs/deploying/github/ . Cụ thể, bạn sẽ có nhiều kho github trong thiết lập của mình. Trước hết, một trong số đó có tất cả các mã nguồn cho trang web của bạn nói là thư mục $WEBSITE, và sau đó là một tệp chỉ có các tệp được tạo tĩnh nằm trong đó $WEBSITE/_deploy. Điều thú vị của thiết lập là có một .gitignoretệp trong $WEBSITEthư mục để thiết lập này thực sự hoạt động.

Giới thiệu đủ. Trong trường hợp này, lỗi cũng có thể đến từ kho lưu trữ trong _deploy.

cd _deploy

git branch -a
* master
remotes/origin/master
remotes/origin/source

Trong .git/configbạn thường sẽ cần phải tìm một cái gì đó như thế này:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = git@github.com:yourname/yourname.github.io.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master

Nhưng trong trường hợp của bạn, chủ chi nhánh không có điều khiển từ xa.

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = git@github.com:yourname/yourname.github.io.git
    fetch = +refs/heads/*:refs/remotes/origin/*

Mà bạn có thể giải quyết bằng cách:

cd _deploy
git branch --set-upstream-to=origin/master

Vì vậy, mọi thứ như torek đã nói với bạn, nhưng điều quan trọng là chỉ ra rằng điều này rất có thể liên quan đến _deploythư mục hơn là gốc của trang web của bạn.

PS: Có thể đáng để sử dụng shell như zshvới gitplugin để không bị thứ này cắn trong tương lai. Nó sẽ ngay lập tức cho thấy rằng _deployliên quan đến một kho lưu trữ khác nhau.


0

Tôi đã có câu hỏi này hai lần và nó luôn bị gây ra bởi sự hỏng hóc của tệp bộ đệm git tại chi nhánh địa phương của tôi. Tôi đã sửa nó bằng cách viết hàm băm cam kết bị thiếu vào tập tin đó. Tôi đã nhận đúng hash hash từ máy chủ và chạy lệnh sau cục bộ:

cat .git/refs/remotes/origin/feature/mybranch \
echo 1edf9668426de67ab764af138a98342787dc87fe \
>> .git/refs/remotes/origin/feature/mybranch

0

Vấn đề: Chi nhánh của bạn dựa trên 'origin / master', nhưng ngược dòng đã biến mất.

Giải pháp: nhánh git - ngược dòng


3
Chào mừng đến với stackoverflow. Câu hỏi không phải là về cách sửa lỗi, anh ta muốn biết tại sao lỗi này được nêu ra và liệu anh ta có nên làm gì đó với nó không. Hãy giải quyết điều này trong câu trả lời của bạn.
cronoik

0

xóa chi nhánh địa phương của bạn bằng cách làm theo lệnh

git branch -d branch_name

bạn cũng có thể làm

git branch -D branch_name 

về cơ bản buộc phải xóa (ngay cả khi cục bộ không được hợp nhất với nguồn)

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.