Nhận danh sách tất cả các cam kết git, bao gồm các cam kết 'bị mất'


139

Hãy nói rằng tôi có một biểu đồ như thế này:

A---B---C---D (master)
     \
      \-E---F (HEAD)

Nếu tôi làm git log --all --oneline, tôi sẽ nhận được tất cả sáu cam kết của mình.

Nhưng nếu đồ thị là

A---B---C---D (master, HEAD)
     \
      \-E---F

Tôi sẽ không thấy E và F. Tôi có thể nhận git để cho tôi biết tất cả các cam kết, bao gồm cả những người trên các nhánh không được đặt tên không?

Cảm ơn

Câu trả lời:


63

Không đặc biệt dễ dàng - nếu bạn bị mất con trỏ vào đầu cành cây, thì giống như tìm kim trong đống cỏ khô. Bạn có thể tìm thấy tất cả các cam kết dường như không được tham chiếu nữa - git fsck --unreachablesẽ thực hiện điều này cho bạn - nhưng sẽ bao gồm các cam kết mà bạn đã vứt đi sau một git commit --amend, các cam kết cũ trên các nhánh mà bạn đã khởi động, v.v. cùng một lúc rất có thể có quá nhiều thông tin để lội qua.

Vì vậy, câu trả lời ngắn gọn là, đừng để mất dấu những thứ bạn quan tâm. Nghiêm trọng hơn, các reflog sẽ giữ các tham chiếu đến tất cả các cam kết bạn đã sử dụng trong 60 ngày qua hoặc lâu hơn theo mặc định. Quan trọng hơn, họ sẽ đưa ra một số bối cảnh về những cam kết đó là gì .


7
+1: Hoàn toàn không có sự khác biệt giữa một cam kết cố tình mồ côi bởi commit --amendhoặc rebasemột người vô tình mồ côi bằng cách làm việc với một TRƯỞNG tách rời, nói.
Cascabel

3
thật. có lẽ cách dễ nhất để phục hồi từ tình huống đó sẽ là nhìn vào bản reflog cho chính nó.
araqnid

@Jefromi: Tuyệt vời chỉ ra về git commit --amendvv để lại ngõ cụt, cam kết bị mất. Tôi đã thực hiện một số cuộc nổi loạn và không chú ý và kết thúc với một số cam kết không thể truy cập từ bất kỳ chi nhánh nào, và cảm thấy một chút bẩn để lại chúng trong repo. Bây giờ suy nghĩ không còn đáng lo ngại nữa. :)
Emil Lundberg

2
@araqnid Tôi nhận được bản thân mình trong cùng một tấm gương với poster ban đầu và đề nghị của bạn để xem reflog chỉ là việc cần làm.
Ignazio

7
Tôi đồng ý với câu trả lời này, nhưng trong trường hợp ai đó không cần phải xem tất cả các cam kết, kể cả những đứa trẻ mồ côi dù cố tình hay vô tình, git fsck --unreachableđều không cung cấp điều đó. Tôi chỉ thử nó. Cách tiếp cận tốt hơn là --reflogtùy chọn cho git log, như kenorb đã trả lời . Điều đặc biệt hay ở đây là kết hợp với --graph, bạn có được một bối cảnh trực quan dễ phân tích, giống như được minh họa trong câu hỏi ban đầu. Ví dụ: thử:git log --graph --all --oneline --reflog
Inigo

111

Thử:

git log --reflog

trong đó liệt kê tất cả các cam kết git bằng cách giả vờ rằng tất cả các đối tượng được đề cập bởi reflogs ( git reflog) được liệt kê trên dòng lệnh như <commit>.


1
Đây là những gì tôi đang tìm kiếm - chức năng của đối số --reflog.
Bất thường

3
Btw, gitk cũng hỗ trợ rằng: gitk --reflog.
ald.li

50

Khi tôi giải quyết vấn đề này, tôi sử dụng lệnh sau:

git reflog |  awk '{ print $1 }' | xargs gitk

