private VersionImpl updateTree(final Tree root, final String key, final byte[] data) throws IOException { ObjectId objectId = writeBytes(data); FileTreeEntry fileTreeEntry = root.addFile(key + "/" + objectId.name()); fileTreeEntry.setId(objectId); Commit commit = commitTree(root); updateHead(commit); VersionImpl version = new VersionImpl(commit, key, fileTreeEntry); return version; }
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 Map<String, Ref> readAdvertisedImpl(final BufferedReader br) throws IOException, PackProtocolException { final TreeMap<String, Ref> avail = new TreeMap<String, Ref>(); for (; ; ) { String line = br.readLine(); if (line == null) break; final int tab = line.indexOf('\t'); if (tab < 0) throw invalidAdvertisement(line); String name; final ObjectId id; name = line.substring(tab + 1); id = ObjectId.fromString(line.substring(0, tab)); if (name.endsWith("^{}")) { name = name.substring(0, name.length() - 3); final Ref prior = avail.get(name); if (prior == null) throw outOfOrderAdvertisement(name); if (prior.getPeeledObjectId() != null) throw duplicateAdvertisement(name + "^{}"); avail.put(name, new Ref(Ref.Storage.NETWORK, name, prior.getObjectId(), id, true)); } else { final Ref prior = avail.put(name, new Ref(Ref.Storage.NETWORK, name, id)); if (prior != null) throw duplicateAdvertisement(name); } } return avail; }
private Map<String, Ref> computeNewRefs() throws IOException { final RevWalk rw = new RevWalk(db); final Map<String, Ref> refs = new HashMap<String, Ref>(); final BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(refList), Constants.CHARSET)); try { String line; while ((line = br.readLine()) != null) { final String[] parts = line.split("[ \t]{1,}"); final ObjectId origId = ObjectId.fromString(parts[0]); final String type = parts[1]; final String name = parts[2]; ObjectId id = rewrites.get(origId); if (id == null) id = origId; try { rw.parseAny(id); } catch (MissingObjectException mue) { if (!Constants.TYPE_COMMIT.equals(type)) { System.err.println("skipping " + type + " " + name); continue; } throw new MissingObjectException(id, type); } refs.put(name, new Ref(Ref.Storage.PACKED, name, id)); } } finally { br.close(); } return refs; }
private void readBundleV2() throws IOException { final byte[] hdrbuf = new byte[1024]; final LinkedHashMap<String, Ref> avail = new LinkedHashMap<String, Ref>(); for (; ; ) { String line = readLine(hdrbuf); if (line.length() == 0) break; if (line.charAt(0) == '-') { prereqs.add(ObjectId.fromString(line.substring(1, 41))); continue; } final String name = line.substring(41, line.length()); final ObjectId id = ObjectId.fromString(line.substring(0, 40)); final Ref prior = avail.put(name, new Ref(Ref.Storage.NETWORK, name, id)); if (prior != null) throw duplicateAdvertisement(name); } available(avail); }
private void detachHead() throws IOException { final String head = db.getFullBranch(); final ObjectId id = db.resolve(Constants.HEAD); if (!ObjectId.isId(head) && id != null) { final LockFile lf; lf = new LockFile(new File(db.getDirectory(), Constants.HEAD)); if (!lf.lock()) throw new IOException("Cannot lock HEAD"); lf.write(id); if (!lf.commit()) throw new IOException("Cannot deatch HEAD"); } }
public void push(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates) throws TransportException { markStartedOperation(); packNames = null; newRefs = new TreeMap<String, Ref>(getRefsMap()); packedRefUpdates = new ArrayList<RemoteRefUpdate>(refUpdates.size()); // Filter the commands and issue all deletes first. This way we // can correctly handle a directory being cleared out and a new // ref using the directory name being created. // final List<RemoteRefUpdate> updates = new ArrayList<RemoteRefUpdate>(); for (final RemoteRefUpdate u : refUpdates.values()) { final String n = u.getRemoteName(); if (!n.startsWith("refs/") || !Repository.isValidRefName(n)) { u.setStatus(Status.REJECTED_OTHER_REASON); u.setMessage("funny refname"); continue; } if (AnyObjectId.equals(ObjectId.zeroId(), u.getNewObjectId())) deleteCommand(u); else updates.add(u); } // If we have any updates we need to upload the objects first, to // prevent creating refs pointing at non-existent data. Then we // can update the refs, and the info-refs file for dumb transports. // if (!updates.isEmpty()) sendpack(updates, monitor); for (final RemoteRefUpdate u : updates) updateCommand(u); // Is this a new repository? If so we should create additional // metadata files so it is properly initialized during the push. // if (!updates.isEmpty() && isNewRepository()) createNewRepository(updates); RefWriter refWriter = new RefWriter(newRefs.values()) { @Override protected void writeFile(String file, byte[] content) throws IOException { dest.writeFile(ROOT_DIR + file, content); } }; if (!packedRefUpdates.isEmpty()) { try { refWriter.writePackedRefs(); for (final RemoteRefUpdate u : packedRefUpdates) u.setStatus(Status.OK); } catch (IOException err) { for (final RemoteRefUpdate u : packedRefUpdates) { u.setStatus(Status.REJECTED_OTHER_REASON); u.setMessage(err.getMessage()); } throw new TransportException(uri, "failed updating refs", err); } } try { refWriter.writeInfoRefs(); } catch (IOException err) { throw new TransportException(uri, "failed updating refs", err); } }
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(); }
/** * Get the object id of the current entry. * * @return an object id for the current entry. */ public ObjectId getEntryObjectId() { return ObjectId.fromRaw(idBuffer(), idOffset()); }
/** * Check if the current entry of both iterators has the same id. * * <p>This method is faster than {@link #getEntryObjectId()} as it does not require copying the * bytes out of the buffers. A direct {@link #idBuffer} compare operation is performed. * * @param otherIterator the other iterator to test against. * @return true if both iterators have the same object id; false otherwise. */ public boolean idEqual(final AbstractTreeIterator otherIterator) { return ObjectId.equals( idBuffer(), idOffset(), otherIterator.idBuffer(), otherIterator.idOffset()); }