2010-10-20 35 views
49

Tôi vừa cam kết nguồn sai cho dự án của mình bằng cách sử dụng tùy chọn --force.Làm thế nào tôi có thể phục hồi từ một bậc thầy git push -f erronous origin?

Có thể hoàn nguyên không? Tôi hiểu rằng tất cả các chi nhánh trước đó đã bị ghi đè bằng cách sử dụng tùy chọn -f, vì vậy tôi có thể đã sửa đổi các bản sửa đổi trước đó của tôi.

+0

có thể trùng lặp của [Có anyway để hoàn tác git push -f?] (Http://stackoverflow.com/questions/14476236/is-there-anyway-to-undo-git- push-f) – cmbuckley

Trả lời

32

Git thường không vứt đi bất kỳ thứ gì, nhưng việc khôi phục từ điều này có thể vẫn phức tạp.

Nếu bạn có nguồn chính xác thì bạn chỉ có thể đẩy nó vào điều khiển từ xa với tùy chọn --force. Git sẽ không xóa bất kỳ chi nhánh nào trừ khi bạn nói với nó. Nếu bạn đã thực sự mất cam kết thì hãy xem this useful guide to recovering commits. Nếu bạn biết SHA-1 của các cam kết bạn muốn thì có thể bạn đã OK.

Điều tốt nhất cần làm: Sao lưu mọi thứ và xem những gì vẫn còn trong kho lưu trữ cục bộ của bạn. Làm tương tự trên điều khiển từ xa nếu có thể. Sử dụng git fsck để xem bạn có thể khôi phục mọi thứ không và trên tất cả KHÔNG chạy git gc.

Trên tất cả, không bao giờ sử dụng tùy chọn --force trừ khi bạn thực sự, thực sự có ý nghĩa.

+37

Bạn rất có thể chỉ cần nhìn vào các reflog để xác định nơi ban đầu các chi nhánh từ xa. Ví dụ, 'git reflog hiển thị điều khiển từ xa/origin/master'. Bạn sẽ có thể thấy sự thúc đẩy của bạn trong đó; cam kết trong dòng trước đó là nơi nó đã được trước khi bạn messed nó lên. Sau đó bạn có thể chỉ cần đẩy bản sửa đổi đó (với '- force') để xuất phát và quay lại vị trí của bạn! – Cascabel

+0

@David: Ồ. Bạn đã không đề cập đến trong câu hỏi của bạn rằng bạn không có repo. (Dĩ nhiên, đây là điều bạn không bao giờ muốn làm). Nếu bạn có quyền truy cập hệ thống tập tin mà bạn đã đẩy đến, bạn vẫn có thể làm tất cả những điều này ở đó. – Cascabel

+1

@David: Yikes. Luôn luôn tốt để có thư mục hiện tại của bạn như là một phần của dấu nhắc của bạn để tránh điều đó. – Cascabel

2

Tôi đã làm điều tương tự trong khi hoàn tác lần đẩy cuối cùng chỉ cho một tệp. Kết thúc sẽ trở lại trạng thái ban đầu của kho lưu trữ. Tôi đã sử dụng lệnh git từ Linus vì tôi đã có bản sao cục bộ trên Linux. May mắn là bản sao vẫn còn nguyên vẹn.

Tất cả tôi đã làm được (sau khi điên cuồng làm vài bản nhiều repo địa phương):

git add . 
git status 

(nó nói rằng nguồn gốc/master đã đi trước bởi 68 cam kết, tiền phạt ... đó là những tất cả các cam kết Tôi đã xóa)

git remote set-url origin <GIT_SSH_URL> 
git push 

Và mọi thứ đã được khôi phục theo cách trước khi tôi đẩy mạnh. Điều quan trọng nhất cần nhớ là không bao giờ thực hiện kiểm tra git. sau khi bạn đã đẩy mạnh. Nhưng cách tốt nhất là tắt tùy chọn đẩy. Tôi không bao giờ sử dụng nó nữa. Đã học bài học của tôi !!

32

Nếu bạn biết băm cam kết, thật dễ dàng, chỉ cần tạo lại chi nhánh của bạn.

5794458...b459f069 master -> master (forced update) 

Xóa chi nhánh từ xa:

git push origin :master 

sau đó tái tạo chi nhánh của bạn với các lệnh sau:

git checkout 5794458 
git branch master 
git push origin master 
+0

THANKS !!! Tôi yêu nó –

+0

Chính xác những gì tôi đang tìm kiếm. –

+0

Genius. Điều này vừa tiết kiệm cho tôi rất nhiều công việc – fduembgen

8

Các giải pháp đã được đề cập here

# work on local master 
git checkout master 

# reset to the previous state of origin/master, as recorded by reflog 
git reset --hard origin/[email protected]{1} 

# at this point verify that this is indeed the desired commit. 
# (if necessary, use git reflog to find the right one, and 
# git reset --hard to that one) 

# finally, push the master branch (and only the master branch) to the server 
git push -f origin master 
0

Nếu bạn không ở trên đó repo địa phương nơi đẩy buộc đến từ, ở cấp độ gốc/thạc sĩ không có cách nào để phục hồi.Nhưng nếu bạn là may mắn đủ để sử dụng GitHub hoặc GitHub for Enterprise, bạn có thể có một cái nhìn vào REST API và lấy mất cam kết như vá, ví dụ:

Danh sách
  1. sự kiện và tìm ra cam kết định dạng dài sha1

https://api.github.com/repos/apache/logging-log4j2/events

  1. Tải los t cam kết và lấy các bản vá liên quan trong đường dẫn json .files []/vá

https://api.github.com/repos/apache/logging-log4j2/commits/889232e28f3863d2a17392c06c1dd8cac68485de

  1. Áp dụng tại địa phương và đẩy lại

git áp dụng patch.patch & & git commit -m "cam kết khôi phục" & & git push origin master

Các vấn đề liên quan