3

I have a git repository that is not corrupt (all object files remains, i can commit to it and so on).

Recently I noticed that some older commits are broken, "error in commit":

git fsck --full
Checking object directories: 100% (256/256), done.
error in commit 1e04e033e642f9310bd7b0e6745f3ef775a15f15: invalid author/committer line - bad email

I had a look at the individual commit:

zpipe -d < .git/objects/1e/04e033e642f9310bd7b0e6745f3ef775a15f15
commit 276tree 591e98a0b53880a22f18f5bedefe133166d3e67d
parent 4c33ebce11897dd52528defa41890eabc59135e3
author Martin Lindhe <martin@xxx.se
> 1382869510 +0100
committer Martin Lindhe <martin@xxx.se
> 1382869510 +0100

commit message

As seen here, the emails have a trailing newline (0x0a, as shown by piping to xxd)

Is it possible to fix the object header?

  • Please checkout: stackoverflow.com/questions/750172/… – alpert Oct 15 '14 at 13:26
  • alpertek: Thanks, but git-filter-branch also fails with the same error message, "invalid author/committer line - bad email" (i had it mentioned in an older version of this question but just removed it to try to make the question easier to comprehend) – Martin Olika Oct 15 '14 at 13:28
0

Before everything, make a backup of your local repository.

Suppose your corrupted commit is <corrupted>.

First of all, create a new commit object based on the corrupted one:

git commit-tree -m "New message line 1" -m "Line 2" <corrupt>^{tree} -p <corrupt>^1

Note: adapt your command (-p for parents to add, -m for commit message lines, etc). See git-commit-tree man page to deal with author name/email etc.

You will get a new commit SHA-1: <fixed>.

Now make a commit replacement (graft):

git replace <corrupted> <fixed>

This will make a "graft" which will artificially change your corrupted commit with the fixed one.

This modification is reversible: you can remove it or show it through git-replace command (see its man page!) or looking into .git/refs/replace/ directory.

To make it permanent, use git filter-branch but all the changed part will be made of new commit objects (that is, new SHA-1s).

# HEAD should point to the most recent commit (certainly master)...
git filter-branch <fixed>~1..HEAD

Finally, delate your replacement (now permanent in your history):

git replace -d <corrupted>

This works well with one master branch, but if you have several active branches (created after <corrupted>), you will have to rebase all of them like this:

git rebase --onto <new-root-branch> <old-root-branch> <branch>

Where:

  • <new-root-branch> is the commit from which the branch should start now (new base SHA-1);
  • <old-root-branch> is the commit from which the branch started before the filter branch call;
  • <branch> is the branch to rebase.

Find these SHA-1s with log commands like:

git log --graph --decorate --all --pretty=oneline

When you double checked that everything is OK (branches, etc.) and when everybody linked to your git repository is completely aware of what is going on, you can git push --force your modifications.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.