Làm thế nào mà `git pull` ăn bài tập về nhà của tôi?


53

Tôi cảm thấy như một đứa trẻ trong văn phòng hiệu trưởng giải thích rằng con chó đã ăn bài tập về nhà của tôi vào đêm trước khi đến hạn, nhưng tôi đang nhìn chằm chằm vào một số lỗi mất dữ liệu điên rồ ở mặt và tôi không thể hiểu được nó đã xảy ra như thế nào. Tôi muốn biết làm thế nào git có thể ăn toàn bộ kho lưu trữ của tôi! Tôi đã đặt git qua máy vắt nhiều lần và nó không bao giờ chớp mắt. Tôi đã sử dụng nó để chia một repo 20 Gig Subversion thành 27 git repos và lọc phân nhánh foo ra khỏi chúng để gỡ rối mớ hỗn độn và nó không bao giờ mất một byte đối với tôi. Các reflog luôn luôn ở đó để trở lại. Lần này thảm đã biến mất!

Từ quan điểm của tôi, tất cả những gì tôi đã làm là chạy git pullvà nó đã thu thập toàn bộ kho lưu trữ cục bộ của tôi. Tôi không có nghĩa là nó "làm hỏng phiên bản đã kiểm tra" hoặc "chi nhánh tôi đã ở" hoặc bất cứ điều gì tương tự. Tôi có nghĩa là toàn bộ điều đã biến mất .

Đây là ảnh chụp màn hình thiết bị đầu cuối của tôi tại sự cố:

chụp màn hình sự cố

Hãy để tôi dẫn bạn qua đó. Dấu nhắc lệnh của tôi bao gồm dữ liệu về repo git hiện tại (sử dụng triển khai vcs_info của prezto) để bạn có thể thấy khi git repo biến mất. Lệnh đầu tiên là đủ bình thường:

  » caleb » jaguar » ~/p/w/incil.info » ◼  zend ★ »
❯❯❯ git co master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

Ở đó bạn có thể thấy tôi đã ở chi nhánh 'zend' và kiểm tra chủ. Càng xa càng tốt. Bạn sẽ thấy trong lời nhắc trước lệnh tiếp theo của tôi rằng nó đã chuyển thành công các nhánh:

  » caleb » jaguar » ~/p/w/incil.info » ◼  master ★ »
❯❯❯ git pull
remote: Counting objects: 37, done.
remote: Compressing objects: 100% (37/37), done.
remote: Total 37 (delta 25), reused 0 (delta 0)
Unpacking objects: 100% (37/37), done.
From gitlab.alerque.com:ipk/incil.info
 + 7412a21...eca4d26 master     -> origin/master  (forced update)
   f03fa5d..c8ea00b  devel      -> origin/devel
 + 2af282c...009b8ec verse-spinner -> origin/verse-spinner  (forced update)
First, rewinding head to replay your work on top of it...
>>> elapsed time 11s

Và cứ như thế nó biến mất. Dấu thời gian đã trôi qua xuất hiện trước dấu nhắc tiếp theo nếu hơn 10 giây đã trôi qua. Git đã không đưa ra bất kỳ đầu ra nào ngoài thông báo rằng nó đang tua lại để phát lại. Không có dấu hiệu cho thấy nó đã hoàn thành.

Dấu nhắc tiếp theo bao gồm không có dữ liệu về chi nhánh chúng tôi đang ở hoặc trạng thái của git.

Không nhận thấy nó đã thất bại, tôi đã cố gắng chạy một lệnh git khác chỉ để nói rằng tôi không ở trong một repo git. Lưu ý NKT không thay đổi:

  » caleb » jaguar » ~/p/w/incil.info »
❯❯❯ git fetch --all
fatal: Not a git repository (or any parent up to mount point /home)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

Sau đó, một cái nhìn xung quanh cho thấy tôi đang ở trong một thư mục hoàn toàn trống rỗng. Không có gì. Không có thư mục '.git', không có gì. Trống.

Git địa phương của tôi là phiên bản 2.0.2. Dưới đây là một vài thông tin từ cấu hình git của tôi có thể liên quan đến việc tìm hiểu điều gì đã xảy ra:

[branch]
        autosetuprebase = always
        rebase = preserve
[pull]
        rebase = true
[rebase]
        autosquash = true
        autostash = true
[alias]
        co = checkout

Ví dụ, tôi đã git pullđặt luôn luôn thực hiện một rebase thay vì hợp nhất, do đó một phần của đầu ra ở trên là bình thường.

Tôi có thể khôi phục dữ liệu. Tôi không nghĩ rằng có bất kỳ đối tượng git nào khác ngoài một số stash không quan trọng đã bị đẩy sang các repos khác, nhưng tôi muốn biết điều gì đã xảy ra .

