GIT khôi phục HEAD tách ra gần đây nhất


85

Làm ơn, tôi có một vấn đề lớn trong dự án của mình: đây là kịch bản. Tôi có một dự án xcode trong GIT. Hôm nay tôi nhận ra rằng cam kết cuối cùng đã phá vỡ một số thử nghiệm, vì vậy tôi đã kiểm tra cam kết trước đó. Tôi đã sử dụng SourceTree và đây là cảnh báo

Làm như vậy sẽ làm cho bản sao làm việc của bạn trở thành 'HEAD tách rời', có nghĩa là bạn sẽ không ở trên một chi nhánh nữa. Nếu bạn muốn cam kết sau đó, bạn có thể muốn kiểm tra lại một chi nhánh hoặc tạo một chi nhánh mới. Điều này có ổn không?

Tôi đã làm việc cả ngày và cuối cùng tôi đã cam kết mọi thứ. Vì vậy, tôi cần phải hợp nhất công việc của mình trên nhánh phát triển để tôi kiểm tra nhánh phát triển và ... công việc của tôi ngay lập tức biến mất :(

Tôi biết đã sai khi tách HEAD của mình và Sourcetree đã cảnh báo tôi ... nhưng có cách nào để khôi phục công việc của tôi?


Một chủ đề liên quan cho vấn đề rất giống nhau ở đây và các kỹ thuật về cách nó xảy ra ở đây .
RBT

Câu trả lời:


254

Nếu bạn nhập git reflog, nó sẽ hiển thị cho bạn lịch sử của những bản sửa đổi HEADđã trỏ đến. Cái đầu tách rời của bạn sẽ ở trong đó. Khi bạn tìm thấy nó, hãy thực hiện git checkout -b my-new-branch abc123hoặc git branch my-new-branch abc123( abc123SHA-1 của HEAD đã tách rời ở đâu) để tạo một nhánh mới trỏ đến đầu tách rời của bạn. Bây giờ bạn có thể hợp nhất chi nhánh đó vào lúc rảnh rỗi.

Nói chung, nếu bạn kiểm tra một nhánh sau khi làm việc trên đầu tách rời, Git sẽ cho bạn biết cam kết từ đầu tách rời mà bạn đã sử dụng, vì vậy bạn có thể khôi phục nó nếu cần. Tôi chưa bao giờ sử dụng SourceTree, vì vậy tôi không biết liệu nó có chuyển tiếp thông báo đó hay không. Nhưng nếu nó đã hiển thị thông báo đó, thì bạn sẽ có thể sử dụng nó để tìm cam kết, và sử dụng lại git checkout -bhoặc git branchtạo một nhánh từ cam kết đó.


4
Cảm ơn Brian. Bạn đã cứu ngày của tôi.
Muzammil,

Brian, bạn đã cứu mạng tôi! Cảm ơn!!
cldrr

Tôi mới sử dụng git .. tôi đang nhận được fatal: A branch named 'mybranch' already exists.Làm thế nào để thêm vào chi nhánh hiện có?
Ramesh Murugesan

1
Là một PSA cho tất cả những người cảm ơn Brian: Nếu bạn đang làm công việc mà bạn không muốn mất, hãy đẩy nó sang điều khiển từ xa (ví dụ: github) vài giờ một lần. Khi sao băng rơi vào máy tính của bạn, bạn sẽ rất vui vì đã làm được điều đó. Nếu bạn chưa sẵn sàng chia sẻ nó với các cộng tác viên, chỉ cần đặt nó vào một nhánh mà hiện tại chưa ai biết đến và sau đó căn cứ lại nó thành master sau.
MatrixManAtYrService

1
Ngoài ra, nếu đó là một cam kết bị mất duy nhất vừa biến mất và bạn tìm thấy nó ở đó, bạn có thể mang nó trở lại git cherry-pick e5b2f7b, e5b2f7bSHA-1 của cam kết ở đó ở đâu.
Aidin

10

Trong Sourcetree, bạn có thể thực hiện việc này bằng GUI.

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

Chuyển ID cam kết đó sang bước tiếp theo.

Nhấn nút "Chi nhánh" ở 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ẽ có được một chi nhánh mới với cam kết bị mất của mình!

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


thực sự hoạt động. Đảm bảo rằng bạn nhìn thấy nhận xét chính xác với id cam kết.
Hammad Khan

@blalond Xin chào, Sau khi đọc câu trả lời của bạn, tôi có một câu hỏi nhỏ: Khi ở trong SourceTree, tôi nhấp đúp vào cam kết trước đó (để kiểm tra nó) Tôi nhận được thông báo tương tự rằng điều này sẽ gây ra đầu tách rời, vì vậy tôi tự hỏi nghĩa là gì khi mọi người nói rằng bạn có thể quay lại bất kỳ bản sửa đổi nào trước đó bằng git? Làm cách nào để quay trở lại một cam kết cụ thể sau đó? Cảm ơn

5

Nếu bạn không muốn giữ các thay đổi của HEAD đã tách rời và muốn chuyển trực tiếp lệnh bên dưới, sử dụng cam kết nhánh mới nhất.

git checkout - 

Lưu ý: Tôi sẽ xóa tất cả các thay đổi của bạn trong HEAD tách rời.


OP đã yêu cầu giữ công việc của họ. Điều này không trả lời câu hỏi ban đầu. Chỉ cần thêm tùy chọn để giữ nó trong một nhánh sẽ khiến câu trả lời này trở nên hữu ích.
manuelvigarcia

1

Một đồng nghiệp của tôi vừa gặp trường hợp này. Trong trường hợp của anh ta, có những cam kết trong cái đầu tách rời - họ làm việc trong R-Studio - và công cụ đã cảnh báo họ rằng họ có thể tạo nhánh bằng tham chiếu SHA này và đó ... nhưng vì tùy chọn duy nhất là "Đóng" --tât nhiên!! đó là một hộp thông tin-- họ đã đóng cuộc đối thoại và mất thông tin mãi mãi ...

Nhờ refloglệnh, chúng tôi có thể thấy rằng các thay đổi không bị mất. Nhưng trong trường hợp của chúng tôi, git branchnó không hoạt động như mong đợi ... hoặc một cái gì đó đến git pullđã làm nó rối tung lên. Chúng tôi phải chỉnh sửa các thay đổi từ bản ghi lại đến nhánh mới được tạo:

 git cherry-pick 0b823d42..3cce27fc

đã đặt tất cả các cam kết mà chúng tôi muốn vào chi nhánh. Sau đó, chúng tôi có thể hợp nhất chi nhánh vào developmà không có vấn đề gì.

Chỉ trong trường hợp điều này là thông tin cho bất kỳ ai, chúng tôi đã xác định các cam kết trên đầu riêng biệt trong reflogbằng cách xem xét các cam kết ở giữa được đánh dấu bằng "thanh toán" (xác định sự chuyển dịch nhánh):

e09f183b HEAD@{3}: pull: Fast-forward
b5bf3e1d HEAD@{4}: checkout: moving from lost_changes to develop
b5bf3e1d HEAD@{5}: checkout: moving from 3cce27fca50177a288df0252f02edd5da5ee64fd to lost_changes
3cce27fc HEAD@{6}: commit: add statistics
417a99a4 HEAD@{7}: commit: add test
0b823d42 HEAD@{8}: commit: new utility class
d9ea8a63 HEAD@{9}: checkout: moving from develop to d9ea8a635d4c2349fcb05b3339a6d7fad5ae2a09
b5bf3e1d HEAD@{10}: pull: Fast-forward

Những người chúng ta muốn là HEAD@{8}để HEAD@{6}(cả bao gồm). Vì vậy, chúng tôi nhận được chúng bằng cách:

git cherry-pick 0b823d42..3cce27fc

Sau đó, việc giải quyết hợp nhất thông thường và cam kết cuối cùng đã để lại cho chúng tôi chi nhánh lost_changes lưu trữ công việc đầu tách rời mà chúng tôi nghĩ đã mất. Lần này, việc hợp nhất nó vào phát triển đã diễn ra nhanh chóng.


0

Tôi đã thử kịch bản này và thấy rằng git cho tôi biết SHA-1 của lần cam kết cuối cùng:

vors@localhost:~/git-test$ git checkout master 
Warning: you are leaving 1 commit behind, not connected to
any of your branches:

  ec600e6 333

If you want to keep them by creating a new branch, this may be a good time
to do so with:

 git branch new_branch_name ec600e6eb2473dd4f3732539c5c1fa5829f631b7

Switched to branch 'master'

Bạn có thấy tin nhắn này không?


Không. hoặc có thể tôi không chú ý. Tôi đang tìm kiếm một bản sao lưu trên máy đo thời gian; (
IgnazioC

1
@IgnazioC Bạn không cần phải xem bản sao lưu. Bạn đã xem qua câu trả lời của tôi? git reflogsẽ cho bạn thấy những gì bạn cần.
Brian Campbell

0

đầu tách rời là được miễn là bạn muốn thực hiện Không thay đổi.

Nếu bạn muốn hoàn nguyên một cam kết, bạn có thể sử dụng git hoàn nguyên trên một nhánh cụ thể

Nếu bạn muốn làm việc với cái đầu tách rời và thực hiện cam kết; tạo một nhánh mới (và sau đó hợp nhất nó);


Vâng! chúng tôi biết các quy tắc. Nhưng khi các đồng nghiệp làm việc với cái đầu tách rời và sau đó bỏ đi những cam kết đó, họ yêu cầu câu trả lời chứ không phải quy tắc.
manuelvigarcia

0
  1. Đầu tiên, chạy git reflogđể xem lịch sử.
  2. Bản sửa đổi cũ nhất sẽ là bản cuối cùng trong danh sách.
  3. Chuyển sang cam kết mong muốn của bạn bằng cách sử dụng git checkout -b temp e35d2b3tại đây e35dd23 là giá trị băm của cam kết của bạn.
  4. Đó là nó. Bây giờ chỉ cần thêm git. Vân vân....

Hãy chấp nhận nó như một câu trả lời nếu nó giải quyết được vấn đề của bạn. Nếu không, hãy chia sẻ bình luận của bạn.

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.