Tại sao “trạng thái git” hiển thị tôi đang ở nhánh chính và “git nhánh” không có trong kho lưu trữ mới được tạo?


83

Tôi đang cố gắng tự động hóa một quy trình và ra git branchlệnh để tìm xem tôi đang ở nhánh nào. Mọi thứ đều hoạt động tốt ngoại trừ một repo mới khởi tạo git branchkhông trả về kết quả nào. Vì tôi chưa làm gì với repo, thậm chí không phải cam kết ban đầu, tôi có thể chấp nhận câu trả lời. Tuy nhiên, nếu tôi chạy git statusnó cho tôi biết tôi đang ở masterchi nhánh, như đã thấy ở đây:

$ mkdir todelete
$ cd todelete
$ git init
Initialized empty Git repository in /u/u70021a/todelete/.git
$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)
$ git branch
$

Tôi có làm điều gì sai? Có một số cài đặt tôi chưa đặt đúng cách không?

Tôi cũng có một số người mới sử dụng Git và tôi không thể giải thích cho họ lý do tại sao lệnh hiển thị nhánh nào họ đang ở lại không hiển thị gì, nhưng lệnh trạng thái thì không.

Câu trả lời:


94

Tôi đã ủng hộ hai câu trả lời khác, nhưng tôi nghĩ cách nghĩ về điều này rất đơn giản: Bạn có thể ở trên một chi nhánh không tồn tại. Điều đó cũng bình thường trong một kho lưu trữ trống mới, bởi vì để tên nhánh tồn tại, tên nhánh đó phải xác định ID băm của một cam kết hợp lệ, hiện có. Một kho lưu trữ trống mới không có cam kết, vì vậy không có tên nhánh nào được phép tồn tại.

Tuy nhiên, ban đầu bạn đang ở trên một nhánh nào đó. Chi nhánh bạn đang ở là chi nhánh có tên được lưu trữ trong tên đặc biệt HEAD. Trong một kho lưu trữ mới, trống, Git lưu trữ tên master(chính xác hơn là refs/heads/master—tên đầy đủ của chi nhánh) HEAD, vì vậy bạn đang ở trên master, trong khi masterkhông tồn tại.

Bạn có thể thay đổi nhánh không tồn tại mà bạn đang sử dụng git checkout -b:

$ git init
Initialized empty Git repository in [path]
$ git checkout -b asdf
Switched to a new branch 'asdf'
$ git checkout -b hello
Switched to a new branch 'hello'

Bất cứ khi nào bạn ở trên một nhánh không tồn tại, lần cam kết tiếp theo mà bạn thực hiện sẽ tạo nhánh. Đây cũng là cách git checkout --orphanhoạt động.


6
Cảm ơn. Trong khi tôi không đồng ý với những gì git đang hiển thị. Ít nhất thì tôi hiểu tại sao. Ví dụ thanh toán của bạn thật thú vị. Theo tài liệu cho "git checkout" thì -b có nghĩa là: Tạo một nhánh mới có tên <new_branch> không hoàn toàn đúng. Trong ví dụ của bạn, không có nhánh asdf hoặc hello thực sự được tạo. Nhưng chúng sẽ như vậy nếu một cam kết được thực hiện. Ý kiến ​​cá nhân của tôi là thông báo "On branch master" nên được thay đổi thành "Next commit to branch master" vì cho đến khi thực hiện một cam kết thì nhánh chính không tồn tại.
GOVarney

2
Tôi không chắc liệu điều này có liên quan đến trường hợp của bạn hay không, nhưng tôi muốn chỉ ra rằng đối với Git, có thể không có ở bất kỳ chi nhánh nào.
sklott 17/07/19

Git trong nội bộ sử dụng cat .git/HEADđể xem những gì chi nhánh đó là ngày, tìm ra các chi nhánh hiện hữu sẽ tiêu thụ nhiều CPU và thời gian đĩa, do đó của lẽ tại sao họ không làm điều đó
Ferrybig

Điều cần đề cập đến của imo là bạn hoàn toàn không nên sử dụng git branchtrong một quy trình tự động vì nó không được thiết kế cho trường hợp sử dụng đó. Sẽ rất thú vị khi xem những gì các lệnh không phải sứ thể hiện ở đây, git symbolic-ref --short HEADcó hành vi tương tự không?
Voo

