「git pull」は私の宿題をどのように食べましたか?


53

私は校長の子供が犬が私の宿題をその前夜に食べたことを説明しているように感じますが、私は顔にいくつかのクレイジーなデータ損失のバグを見つめています、そしてそれがどのように起こったのかわかりません。gitがリポジトリ全体をどのように食べられるかを知りたい!私はgitを絞り器に何度も入れましたが、点滅することはありません。20 Gig 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コマンドを実行しようとしました。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」ディレクトリはなく、何もありません。空の。

私のローカルgitはバージョン2.0.2です。git configからの2、3のヒントを以下に示します。

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

たとえばgit pull、マージの代わりに常にリベースを行うように設定しているため、上記の出力の一部は正常です。

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

私はチェックしました:

  • dmesgまたはsystemdジャーナルのメッセージ。リモートでも関連するものはありません。
  • ドライブまたはファイルシステムの障害の兆候はありません(LVM + LUKS + EXT4はすべて正常に見えます)。lost + foundには何もありません。
  • 他には何もしませんでした。私が上に示していない歴史には何もありませんし、この期間中に他の端末は使用されませんでした。rm間違ったCWDなどで実行された可能性のあるコマンドはありません。
  • 別のディレクトリの別のgitリポジトリを突くと、git pullsを実行している明らかな異常はありません。

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


4
@Patrick質問ですでに説明したように、.git存在するものはありません。何もしません— gitルートディレクトリであったものには何も含まれていません。
カレブ14

2
@Alexanderプル操作は正常です(それ以外はマージではなくリベースです)。強制更新に関する通知は、私がプルしようとしているレポが、ローカルレポが最後に見たのとは異なる位置からそれをリセットするフォースプッシュがあったことを示しています。これは正常なことです。なぜなら、私は積極的に開発され、頻繁にリベースされた素材を自分のコンピューター間で同期しているからです。
カレブ14

3
@Calebシェルプロンプトにはgitブランチの指示が含まれます。つまり、PS1を形成すると、ログに表示されないgitコマンドが含まれます。彼らは主に状況を変え、問題の原因になります。シェルプロンプトがどのように形成されるか、現在のブランチを取得するために実行されるコマンドを正確に説明する質問を更新し、リポジトリを損なう方法を再検討する必要があります。
ネッチ14

2
@Caleb git developmentメーリングリストで本当に尋ねるべきです。それをバグレポートとして書くか、単に非公式に尋ねることができます-とにかく同じです。gitを非常によく知っている開発者もいます-直観的に何が起こったのかを知ることができます。(そうでない場合、彼らは静かに議論をたどるだけです。)そして、彼らはそれが以前に起こったかどうかを知っています。(それを報告すると、gitのバグを報告する「公式の」方法があります)
Volker Siegel 14年

7
@Wildcard実際、私は実際に何が起こったのかを理解したので、これに対する答えをまとめるつもりでした。システムは最近スリープ状態から立ち上がっており、ネットワークはスリープ状態になる前に数日間停止していました。そのプロセスのどこかで、システム上の何かをアップグレードしようとしていたpacmanプロセスを実行したままにしました。長い話を短くすると、glibcが更新され、gitバイナリが上書きされたことがわかります。それがそれ自体を分岐させた方法のために、1つのインスタンスは他のものとは異なってしまい、お互いの昼食を食べました。ディレクトリには、実際には明朝ない(空でした
カレブ

回答:


6

はい、git宿題を食べました。それのすべて。

ddは事件の後にこのディスクの画像を作り、後でそれをいじりました。システムログから一連のイベントを再構築すると、何が起こったのかは次のように推測できます。

  1. この更新のpacman -Syu数日前にシステム更新コマンド()が発行されていました。
  2. ネットワークが長時間停止すると、パッケージのダウンロードを再試行することになります。インターネットの欠如に不満を感じ、私はシステムをスリープ状態にして寝ました。
  3. 数日後、システムが起動され、パッケージの検索とダウンロードが再び開始されました。
  4. パッケージのダウンロードは、たまたまこのリポジトリをいじる直前に終了しました。
  5. システムglibcのインストールはgit checkout、の前後で更新されましたgit pull
  6. git後にバイナリが置き換えられてしまっgit pull開始し、それが終了する前に。
  7. そして7日目に、gitそのすべての労働から休んだ。そして世界を削除したので、他のみんなも休まなければなりませんでした。

これを引き起こした競合状態がどのように発生したのか正確にはわかりませんが、操作の途中でバイナリをスワップアウトすることは確かに良いことでも、テスト可能な/繰り返し可能な状態でもありません。通常、実行中のバイナリのコピーはメモリに保存されますが、git奇妙であり、それ自体のバージョンを再生成する方法について何かが、この混乱につながったと確信しています。明らかに、すべてを破壊するのではなく死んだはずですが、それが起こったのです。


1
gitは単一のバイナリではなく、differendコマンドを使用してmakeを実行するため、gitは失敗する可能性があります。シンプルなgitのプル実行git-fetchgit-rebaseまたはgit-mergeおよびgit gc
Ferrybig

2

削除するファイルパスの定義に失敗した可能性があります。

あなたのケースremove(path)は、与えられたパラメーターが空の文字列で、OSがルートフォルダーとして修正した(!)ため、私の自家製の方法がルートフォルダーを削除しようとした美しい日を思い出させてくれました。

これは同様のgitバグかもしれません。そのような:

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

1

運が良ければ、次のコマンドでこれを修正できます。

git reset --hard ORIG_HEAD  

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

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


4
質問全体を読んだとは思わない。git meta-dataがないため、この種の修正は完全に問題外です。このようなリセットを行うには、既存の.gitディレクトリとその中のいくつかのオブジェクトが動作する必要があります。私には何もない。それは単に作業ディレクトリが台無しになっているだけでなく、いかなる種類のリポジトリでもありません。
カレブ14

ああ、おaびします。それは非常に珍しいことです。gitリポジトリがなくなった場合、Linuxでファイルをシャドウイングし、ファイルのfsバックアップがない限り、復旧する方法はないと思います。回答は無関係なので削除します。
Routhinator

はい、私はそれが異常な問題であることを知っています(そして、私はバックアップを持っています)。ここでの私の質問は、それがどのようにうまくいかなかったかです... gitや私のファイルシステムドライバー、またはこのような操作の途中でディレクトリを食べるために中断された他の何かのバグを探す場所です。
カレブ14

私もとても興味があります。私のリポジトリにこのようなことが起こるのを嫌います。
Routhinator

-1

誰かがgit push --forceこのレポで実行したように見えるので、それらの変更をプルダウンしました。レポジトリを新しくクローンしてみてください。これにより、再び正常な動作状態に戻ります。


1
強制プッシュは、最後の一握りのコミットをリベースしました。それは私がプルダウンしたものではありませんでした(作業ディレクトリはもはや作業ディレクトリではありません!)そして、それが再クローニングだったとしても意味がありません。
カレブ14

4
私はあなたが誰かの削除ができないと思う.git強制的にプッシュしてディレクトリを
グジェゴシ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.