なぜ `git pull`は私の仕事を食べましたか?

なぜ `git pull`は私の仕事を食べましたか?

締め切りの前日の夜に犬が私の宿題を食べてしまったと校長室で説明する子供になったような気がします。ところで、クレイジーなデータ損失エラーが発生し、どのようにこれが起こったのか理解できません。 Gitが私の店全体をどのように食べるのか知りたいです!私はgitで何度も頭を傷つけましたが、決して点滅しませんでした。私はそれを使って20Gig Subversionリポジトリを27のgitリポジトリに分割し、ここでブランチfooをフィルタリングして混乱を解決し、1バイトも失うことはありませんでした。 reflogは常に信頼できます。今回はカーペットが消えました!

私の観点から私がしたことは実行だけでgit pullあり、ローカルストレージ全体が破壊されました。 「チェックアウト版が台無しにされた」、「私が持っていたブランチ」などを意味するわけではありません。私の言葉はすべてが消えた

以下は、イベントが発生したときの私の端末のスクリーンショットです。

イベントのスクリーンショット

その内容をご案内いたします。私のコマンドプロンプトには現在のgitリポジトリ(preztoのvcs_info実装を使用)のデータが含まれているので、gitリポジトリがいつ消えるかを確認できます。最初のコマンドは正常です。

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

そこから私が「zend」ブランチにいて、マスターをチェックアウトしたことがわかります。今まではそんなに良くなった。次のコマンドの前のプロンプトで、ブランチが正常に切り替えられたことを確認できます。

  » 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

そしてそれは消えた。経過時間が10秒を超えると、次のプロンプトの前に経過したタイムスタンプが出力されます。 Gitは再生を巻き戻しているという通知以外に出力を提供しません。完了したという表示はありません。

次のプロンプトには、現在存在するブランチまたはGitステータスに関するデータは含まれていません。

私はそれが失敗したことを知らず、誤って別のgitコマンドを実行しようとしましたが、私はgitリポジトリにいないと言われました。 PWDは変更されていません。

  » 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).

周りを見回した後、私は完全に空のディレクトリにあることがわかりました。何もありません。 ".git"ディレクトリはありません。何もありません。空です。

私のローカル子バージョンは2.0.2です。以下は、何が起こっているのかを理解するのに関連している可能性がある私のgit設定のいくつかの有用な情報です。

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

たとえば、git pullマージではなく常にリベースするように設定したため、上記の出力部分は正常です。

データを回復できます。いくつかの重要ではないリポジトリを除いて、他のリポジトリにプッシュされていないgitオブジェクトがないと思います。何が起こったのか知りたい

私が確認した内容は次のとおりです。

  • dmesg または systemd ログのメッセージ。関連性がありません。
  • ドライブまたはファイルシステムエラーの表示はありません(LVM + LUKS + EXT4はすべて大丈夫です)。紛失物には何もありません。
  • 私は他を実行しません。上記には履歴は表示されず、この期間中は他の端末は使用されませんでした。rm誤ったCWDでコマンドなどを実行する可能性はありません。
  • 別のディレクトリの別のgit repoをパーキングすると、git pull実行に関する明白な例外は表示されません。

ここで何を探すべきですか?

答え1

うん、git宿題を食べました。すべて。

dd事件後、このディスクのイメージを作成し、後で修正しました。システムログで一連のイベントを再設定すると、何が起こったのかを推測できます。

  1. pacman -Syuこの事故が発生する数日前に、システム更新コマンド()が発行されました。
  2. ネットワークの中断が長い場合は、パッケージのダウンロードを再試行する必要があることを意味します。インターネットが足りなくて苦しくてシステムをスリープ状態にして寝てしまいました。
  3. 数日後、システムが目覚め、パッケージを再度見つけてダウンロードを開始します。
  4. このリポジトリを扱う前にパッケージのダウンロードが完了しました。
  5. システムglibc前後にインストールがgit checkout更新されましたgit pull
  6. バイナリは開始後および完了前にgit交換されます。git pull
  7. 7日目にはgitすべてのことを休んだ。そして他の人も休むように世界を削除しました。

全然知らない正確に何らかの競合状態が発生し、このようなことが起こりますが、作業中にバイナリを交換することは間違いなくテスト可能/繰り返し可能な条件ではありません。通常、実行中のバイナリのコピーはメモリに保存されますが、これは奇妙であり、git独自のバージョンを再生成する方法がこの混乱を引き起こすと確信しています。明らかにすべてを破壊するのではなく死ぬべきですが、それはすべてです。

答え2

削除するファイルパスを定義できなかったためです。

remove(path)あなたのケースは、私のホームブレークメソッドがルートフォルダを削除しようとし、与えられた引数が空の文字列だったので、OSがそれをルートフォルダ(!)に変更した良い日を思い出させます。

これは同様の子のバグかもしれません。だから:

  1. Rebaseコマンドはファイル(remove(project_folder + file_path)疑似コードなど)を削除しようとします。
  2. なんかfile_pathその当時は空いていました。
  3. コマンドは次のように評価されます。remove(project_folder)

答え3

幸運な場合は、次のコマンドを使用してこの問題を解決できます。

git reset --hard ORIG_HEAD  

潜在的に危険な変更が開始されると、gitは現在の状態をORIG_HEADに保存します。これにより、マージまたはリベースを元に戻すことができます。

Git マニュアル: マージの取り消し

答え4

git push --force誰かがこのリポジトリを実行し、あなたが変更をもたらしたようです。新しいリポジトリを複製してみてください。これにより、クリーンな作業状態に戻ります。

関連情報