Tôi đã kiểm tra:

  • Tin nhắn trong dmesg hoặc tạp chí systemd. Thậm chí không có gì liên quan từ xa.
  • Không có dấu hiệu của lỗi ổ đĩa hoặc hệ thống tệp (LVM + LUKS + EXT4 đều trông bình thường). Không có gì trong mất + tìm thấy.
  • Tôi đã không chạy bất cứ điều gì khác. Không có gì trong lịch sử tôi không hiển thị ở trên và không có thiết bị đầu cuối nào khác được sử dụng trong thời gian này. Không có rmlệnh nào trôi nổi xung quanh có thể đã thực thi trong CWD sai, v.v.
  • Chọc vào một repo git khác trong một thư mục khác cho thấy không có bất thường rõ ràng thực thi git pulls.

Những gì khác tôi nên tìm kiếm ở đây?


4
@Patrick Như tôi đã giải thích trong câu hỏi rồi, .gitkhông tồn tại. Không có gì làm những gì từng là thư mục gốc git không có gì trong đó cả.
Caleb

2
@Alexander Hoạt động kéo là bình thường (khác là một rebase chứ không phải là hợp nhất). Thông báo về một bản cập nhật bắt buộc đang chỉ ra rằng repo mà tôi đang kéo có lực đẩy khiến nó đặt lại từ một vị trí khác với repo cục bộ nhìn thấy lần cuối. Điều này là bình thường vì tôi đang đồng bộ hóa tài liệu được phát triển tích cực và thường xuyên được khởi động lại giữa các máy tính của riêng tôi, không phải là một nhánh công cộng mà các nhà phát triển khác sẽ thấy.
Caleb

3
@Caleb Dấu nhắc shell của bạn bao gồm chỉ thị nhánh git, có nghĩa là hình thành PS1 bao gồm các lệnh git không được hiển thị trong nhật ký của bạn. Họ chủ yếu có thể thay đổi hình ảnh và có thể là nguồn vấn đề. Bạn nên cập nhật câu hỏi mô tả chính xác cách dấu nhắc shell của bạn được hình thành, những lệnh nào được chạy để có được một nhánh hiện tại và xem xét lại cách chúng có thể làm hỏng repo của bạn.
Lấy

2
@Caleb Bạn thực sự nên hỏi về danh sách gửi thư phát triển git; Bạn có thể viết nó như một báo cáo lỗi, hoặc chỉ hỏi một cách không chính thức - dù sao nó cũng giống nhau. Có một số nhà phát triển biết rất rõ về git - họ có thể biết được bằng trực giác những gì có thể xảy ra. (Nếu không, họ sẽ chỉ theo dõi cuộc thảo luận một cách lặng lẽ.) Và họ biết liệu điều đó có xảy ra trước đó không. (Báo cáo đó là cách "chính thức" để báo cáo lỗi cho git)
Volker Siegel

