newren / git-filter-repo

Quickly rewrite git repository history (filter-branch replacement)
Other
8.13k stars 693 forks source link

fatal: replace depth too high for object #401

Open Hxppdv opened 1 year ago

Hxppdv commented 1 year ago

I used git filter-repo to rename a directory back and forth

git filter-repo --path-rename test:test1 --force 
git filter-repo --path-rename test1:test 

Then I got an error

Parsed 1 commits
New history written in 0.01 seconds; now repacking/cleaning...
Repacking your repo and cleaning out old unneeded objects
fatal: replace depth too high for object 85719f71223001a2409cf16943c87873731fd601
fatal: replace depth too high for object 85719f71223001a2409cf16943c87873731fd601
fatal: failed to run pack-refs
Completely finished after 0.01 seconds.

I used git show-ref to check the replace ref 85719f71223001a2409cf16943c87873731fd601 refs/replace/85719f71223001a2409cf16943c87873731fd601 so I ran git replace -d 85719f71223001a2409cf16943c87873731fd601 to fix that.

It look like git-filter-repo created a replace ref that points to itself. Is this a bug? I know this is because the new commit is the same as the original commit. Maybe we can avoid this error by not creating the replace ref at this time.

newren commented 1 year ago

Yep, sounds like a bug. Thanks for the report and the clear steps on how to trigger.

gdlxn-ibm commented 5 months ago

Any update on a fix?

gdlxn-ibm commented 4 months ago

I'm going to look at fixing this bug.

@newren I don't seem to have the authority to assign this issue to myself. Please feel do this for me (or give me the necessary authority). I've read the contributing guideline; please feel free to share any additional suggestions.

gdlxn-ibm commented 3 months ago

I found what looks to be a workaround to this bug at Rewriting git history simply with git-filter-repo. The workaround is to add the --replace-refs delete-no-add option

Without the --replace-refs delete-no-add option I get the error:

gdlxn@geoff-test4:\~/git-filter-repo$ mkdir repo1 gdlxn@geoff-test4:\~/git-filter-repo$ cd repo1 gdlxn@geoff-test4:\~/git-filter-repo/repo1$ git init Initialized empty Git repository in /home/gdlxn/git-filter-repo/repo1/.git/ gdlxn@geoff-test4:\~/git-filter-repo/repo1$ touch f1 gdlxn@geoff-test4:\~/git-filter-repo/repo1$ git add f1 gdlxn@geoff-test4:\~/git-filter-repo/repo1$ git commit -m "Add f1" [master (root-commit) 2849e86] Add f1 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 f1 gdlxn@geoff-test4:\~/git-filter-repo/repo1$ git filter-repo --path-rename f1:f2 --force Parsed 1 commits New history written in 0.03 seconds; now repacking/cleaning... Repacking your repo and cleaning out old unneeded objects HEAD is now at e936435 Add f1 Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Writing objects: 100% (3/3), done. Total 3 (delta 0), reused 0 (delta 0) Completely finished after 0.10 seconds. gdlxn@geoff-test4:\~/git-filter-repo/repo1$ git filter-repo --path-rename f2:f1 --force Parsed 1 commits New history written in 0.03 seconds; now repacking/cleaning... Repacking your repo and cleaning out old unneeded objects fatal: replace depth too high for object 2849e86317c666f417bbd657e9db03154915ae9d fatal: replace depth too high for object 2849e86317c666f417bbd657e9db03154915ae9d fatal: replace depth too high for object 2849e86317c666f417bbd657e9db03154915ae9d fatal: failed to run pack-refs Completely finished after 0.06 seconds.

With the --replace-refs delete-no-add option I don't get the error:

gdlxn@geoff-test4:\~/git-filter-repo$ mkdir repo1 gdlxn@geoff-test4:\~/git-filter-repo$ cd repo1 gdlxn@geoff-test4:\~/git-filter-repo/repo1$ git init Initialized empty Git repository in /home/gdlxn/git-filter-repo/repo1/.git/ gdlxn@geoff-test4:\~/git-filter-repo/repo1$ touch f1 gdlxn@geoff-test4:\~/git-filter-repo/repo1$ git add f1 gdlxn@geoff-test4:\~/git-filter-repo/repo1$ git commit -m "Add f1" [master (root-commit) b44afa8] Add f1 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 f1 gdlxn@geoff-test4:\~/git-filter-repo/repo1$ git filter-repo --replace-refs delete-no-add --path-rename f1:f2 --force Parsed 1 commits New history written in 0.03 seconds; now repacking/cleaning... Repacking your repo and cleaning out old unneeded objects HEAD is now at e095b52 Add f1 Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Writing objects: 100% (3/3), done. Total 3 (delta 0), reused 0 (delta 0) Completely finished after 0.09 seconds. gdlxn@geoff-test4:\~/git-filter-repo/repo1$ git filter-repo --replace-refs delete-no-add --path-rename f2:f1 --force Parsed 1 commits New history written in 0.03 seconds; now repacking/cleaning... Repacking your repo and cleaning out old unneeded objects HEAD is now at b44afa8 Add f1 Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Writing objects: 100% (3/3), done. Total 3 (delta 0), reused 1 (delta 0) Completely finished after 0.09 seconds.

newren commented 1 month ago

So, while git-filter-repo creates the original replace ref the first time you invoke filter-repo (at which point it points to an independent separate commit), it never touches the replace ref after that. The second time you invoke git-filter-repo, it is actually git-fast-export that outputs information about it, and git-fast-import that writes the updated version (which points at itself). git-filter-repo never touches the replace ref on the second invocation (for updating or writing -- other than parsing and re-outputing the fast-export stream about it as-is), so it really seems like filter-repo is the wrong level to fix the bug. At best, you'd get a workaround like the one @gdlxn-ibm highlights.

Further, you can create similar scenarios that do not involve git-filter-repo at all and trigger the same "replace depth too high" messages with self-pointing replacement references. So, I think this is an upstream git bug. This commit seems to fix it: https://github.com/newren/git/commit/9559b82e7afd29d94c047827973b1530c970c56b (an alternative fix would be to make it so that you can have a self-pointing replace ref, but have git just ignore it, but that seems slightly ugly). Git v2.46.0 was just released, though, so Git discussions and submissions should focus on making sure the new release doesn't have any weird regressions -- or that if it does, we quickly release a fix. Independent fixes and new features should wait a week or so to be submitted, so I'll wait a bit to submit this fix.