Đầu trong git là gì?


232

Dường như có một sự khác biệt giữa lần xác nhận cuối cùng, CHÍNH và trạng thái của tệp mà tôi có thể thấy trong thư mục của mình.

TRƯỚC là gì, tôi có thể làm gì với nó và tôi nên tránh sai lầm gì?



1
Bắt đầu với Git v1.8.4, tất cả các câu trả lời dưới đây sử dụng đó HEADhoặc headcó thể sử dụng @thay cho HEADthay thế. Xem câu trả lời này (phần cuối) để tìm hiểu lý do tại sao bạn có thể làm điều đó.

3
Từ git-scm : HEAD trong Git là con trỏ tới tham chiếu nhánh hiện tại, lần lượt là một con trỏ đến lần xác nhận cuối cùng bạn thực hiện hoặc lần xác nhận cuối cùng được kiểm tra trong thư mục làm việc của bạn. Điều đó cũng có nghĩa nó sẽ là cha mẹ của lần cam kết tiếp theo bạn làm. Nói chung đơn giản nhất khi nghĩ về nó vì CHÍNH là ảnh chụp nhanh về cam kết cuối cùng của bạn.
Quazi Irfan

3
Bản sao có thể có của HEAD trong Git là gì?
Buts

Câu trả lời:


185

HEAD là một tham chiếu đến cam kết cuối cùng trong nhánh thanh toán hiện tại.


Có một ngoại lệ nhỏ cho vấn đề này, đó là ĐẦU tách rời. Một tiêu đề tách rời là tình huống bạn kết thúc bất cứ khi nào bạn kiểm tra một cam kết (hoặc thẻ) thay vì một chi nhánh. Trong trường hợp này, bạn phải tưởng tượng đây là một nhánh tạm thời không có tên; Vì vậy, thay vì có một tham chiếu chi nhánh được đặt tên, chúng tôi chỉ có ĐẦU. Nó vẫn sẽ cho phép bạn thực hiện các cam kết (sẽ cập nhật CHÍNH), vì vậy định nghĩa ngắn ở trên vẫn đúng nếu bạn nghĩ rằng một ĐẦU tách rời là một nhánh tạm thời không có tên.


1
Vậy tại sao bạn có thể có hai cái đầu?
e-satis

1
@ e-satis: đôi khi bạn sẽ thấy các chi nhánh được gọi là đầu - chúng được lưu trữ trong refs/heads. Đầu chữ thường là khác nhau HEAD, mặc dù. Câu trả lời của tôi làm rõ điều này một chút.
Cascabel

7
@ e-satis: Đó không phải là regex. Đây ^chỉ là ký hiệu của git cho "cam kết trước" - đó là cam kết trước hiện tại. (Nếu hiện tại là hợp nhất, nó sử dụng cha mẹ đầu tiên.)
Cascabel

1
@ e-satis: Xem phần sửa đổi chỉ định của trang man để biết git-rev-list để biết thêm thông tin về tất cả các cách để xác định cam kết - đây chỉ là một phần nhỏ. kernel.org/pub/software/scm/git/docs/ từ
Cascabel

1
Không, khi rev và HEAD đang trỏ đến cùng một cam kết, không có sự khác biệt. Và thậm chí bạn có thể viết id xác nhận (giá trị SHA-1) thay vì rev hoặc HEAD. Và đừng lo lắng, bạn đừng quấy rối chúng tôi bằng các câu hỏi :) (ít nhất là tôi: P)
chọc

87

HEAD là một tham chiếu (tham chiếu) cho cam kết hiện đang được kiểm tra.

Ở trạng thái bình thường, nó thực sự là một ref mang tính biểu tượng cho chi nhánh mà bạn đã kiểm tra - nếu bạn nhìn vào nội dung của .git / Head, bạn sẽ thấy một cái gì đó như "ref: refs / Heads / master". Chi nhánh chính nó là một tham chiếu đến cam kết ở đầu chi nhánh. Do đó, ở trạng thái bình thường,HEAD có hiệu quả đề cập đến cam kết ở đầu nhánh hiện tại.

