private ObjectIdRef doPeel(final Ref leaf) throws MissingObjectException, IOException { try (RevWalk rw = new RevWalk(getRepository())) { RevObject obj = rw.parseAny(leaf.getObjectId()); if (obj instanceof RevTag) { return new ObjectIdRef.PeeledTag( leaf.getStorage(), leaf.getName(), leaf.getObjectId(), rw.peel(obj).copy()); } else { return new ObjectIdRef.PeeledNonTag(leaf.getStorage(), leaf.getName(), leaf.getObjectId()); } } }
@Override protected Result doLink(String target) throws IOException { final SymbolicRef newRef = new SymbolicRef(dstRef.getName(), new ObjectIdRef.Unpeeled(Storage.NEW, target, null)); if (getRefDatabase().compareAndPut(dstRef, newRef)) { getRefDatabase().stored(newRef); if (dstRef.getStorage() == Ref.Storage.NEW) return Result.NEW; return Result.FORCED; } return Result.LOCK_FAILURE; }
/** * Make sure a ref is peeled and has the Storage PACKED. If the given ref has this attributes * simply return it. Otherwise create a new peeled {@link ObjectIdRef} where Storage is set to * PACKED. * * @param f * @return a ref for Storage PACKED having the same name, id, peeledId as f * @throws MissingObjectException * @throws IOException */ private Ref peeledPackedRef(Ref f) throws MissingObjectException, IOException { if (f.getStorage().isPacked() && f.isPeeled()) { return f; } if (!f.isPeeled()) { f = peel(f); } ObjectId peeledObjectId = f.getPeeledObjectId(); if (peeledObjectId != null) { return new ObjectIdRef.PeeledTag(PACKED, f.getName(), f.getObjectId(), peeledObjectId); } else { return new ObjectIdRef.PeeledNonTag(PACKED, f.getName(), f.getObjectId()); } }
@Override public Ref peel(final Ref ref) throws IOException { final Ref leaf = ref.getLeaf(); if (leaf.isPeeled() || leaf.getObjectId() == null) return ref; ObjectIdRef newLeaf = doPeel(leaf); // Try to remember this peeling in the cache, so we don't have to do // it again in the future, but only if the reference is unchanged. if (leaf.getStorage().isLoose()) { RefList<LooseRef> curList = looseRefs.get(); int idx = curList.find(leaf.getName()); if (0 <= idx && curList.get(idx) == leaf) { LooseRef asPeeled = ((LooseRef) leaf).peel(newLeaf); RefList<LooseRef> newList = curList.set(idx, asPeeled); looseRefs.compareAndSet(curList, newList); } } return recreate(ref, newLeaf); }
void delete(RefDirectoryUpdate update) throws IOException { Ref dst = update.getRef(); String name = dst.getName(); // Write the packed-refs file using an atomic update. We might // wind up reading it twice, before and after the lock, to ensure // we don't miss an edit made externally. final PackedRefList packed = getPackedRefs(); if (packed.contains(name)) { LockFile lck = new LockFile(packedRefsFile); if (!lck.lock()) throw new LockFailedException(packedRefsFile); try { PackedRefList cur = readPackedRefs(); int idx = cur.find(name); if (0 <= idx) commitPackedRefs(lck, cur.remove(idx), packed); } finally { lck.unlock(); } } RefList<LooseRef> curLoose, newLoose; do { curLoose = looseRefs.get(); int idx = curLoose.find(name); if (idx < 0) break; newLoose = curLoose.remove(idx); } while (!looseRefs.compareAndSet(curLoose, newLoose)); int levels = levelsIn(name) - 2; delete(logWriter.logFor(name), levels); if (dst.getStorage().isLoose()) { update.unlock(); delete(fileFor(name), levels); } modCnt.incrementAndGet(); fireRefsChanged(); }
private Ref readRef(final TreeMap<String, Ref> avail, final String rn) throws TransportException { final String s; String ref = ROOT_DIR + rn; try { final BufferedReader br = openReader(ref); try { s = br.readLine(); } finally { br.close(); } } catch (FileNotFoundException noRef) { return null; } catch (IOException err) { throw new TransportException(getURI(), "read " + ref, err); } if (s == null) throw new TransportException(getURI(), "Empty ref: " + rn); if (s.startsWith("ref: ")) { final String target = s.substring("ref: ".length()); Ref r = avail.get(target); if (r == null) r = readRef(avail, target); if (r == null) return null; r = new Ref(r.getStorage(), rn, r.getObjectId(), r.getPeeledObjectId(), r.isPeeled()); avail.put(r.getName(), r); return r; } if (ObjectId.isId(s)) { final Ref r = new Ref(loose(avail.get(rn)), rn, ObjectId.fromString(s)); avail.put(r.getName(), r); return r; } throw new TransportException(getURI(), "Bad ref: " + rn + ": " + s); }
private Storage loose(final Ref r) { if (r != null && r.getStorage() == Storage.PACKED) return Storage.LOOSE_PACKED; return Storage.LOOSE; }