Trong Git, các nhánh chỉ là con trỏ (tham chiếu) để cam kết trong một biểu đồ tuần hoàn theo hướng (DAG) của các cam kết. Điều này có nghĩa là việc xóa một nhánh chỉ loại bỏ các tham chiếu đến các cam kết, mà có thể làm cho một số cam kết trong DAG không thể truy cập, do đó vô hình. Nhưng tất cả các cam kết trên một nhánh bị xóa sẽ vẫn nằm trong kho lưu trữ, ít nhất là cho đến khi các cam kết không thể truy cập được cắt bớt (ví dụ: sử dụng git gc
).
Lưu ý rằng git branch -d
sẽ từ chối xóa chi nhánh nếu không thể chắc chắn rằng việc xóa nó sẽ không để lại các cam kết không thể truy cập được. Bạn cần phải sử dụng mạnh mẽ hơn git branch -D
để buộc xóa chi nhánh nếu nó có thể để lại các cam kết không thể truy cập được. Lưu ý rằng các cam kết không thể truy cập, nếu chúng có mặt, chỉ là những cam kết giữa mũi cuối cùng của nhánh bị xóa và cam kết được sáp nhập với một nhánh khác hiện có, bất kỳ cam kết được gắn thẻ nào hoặc điểm phân nhánh; Bất cứ cái nào đến sau. Ví dụ: trong trường hợp sau:
----O----*----*----/M----* <-- master <-- HEAD
\ /
\--.----.--/--x---y <-- deleted branch
chỉ cam kết 'x' và 'y' sẽ không thể truy cập được sau khi xóa chi nhánh.
Nếu bạn hoạt động trên một nhánh bị xóa trong thời hạn gc.reflogExpire
, mặc định 90 ngày, bạn sẽ có lời khuyên cuối cùng của một chi nhánh xóa ghi trong TRỤ reflog (xem git reflog show HEAD
, hoặc git log --oneline --walk-reflogs HEAD
). Bạn sẽ có thể sử dụng HEAD reflog để phục hồi con trỏ đã xóa. Cũng lưu ý rằng trong trường hợp này, các cam kết không thể truy cập trong một chi nhánh đã xóa sẽ được bảo vệ khỏi việc cắt xén (xoá) trong khoảng thời gian gc.reflogExpireUnreachable
, theo mặc định là 30 ngày.
Nếu bạn không thể tìm thấy đỉnh của một chi nhánh chỉ xóa trong reflog cho HEAD, bạn có thể thử sử dụng git fsck
để tìm "unreachable cam <sha1>", và kiểm tra những người (qua git show <sha1>
hoặc git log <sha1>
) để tìm đầu của nhánh bị xóa.
độc lập về cách bạn tìm thấy những đỉnh của một chi nhánh xóa, bạn có thể hoàn tác xóa, hay đúng hơn là tái tạo một chi nhánh chỉ cần xóa bằng
git branch <deleted-branch> <found-sha1-id>
Lưu ý tuy nhiên đó reflog cho một chi nhánh sẽ bị mất.
Ngoài ra còn có git-resurrect.sh kịch bản trong contrib/
giúp tìm dấu vết của một mẹo chi nhánh với tên nhất định và hồi sinh (phục hồi) nó.
Cảm ơn câu trả lời. Bạn có thể làm rõ những gì bạn có nghĩa là "mỗi cam kết có một cây nguồn hoàn chỉnh"? Như tôi đã hiểu, mỗi cam kết trong git là một tập hợp các vùng đồng bằng tham chiếu đến một commit cha, chứ không phải toàn bộ cây. –
Không, mỗi cam kết là trạng thái của cây tại một điểm nhất định. Các vùng đồng bằng chỉ được tính sau này để hiển thị và rebasing và whatnot, nhưng các cam kết id là băm của toàn bộ cây. – ben
@Ken Liu: Một cam kết chứa các con trỏ tới số không hoặc nhiều commit cha, một đối tượng cây và một số siêu dữ liệu về cam kết. Do đó, cam kết xác định duy nhất cả hai cây nguồn và, khi được xem với (các) cha mẹ của nó, những thay đổi mà nó đã giới thiệu. –