@Voo: git symbolic-refhiển thị tên có trong HEAD(do đó là tham chiếu nhánh mồ côi / chưa sinh) với điều kiện HEADkhông được tách ra. Trong kho lưu trữ trống mới, HEAD không thể tách rời vì HEAD đã tách rời phải chứa mã băm của một cam kết hợp lệ, hiện có. (Trong một kho rỗng, với một cái đầu tách ra, git symbolic-reftạo ra một lỗi.)
torek

23

git branchkhông hiển thị gì vì không có chi nhánh. Tuy nhiên, như bạn có thể đọc trong man git init:

Lệnh này tạo một kho lưu trữ Git trống - về cơ bản là một thư mục .git với các thư mục con cho các đối tượng, refs / heads, refs / tags và các tệp mẫu. Tệp HEAD ban đầu tham chiếu đến HEAD của nhánh chính cũng được tạo.

Tôi đã tô đậm phần mà tôi nghĩ là có liên quan - có vẻ như mặc dù chưa có nhánh chính, nhưng một tham chiếu đến nó đã tồn tại và đó là lý do tại sao nó được hiển thị git status. Một nhánh thích hợp sẽ được tạo khi cam kết.


3
Vì vậy, có vẻ như "trạng thái git" chỉ hiển thị "tên chi nhánh" như được thấy trong .git / HEAD (ref: refs / heads / master) nhưng không kiểm tra tính nhất quán bằng cách nhìn vào .git / refs / heads để xem nó thực sự tồn tại.
GOVarney

Tôi không thể nói chắc chắn, vì tôi đã không kiểm tra mã của git, nhưng những gì bạn viết có ý nghĩa với tôi. Nhưng tôi vẫn thích câu trả lời của tôi hơn :).
Stanowczo

17

Các câu trả lời hiện tại giải quyết câu hỏi theo nghĩa đen là tại sao đầu ra là như thế nào, nhưng tôi nghĩ rằng chúng đã loại bỏ vấn đề thực sự ...

Bạn nói rằng bạn đang tự động hóa một cái gì đó, vì vậy tôi đề nghị rằng đó cũng không git statusphải git branchlà công cụ tốt nhất trong bối cảnh kịch bản.

Có thể tìm thấy một số lựa chọn thay thế trong cuộc thảo luận này: Cách xác định theo chương trình nhánh Git đã kiểm tra hiện tại

Nếu không biết nhu cầu của bạn (hoặc bạn muốn một nhánh chưa sinh hoạt động như thế nào) thì tôi không nhất thiết phải đưa ra đề xuất, nhưng điểm tôi hiểu là, một số lệnh dành cho tương tác của con người (sứ) và những lệnh khác dành cho tập lệnh ( ống nước)


15

Chi nhánh vẫn chưa được sinh ra. Do đó git branchkhông hiển thị nó ( git symbolic-ref HEADchỉ ra rằng HEAD của bạn đang trỏ đến nhánh cái mặc định và nó chưa được sinh ra cũng như git branchkhông hiển thị nó, tức là bạn có thể ở trên nhánh chưa tồn tại). Tuy nhiên, cam kết một cái gì đó sẽ tạo ra nhánh.

Đây cũng là trường hợp nếu bạn thanh toán một orphanchi nhánh.

Tôi cho rằng git statushiển thị tên chi nhánh vì đây là chi nhánh sẽ được tạo.

Đối với tập lệnh, hãy xem Cách xác định theo chương trình nhánh Git đã kiểm tra hiện tại


2

Trong git, nhánh mặc định là master. Khi bạn commit, git sẽ "sử dụng" nhánh hiện tại mà bạn đang sử dụng. Vì bạn đã khởi tạo một kho lưu trữ mới nên bạn đang ở nhánh "mặc định" và đây là lý do tại sao bạn không thấy nó trong danh sách các nhánh của mình, nó sẽ hiển thị khi bạn thực hiện các thay đổi của mình.

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây


2
Tôi hiểu về sự phân nhánh, tôi không hiểu tại sao "git status" lại nói rằng tôi đang ở trên một chi nhánh không tồn tại.
GOVarney
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.