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

Re: git-repack -a -d produces unusable packs with 1.4.0

From
Junio C Hamano <junkio@cox.net>
Date
Jun 25, 2006, 12:23 UTC
Message-ID
<7vbqshtodj.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<20060625113522.GC19210@cip.informatik.uni-erlangen.de>
Thomas Glanzmann <sithglan@stud.uni-erlangen.de> writes:
>         Pack pack-ce49d2efd5af06ed6093049050b5ba41da8b683f created.
>         mv: overwrite `.git/objects/pack/pack-ce49d2efd5af06ed6093049050b5ba41da8b683f.pack', overriding mode 0444? y
>         mv: overwrite `.git/objects/pack/pack-ce49d2efd5af06ed6093049050b5ba41da8b683f.idx', overriding mode 0444? y
>         fatal: packfile .git/objects/pack/pack-ce49d2efd5af06ed6093049050b5ba41da8b683f.pack does not match index.

I would understand if you answer 'y' to one but 'n' to the other it would result in a situation with unmatching .pack and .idx and you would see something like the above (by the way, the "fatal" is coming from update-server-info that tries to read from freshly moved packfiles); but the above is different, so it does not explain the symptom. I am worried and curious as to what happened, since you are answering 'y' to both of them. This would trigger immediately after a clone which creates pack and idx unwritable; repack leaves the results writable unless your umask is 0222, so "mv" would not even ask the silly questions.

Did you happen to have .tmp-pack-ce49d2ef... at the project root level after this failure? If so which one (either .pack or .idx)?

If you had .tmp-pack-*.pack then .git/objects/pack/pack-ce49...pack is from the old round and .git/objects/pack/pack-ce49...idx is from the new one. Moving .tmp-pack-* to .git/objects/pack/pack-* would hopefully solve this problem.

Nevertheless, this _is_ a dangerous and grave bug, and thanks for reporting it.

Maybe we would want to do something like this:

-- >8 -- git-repack: Be careful when updating the same pack as existing one.

After clone, packfiles are read-only by default and "mv" went interactive asking if the user wants to replace it with a repacked copy. If one is successfully moved and the other is not, the pack and its idx would become out-of-sync and corrupts the repository.

Recovering is straightforward -- it is just the matter of finding the remaining .tmp-pack-* and make sure they are both moved -- but we should be extra careful not to do something so alarming to the users.

---
diff --git a/git-repack.sh b/git-repack.sh
index eb75c8c..b58cf91 100755
--- a/git-repack.sh
+++ b/git-repack.sh
@@ -54,9 +54,21 @@ else
 	fi
 	mkdir -p "$PACKDIR" || exit
 
-	mv .tmp-pack-$name.pack "$PACKDIR/pack-$name.pack" &&
-	mv .tmp-pack-$name.idx  "$PACKDIR/pack-$name.idx" ||
-	exit
+	for sfx in pack idx
+	do
+		if test -f "$PACKDIR/pack-$name.$sfx"
+		then
+			mv -f "$PACKDIR/pack-$name.$sfx" "$PACKDIR/old-pack-$name.$sfx"
+		fi
+	done
+	mv -f .tmp-pack-$name.pack "$PACKDIR/pack-$name.pack" &&
+	mv -f .tmp-pack-$name.idx  "$PACKDIR/pack-$name.idx" || {
+		echo >&2 "Couldn't replace the existing pack with updated one."
+		echo >&2 "The original set of packs have been saved as"
+		echo >&2 "old-pack-$name.{pack,idx} in $PACKDIR."
+		exit 1
+	}
+	rm -f "$PACKDIR/old-pack-$name.pack" "$PACKDIR/old-pack-$name.idx" 
 fi
 
 if test "$remove_redundant" = t
Previous: Thomas Glanzmann
Message 2 of 2 in “git-repack -a -d produces unusable packs with 1.4.0”
  1. Thomas GlanzmannJun 25, 2006
  2. Junio C HamanoJun 25, 2006

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.