diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2011-11-17 11:23:18 -0800 |
---|---|---|
committer | Shawn O. Pearce <spearce@spearce.org> | 2011-11-18 15:55:52 -0800 |
commit | 60e51251db0b703db8374a9470fa035dc0f811f9 (patch) | |
tree | 471577614786f23e8687251e94339080e4c44243 | |
parent | 1421106d7627eb2c55b97b70d105b5ba1e26a2c0 (diff) | |
download | jgit-60e51251db0b703db8374a9470fa035dc0f811f9.tar.gz jgit-60e51251db0b703db8374a9470fa035dc0f811f9.zip |
Do not write edge objects to the pack stream
Consider two objects A->B where A uses B as a delta base, and these
are in the same source pack file ordered as "A B".
If cached packs is enabled and B is also in the cached pack that
will be appended onto the end of the thin pack, and both A, B are
supposed to be in the thin pack, PackWriter must consider the fact
that A's base B is an edge object that claims to be part of the
new pack, but is actually "external" and cannot be written first.
If the object reuse system considered B candidates fist this bug
does not arise, as B will be marked as edge due to it existing in
the cached pack. When the A candidates are later examined, A sees a
valid delta base is available as an edge, and will not later try to
"write base first" during the writing phase.
However, when the reuse system considers A candidates first they
see that B will be in the outgoing pack, as it is still part of
the thin pack, and arrange for A to be written first. Later when A
switches from being in-pack to being an edge object (as it is part
of the cached pack) the pointer in B does not get its type changed
from ObjectToPack to ObjectId, so B thinks A is non-edge.
We work around this case by also checking that the delta base B
is non-edge before writing the object to the pack. Later when A
writes its object header, delta base B's ObjectToPack will have
an offset == 0, which makes isWritten() = false, and the OBJ_REF
delta format will be used for A's header. This will be resolved by
the client to the copy of B that appears in the later cached pack.
Change-Id: Ifab6bfdf3c0aa93649468f49bcf91d67f90362ca
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java index 2d4279ebc2..a7db92aa01 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java @@ -1396,10 +1396,10 @@ public class PackWriter { otp.setCRC(out.getCRC32()); } - private void writeBase(PackOutputStream out, ObjectToPack baseInPack) + private void writeBase(PackOutputStream out, ObjectToPack base) throws IOException { - if (baseInPack != null && !baseInPack.isWritten()) - writeObjectImpl(out, baseInPack); + if (base != null && !base.isWritten() && !base.isEdge()) + writeObjectImpl(out, base); } private void writeWholeObjectDeflate(PackOutputStream out, |