Sự khác biệt giữa git reflog và log là gì?


158

Trang man nói rằng nhật ký hiển thị nhật ký cam kết và reflog quản lý thông tin reflog. Chính xác thì thông tin reflog là gì và bản ghi đó không có gì? Nhật ký có vẻ chi tiết hơn nhiều.

Câu trả lời:


221

git logcho thấy ĐẦU hiện tại và tổ tiên của nó. Đó là, nó in các điểm CHÍNH cam kết, sau đó là cha mẹ của nó, cha mẹ của nó, v.v. Nó đi ngược trở lại qua tổ tiên của repo, bằng cách đệ quy tìm kiếm cha mẹ của mỗi cam kết.

(Trong thực tế, một số cam kết có nhiều hơn một cha mẹ. Để xem nhật ký đại diện hơn, hãy sử dụng một lệnh như git log --oneline --graph --decorate.)

git refloghoàn toàn không đi qua tổ tiên của CHÍNH. Reflog là một danh sách theo thứ tự các cam kết mà HEAD đã chỉ ra: đó là hoàn tác lịch sử cho repo của bạn. Reflog không phải là một phần của chính repo (nó được lưu trữ riêng cho các cam kết) và không được bao gồm trong các lần đẩy, tìm nạp hoặc nhân bản; nó hoàn toàn là địa phương.

Ngoài ra: hiểu về reflog có nghĩa là bạn thực sự không thể mất dữ liệu từ repo của mình một khi nó đã được cam kết. Nếu bạn vô tình thiết lập lại một cam kết cũ hơn hoặc phản hồi sai hoặc bất kỳ thao tác nào khác "xóa" cam kết, bạn có thể sử dụng reflog để xem bạn đã ở đâu trước và git reset --hardquay lại ref đó để khôi phục trạng thái trước đó. Hãy nhớ rằng, refs ngụ ý không chỉ là cam kết mà là toàn bộ lịch sử đằng sau nó.


26
Một lời cảnh báo: đôi khi bạn CÓ THỂ bị mất dữ liệu vì các mục nhập từ chối không tồn tại vĩnh viễn - chúng bị thanh trừng theo các điều kiện nhất định. Xem câu trả lời này và các tài liệu cho git-refloggit-gc . Nói chung, nếu hoạt động phá hoại không quá 2 tuần trước, rất có thể bạn an toàn.
mcmlxxxvi 14/07/2015

@mcmlxxxvi Tôi có hai thư mục cục bộ cho cùng một repo, tôi có thể hợp nhất các reflog cho hai thư mục không?
Tmx

@Tmx, tôi không hiểu lắm về trường hợp của bạn - ý nghĩa của hai thư mục cục bộ cho cùng một repo là gì? Nếu bạn có hai bản sao của cùng một repo, được cập nhật và bạn muốn "hợp nhất" lịch sử chỉnh sửa của chúng, các .git/logs/refs/<branch>mục có định dạng <old_rev> <new_rev> [...] <timestamp> [...]. Bạn có thể thử nối và sắp xếp theo dấu thời gian. Tuy nhiên, một số dòng ' new_revcó thể không khớp với dòng tiếp theo old_rev, trong trường hợp đó tôi nghi ngờ rằng reflog sẽ không hợp lệ. Sau đó, bạn có thể thử chèn các mục giả mạo để "sửa" trình tự, nhưng có vẻ như quá nhiều rắc rối với tôi.
mcmlxxxvi

62
  • git log hiển thị nhật ký cam kết có thể truy cập từ các ref (đầu, thẻ, điều khiển từ xa)
  • git refloglà một bản ghi của tất cả các cam kết đang hoặc được tham chiếu trong repo của bạn bất cứ lúc nào.

Đó là lý do tại sao git reflog(một bản ghi cục bộ được cắt tỉa sau 90 ngày theo mặc định) được sử dụng khi bạn thực hiện thao tác "phá hủy" (như xóa một nhánh), để lấy lại SHA1 được tham chiếu bởi nhánh đó.
Xem git config:

