Điều gì xảy ra với các cam kết git được tạo trong trạng thái CHÍNH tách ra?


137

Đây là những gì đã xảy ra:

Tôi có một chi nhánh A. Trên chi nhánh AI đã cam kết một loạt các thay đổi. Tôi không hài lòng với mã, vì vậy tôi đã kiểm tra cam kết trước đó trong chi nhánh A. Sau đó tôi đã thực hiện một loạt các thay đổi và cam kết chúng trên chi nhánh A. Bây giờ tôi không thể tìm thấy cam kết này ở bất cứ đâu. Tôi đã mất mã này?


Khi bạn nói "Tôi đã kiểm tra cam kết trước đó trong nhánh A", bạn có nghĩa là "Tôi đặt lại nhánh A về cam kết trước đó"? tức là bạn đã thực sự git resetchứ không phải git checkout?
CB Bailey

Không, tôi đã sử dụng thanh toán. reflog làm việc.
Mausimo

Nếu bạn đã sử dụng thanh toán thì bạn sẽ ở trên một HEADnhánh và chi nhánh A sẽ ở lại trên cam kết trước đó. Chính xác những lệnh bạn đã chạy?
CB Bailey

1
Tôi đã sử dụng GUI GIT SourceTree trên OSX Lion. Tôi đã ở chi nhánh A và thực hiện kiểm tra cam kết trước đó trên Chi nhánh A. Sau đó tôi đã thực hiện một loạt các thay đổi mã và cam kết (Chi nhánh A). Tôi tin rằng tôi đã có một ĐẦU tách ra.
Mausimo

OK, tôi nghĩ rằng tôi đã nhầm lẫn khi bạn nói rằng bạn cam kết thay đổi một bó hơn về chi nhánh A .
CB Bailey

Câu trả lời:


185

Các cam kết cũ vẫn còn trong reflog.

git reflog

Điều này sẽ hiển thị một danh sách các cam kết và cam kết "bị mất" sẽ ở đó. Bạn có thể làm cho nó thành một chi nhánh mới. Ví dụ: nếu SHA-1 là ba5a739, thì bạn có thể tạo một nhánh mới có tên là "nhánh mới" tại cam kết cũ với:

git branch new-branch ba5a739

Lưu ý rằng các cam kết "bị mất" sẽ bị xóa khi cơ sở dữ liệu được cắt tỉa.


3
Tôi đã làm điều tương tự và về một cơn đau tim nghĩ rằng nó đã bị mất. Cảm ơn bạn về thông tin!
Đuổi theo

14
Sử dụng git cherry-pick [SHA]để di chuyển cam kết vào một chi nhánh hiện có trong trường hợp bạn vô tình cam kết trong khi ở trạng thái tách rời
Jan Aagaard Meier

3
Ngoài ra, bạn có thể chuyển sang một nhánh hiện có và thực hiện "git merge HEAD @ {n}" n tương ứng với cam kết "bị mất" được liệt kê trong reflog.
eaykin

Bạn có biết nếu prunexóa cũng sẽ tách các cam kết đang được tham chiếu trong các thông điệp cam kết không? Hay điều đó làm cho chúng có thể truy cập ?
Kamafeather

@Kamafeather: Tôi không nghĩ điều đó làm cho chúng có thể truy cập được.
Dietrich Epp

63

Cam kết của bạn vẫn có sẵn trong reflog, như đã chỉ ra. Ngoài các câu trả lời khác, đây là một cách để tiếp quản các cam kết tách rời trực tiếp vào chi nhánh hiện tại của bạn mà không cần tạo và hợp nhất một chi nhánh mới:

  1. Tra cứu băm SHA-1 của các cam kết bạn đã thực hiện ở trạng thái CHÍNH tách rời với

    git reflog
    
  2. Sau đó thực hiện, với tất cả các giá trị băm cam kết được sắp xếp từ cũ nhất đến gần đây nhất:

    git cherry-pick <hash1> <hash2> <hash3> ...
    

    Ví dụ: nếu tôi chỉ có một, được đưa ra ở định dạng băm ngắn "7 ký tự đầu tiên":

    git cherry-pick a21d053
    

