示例#1
0
 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;
 }
示例#2
0
    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);
      }
    }
示例#3
0
    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;
  }
示例#5
0
    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");
   }
 }
示例#7
0
  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());
 }