My git repository was recently screwed up by a Nextcloud sync. This left it with a commit that was missing a tree.
broken link from commit ddf33d3d1b8278e1fd0d395209f2dbbd168f45c6 (refs/heads/master@{1632991805})
to tree b34b983985fdbe6b1173e2c1e442577bfbf393c1 (refs/heads/master@{1632991805}:)
I would like to overwrite the missing tree with the tree in the next commit, so I can fix the issue while keeping my history. Simply rebasing, to drop the commit fails with fatal: unable to read tree b34b983985fdbe6b1173e2c1e442577bfbf393c1
.
Any help is appreciated!
CodePudding user response:
Technically, you can't change anything about any existing Git object. So you can't change the tree to which some commit points.
That said, you don't have to do that. Consider instead using git replace
, which works for arbitrary objects: use git replace
to make your Git use the next (or previous) commit's tree instead of the missing tree. Just use the git replace object replacement
syntax:
git replace b34b983985fdbe6b1173e2c1e442577bfbf393c1 ...
(fill in the ...
with the desired tree).
This should allow your rebase to progress.
Note: it's probably a good idea to back up the bad repository now (you can use a simple recursive copy), and then clone it to a new one once you have it adjusted as desired and discard (or at least stop using) the intermediate copy with the replacement.
Edit: git replace
is being too smart, so use git replace --edit commit-with-bad-tree
to work around that. You'll still want to clone the edited clone. To make everything show up in the clone-of-the-clone and then remove the traces of cloning the clone, use:
git clone file://<path> new-clone
cd new-clone
git fetch origin ' refs/*:refs/*'
git remote remove origin
and a subsequent git remote add origin ...
if appropriate.
Edit 2: git clone
will almost certainly fail as it won't obey the replacements. You'll need to run git filter-branch
(with no filters), which intentionally damages the bad repository in the name of fixing it (not great although probably harmless in the end), or use the new git filter-repo
command to make the corrected clone. I haven't tried the latter myself, so I don't have any particular instructions here.