Điều này cho phép tôi hình dung các cam kết gần đây đã trở nên không đầu.

Tôi có gói này trong một trình trợ giúp kịch bản được gọi ~/bin/git-reflog-gitk.


1
Điều này chỉ giúp tôi tiết kiệm thời gian lớn ... CẢM ƠN BẠN!
Bret Royster

điều này thật tuyệt! cảm ơn bạn! nó thực sự hình dung những phần quan trọng của cây.
Mladen B.

Chỉ là một mẹo: Điều này sẽ chỉ hoạt động cho công việc địa phương của bạn dưới dạng hồ sơ reflog when the tips of branches and other references were updated in the *local repository*. Bạn có thể muốn sử dụng git log --reflognếu bạn muốn làm điều này cho những thay đổi không phải là người địa phương
Krishna Gupta

29

Điều đã cứu cuộc đời tôi là mệnh lệnh sau:

git reflog

Ở đó bạn tìm thấy một màn hình với các cam kết lịch sử được thực hiện để git như thế này:

nhập mô tả hình ảnh ở đây

Tại thời điểm này, bạn chỉ phải tìm thứ HEAD@{X}bạn cần, tạo một nhánh tạm thời và di chuyển đến nó như thế này:

git checkout -b temp_branch HEAD@{X}

Bằng cách đó, bạn sẽ có một nhánh tạm thời với cam kết bị mất của mình mà không cần khởi động lại hoặc phá vỡ thêm kho git của bạn.

Hi vọng điêu nay co ich...


26

Giống như Câu trả lời của @Kieran, nhưng dành cho bảng điều khiển: git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')


Bạn có cần bao gồm phần cuối cùng: $ (git reflog | awk '{print $ 1}') không? Cái này làm gì Sau khi thử giải pháp của bạn, có vẻ như nó tạo ra cùng một đầu ra ngay cả khi không có phần cuối cùng đó.
wmock

Nếu bạn di chuyển con trỏ nhánh của mình và để lại một số xác nhận mà không có tham chiếu (như OP đã làm), chúng sẽ không còn hiển thị nữa git log --all. Một ví dụ nhanh: Sau khi một git reset --hard @^cam kết HEAD @ {0} của bạn sẽ chỉ có trong reflog và vì git reflogkhông hỗ trợ --graphnên bạn phải vượt qua các cam kết git log --graphđể có được một biểu diễn trực quan.
Florian Fida

5
bạn có thể sử dụng --reflogthay vì $(git reflog | awk '{print $1}')
Sild

Tôi đã so sánh git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')với git log --oneline --all --graph --decorate --reflog, chúng gần giống nhau ngoại trừ --reflog bao gồm các chi tiết như các mục WIP.
Script Wolf

@FlorianFida, thay vì reflogtại sao không sử dụng log --reflogthay thế?
Pacerier

9

Làm thế nào tôi giải quyết vấn đề này? Sử dụng git fsckvà đăng nhập!

Đầu tiên tạo một tệp chứa các xác nhận và các đốm màu bị mất (không thể truy cập). (LƯU Ý: nếu bạn đã làm một cái gì đó như thế git gcthì nó sẽ thu gom tất cả những gì họ cam kết và bạn sẽ không tìm thấy chúng ở đây!)

$git fsck --lost-found > lost_found.commits

Điều đó cung cấp cho bạn một tập tin như thế này:

tòn ten cam dec2c5e72a81ef06963397a49c4b068540fc0dc3
lủng lẳng blob f8c2579e6cbfe022f08345fa7553feb08d60a975
lủng lẳng blob 0eb3e86dc112332ceadf9bc826c49bd371acc194
lủng lẳng blob 11cbd8eba79e01f4fd7f496b1750953146a09502
tòn ten cam 18733e44097d2c7a800650cea442febc5344f9b3
lủng lẳng blob 1e53a5cdb3ecdde27081ec6e8b31e4070106ee05