gc.reflogexpire
gc.<pattern>.reflogexpire

git refloghết hạn loại bỏ các mục reflog cũ hơn thời gian này; mặc định là 90 ngày.
Với " <pattern>" (ví dụ " refs/stash") ở giữa, cài đặt chỉ áp dụng cho các ref phù hợp với <pattern>.

mạng lưới an toàn

git reflogthường được gọi là " mạng lưới an toàn của bạn "

Trong trường hợp gặp sự cố, lời khuyên chung, khi nhật ký git không hiển thị cho bạn những gì bạn đang tìm kiếm, là:

" Giữ bình tĩnh và sử dụnggit reflog "

giữ bình tĩnh

Một lần nữa, reflog là bản ghi cục bộ của SHA1 của bạn.
Trái ngược với git log: nếu bạn đẩy repo của mình lên một repo ngược dòng , bạn sẽ thấy tương tự git log, nhưng không nhất thiết phải giống nhau git reflog.


14

Đây là lời giải thích reflogtừ cuốn sách Pro Git :

Một trong những điều Git làm trong nền trong khi bạn đang làm việc là giữ lại một bản cập nhật - nhật ký về nơi các tài liệu tham khảo CHÍNH và chi nhánh của bạn đã ở trong vài tháng qua.

Bạn có thể xem reflog của mình bằng cách sử dụng git reflog:

$ git reflog
734713b... HEAD@{0}: commit: fixed refs handling, added gc auto, updated
d921970... HEAD@{1}: merge phedders/rdocs: Merge made by recursive.
1c002dd... HEAD@{2}: commit: added some blame and merge stuff
1c36188... HEAD@{3}: rebase -i (squash): updating HEAD
95df984... HEAD@{4}: commit: # This is a combination of two commits.
1c36188... HEAD@{5}: rebase -i (squash): updating HEAD
7e05da5... HEAD@{6}: rebase -i (pick): updating HEAD

Mỗi khi mẹo chi nhánh của bạn được cập nhật vì bất kỳ lý do gì, Git lưu trữ thông tin đó cho bạn trong lịch sử tạm thời này. Và bạn cũng có thể chỉ định các cam kết cũ hơn với dữ liệu này.

Các refloglệnh cũng có thể được sử dụng để xóa các mục hoặc hết hạn mục từ reflog đó là quá già. Từ tài liệu chính thức của Linux Kernel Git choreflog :

Tiểu ban expire được sử dụng để cắt tỉa các mục reflog cũ hơn.

Để xóa các mục đơn từ reflog, hãy sử dụng tiểu ban deletevà chỉ định mục chính xác (ví dụ git reflog delete master@{2}).


Nhưng không git logcung cấp cho bạn cùng một thông tin? Xin lỗi nếu điều đó có vẻ hiển nhiên, tôi rất mới với GIT và muốn có một số điều cơ bản ngay trước OMG đầu tiên của tôi.
Noich

2
Nhật ký Git là một bản ghi các cam kết của bạn . Các reflog, như cuốn sách Pro Git, là một bản ghi các tài liệu tham khảo của bạn (về cơ bản, các con trỏ nhánh và HEADcon trỏ của bạn ), và cam kết chúng đã được trỏ đến. Điều đó có ý nghĩa? Ngoài ra, logcũng có thể hiển thị cho bạn thông tin từ chối, nhưng bạn phải truyền một cờ tùy chọn đặc biệt làm đối số cho nó , --walk-reflogs.

3
Ngoài ra, vì bạn là người mới bắt đầu Git, tôi khuyên bạn nên đọc cuốn sách Git Pro, đó là cách tôi học hầu hết những gì tôi đã học về Git. Tôi đề nghị các chương 1-3 và 6-6.5. Tôi cũng khuyên bạn nên học cách rebase cả tương tác và không tương tác.

8