Cũng có thể có một "ĐẦU tách ra". Điều này xảy ra khi bạn kiểm tra một cái gì đó ngoài một nhánh (cục bộ), như một nhánh từ xa, một cam kết cụ thể hoặc một thẻ. Nơi phổ biến nhất để thấy điều này là trong một cuộc nổi loạn tương tác, khi bạn chọn chỉnh sửa một cam kết. Ở trạng thái CHÍNH tách rời, ĐẦU của bạn là một tham chiếu trực tiếp đến một cam kết - nội dung của .git / HEAD sẽ là hàm băm SHA1.

Nói chung, HEAD chỉ là một tên thuận tiện có nghĩa là "những gì bạn đã kiểm tra" và bạn không thực sự phải lo lắng nhiều về nó. Chỉ cần lưu ý về những gì bạn đã kiểm tra và nhớ rằng bạn có thể không muốn cam kết nếu bạn không ở trong một chi nhánh (trạng thái CHÍNH tách rời) trừ khi bạn biết bạn đang làm gì (ví dụ như trong một cuộc nổi loạn tương tác) .


6
Đây là điều tôi không hiểu. Nếu bạn kiểm tra một chi nhánh từ xa, tại sao bạn lại kết thúc với một "ĐẦU tách rời". Tại sao bạn không tự động nhảy vào chi nhánh trong repo địa phương tương ứng với điều khiển từ xa của bạn?
e-satis

3
@ e-satis: Nếu bạn muốn chi nhánh địa phương, hãy kiểm tra chi nhánh địa phương. Hãy nhớ rằng hai cái này không nhất thiết giống nhau - bạn phải nói với cái cục bộ để hợp nhất cái từ xa (hoặc kéo). Việc theo dõi chỉ để nó biết cái nào sẽ tự động kéo khi bạn yêu cầu. Lý do nó tách ra là vì nhánh từ xa được dự định là một con trỏ đến vị trí nhìn thấy lần cuối của nhánh trong repo từ xa. Nếu bạn cố gắng cam kết với nó, repo từ xa sẽ không thay đổi, vì vậy chi nhánh từ xa cũng không nên.
Cascabel

1
OK, đó là những gì tôi đã không nhận được: có một chi nhánh địa phương được đặt tên theo cách không ngụ ý nó giống như điều khiển từ xa. Thực sự rất khó để có được ngay từ đầu vì tôi đến từ một nền tảng SVN :-) Cảm ơn người đàn ông. BTW, làm thế nào để bạn di chuyển một Head không đầu đến một chi nhánh địa phương để cam kết nó ở đây?
e-satis

3
@ e-satis: Câu trả lời chung là git rebase <branch> HEAD. Điều này sẽ tìm ra tổ tiên chung cuối cùng của <branch>HEAD, sau đó lấy tất cả các cam kết từ đó đến HEADvà áp dụng chúng (rebase chúng) lên <branch>. Về cơ bản, nó thực hiện điều này bằng cách áp dụng chúng như các bản vá, vì vậy nếu hai nhánh thực sự khác nhau, có thể có xung đột. Nhưng nếu <branch>là tổ tiên của HEAD(tức là bạn đã ở đúng nơi, chỉ cần quên bạn đã tách ra HEAD) thì rebase chỉ là một sự hợp nhất nhanh chóng.
Cascabel

3
Đây là một trong những mô tả rõ ràng và chính xác nhất về git HEAD mà tôi đã thấy, sau khi tìm kiếm một lúc.
LarsH

21

Tôi luôn nghĩ HEAD~5có nghĩa là GO đến 5 lần cam kết trước đó. Nhưng nó không mang phần GO của lệnh. Nó chỉ mang tham chiếu / 'nơi để' một phần của lệnh.