Điều này sẽ tạo ra các cam kết mới cho chi nhánh hiện tại của bạn, một cam kết cho mỗi hàm băm tách rời-ĐẦU-cam kết mà bạn đề cập trong lệnh. Nó cũng tiếp quản các thông điệp cam kết ban đầu.


11

Bạn có thể tìm thấy các cam kết bị mất (lơ lửng) với lệnh sau:

git fsck --lost-found

Lưu ý, nếu đầu hiện tại của bạn đang treo lủng lẳng, nó không được liệt kê là bị mất.

Bạn có thể tìm thêm thông tin tại Trang hướng dẫn git-fsck (1)

Sau đó, bạn có thể tạo chi nhánh trên cam kết bị mất đó:

git branch new-branch ba5a739

Lần đầu tiên tôi sử dụng lệnh "git reflog" sau đó "git nhánh new-Branch ba5a739" cho một mô hình con, nó đã hoạt động.
ondermerol

7

Cách nói của Git cho trạng thái của thư mục làm việc của bạn là một ĐẦU tách rời . Đây là một nơi khác git refloglàm cho tiết kiệm.

$ git reflog
0b40dd6 HEAD@{0}: commit: my commit on detached HEAD
...

Nếu tôi cố gắng kiểm tra một chi nhánh khác, git-1.7.5.1 sẽ đưa ra một gợi ý hữu ích.

$ git thanh toán chính
Cảnh báo: bạn để lại 1 cam kết phía sau, không kết nối với
bất kỳ chi nhánh nào của bạn:

  0b40dd6 cam kết của tôi về ĐẦU tách ra

Nếu bạn muốn giữ chúng bằng cách tạo một nhánh mới, đây có thể là thời điểm tốt
làm như vậy với:

 chi nhánh git new_branch_name 0b40dd65c06bb215327863c2ca10fdb4f904215b

Chuyển sang nhánh 'chủ'

Cảm ơn thông tin và liên kết. Các liên kết giúp tôi hiểu những gì đang xảy ra.
Mausimo

6

Bạn đã không mất nó, Git vẫn giữ một bản sao (nhưng hiện tại nó không thể truy cập được bởi bất kỳ người đứng đầu chi nhánh nào). Bạn có thể tìm thấy cam kết bị thiếu của bạn bằng cách sử dụng git refloglệnh. Các reflog theo dõi các vị trí lịch sử của một người đứng đầu chi nhánh, và bạn có thể sử dụng nó để tìm những thứ mà người đứng đầu chi nhánh đã chỉ vào trước đó.


4

Thực hiện theo các bước sau để liên kết đầu tách rời của bạn trở lại git repo

  1. git checkout "your branch with path but without remote name"

ví dụ: nếu tên từ xa là nguồn gốc và tên chi nhánh bugfix/somebranchthì sử dụnggit checkout bugfix/somebranch

  1. git reflog nhận được cam kết SHA được liệt kê từ danh sách cam kết của chi nhánh tách ra.

  2. git cherry-pick "commit hash1" "commit hash2" "commit hash3"

  3. git push

TẤT CẢ CÁC THIẾT LẬP!!


2

Trong Sourcetree, tôi thấy rằng git reflog không hoạt động, vì vậy tôi đã tìm ra cách để làm điều này bằng GUI.

Trước tiên, hãy thử tìm cam kết "bị mất" bằng cách tìm kiếm một thông báo trong Lịch sử lệnh (xem: Hiển thị đầu ra lệnh). Hy vọng rằng nó sẽ nằm trong lệnh "Chuyển nhánh" sau khi cam kết bạn bị mất và bạn sẽ thấy nhận xét cam kết với ID cam kết 1234567.

Lấy ID Cam kết đó sang bước tiếp theo.

Nhấn nút "Chi nhánh" trong thanh công cụ trên cùng và bạn sẽ nhận được hộp thoại "Chi nhánh mới" nơi bạn có thể chỉ định một cam kết nhất định. Đặt ID cam kết đó vào đó, chỉ định tên chi nhánh mới, nhấn Tạo chi nhánh và bạn sẽ nhận được một chi nhánh mới với cam kết bị mất của mình!

Điều này mang lại một số công việc bị mất cho tôi!

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.