private void verifyPrerequisites() throws TransportException { if (prereqs.isEmpty()) return; final RevWalk rw = new RevWalk(local); final RevFlag PREREQ = rw.newFlag("PREREQ"); final RevFlag SEEN = rw.newFlag("SEEN"); final List<ObjectId> missing = new ArrayList<ObjectId>(); final List<RevObject> commits = new ArrayList<RevObject>(); for (final ObjectId p : prereqs) { try { final RevCommit c = rw.parseCommit(p); if (!c.has(PREREQ)) { c.add(PREREQ); commits.add(c); } } catch (MissingObjectException notFound) { missing.add(p); } catch (IOException err) { throw new TransportException(uri, "Cannot read commit " + p.name(), err); } } if (!missing.isEmpty()) throw new MissingBundlePrerequisiteException(uri, missing); for (final Ref r : local.getAllRefs().values()) { try { rw.markStart(rw.parseCommit(r.getObjectId())); } catch (IOException readError) { // If we cannot read the value of the ref skip it. } } int remaining = commits.size(); try { RevCommit c; while ((c = rw.next()) != null) { if (c.has(PREREQ)) { c.add(SEEN); if (--remaining == 0) break; } } } catch (IOException err) { throw new TransportException(uri, "Cannot read object", err); } if (remaining > 0) { for (final RevObject o : commits) { if (!o.has(SEEN)) missing.add(o); } throw new MissingBundlePrerequisiteException(uri, missing); } }
private void markReachable(final Set<ObjectId> have, final int maxTime) throws IOException { for (final Ref r : local.getAllRefs().values()) { try { final RevCommit o = walk.parseCommit(r.getObjectId()); o.add(REACHABLE); reachableCommits.add(o); } catch (IOException readError) { // If we cannot read the value of the ref skip it. } } for (final ObjectId id : have) { try { final RevCommit o = walk.parseCommit(id); o.add(REACHABLE); reachableCommits.add(o); } catch (IOException readError) { // If we cannot read the value of the ref skip it. } } if (maxTime > 0) { // Mark reachable commits until we reach maxTime. These may // wind up later matching up against things we want and we // can avoid asking for something we already happen to have. // final Date maxWhen = new Date(maxTime * 1000L); walk.sort(RevSort.COMMIT_TIME_DESC); walk.markStart(reachableCommits); walk.setRevFilter(CommitTimeRevFilter.after(maxWhen)); for (; ; ) { final RevCommit c = walk.next(); if (c == null) break; if (c.has(ADVERTISED) && !c.has(COMMON)) { // This is actually going to be a common commit, but // our peer doesn't know that fact yet. // c.add(COMMON); c.carry(COMMON); reachableCommits.add(c); } } } }
private void recreateCommitGraph() throws IOException { final RevWalk rw = new RevWalk(db); final Map<ObjectId, ToRewrite> toRewrite = new HashMap<ObjectId, ToRewrite>(); List<ToRewrite> queue = new ArrayList<ToRewrite>(); final BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(graph), Constants.CHARSET)); try { String line; while ((line = br.readLine()) != null) { final String[] parts = line.split("[ \t]{1,}"); final ObjectId oldId = ObjectId.fromString(parts[0]); try { rw.parseCommit(oldId); // We have it already. Don't rewrite it. continue; } catch (MissingObjectException mue) { // Fall through and rewrite it. } final long time = Long.parseLong(parts[1]) * 1000L; final ObjectId[] parents = new ObjectId[parts.length - 2]; for (int i = 0; i < parents.length; i++) { parents[i] = ObjectId.fromString(parts[2 + i]); } final ToRewrite t = new ToRewrite(oldId, time, parents); toRewrite.put(oldId, t); queue.add(t); } } finally { br.close(); } pm.beginTask("Rewriting commits", queue.size()); final ObjectWriter ow = new ObjectWriter(db); final ObjectId emptyTree = ow.writeTree(new Tree(db)); final PersonIdent me = new PersonIdent("jgit rebuild-commitgraph", "rebuild-commitgraph@localhost"); while (!queue.isEmpty()) { final ListIterator<ToRewrite> itr = queue.listIterator(queue.size()); queue = new ArrayList<ToRewrite>(); REWRITE: while (itr.hasPrevious()) { final ToRewrite t = itr.previous(); final ObjectId[] newParents = new ObjectId[t.oldParents.length]; for (int k = 0; k < t.oldParents.length; k++) { final ToRewrite p = toRewrite.get(t.oldParents[k]); if (p != null) { if (p.newId == null) { // Must defer until after the parent is rewritten. queue.add(t); continue REWRITE; } else { newParents[k] = p.newId; } } else { // We have the old parent object. Use it. // newParents[k] = t.oldParents[k]; } } final Commit newc = new Commit(db); newc.setTreeId(emptyTree); newc.setAuthor(new PersonIdent(me, new Date(t.commitTime))); newc.setCommitter(newc.getAuthor()); newc.setParentIds(newParents); newc.setMessage("ORIGINAL " + t.oldId.name() + "\n"); t.newId = ow.writeCommit(newc); rewrites.put(t.oldId, t.newId); pm.update(1); } } pm.endTask(); }