1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 package org.eclipse.jgit.pgm.debug;
45
46 import java.io.ByteArrayInputStream;
47 import java.io.ByteArrayOutputStream;
48 import java.io.IOException;
49 import java.util.Collections;
50 import java.util.zip.InflaterInputStream;
51
52 import org.eclipse.jgit.errors.MissingObjectException;
53 import org.eclipse.jgit.errors.StoredObjectRepresentationNotAvailableException;
54 import org.eclipse.jgit.internal.storage.pack.BinaryDelta;
55 import org.eclipse.jgit.internal.storage.pack.ObjectReuseAsIs;
56 import org.eclipse.jgit.internal.storage.pack.ObjectToPack;
57 import org.eclipse.jgit.internal.storage.pack.PackOutputStream;
58 import org.eclipse.jgit.internal.storage.pack.PackWriter;
59 import org.eclipse.jgit.internal.storage.pack.StoredObjectRepresentation;
60 import org.eclipse.jgit.lib.NullProgressMonitor;
61 import org.eclipse.jgit.lib.ObjectId;
62 import org.eclipse.jgit.lib.ObjectReader;
63 import org.eclipse.jgit.pgm.Command;
64 import org.eclipse.jgit.pgm.TextBuiltin;
65 import org.eclipse.jgit.revwalk.RevObject;
66 import org.eclipse.jgit.revwalk.RevWalk;
67 import org.eclipse.jgit.util.TemporaryBuffer;
68 import org.kohsuke.args4j.Argument;
69
70 @Command(usage = "usage_ShowPackDelta")
71 class ShowPackDelta extends TextBuiltin {
72 @Argument(index = 0)
73 private ObjectId objectId;
74
75
76 @Override
77 protected void run() throws Exception {
78 ObjectReader reader = db.newObjectReader();
79 RevObject obj;
80 try (RevWalk rw = new RevWalk(reader)) {
81 obj = rw.parseAny(objectId);
82 }
83 byte[] delta = getDelta(reader, obj);
84
85
86
87
88 long size = reader.getObjectSize(obj, obj.getType());
89 try {
90 if (BinaryDelta.getResultSize(delta) != size)
91 throw die("Object " + obj.name() + " is not a delta");
92 } catch (ArrayIndexOutOfBoundsException bad) {
93 throw die("Object " + obj.name() + " is not a delta");
94 }
95
96 outw.println(BinaryDelta.format(delta));
97 }
98
99 private static byte[] getDelta(ObjectReader reader, RevObject obj)
100 throws IOException, MissingObjectException,
101 StoredObjectRepresentationNotAvailableException {
102 ObjectReuseAsIs asis = (ObjectReuseAsIs) reader;
103 ObjectToPack target = asis.newObjectToPack(obj, obj.getType());
104
105 PackWriter pw = new PackWriter(reader) {
106 @Override
107 public void select(ObjectToPack otp, StoredObjectRepresentation next) {
108 otp.select(next);
109 }
110 };
111
112 ByteArrayOutputStream buf = new ByteArrayOutputStream();
113 asis.selectObjectRepresentation(pw, NullProgressMonitor.INSTANCE,
114 Collections.singleton(target));
115 asis.copyObjectAsIs(new PackOutputStream(NullProgressMonitor.INSTANCE,
116 buf, pw), target, true);
117
118
119
120
121
122 byte[] bufArray = buf.toByteArray();
123 int ptr = 0;
124 while ((bufArray[ptr] & 0x80) != 0)
125 ptr++;
126 ptr++;
127
128 try (TemporaryBuffer.Heap raw = new TemporaryBuffer.Heap(
129 bufArray.length);
130 InflaterInputStream inf = new InflaterInputStream(
131 new ByteArrayInputStream(bufArray, ptr,
132 bufArray.length))) {
133 raw.copy(inf);
134 return raw.toByteArray();
135 }
136 }
137 }