Tôi cũng tò mò về điều này và chỉ muốn xây dựng và tóm tắt một chút:

  1. git loghiển thị lịch sử của tất cả các cam kết của bạn cho chi nhánh bạn đang ở. Kiểm tra một chi nhánh khác và bạn sẽ thấy một lịch sử cam kết khác. Nếu bạn muốn thấy bạn cam kết lịch sử cho tất cả các chi nhánh, hãy nhập git log --all.

  2. git refloghiển thị một bản ghi các tài liệu tham khảo của bạn như Cupcake nói. Có một mục mỗi lần cam kết hoặc kiểm tra nó được thực hiện. Hãy thử chuyển đổi qua lại giữa hai chi nhánh một vài lần bằng cách sử dụng git checkoutvà chạy git reflogsau mỗi lần thanh toán. Bạn sẽ thấy mục hàng đầu được cập nhật mỗi lần dưới dạng mục "thanh toán". Bạn không thấy các loại mục trong git log.

Tài liệu tham khảo: http://www.lornajane.net/posts/2014/git-log-all-branches


1

Tôi thích nghĩ về sự khác biệt giữa nhật ký git và reflog là sự khác biệt giữa hồ sơ riêng và hồ sơ công khai.

Riêng tư vs công khai

Với phần giới thiệu git, nó theo dõi mọi thứ bạn đã thực hiện tại địa phương. Bạn đã cam kết? Reflog theo dõi nó. Bạn đã làm một thiết lập lại cứng? Reflog theo dõi nó. Bạn đã sửa đổi một cam kết ? Reflog theo dõi nó. Tất cả mọi thứ bạn đã thực hiện tại địa phương, có một mục cho nó trong reflog.

Điều này không đúng với nhật ký. Nếu bạn sửa đổi một cam kết, nhật ký chỉ hiển thị cam kết mới. Nếu bạn thực hiện đặt lại và bỏ qua một vài lần xác nhận trong lịch sử của mình, những cam kết bạn đã bỏ qua sẽ không hiển thị trong nhật ký. Khi bạn đẩy các thay đổi của mình sang nhà phát triển khác hoặc tới GitHub hoặc đại loại như thế, chỉ nội dung được theo dõi trong nhật ký sẽ xuất hiện. Đối với một nhà phát triển khác, nó sẽ trông giống như việc đặt lại không bao giờ xảy ra hoặc sửa đổi không bao giờ xảy ra.

Nhật ký được đánh bóng. Các reflog là lapidary.

Vì vậy, yeah, tôi thích sự tương tự 'riêng tư và công cộng'. Hoặc có thể là một bản ghi tốt hơn so với reflog tương tự là 'đánh bóng vs lapidary'. Các reflog cho thấy tất cả các thử nghiệm và lỗi của bạn. Nhật ký chỉ hiển thị một phiên bản sạch sẽ và lịch sự của lịch sử công việc của bạn.

Hãy nhìn vào hình ảnh này để nhấn mạnh điểm. Một số sửa đổi và đặt lại đã xảy ra kể từ khi kho được khởi tạo. Các reflog cho thấy tất cả của nó. Tuy nhiên, lệnh log làm cho nó trông như thể chỉ có một cam kết chống lại repo:

Nhật ký được đánh bóng.  Reflog là lố lăng.

Quay lại ý tưởng 'mạng lưới an toàn'

Ngoài ra, vì reflog theo dõi những thứ bạn đã sửa đổi và cam kết bạn đặt lại , nó cho phép bạn quay lại và tìm những cam kết đó vì nó sẽ cung cấp cho bạn id id. Giả sử kho lưu trữ của bạn chưa bị xóa các cam kết cũ, điều đó cho phép bạn phục hồi các mục không còn hiển thị trong nhật ký. Đó là cách mà việc reflog đôi khi kết thúc việc cứu lấy làn da của ai đó khi họ cần lấy lại thứ mà họ nghĩ rằng họ đã vô tình làm mất.


-6

Trên thực tế, reflog là một bí danh cho

 git log -g --abbrev-commit --pretty=oneline

Vì vậy, câu trả lời nên là: đó là một trường hợp cụ thể.


9
Trong git log, -glà hình thức ngắn cho --walk-reflogs. Vì vậy, điều đó không giải thích bất cứ điều gì.
Adrian W
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.