8

ツリー内のコミット エントリの sha1 がヌルの git リポジトリを継承したため、FishEye がリポジトリをインデックス化できません。

$ git fsck
Checking object directoriies: 100%(256/256), done.
warning in tree db22a67df70dc4ff90ec4cd666da91e9c2cb0d9:
    contains entries pointing to null sha1
Checking objects: 100% (416532/416532), done.
Checking connectivity: 416532, done.

指定されたツリーを探すと、次の結果が得られます。

$ git ls-tree db22a6
100644 blob e615f18b55a39f2719112ce209c2505dd92d8e75    .gitignore
100644 blob ac852f06c5a04420356c1d5efca44d9a864e78b0    .project
160000 commit 0000000000000000000000000000000000000000  SomeDirectory
100644 blob 631c17e28026261a2ccf6bc570842cf4af9f181c    GoDeploy.bat
100644 blob 40e992ab5c3868af2910135c3ac4610c3646e7f8    pom.xml

履歴をSomeDirectory調べると、最初は git サブモジュールであり、問​​題を引き起こしていると思われるコミットは と の両方を削除したものであること.gitmodulesがわかりましたSomeDirectory。現在、SomeDirectory犯人がいたのとまったく同じ場所に呼び出された実際のディレクトリがあります。
run a を修正しgit filter-branchて、最終的にどうなるかを確認することはできますが、機能しません。

$ git filter-branch --force --index-filter \
$ 'git rm --cached --ignore-unmatch SomeDirectory' \
$ --prune-empty --tag-name-filter cat -- --all
[... striped out for clarity]
Rewrite c571a3ec94e9f84471577bac41ac7375c729ef08 (76/18522)error:
    cache enttry has null sha1: SomeDirectory
fatal: unable to write new index file
Could not initialize the index
[... striped out for clarity]

問題の原因となるコミットの前に認識しているバックアップがないことを知って、次に何を試みる必要がありますか。

4

3 に答える 3

15

表示されるメッセージは、不適切なサブモジュールを持つツリーが 1 つしかないことを示唆しています。その場合、クリーンアップする必要はほとんどありません。この問題のない新しい固定ツリーを作成できます。

$ git ls-tree db22a67df70dc4ff90ec4cd666da91e9c2cb0d9 |
> sed -e '/0\{40\}/d' |
> git mktree
(新しいツリー SHA1 はこちら)

あなたの質問はgit ls-treeすでに出力を示しています。はsed、不正なサブモジュールを含む行を削除しgit mktree、結果から新しいツリー オブジェクトを作成します。

固定ツリーを取得したら、このツリーを使用して固定コミットを作成できます。

$ git cat-file commit c571a3ec94e9f84471577bac41ac7375c729ef08 |
> sed 's/db22a67df70dc4ff90ec4cd666da91e9c2cb0d9/(ここに新しいツリー SHA1)/' |
> git ハッシュ オブジェクト -t コミット -w --stdin
(新しいコミット SHA1 はこちら)

git cat-file commit c571a3ec94e9f84471577bac41ac7375c729ef08問題のあるコミット オブジェクトをテキスト形式で出力します。で始まりtree db22a67df70dc4ff90ec4cd666da91e9c2cb0d9、残りのコミット情報 (親、作成者、コミッター、コミット メッセージ) に続きます。は、行の古いツリーへの参照を新しいものにsed置き換えます。結果から新しいコミット オブジェクトを作成し、それをリポジトリに書き込み、その ID を出力します。treegit hash-object -t commit -w --stdin

固定コミットを取得したら、次を使用できますgit replace

$ git replace c571a3ec94e9f84471577bac41ac7375c729ef08 (ここに新しいコミット SHA1)

これは実際にはまだ何も変更していませんが、 commit を読み取るときはいつでも、c571a3ec94e9f84471577bac41ac7375c729ef08代わりに新しい commit オブジェクトを読み取る必要があることを Git に伝えます。

そして最後に、git filter-branchそれを永続的にするために使用します。これはすべてのコミットを通過し、それらを読み取り、それらを書き戻します。通常、コミットを変更するオプションがない場合、これはあまり効果がありませんが、以前のgit replace.c571a3ec94e9f84471577bac41ac7375c729ef08書き直したものなど。

于 2014-06-15T09:50:36.007 に答える
0

インタラクティブなリベースを使用して、面倒な SomeDirectory コミット参照を含むコミットを変更することができるかもしれません。

$ git branch backup_branch       # To be able to revert if not satisfied
$ git rebase -i db22a6^          # From parent to db22a6
...
# You then select Edit for commit db22a6 in the editor
...
$ git reset HEAD^             # Reset the commit db22a6 but not its changes
$ git status
...
# should list as modified: .gitignore .project SomeDirectory GoDeploy.bat pom.xml
...
$ git checkout SomeDirectory     # Cancel the troublesome change
$ git add .gitignore .project GoDeploy.bat pom.xml
$ git commit -m "your commit message"
$ git rebase --continue
于 2014-06-12T13:27:48.253 に答える