ĐẦU và ORIG_HEAD trong Git


252

Những biểu tượng này đề cập đến điều gì và chúng có ý nghĩa gì?

(Tôi không thể tìm thấy bất kỳ lời giải thích trong tài liệu chính thức)


4
Lưu ý: HEADhiện tại (sắp tới git1.8.4) ' @'! Xem câu trả lời được chỉnh sửa của tôi dưới đây
VonC

Lưu ý-bis: ' @' (cho HEAD) vẫn đang đến, nhưng không phải cho câu trả lời 1.8.4 được chỉnh sửa và sửa đổi .
VonC

1
Lưu ý ter: ' @' cho HEADtrở lại cho git 1.8.5 / 1.9. Trả lời chỉnh sửa lại .
VonC

21
HEADORIG_HEADtrong Git là như thế $PWD$OLDPWDtrong Bash. :)
musiphil

Câu trả lời:


325

HEADlà (trực tiếp hoặc gián tiếp, tức là tượng trưng) tham chiếu đến cam kết hiện tại. Đó là một cam kết mà bạn đã kiểm tra trong thư mục làm việc (trừ khi bạn thực hiện một số thay đổi hoặc tương đương) và đó là một cam kết trên đó "git commit" sẽ tạo một cam kết mới. Thông thường HEADlà tham chiếu tượng trưng cho một số chi nhánh được đặt tên khác; chi nhánh này hiện đang được kiểm tra chi nhánh hoặc chi nhánh hiện tại. HEADcũng có thể trỏ trực tiếp đến một cam kết; trạng thái này được gọi là "ĐẦU tách rời" và có thể được hiểu là nằm trên nhánh ẩn danh, ẩn danh.

@một mình là một lối tắt cho HEAD, vì Git 1.8.5

ORIG_HEADlà trạng thái trước đó HEAD, được thiết lập bởi các lệnh có hành vi nguy hiểm, để dễ dàng hoàn nguyên chúng. Bây giờ nó ít hữu ích hơn khi Git đã reflog: HEAD@{1}gần tương đương với ORIG_HEAD( HEAD@{1}luôn là giá trị cuối cùng của HEAD, ORIG_HEADlà giá trị cuối cùng HEADtrước khi hoạt động nguy hiểm).

Để biết thêm thông tin đọc git (1) manpage , hướng dẫn sử dụng Git của người sử dụng , các Sách Git Cộng đồngGit Thuật ngữ


2
Xin chào Jakub. +1 cho lời giải thích. Bạn có thể nói chi tiết về phần "gần tương đương" của HEAD @ {1} không? Tôi tham khảo câu trả lời của mình cho chủ đề thread.gmane.org/gmane.comp.version-control.git/38379 (bạn đã ở trong đó, trở lại vào tháng 2 năm 2007) và tôi không hiểu chính xác cuộc thảo luận mà các bạn đang có cú pháp @ {...}.
VonC

19
ORIG_HEAD được thiết lập (tôi nghĩ) chỉ bằng các lệnh 'nguy hiểm', di chuyển CHÍNH nhiều hơn một cam kết. Vì vậy, ORIG_HEAD không phải lúc nào cũng được đặt, trong khi HEAD @ {1} luôn được đặt. @ {1} là $ (git Symbolic-ref HEAD) @ {1}, tức là nó sử dụng reflog cho nhánh hiện tại, không phải là reflog.
Jakub Narębski

Riiight ... Tôi hiểu rồi :) Cảm ơn bạn đã làm rõ điều đó. Đối với những gì nó có giá trị, tôi cũng nâng cao nhận xét của bạn!
VonC

1
"Và ĐẦU là một cam kết trên đó" git commit "sẽ tạo một cam kết mới." - thật tốt để nhớ, cảm ơn! Cũng từ @VonC, 'Đó là cam kết "git commit" được xây dựng trên đầu trang và "git diff --cached" và "git status" so sánh với.'
Minqi Pan

1
bản sửa đổi trợ giúp git sẽ hiển thị git-scm.com/docs/gitrevutions , mô tả tất cả các cách để tham chiếu các cam kết (bao gồm HEADORIG_HEAD).
dahlbyk

