1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.transport.internal;
12
13 import java.io.IOException;
14 import java.util.Set;
15
16 import org.eclipse.jgit.errors.MissingObjectException;
17 import org.eclipse.jgit.internal.JGitText;
18 import org.eclipse.jgit.lib.Constants;
19 import org.eclipse.jgit.lib.ObjectId;
20 import org.eclipse.jgit.lib.ObjectIdSubclassMap;
21 import org.eclipse.jgit.lib.ProgressMonitor;
22 import org.eclipse.jgit.revwalk.ObjectWalk;
23 import org.eclipse.jgit.revwalk.RevBlob;
24 import org.eclipse.jgit.revwalk.RevCommit;
25 import org.eclipse.jgit.revwalk.RevFlag;
26 import org.eclipse.jgit.revwalk.RevObject;
27 import org.eclipse.jgit.revwalk.RevSort;
28 import org.eclipse.jgit.revwalk.RevTree;
29 import org.eclipse.jgit.transport.ConnectivityChecker;
30 import org.eclipse.jgit.transport.ReceiveCommand;
31 import org.eclipse.jgit.transport.ReceiveCommand.Result;
32
33
34
35
36
37
38
39 public final class FullConnectivityChecker implements ConnectivityChecker {
40 @Override
41 public void checkConnectivity(ConnectivityCheckInfo connectivityCheckInfo,
42 Set<ObjectId> haves, ProgressMonitor pm)
43 throws MissingObjectException, IOException {
44 pm.beginTask(JGitText.get().countingObjects,
45 ProgressMonitor.UNKNOWN);
46 try (ObjectWalkObjectWalk.html#ObjectWalk">ObjectWalk ow = new ObjectWalk(connectivityCheckInfo.getRepository())) {
47 if (!markStartAndKnownNodes(connectivityCheckInfo, ow, haves,
48 pm)) {
49 return;
50 }
51 checkCommitTree(connectivityCheckInfo, ow, pm);
52 checkObjects(connectivityCheckInfo, ow, pm);
53 } finally {
54 pm.endTask();
55 }
56 }
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 private boolean markStartAndKnownNodes(
72 ConnectivityCheckInfo connectivityCheckInfo,
73 ObjectWalk ow,
74 Set<ObjectId> haves, ProgressMonitor pm)
75 throws IOException {
76 boolean markTrees = connectivityCheckInfo
77 .isCheckObjects()
78 && !connectivityCheckInfo.getParser().getBaseObjectIds()
79 .isEmpty();
80 if (connectivityCheckInfo.isCheckObjects()) {
81 ow.sort(RevSort.TOPO);
82 if (!connectivityCheckInfo.getParser().getBaseObjectIds()
83 .isEmpty()) {
84 ow.sort(RevSort.BOUNDARY, true);
85 }
86 }
87 boolean hasInteresting = false;
88
89 for (ReceiveCommand cmd : connectivityCheckInfo.getCommands()) {
90 if (cmd.getResult() != Result.NOT_ATTEMPTED) {
91 continue;
92 }
93 if (cmd.getType() == ReceiveCommand.Type.DELETE) {
94 continue;
95 }
96 if (haves.contains(cmd.getNewId())) {
97 continue;
98 }
99 ow.markStart(ow.parseAny(cmd.getNewId()));
100 pm.update(1);
101 hasInteresting = true;
102 }
103 if (!hasInteresting) {
104 return false;
105 }
106 for (ObjectId have : haves) {
107 RevObject o = ow.parseAny(have);
108 ow.markUninteresting(o);
109 pm.update(1);
110
111 if (markTrees) {
112 o = ow.peel(o);
113 if (o instanceof RevCommit) {
114 o = ((RevCommit) o).getTree();
115 }
116 if (o instanceof RevTree) {
117 ow.markUninteresting(o);
118 }
119 }
120 }
121 return true;
122 }
123
124
125
126
127
128
129
130
131
132
133
134 private void checkCommitTree(ConnectivityCheckInfo connectivityCheckInfo,
135 ObjectWalk ow,
136 ProgressMonitor pm) throws IOException {
137 RevCommit c;
138 ObjectIdSubclassMap<ObjectId> newObjectIds = connectivityCheckInfo
139 .getParser()
140 .getNewObjectIds();
141 while ((c = ow.next()) != null) {
142 pm.update(1);
143 if (connectivityCheckInfo.isCheckObjects()
144 && !c.has(RevFlag.UNINTERESTING)
145 && !newObjectIds.contains(c)) {
146 throw new MissingObjectException(c, Constants.TYPE_COMMIT);
147 }
148 }
149 }
150
151
152
153
154
155
156
157
158
159
160
161
162 private void checkObjects(ConnectivityCheckInfo connectivityCheckInfo,
163 ObjectWalk ow,
164 ProgressMonitor pm) throws IOException {
165 RevObject o;
166 ObjectIdSubclassMap<ObjectId> newObjectIds = connectivityCheckInfo
167 .getParser()
168 .getNewObjectIds();
169
170 while ((o = ow.nextObject()) != null) {
171 pm.update(1);
172 if (o.has(RevFlag.UNINTERESTING)) {
173 continue;
174 }
175
176 if (connectivityCheckInfo.isCheckObjects()) {
177 if (newObjectIds.contains(o)) {
178 continue;
179 }
180 throw new MissingObjectException(o, o.getType());
181
182 }
183
184 if (o instanceof RevBlob
185 && !connectivityCheckInfo.getRepository().getObjectDatabase()
186 .has(o)) {
187 throw new MissingObjectException(o, Constants.TYPE_BLOB);
188 }
189 }
190
191 if (connectivityCheckInfo.isCheckObjects()) {
192 for (ObjectId id : connectivityCheckInfo.getParser()
193 .getBaseObjectIds()) {
194 o = ow.parseAny(id);
195 if (!o.has(RevFlag.UNINTERESTING)) {
196 throw new MissingObjectException(o, o.getType());
197 }
198 }
199 }
200 }
201 }