git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Git clone error

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Aug 1, 2007, 17:17 UTC
Message-ID
<Pine.LNX.4.64.0708011802020.14781@racer.site>
In-Reply-To
<alpine.LFD.0.999.0708010929070.3582@woody.linux-foundation.org>
Hi,
On Wed, 1 Aug 2007, Linus Torvalds wrote:
Show 29 quoted lines
> On Wed, 1 Aug 2007, Linus Torvalds wrote:
> > 
> > > If I just recreate a version I'm happy with, can I add that to the repo and
> > > go from there?
> > 
> > Well, it's not so much a version _you_ are happy with: you'd have to 
> > be able to re-create the exact old version (with the exact same SHA1), 
> > in order for git to be happy.
> 
> Btw, if you really cannot re-generate it, you'd basically need to create 
> a whole new git archive without that blob (or basically with that blob 
> replaced by another version).
> 
> We don't have wonderfully good support for that, because, quite frankly, 
> we've not had this happen before. I think every time before, people have 
> had the blob in some other copy of their git archive.
> 
> But the thing to use is "git filter-branch", which can take a git history 
> and munge it arbitrarily. It would be the "tree-filter" that you'd use to 
> replace that one blob that you cannot regenerate with another (ie you 
> might decide to just replace the original version of the file with that 
> *second* version, and regenerate the tree that way).
> 
> I'm cc'ing Dscho explicitly to see if he can help you with the exact 
> syntax, and maybe we could even make this into a user-manual entry about 
> how to handle corruption. I don't think we have anything in the 
> documentation about this - we only cover the trivial cases where the 
> objects are all good, but you've lost the pointers into it because you 
> removed a branch by mistake or something.

I doubt it would be that easy; the tree filter expects a _valid_ tree, which it checks out, and only then you can filter it.

But this is what I would do if I had the problem: I would try to create a state which is as close to the corrupt revision as possible, use a graft to replace the initial commit with that revision, and rewrite the branch. I'd probably start by doing something like this:

	$ git symbolic-ref HEAD refs/heads/recreate-first && rm .git/index
	$ git ls-tree -r --name-only <initial-commit> |
		grep -v "^condor/condor-uninstall.sh$" |
		xargs git checkout <initial-commit>
	$ git checkout <second-commit> condor/condor-uninstall.sh
	[possibly some minor hacking on the latter file to make it work]
	$ git commit -c <initial-commit>

This starts a new branch, which has no ancestor yet. It takes all files except the corrupt one from the first commit, and a replacement of the corrupt one from the second commit. Then it takes all the meta-data from the first commit to create a replacement for the first commit.

Now I'd graft the second commit onto the first:
	$ git rev-parse <second-commit> recreate-first >> .git/info/grafts

This explicitely tells git to disregard the parent information given in <second-commit>, and to pretend that the recreated commit is its parent.

	BEWARE! Grafts are a powerful weapon, and you can spend tons of 
	time looking for an error, when all you did was grafting parts of 
	the history onto other parts of the history.  For example, I was 
	searching several nights for the bug preventing me to push one of 
	my repos, and it always gave an "unpacking" error.  Once I moved 
	the grafts out of the way, it miraculously worked.

After that, just call git-filter-branch (not yet released, but will probably be part of 1.5.3):

	$ git filter-branch <branchname>

Many things can go wrong through that process, so you want to make sure that all steps actually worked as intended (especially since I tested none of this, but wrote it in the mail program)!

Hth, Dscho

Previous: Linus TorvaldsNext: Denis Bueno
Message 7 of 13 in “Git clone error”
  1. Denis BuenoJul 31, 2007
  2. Junio C HamanoAug 1, 2007
  3. Linus TorvaldsAug 1, 2007
  4. Denis BuenoAug 1, 2007
  5. Linus TorvaldsAug 1, 2007
  6. Linus TorvaldsAug 1, 2007
  7. Johannes SchindelinAug 1, 2007
  8. Denis BuenoAug 1, 2007
  9. Johannes SchindelinAug 1, 2007
  10. Denis BuenoAug 2, 2007
  11. Johannes SchindelinAug 2, 2007
  12. Linus TorvaldsAug 2, 2007
  13. Steffen ProhaskaAug 1, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.