Trước tiên, hãy làm rõ CHÍNH là gì và ý nghĩa của nó khi nó bị tách ra.
ĐẦU là tên tượng trưng cho cam kết hiện đang được kiểm tra. Khi không bị tách ra ( tình huống TRỌNG 1 bình thường : bạn có một chi nhánh đã được kiểm tra), thì TRỰC TIẾP thực sự chỉ vào một lượt giới thiệu của Chi nhánh và chi nhánh chỉ vào cam kết. Do đó, ĐẦU TIÊN gắn liền với một chi nhánh. Khi bạn thực hiện một cam kết mới, nhánh mà ĐẦU trỏ tới được cập nhật để trỏ đến cam kết mới. ĐẦU theo sau tự động vì nó chỉ vào nhánh.
git symbolic-ref HEAD
năng suất refs/heads/master
Chi nhánh có tên là chủ cấp chủ đề được kiểm tra.
git rev-parse refs/heads/master
năng suất 17a02998078923f2d62811326d130de991d1a95a
Cam kết đó là tiền boa hiện tại hoặc trên đầu của nhánh nhánh.
git rev-parse HEAD
cũng mang lại 17a02998078923f2d62811326d130de991d1a95a
Đây là ý nghĩa của việc trở thành một ref ref tượng trưng của người Viking. Nó trỏ đến một đối tượng thông qua một số tài liệu tham khảo khác.
(Các tham chiếu tượng trưng ban đầu được triển khai dưới dạng các liên kết tượng trưng, nhưng sau đó đã thay đổi thành các tệp đơn giản với giải thích thêm để chúng có thể được sử dụng trên các nền tảng không có liên kết tượng trưng.)
Chúng ta có HEAD
→ refs/heads/master
→17a02998078923f2d62811326d130de991d1a95a
Khi ĐẦU được tách ra, nó chỉ trực tiếp vào một cam kết thay vì gián tiếp chỉ vào một người thông qua một nhánh. Bạn có thể nghĩ về một ĐẦU tách ra như đang ở trên một nhánh không tên.
git symbolic-ref HEAD
thất bại với fatal: ref HEAD is not a symbolic ref
git rev-parse HEAD
năng suất 17a02998078923f2d62811326d130de991d1a95a
Vì nó không phải là một tham chiếu tượng trưng, nó phải trỏ trực tiếp vào chính cam kết.
Chúng ta có HEAD
→17a02998078923f2d62811326d130de991d1a95a
Điều quan trọng cần nhớ với một ĐẦU tách rời là nếu cam kết mà nó trỏ đến không được ước tính (không có tham chiếu nào khác có thể đạt được), thì nó sẽ trở thành một trò chơi nguy hiểm khi bạn kiểm tra một số cam kết khác. Cuối cùng, các cam kết lơ lửng như vậy sẽ được cắt xén thông qua quy trình thu gom rác (theo mặc định, chúng được giữ trong ít nhất 2 tuần và có thể được giữ lâu hơn bằng cách được giới thiệu bởi reflog của HEAD).
1
Hoàn toàn ổn khi thực hiện công việc bình thường, với một đầu tách rời, bạn chỉ cần theo dõi những gì bạn đang làm để tránh phải bỏ lịch sử ra khỏi reflog.
Các bước trung gian của một rebase tương tác được thực hiện với một ĐẦU tách rời (một phần để tránh gây ô nhiễm cho reflog của nhánh hoạt động). Nếu bạn hoàn thành thao tác rebase đầy đủ, nó sẽ cập nhật nhánh ban đầu của bạn với kết quả tích lũy của thao tác rebase và gắn lại HEAD vào nhánh ban đầu. Tôi đoán là bạn không bao giờ hoàn thành đầy đủ quá trình rebase; điều này sẽ để lại cho bạn một ĐẦU tách rời chỉ vào cam kết được xử lý gần đây nhất bởi thao tác rebase.
Để phục hồi từ tình huống của bạn, bạn nên tạo một nhánh trỏ đến cam kết hiện được chỉ ra bởi ĐẦU bị tách ra của bạn:
git branch temp
git checkout temp
(hai lệnh này có thể được viết tắt là git checkout -b temp
)
Điều này sẽ gắn lại ĐẦU của bạn vào temp
chi nhánh mới .
Tiếp theo, bạn nên so sánh cam kết hiện tại (và lịch sử của nó) với nhánh thông thường mà bạn dự kiến sẽ làm việc:
git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp
(Bạn có thể sẽ muốn thử nghiệm các tùy chọn nhật ký: thêm -p
, bỏ đi --pretty=…
để xem toàn bộ thông điệp tường trình, v.v.)
Nếu temp
chi nhánh mới của bạn có vẻ tốt, bạn có thể muốn cập nhật (ví dụ) master
để trỏ đến chi nhánh :
git branch -f master temp
git checkout master
(hai lệnh này có thể được viết tắt là git checkout -B master temp
)
Sau đó, bạn có thể xóa chi nhánh tạm thời:
git branch -d temp
Cuối cùng, bạn có thể sẽ muốn đẩy lịch sử tái lập:
git push origin master
Bạn có thể cần phải thêm --force
vào cuối lệnh này để đẩy nếu nhánh từ xa không thể chuyển đổi nhanh chóng sang Cam kết mới (nghĩa là bạn đã bỏ hoặc viết lại một số cam kết hiện có hoặc viết lại một chút lịch sử).
Nếu bạn đang ở giữa một hoạt động rebase, có lẽ bạn nên dọn sạch nó. Bạn có thể kiểm tra xem rebase có đang được xử lý hay không bằng cách tìm thư mục .git/rebase-merge/
. Bạn có thể tự dọn sạch rebase đang thực hiện bằng cách xóa thư mục đó (ví dụ: nếu bạn không còn nhớ mục đích và bối cảnh của hoạt động rebase đang hoạt động). Thông thường bạn sẽ sử dụng git rebase --abort
, nhưng đó là một số thiết lập lại bổ sung mà bạn có thể muốn tránh (nó di chuyển CHÍNH trở lại nhánh ban đầu và đặt lại nó về cam kết ban đầu, sẽ hoàn tác một số công việc chúng tôi đã làm ở trên).