Sau đó, bạn có thể mở tệp này với trình soạn thảo văn bản yêu thích của mình để sao chép các băm cam kết / blog từ đó. (* ho * vim macro hoạt động tuyệt vời cho việc này * ho *)

Bây giờ bạn có thể đăng nhập lại từ cam kết này với một cái gì đó như git log --oneline <commit hash>. Ngoài ra, gitk, tig hoặc bất kỳ người xem git nào khác nên hoạt động.

Trong trường hợp của bạn nếu bạn tìm thấy hàm băm cho cam kết F, nhật ký sẽ hiển thị cho bạn một cái gì đó như thế này,

A---B---E---F

Nhanh chóng và dễ dàng! Bây giờ bạn có thể tìm thấy bối cảnh đằng sau tất cả những cam kết lơ lửng đó.

PS Vâng, tôi biết, bài đăng muộn, nhưng ồ, ai đó có thể tìm thấy nó ở đây và thấy nó hữu ích. (Chủ yếu là tôi sau 6 tháng nữa khi tôi google lại lần nữa)


5

Tôi đã may mắn phục hồi cam kết bằng cách nhìn vào reflog, được đặt tại .git/logs/HEAD

Sau đó tôi phải tìm đến cuối tập tin và tôi thấy cam kết tôi vừa mất.


Đây là những gì vừa kết thúc khi tôi làm hỏng một cái gì đó. Đã cố gắng để cam kết với chủ và Stash chùn bước khi tôi đẩy. Tôi đặt lại - xin lỗi, sau đó nhận ra sai lầm của mình. Các cam kết là trong reflog, vì vậy tôi đã kiểm tra nó, tạo ra một nhánh từ nó, sau đó đẩy nó. Tất cả mọi thứ làm việc cuối cùng.
David

5

git logĐôi khi chúng ta sẽ không tốt để có được tất cả các cam kết chi tiết, vì vậy để xem ...

Đối với Mac: Tham gia vào dự án git của bạn và nhập:

$ nano .git/logs/HEAD

để xem tất cả các bạn cam kết trong đó, hoặc:

$ gedit .git/logs/HEAD

để xem tất cả các bạn cam kết trong đó,

sau đó bạn có thể chỉnh sửa trong bất kỳ trình duyệt yêu thích nào của bạn.


3

@bsimmons

git fsck --lost-found | grep commit

Sau đó tạo một nhánh cho mỗi cái:

$ git fsck --lost-found | grep commit
Checking object directories: 100% (256/256), done.
dangling commit 2806a32af04d1bbd7803fb899071fcf247a2b9b0
dangling commit 6d0e49efd0c1a4b5bea1235c6286f0b64c4c8de1
dangling commit 91ca9b2482a96b20dc31d2af4818d69606a229d4

$ git branch  branch_2806a3 2806a3
$ git branch  branch_6d0e49 6d0e49
$ git branch  branch_91ca9b 91ca9b

Bây giờ nhiều công cụ sẽ hiển thị cho bạn một hình ảnh đồ họa của những cam kết bị mất.


2

Nếu bạn sử dụng GUI Git Tiện ích mở rộng, nó có thể hiển thị cho bạn một hình ảnh trực quan về các cam kết lơ lửng nếu bạn chọn "Xem -> Hiển thị các tham chiếu reflog". Điều này sẽ hiển thị các cam kết lơ lửng trên cây, giống như tất cả các tham chiếu khác. Cách này dễ dàng hơn để tìm thấy những gì bạn đang tìm kiếm.

Xem hình ảnh này để trình diễn. Cam kết C2, C3, C4 và C5 trên hình ảnh được treo lủng lẳng nhưng vẫn có thể nhìn thấy.


2
git log --reflog

cứu tôi! Tôi đã mất trong khi sáp nhập CHÍNH và không thể tìm thấy cam kết của mình! Không hiển thị trong cây nguồn nhưng git log --refloghiển thị tất cả các cam kết cục bộ của tôi trước đó

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.