7
@Wildcard Thật ra tôi đã có ý định đưa ra một câu trả lời cho điều này vì tôi thực sự đã tìm ra điều gì đã xảy ra. Hệ thống gần đây đã đi lên từ giấc ngủ và mạng đã bị tắt trong nhiều ngày trước khi nó đi ngủ. Ở đâu đó trong quá trình đó, tôi đã để lại một quá trình pacman đang chạy để cố nâng cấp một cái gì đó trên hệ thống. Để làm cho một câu chuyện dài ngắn, hóa ra glibc đã được cập nhật và nhị phân git đã bị ghi đè. Bởi vì cách nó tự rẽ nhánh, một trường hợp cuối cùng khác với người khác và họ đã ăn bữa trưa của nhau. Thư mục thực sự trống rỗng (không chỉ rõ ràng
Caleb

Câu trả lời:


6

Vâng, gitđã ăn bài tập về nhà của tôi. Tất cả.

Tôi đã tạo một ddhình ảnh của đĩa này sau sự cố và làm hỏng nó sau đó. Tái tạo chuỗi các sự kiện từ nhật ký hệ thống, tôi suy luận những gì đã xảy ra là như thế này:

  1. Một lệnh cập nhật hệ thống ( pacman -Syu) đã được ban hành vài ngày trước khi sự cố này xảy ra.
  2. Mất mạng kéo dài có nghĩa là nó đã cố gắng tải lại các gói. Thất vọng vì thiếu internet, tôi đã đặt hệ thống ngủ và đi ngủ.
  3. Vài ngày sau, hệ thống được đánh thức và nó bắt đầu tìm và tải lại các gói.
  4. Tải xuống gói hoàn thành đôi khi ngay trước khi tôi tình cờ gặp phải kho lưu trữ này.
  5. Cài đặt hệ thống glibc đã được cập nhật sau git checkoutvà trước git pull.
  6. Các gitnhị phân bị thay thế sau khi git pullbắt đầu và trước khi nó kết thúc.
  7. Và vào ngày thứ bảy, gitnghỉ ngơi từ tất cả lao động của nó. Và xóa thế giới để mọi người khác cũng phải nghỉ ngơi.

Tôi không biết chính xác điều kiện cuộc đua nào đã xảy ra khiến điều này xảy ra, nhưng việc trao đổi nhị phân ở giữa một hoạt động chắc chắn không tốt cũng không phải là điều kiện có thể kiểm tra / lặp lại. Thông thường, một bản sao của nhị phân đang chạy được lưu trữ trong bộ nhớ, nhưng gitthật kỳ lạ và một cái gì đó về cách nó tái sinh các phiên bản của chính nó Tôi chắc chắn đã dẫn đến mớ hỗn độn này. Rõ ràng là nó đáng lẽ phải chết chứ không phải phá hủy mọi thứ, nhưng đó là những gì đã xảy ra.


1
git có thể đã thất bại vì git được tạo bằng các lệnh differend, thay vào đó là một nhị phân duy nhất. Một git pull đơn giản thực hiện git-fetch, git-rebasehoặc git-mergegit gc
Ferrybig

2

Có thể bằng cách không xác định đường dẫn tệp sẽ bị xóa.

Trường hợp của bạn đã nhắc nhở tôi một ngày đẹp trời rằng khi remove(path)phương thức tự chế của tôi cố xóa thư mục gốc vì tham số đã cho là chuỗi rỗng mà HĐH đã sửa (!) Làm thư mục gốc.

Đây có thể là một lỗi git tương tự. Như vậy mà:

  1. Lệnh Rebase muốn xóa một tệp như remove(project_folder + file_path)(mã giả)
  2. Bằng cách nào đó file_pathđã trống rỗng vào thời điểm đó.
  3. Lệnh được đánh giá là một số thứ như remove(project_folder)

1

Nếu may mắn, bạn có thể khắc phục điều này bằng lệnh sau:

git reset --hard ORIG_HEAD  

Khi nguy cơ thay đổi nguy hiểm bắt đầu, git sẽ xóa trạng thái hiện tại của bạn trong ORIG_HEAD. Với nó, bạn có thể hoàn tác hợp nhất hoặc rebase.

Hướng dẫn sử dụng Git: Hoàn tác hợp nhất


4
Tôi không nghĩ bạn đọc toàn bộ câu hỏi. Loại sửa chữa này là hoàn toàn không có vấn đềkhông có dữ liệu meta git . Thực hiện thiết lập lại như thế này đòi hỏi một thư mục .git còn tồn tại và một số đối tượng trong đó để làm việc. Tôi không có gì cả. Nó không chỉ là một thư mục làm việc lộn xộn, nó không còn là kho lưu trữ dưới bất kỳ hình thức nào.
Caleb

Ahh, lời xin lỗi của tôi. Điều đó rất bất thường. Nếu git repo không còn nữa, tôi cho rằng sẽ không có cách nào để phục hồi trừ khi bạn đang tạo tập tin trong linux và có bản sao lưu fs của tập tin. Tôi sẽ xóa câu trả lời của tôi vì nó không liên quan.
Routhinator

Có tôi biết đó là một vấn đề bất thường (và tôi có bản sao lưu). Câu hỏi của tôi ở đây là làm thế nào nó đi sai ... nơi để tìm lỗi trong git hoặc trình điều khiển hệ thống tệp của tôi hoặc bất cứ điều gì khác có thể đã ăn để thư mục ở giữa một hoạt động như thế này.
Caleb

Tôi cũng rất tò mò. Sẽ hatr cho một cái gì đó như thế này xảy ra với repos của tôi.
Routhinator

-1

Có vẻ như ai đó đã chạy git push --forcetrên repo này, và bạn đã kéo những thay đổi đó xuống. Hãy thử nhân bản repo mới, điều đó sẽ đưa bạn trở lại trạng thái làm việc sạch sẽ một lần nữa.


1
Sự thúc đẩy bắt buộc đã đẩy lùi những cam kết cuối cùng. Đó không phải là những gì tôi đã kéo xuống (thư mục làm việc không còn là thư mục hoạt động nữa!) Và ngay cả khi nó được nhân bản lại cũng không có ý nghĩa gì.
Caleb

4
Tôi không nghĩ rằng bạn có thể xóa .gitthư mục của ai đó bằng một cú đẩy bắt buộc
Grzegorz
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.