示例#1
0
  /**
   * Adds a set of refs to the set of packed-refs. Only non-symbolic refs are added. If a ref with
   * the given name already existed in packed-refs it is updated with the new value. Each loose ref
   * which was added to the packed-ref file is deleted. If a given ref can't be locked it will not
   * be added to the pack file.
   *
   * @param refs the refs to be added. Must be fully qualified.
   * @throws IOException
   */
  public void pack(List<String> refs) throws IOException {
    if (refs.size() == 0) return;
    FS fs = parent.getFS();

    // Lock the packed refs file and read the content
    LockFile lck = new LockFile(packedRefsFile);
    if (!lck.lock())
      throw new IOException(MessageFormat.format(JGitText.get().cannotLock, packedRefsFile));

    try {
      final PackedRefList packed = getPackedRefs();
      RefList<Ref> cur = readPackedRefs();

      // Iterate over all refs to be packed
      for (String refName : refs) {
        Ref ref = readRef(refName, cur);
        if (ref.isSymbolic()) continue; // can't pack symbolic refs
        // Add/Update it to packed-refs
        int idx = cur.find(refName);
        if (idx >= 0) cur = cur.set(idx, peeledPackedRef(ref));
        else cur = cur.add(idx, peeledPackedRef(ref));
      }

      // The new content for packed-refs is collected. Persist it.
      commitPackedRefs(lck, cur, packed);

      // Now delete the loose refs which are now packed
      for (String refName : refs) {
        // Lock the loose ref
        File refFile = fileFor(refName);
        if (!fs.exists(refFile)) continue;
        LockFile rLck = new LockFile(refFile);
        if (!rLck.lock()) continue;
        try {
          LooseRef currentLooseRef = scanRef(null, refName);
          if (currentLooseRef == null || currentLooseRef.isSymbolic()) continue;
          Ref packedRef = cur.get(refName);
          ObjectId clr_oid = currentLooseRef.getObjectId();
          if (clr_oid != null && clr_oid.equals(packedRef.getObjectId())) {
            RefList<LooseRef> curLoose, newLoose;
            do {
              curLoose = looseRefs.get();
              int idx = curLoose.find(refName);
              if (idx < 0) break;
              newLoose = curLoose.remove(idx);
            } while (!looseRefs.compareAndSet(curLoose, newLoose));
            int levels = levelsIn(refName) - 2;
            delete(refFile, levels, rLck);
          }
        } finally {
          rLck.unlock();
        }
      }
      // Don't fire refsChanged. The refs have not change, only their
      // storage.
    } finally {
      lck.unlock();
    }
  }
示例#2
0
    private void scanOne(String name) {
      LooseRef cur;

      if (curIdx < curLoose.size()) {
        do {
          cur = curLoose.get(curIdx);
          int cmp = RefComparator.compareTo(cur, name);
          if (cmp < 0) {
            // Reference is not loose anymore, its been deleted.
            // Skip the name in the new result list.
            if (newLoose == null) newLoose = curLoose.copy(curIdx);
            curIdx++;
            cur = null;
            continue;
          }

          if (cmp > 0) // Newly discovered loose reference.
          cur = null;
          break;
        } while (curIdx < curLoose.size());
      } else cur = null; // Newly discovered loose reference.

      LooseRef n;
      try {
        n = scanRef(cur, name);
      } catch (IOException notValid) {
        n = null;
      }

      if (n != null) {
        if (cur != n && newLoose == null) newLoose = curLoose.copy(curIdx);
        if (newLoose != null) newLoose.add(n);
        if (n.isSymbolic()) symbolic.add(n);
      } else if (cur != null) {
        // Tragically, this file is no longer a loose reference.
        // Kill our cached entry of it.
        if (newLoose == null) newLoose = curLoose.copy(curIdx);
      }

      if (cur != null) curIdx++;
    }
示例#3
0
  LooseRef scanRef(LooseRef ref, String name) throws IOException {
    final File path = fileFor(name);
    FileSnapshot currentSnapshot = null;

    if (ref != null) {
      currentSnapshot = ref.getSnapShot();
      if (!currentSnapshot.isModified(path)) return ref;
      name = ref.getName();
    }

    final int limit = 4096;
    final byte[] buf;
    FileSnapshot otherSnapshot = FileSnapshot.save(path);
    try {
      buf = IO.readSome(path, limit);
    } catch (FileNotFoundException noFile) {
      if (path.exists() && path.isFile()) {
        throw noFile;
      }
      return null; // doesn't exist or no file; not a reference.
    }

    int n = buf.length;
    if (n == 0) return null; // empty file; not a reference.

    if (isSymRef(buf, n)) {
      if (n == limit) return null; // possibly truncated ref

      // trim trailing whitespace
      while (0 < n && Character.isWhitespace(buf[n - 1])) n--;
      if (n < 6) {
        String content = RawParseUtils.decode(buf, 0, n);
        throw new IOException(MessageFormat.format(JGitText.get().notARef, name, content));
      }
      final String target = RawParseUtils.decode(buf, 5, n);
      if (ref != null && ref.isSymbolic() && ref.getTarget().getName().equals(target)) {
        assert (currentSnapshot != null);
        currentSnapshot.setClean(otherSnapshot);
        return ref;
      }
      return newSymbolicRef(otherSnapshot, name, target);
    }

    if (n < OBJECT_ID_STRING_LENGTH)
      return null; // impossibly short object identifier; not a reference.

    final ObjectId id;
    try {
      id = ObjectId.fromString(buf, 0);
      if (ref != null && !ref.isSymbolic() && id.equals(ref.getTarget().getObjectId())) {
        assert (currentSnapshot != null);
        currentSnapshot.setClean(otherSnapshot);
        return ref;
      }

    } catch (IllegalArgumentException notRef) {
      while (0 < n && Character.isWhitespace(buf[n - 1])) n--;
      String content = RawParseUtils.decode(buf, 0, n);

      IOException ioException =
          new IOException(MessageFormat.format(JGitText.get().notARef, name, content));
      ioException.initCause(notRef);
      throw ioException;
    }
    return new LooseUnpeeled(otherSnapshot, name, id);
  }