104

Từ thiết lập lại git

"Kéo" hoặc "hợp nhất" luôn để lại đầu ban đầu của nhánh hiện tại ORIG_HEAD.

git reset --hard ORIG_HEAD

Đặt lại khó khăn cho nó đưa tệp chỉ mục của bạn và cây làm việc trở lại trạng thái đó và đặt lại đầu của nhánh cho cam kết đó.

git reset --merge ORIG_HEAD

Sau khi kiểm tra kết quả của việc hợp nhất, bạn có thể thấy rằng sự thay đổi trong nhánh khác là không thỏa đáng. Chạy " git reset --hard ORIG_HEAD" sẽ cho phép bạn quay lại nơi bạn đã ở, nhưng nó sẽ loại bỏ những thay đổi cục bộ của bạn, điều mà bạn không muốn. " git reset --merge" Giữ những thay đổi cục bộ của bạn.


Trước khi áp dụng bất kỳ bản vá nào, ORIG_HEAD được đặt thành đầu của nhánh hiện tại.
Điều này hữu ích nếu bạn gặp vấn đề với nhiều lần xác nhận, như chạy ' git am' trên nhánh sai hoặc lỗi trong các cam kết dễ khắc phục hơn bằng cách thay đổi hộp thư (ví dụ + lỗi trong dòng "Từ:").

Ngoài ra, hợp nhất luôn đặt ' .git/ORIG_HEAD' về trạng thái ban đầu của CHÍNH để có thể xóa hợp nhất có vấn đề bằng cách sử dụng ' git reset ORIG_HEAD'.


Lưu ý: từ đây

Đầu là một con trỏ di chuyển. Đôi khi nó có nghĩa là chi nhánh hiện tại, đôi khi không.

Vì vậy, HEAD KHÔNG phải là từ đồng nghĩa với "chi nhánh hiện tại" ở mọi nơi.

HEAD có nghĩa là "hiện tại" ở mọi nơi trong git, nhưng nó không nhất thiết có nghĩa là "nhánh hiện tại" (tức là tách ra).

Nhưng nó hầu như luôn có nghĩa là "cam kết hiện tại".
Đó là cam kết " git commit" được xây dựng trên đầu trang và " git diff --cached" và " git status" so sánh với.
Điều đó có nghĩa là chi nhánh hiện tại chỉ trong bối cảnh rất hạn chế (chính xác là khi chúng tôi muốn một tên chi nhánh hoạt động trên --- đặt lại và phát triển đầu chi nhánh thông qua commit / rebase / vv.).

Reflog là một phương tiện để quay ngược thời gian và cỗ máy thời gian có sự tương tác thú vị với khái niệm "hiện tại".

HEAD@{5.minutes.ago}có thể có nghĩa là "bản tóm tắt chính thức để tìm hiểu xem chúng ta đang ở chi nhánh nào NGAY BÂY GIỜ, và sau đó tìm xem đầu của chi nhánh đó cách đây 5 phút".
Ngoài ra, nó có thể có nghĩa là "cam kết mà tôi đã gọi là ĐẦU 5 phút trước, ví dụ như nếu tôi đã" git show HEAD "hồi đó".


git1.8.4 (tháng 7 năm 2013) giới thiệu giới thiệu một ký hiệu mới!
(thực tế, nó sẽ dành cho phiên bản 1.8.5 hoặc 1.9, Q4 2013: giới thiệu lại với cam kết 9ba89f4 )

Thay vì gõ bốn chữ in hoa " HEAD", bạn có thể nói " @" ngay bây giờ,
ví dụ " git log @".

Xem cam kết cdfd948

Nhập ' HEAD' là tẻ nhạt, đặc biệt là khi chúng ta có thể sử dụng ' @' thay vào đó.

Lý do chọn ' @' là vì nó tuân theo ref@opcú pháp một cách tự nhiên (ví dụ HEAD@{u}), ngoại trừ chúng tôi không có ref, và không có thao tác, và khi chúng tôi không có chúng, sẽ rất hợp lý khi giả định ' HEAD'.