Trong điều kiện của giáo nó được sử dụng để trả lời các câu hỏi về: Ở ĐÂU tôi nên đi đâu? Để cam kết?

  • HEAD có nghĩa là (tham chiếu đến) cam kết hiện tại
  • HEAD~1 có nghĩa là (tham chiếu đến) 1 cam kết trước
  • HEAD~ CSONG có nghĩa là (tham chiếu đến) 1 cam kết trước
  • HEAD~87 có nghĩa là (tham chiếu đến) 87 cam kết trước

Sử dụng:

  • git checkout HEAD~1 sẽ thực sự GO / thanh toán đến 1 cam kết / tham chiếu trước
  • git reset HEAD~3 sẽ không phổ biến 3 lần xác nhận cuối cùng của bạn - mà không xóa các thay đổi, tức là bạn có thể thấy tất cả các thay đổi được thực hiện trong 3 lần xác nhận gần nhất cùng nhau, xóa bất kỳ điều gì bạn không thích hoặc thêm vào đó và sau đó cam kết lại tất cả.
  • git diff HEAD~3 để kiểm tra các thay đổi trong 3 lần xác nhận gần nhất

3
trở lại câu trả lời của riêng tôi :)
Honey

15

Con trỏ đầu trong Git

Git duy trì một biến tham chiếu có tên là HEAD. Và chúng tôi gọi biến này là một con trỏ, vì mục đích của nó là để tham chiếu hoặc trỏ đến một cam kết cụ thể trong kho lưu trữ. Khi chúng ta thực hiện các xác nhận mới, con trỏ sẽ thay đổi hoặc di chuyển để trỏ đến một cam kết mới. HEAD luôn chỉ đến đỉnh của nhánh hiện tại trong kho lưu trữ của chúng tôi. Bây giờ, điều này phải làm với kho lưu trữ của chúng tôi, không phải chỉ mục dàn dựng hoặc thư mục làm việc của chúng tôi.

Một cách khác để nghĩ về nó là trạng thái cuối cùng của kho lưu trữ của chúng tôi hoặc trạng thái được kiểm tra lần cuối và bởi vì đó là nơi kho lưu trữ rời khỏi hoặc trạng thái cuối cùng, bạn cũng có thể nói rằng CHÍNH chỉ đến cha mẹ của cam kết tiếp theo hoặc nó nơi cam kết viết sẽ diễn ra.

Tôi nghĩ rằng một phép ẩn dụ tốt để nghĩ về điều này là đầu phát lại và ghi âm trên một máy ghi băng cassette. Khi chúng tôi bắt đầu ghi âm thanh, băng di chuyển qua đầu và nó ghi vào nó. Khi chúng ta nhấn Dừng nơi dừng đầu ghi đó là nơi nó sẽ bắt đầu ghi lại khi chúng ta nhấn Ghi lần thứ hai. Bây giờ chúng ta có thể di chuyển xung quanh, chúng ta có thể di chuyển đầu đến các vị trí khác nhau, nhưng bất cứ nơi nào đầu được định vị khi chúng tôi nhấn Record một lần nữa, đó là nơi nó sẽ bắt đầu ghi âm.

Con trỏ CHÍNH trong Git rất giống nhau, nó trỏ đến nơi chúng ta sẽ bắt đầu ghi âm tiếp theo. Đó là nơi chúng tôi rời khỏi kho lưu trữ của chúng tôi cho những thứ mà chúng tôi đã cam kết.


0

Nói một cách đơn giản, HEAD là một tham chiếu đến cam kết cuối cùng trong nhánh thanh toán hiện tại.

Hãy nghĩ về ĐẦU là "nhánh hiện tại". Khi bạn chuyển đổi các nhánh với kiểm tra git, bản sửa đổi CHÍNH sẽ thay đổi để trỏ đến đỉnh của nhánh mới.

Bạn có thể thấy những gì CHÍNH chỉ ra bằng cách làm:

cat .git/HEAD

TRƯỚC có thể đề cập đến một sửa đổi cụ thể không liên quan đến tên chi nhánh. Tình huống này được gọi là một ĐẦU tách ra.

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.