Vì vậy, bây giờ chúng ta có thể sử dụng ' git show @~1', và tất cả những điều tốt đẹp đó.

Cho đến bây giờ ' @' là một tên hợp lệ, nhưng nó mâu thuẫn với ý tưởng này, vì vậy hãy làm cho nó không hợp lệ. Có lẽ rất ít người, nếu có, sử dụng tên này.


Một bài đăng trên blog trong khoảng thời gian 1.8.4-RC3 (ngày 14 tháng 8 năm 2013) đã thông báo rằng tính năng này đã được hoàn nguyên và bị trì hoãn (Cảm ơn Cupcake vì đã hỗ trợ ).
Một lần nữa, nó được giới thiệu một lần nữa với cam kết 9ba89f4 (tháng 9 năm 2013).

Xem cam kết 2c2b664 :

Hoàn nguyên "Thêm @phím tắt mới cho HEAD"

Điều này hoàn nguyên cam kết cdfd948 , vì nó không chỉ áp dụng cho " @" (và các biểu mẫu có sửa đổi như @{u}được áp dụng cho nó), mà còn ảnh hưởng đến ví dụ " refs/heads/@/foo", điều này không nên.

Ý tưởng cơ bản về việc đưa ra một bàn tay ngắn có thể là tốt và chủ đề có thể được thử lại sau, nhưng chúng ta hãy hoàn nguyên để tránh ảnh hưởng đến các trường hợp sử dụng hiện tại cho bản phát hành sắp tới.


Sau khi chạy git reset ORIG_HEAD và cam kết. ORIG_HEAD vẫn còn đó trong phần Tài liệu tham khảo bên cạnh CHÍNH. Tại sao nó không bị xóa khỏi chế độ xem?
bột366

@ Powder366 nhưng a git resetsẽ tạo ra a ORIG_HEAD. Vì vậy, bạn cần phải làm rmbằng tay. Xem stackoverflow.com/a/12418078/6309 chẳng hạn.
VonC

1
@VonC @bí danh cho HEADđang được hoàn nguyên (tạm thời?) Cho bản phát hành Git 1.8.4 ! Nó vừa được công bố ngày hôm nay!

Rất thích bình luận "ngẩng cao đầu"!
Robino

2

Sự hiểu biết của tôi là HEAD chỉ ra nhánh hiện tại, trong khi ORIG_HEAD được sử dụng để lưu trữ HEAD trước đó trước khi thực hiện các thao tác "nguy hiểm".

Ví dụ: git-rebase và git-am ghi lại đầu gốc của nhánh trước khi chúng áp dụng bất kỳ thay đổi nào.


4
ĐẦU không phải lúc nào cũng chỉ vào nhánh hiện tại (nó có thể tách ra)
VonC

1
Vậy "nhánh hiện tại" là gì khi HEAD bị "tách ra?"
cjs

@ CurtJ.Sampson Đó là "không có chi nhánh". đó là lý do tại sao khi bạn ở trong đầu, bạn làm git branch foo -bđể "tạo ra" một nhánh cho những đứa trẻ mồ côi đó.
Royi Namir

1

Từ man 7 gitrevisions:

ĐẦU đặt tên cho cam kết mà bạn dựa trên các thay đổi trong cây làm việc. FETCH_HEAD ghi lại nhánh mà bạn đã tìm nạp từ kho lưu trữ từ xa với lệnh gọi git cuối cùng của bạn. ORIG_HEAD được tạo bởi các lệnh di chuyển ĐẦU của bạn một cách quyết liệt, để ghi lại vị trí của ĐẦU trước khi hoạt động, để bạn có thể dễ dàng thay đổi đầu nhánh trở lại trạng thái trước khi bạn chạy chúng. MERGE_HEAD ghi lại (các) cam kết mà bạn đang hợp nhất vào chi nhánh của mình khi bạn chạy git merge. CHERRY_PICK_HEAD ghi lại cam kết mà bạn đang chọn anh đào khi bạn chạy git cherry-pick.

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.