private static void assertV3TreeEntry(
     int indexPosition, String path, boolean skipWorkTree, boolean intentToAdd, DirCache dc) {
   final DirCacheEntry entry = dc.getEntry(indexPosition);
   assertEquals(path, entry.getPathString());
   assertEquals(skipWorkTree, entry.isSkipWorkTree());
   assertEquals(intentToAdd, entry.isIntentToAdd());
 }
Example #2
0
 private void assumeUnchanged(String path) throws IOException {
   final DirCache dirc = db.lockDirCache();
   final DirCacheEntry ent = dirc.getEntry(path);
   if (ent != null) ent.setAssumeValid(true);
   dirc.write();
   if (!dirc.commit()) throw new IOException("could not commit");
 }
 @Test
 public void testUnsupportedOptionalExtension() throws Exception {
   final DirCache dc = new DirCache(pathOf("gitgit.index.ZZZZ"), FS.DETECTED);
   dc.read();
   assertEquals(1, dc.getEntryCount());
   assertEquals("A", dc.getEntry(0).getPathString());
 }
 @Test
 public void testReadIndex_LsFiles() throws Exception {
   final Map<String, CGitIndexRecord> ls = readLsFiles();
   final DirCache dc = new DirCache(index, FS.DETECTED);
   assertEquals(0, dc.getEntryCount());
   dc.read();
   assertEquals(ls.size(), dc.getEntryCount());
   {
     final Iterator<CGitIndexRecord> rItr = ls.values().iterator();
     for (int i = 0; rItr.hasNext(); i++) assertEqual(rItr.next(), dc.getEntry(i));
   }
 }
Example #5
0
  @Test
  public void testPathsResetOnUnbornBranch() throws Exception {
    git = new Git(db);
    writeTrashFile("a.txt", "content");
    git.add().addFilepattern("a.txt").call();
    // Should assume an empty tree, like in C Git 1.8.2
    git.reset().addPath("a.txt").call();

    DirCache cache = db.readDirCache();
    DirCacheEntry aEntry = cache.getEntry("a.txt");
    assertNull(aEntry);
  }
Example #6
0
  @Test
  public void testMixedResetRetainsSizeAndModifiedTime() throws Exception {
    git = new Git(db);

    writeTrashFile("a.txt", "a").setLastModified(System.currentTimeMillis() - 60 * 1000);
    assertNotNull(git.add().addFilepattern("a.txt").call());
    assertNotNull(git.commit().setMessage("a commit").call());

    writeTrashFile("b.txt", "b").setLastModified(System.currentTimeMillis() - 60 * 1000);
    assertNotNull(git.add().addFilepattern("b.txt").call());
    RevCommit commit2 = git.commit().setMessage("b commit").call();
    assertNotNull(commit2);

    DirCache cache = db.readDirCache();

    DirCacheEntry aEntry = cache.getEntry("a.txt");
    assertNotNull(aEntry);
    assertTrue(aEntry.getLength() > 0);
    assertTrue(aEntry.getLastModified() > 0);

    DirCacheEntry bEntry = cache.getEntry("b.txt");
    assertNotNull(bEntry);
    assertTrue(bEntry.getLength() > 0);
    assertTrue(bEntry.getLastModified() > 0);

    git.reset().setMode(ResetType.MIXED).setRef(commit2.getName()).call();

    cache = db.readDirCache();

    DirCacheEntry mixedAEntry = cache.getEntry("a.txt");
    assertNotNull(mixedAEntry);
    assertEquals(aEntry.getLastModified(), mixedAEntry.getLastModified());
    assertEquals(aEntry.getLastModified(), mixedAEntry.getLastModified());

    DirCacheEntry mixedBEntry = cache.getEntry("b.txt");
    assertNotNull(mixedBEntry);
    assertEquals(bEntry.getLastModified(), mixedBEntry.getLastModified());
    assertEquals(bEntry.getLastModified(), mixedBEntry.getLastModified());
  }
Example #7
0
  @Test
  public void testHardResetOnUnbornBranch() throws Exception {
    git = new Git(db);
    File fileA = writeTrashFile("a.txt", "content");
    git.add().addFilepattern("a.txt").call();
    // Should assume an empty tree, like in C Git 1.8.2
    git.reset().setMode(ResetType.HARD).call();

    DirCache cache = db.readDirCache();
    DirCacheEntry aEntry = cache.getEntry("a.txt");
    assertNull(aEntry);
    assertFalse(fileA.exists());
    assertNull(db.resolve(Constants.HEAD));
  }
Example #8
0
  /**
   * Reverts the worktree after an unsuccessful merge. We know that for all modified files the old
   * content was in the old index and the index contained only stage 0. In case if inCore operation
   * just clear the history of modified files.
   *
   * @throws IOException
   * @throws CorruptObjectException
   * @throws NoWorkTreeException
   * @since 3.4
   */
  protected void cleanUp() throws NoWorkTreeException, CorruptObjectException, IOException {
    if (inCore) {
      modifiedFiles.clear();
      return;
    }

    DirCache dc = db.readDirCache();
    Iterator<String> mpathsIt = modifiedFiles.iterator();
    while (mpathsIt.hasNext()) {
      String mpath = mpathsIt.next();
      DirCacheEntry entry = dc.getEntry(mpath);
      if (entry != null) DirCacheCheckout.checkoutEntry(db, entry, reader);
      mpathsIt.remove();
    }
  }
  @Test
  public void testEntriesWithin() throws Exception {
    final DirCache dc = db.readDirCache();

    final String[] paths = {"a.", "a/b", "a/c", "a/d", "a0b"};
    final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
    for (int i = 0; i < paths.length; i++) {
      ents[i] = new DirCacheEntry(paths[i]);
      ents[i].setFileMode(FileMode.REGULAR_FILE);
    }
    final int aFirst = 1;
    final int aLast = 3;

    final DirCacheBuilder b = dc.builder();
    for (int i = 0; i < ents.length; i++) b.add(ents[i]);
    b.finish();

    assertEquals(paths.length, dc.getEntryCount());
    for (int i = 0; i < ents.length; i++) assertSame(ents[i], dc.getEntry(i));

    {
      final DirCacheEntry[] aContents = dc.getEntriesWithin("a");
      assertNotNull(aContents);
      assertEquals(aLast - aFirst + 1, aContents.length);
      for (int i = aFirst, j = 0; i <= aLast; i++, j++) assertSame(ents[i], aContents[j]);
    }
    {
      final DirCacheEntry[] aContents = dc.getEntriesWithin("a/");
      assertNotNull(aContents);
      assertEquals(aLast - aFirst + 1, aContents.length);
      for (int i = aFirst, j = 0; i <= aLast; i++, j++) assertSame(ents[i], aContents[j]);
    }
    {
      final DirCacheEntry[] aContents = dc.getEntriesWithin("");
      assertNotNull(aContents);
      assertEquals(ents.length, aContents.length);
      for (int i = 0; i < ents.length; i++) assertSame(ents[i], aContents[i]);
    }

    assertNotNull(dc.getEntriesWithin("a."));
    assertEquals(0, dc.getEntriesWithin("a.").length);

    assertNotNull(dc.getEntriesWithin("a0b"));
    assertEquals(0, dc.getEntriesWithin("a0b.").length);

    assertNotNull(dc.getEntriesWithin("zoo"));
    assertEquals(0, dc.getEntriesWithin("zoo.").length);
  }
Example #10
0
  /**
   * Update the submodules in one branch of one repository.
   *
   * @param subscriber the branch of the repository which should be changed.
   * @param updates submodule updates which should be updated to.
   * @throws SubmoduleException
   */
  private void updateGitlinks(
      ReviewDb db, Branch.NameKey subscriber, Collection<SubmoduleSubscription> updates)
      throws SubmoduleException {
    PersonIdent author = null;

    Repository pdb = null;
    RevWalk recRw = null;

    StringBuilder msgbuf = new StringBuilder("Updated git submodules\n\n");
    try {
      boolean sameAuthorForAll = true;

      pdb = repoManager.openRepository(subscriber.getParentKey());
      if (pdb.getRef(subscriber.get()) == null) {
        throw new SubmoduleException(
            "The branch was probably deleted from the subscriber repository");
      }

      DirCache dc = readTree(pdb, pdb.getRef(subscriber.get()));
      DirCacheEditor ed = dc.editor();

      for (SubmoduleSubscription s : updates) {
        try (Repository subrepo = repoManager.openRepository(s.getSubmodule().getParentKey());
            RevWalk rw = CodeReviewCommit.newRevWalk(subrepo)) {
          Ref ref = subrepo.getRefDatabase().exactRef(s.getSubmodule().get());
          if (ref == null) {
            ed.add(new DeletePath(s.getPath()));
            continue;
          }

          final ObjectId updateTo = ref.getObjectId();
          RevCommit newCommit = rw.parseCommit(updateTo);

          if (author == null) {
            author = newCommit.getAuthorIdent();
          } else if (!author.equals(newCommit.getAuthorIdent())) {
            sameAuthorForAll = false;
          }

          DirCacheEntry dce = dc.getEntry(s.getPath());
          ObjectId oldId = null;
          if (dce != null) {
            if (!dce.getFileMode().equals(FileMode.GITLINK)) {
              log.error(
                  "Requested to update gitlink "
                      + s.getPath()
                      + " in "
                      + s.getSubmodule().getParentKey().get()
                      + " but entry "
                      + "doesn't have gitlink file mode.");
              continue;
            }
            oldId = dce.getObjectId();
          } else {
            // This submodule did not exist before. We do not want to add
            // the full submodule history to the commit message, so omit it.
            oldId = updateTo;
          }

          ed.add(
              new PathEdit(s.getPath()) {
                @Override
                public void apply(DirCacheEntry ent) {
                  ent.setFileMode(FileMode.GITLINK);
                  ent.setObjectId(updateTo);
                }
              });
          if (verboseSuperProject) {
            msgbuf.append("Project: " + s.getSubmodule().getParentKey().get());
            msgbuf.append(" " + s.getSubmodule().getShortName());
            msgbuf.append(" " + updateTo.getName());
            msgbuf.append("\n\n");

            try {
              rw.markStart(newCommit);

              if (oldId != null) {
                rw.markUninteresting(rw.parseCommit(oldId));
              }
              for (RevCommit c : rw) {
                msgbuf.append(c.getFullMessage() + "\n\n");
              }
            } catch (IOException e) {
              logAndThrowSubmoduleException(
                  "Could not perform a revwalk to " + "create superproject commit message", e);
            }
          }
        }
      }
      ed.finish();

      if (!sameAuthorForAll || author == null) {
        author = myIdent;
      }

      ObjectInserter oi = pdb.newObjectInserter();
      ObjectId tree = dc.writeTree(oi);

      ObjectId currentCommitId = pdb.getRef(subscriber.get()).getObjectId();

      CommitBuilder commit = new CommitBuilder();
      commit.setTreeId(tree);
      commit.setParentIds(new ObjectId[] {currentCommitId});
      commit.setAuthor(author);
      commit.setCommitter(myIdent);
      commit.setMessage(msgbuf.toString());
      oi.insert(commit);
      oi.flush();

      ObjectId commitId = oi.idFor(Constants.OBJ_COMMIT, commit.build());

      final RefUpdate rfu = pdb.updateRef(subscriber.get());
      rfu.setForceUpdate(false);
      rfu.setNewObjectId(commitId);
      rfu.setExpectedOldObjectId(currentCommitId);
      rfu.setRefLogMessage("Submit to " + subscriber.getParentKey().get(), true);

      switch (rfu.update()) {
        case NEW:
        case FAST_FORWARD:
          gitRefUpdated.fire(subscriber.getParentKey(), rfu);
          changeHooks.doRefUpdatedHook(subscriber, rfu, account);
          // TODO since this is performed "in the background" no mail will be
          // sent to inform users about the updated branch
          break;

        default:
          throw new IOException(rfu.getResult().name());
      }
      recRw = new RevWalk(pdb);
      // Recursive call: update subscribers of the subscriber
      updateSuperProjects(db, Sets.newHashSet(subscriber));
    } catch (IOException e) {
      throw new SubmoduleException("Cannot update gitlinks for " + subscriber.get(), e);
    } finally {
      if (recRw != null) {
        recRw.close();
      }
      if (pdb != null) {
        pdb.close();
      }
    }
  }
Example #11
0
 private boolean isInIndex(Repository db, String path) throws IOException {
   DirCache dc = DirCache.read(db.getIndexFile(), db.getFS());
   return dc.getEntry(path) != null;
 }
Example #12
0
  private boolean doCheckout()
      throws CorruptObjectException, IOException, MissingObjectException,
          IncorrectObjectTypeException, CheckoutConflictException, IndexWriteException {
    toBeDeleted.clear();

    ObjectReader objectReader = repo.getObjectDatabase().newReader();
    try {
      if (headCommitTree != null) preScanTwoTrees();
      else prescanOneTree();

      if (!conflicts.isEmpty()) {
        if (failOnConflict)
          throw new CheckoutConflictException(conflicts.toArray(new String[conflicts.size()]));
        else cleanUpConflicts();
      }

      // update our index
      builder.finish();

      File file = null;
      String last = ""; // $NON-NLS-1$
      // when deleting files process them in the opposite order as they have
      // been reported. This ensures the files are deleted before we delete
      // their parent folders
      for (int i = removed.size() - 1; i >= 0; i--) {
        String r = removed.get(i);
        file = new File(repo.getWorkTree(), r);
        if (!file.delete() && file.exists()) {
          // The list of stuff to delete comes from the index
          // which will only contain a directory if it is
          // a submodule, in which case we shall not attempt
          // to delete it. A submodule is not empty, so it
          // is safe to check this after a failed delete.
          if (!file.isDirectory()) toBeDeleted.add(r);
        } else {
          if (!isSamePrefix(r, last)) removeEmptyParents(new File(repo.getWorkTree(), last));
          last = r;
        }
      }
      if (file != null) removeEmptyParents(file);

      for (String path : updated.keySet()) {
        // ... create/overwrite this file ...
        file = new File(repo.getWorkTree(), path);
        if (!file.getParentFile().mkdirs()) {
          // ignore
        }

        DirCacheEntry entry = dc.getEntry(path);

        // submodules are handled with separate operations
        if (FileMode.GITLINK.equals(entry.getRawMode())) continue;

        checkoutEntry(repo, file, entry, objectReader);
      }

      // commit the index builder - a new index is persisted
      if (!builder.commit()) throw new IndexWriteException();
    } finally {
      objectReader.release();
    }
    return toBeDeleted.size() == 0;
  }
Example #13
0
  public int getDirCacheEntryLength(String path) throws IOException {
    String repoPath = getRepoRelativePath(path);
    DirCache dc = DirCache.read(repository.getIndexFile(), repository.getFS());

    return dc.getEntry(repoPath).getLength();
  }
Example #14
0
  public long lastModifiedInIndex(String path) throws IOException {
    String repoPath = getRepoRelativePath(path);
    DirCache dc = DirCache.read(repository.getIndexFile(), repository.getFS());

    return dc.getEntry(repoPath).getLastModified();
  }
Example #15
0
  public boolean inIndex(String path) throws IOException {
    String repoPath = getRepoRelativePath(path);
    DirCache dc = DirCache.read(repository.getIndexFile(), repository.getFS());

    return dc.getEntry(repoPath) != null;
  }
Example #16
0
  @Override
  protected void run() throws Exception {
    if (file == null) {
      if (revision == null) throw die(CLIText.get().fileIsRequired);
      file = revision;
      revision = null;
    }

    boolean autoAbbrev = abbrev == 0;
    if (abbrev == 0)
      abbrev = db.getConfig().getInt("core", "abbrev", 7); // $NON-NLS-1$ //$NON-NLS-2$
    if (!showBlankBoundary)
      root =
          db.getConfig().getBoolean("blame", "blankboundary", false); // $NON-NLS-1$ //$NON-NLS-2$
    if (!root)
      root = db.getConfig().getBoolean("blame", "showroot", false); // $NON-NLS-1$ //$NON-NLS-2$

    if (showRawTimestamp) dateFmt = new SimpleDateFormat("ZZZZ"); // $NON-NLS-1$
    else dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ZZZZ"); // $NON-NLS-1$

    reader = db.newObjectReader();
    try (BlameGenerator generator = new BlameGenerator(db, file)) {
      RevFlag scanned = generator.newFlag("SCANNED"); // $NON-NLS-1$
      generator.setTextComparator(comparator);

      if (!reverseRange.isEmpty()) {
        RevCommit rangeStart = null;
        List<RevCommit> rangeEnd = new ArrayList<RevCommit>(2);
        for (RevCommit c : reverseRange) {
          if (c.has(RevFlag.UNINTERESTING)) rangeStart = c;
          else rangeEnd.add(c);
        }
        generator.reverse(rangeStart, rangeEnd);
      } else if (revision != null) {
        generator.push(null, db.resolve(revision + "^{commit}")); // $NON-NLS-1$
      } else {
        generator.push(null, db.resolve(Constants.HEAD));
        if (!db.isBare()) {
          DirCache dc = db.readDirCache();
          int entry = dc.findEntry(file);
          if (0 <= entry) generator.push(null, dc.getEntry(entry).getObjectId());

          File inTree = new File(db.getWorkTree(), file);
          if (db.getFS().isFile(inTree)) generator.push(null, new RawText(inTree));
        }
      }

      blame = BlameResult.create(generator);
      begin = 0;
      end = blame.getResultContents().size();
      if (rangeString != null) parseLineRangeOption();
      blame.computeRange(begin, end);

      int authorWidth = 8;
      int dateWidth = 8;
      int pathWidth = 1;
      int maxSourceLine = 1;
      for (int line = begin; line < end; line++) {
        RevCommit c = blame.getSourceCommit(line);
        if (c != null && !c.has(scanned)) {
          c.add(scanned);
          if (autoAbbrev) abbrev = Math.max(abbrev, uniqueAbbrevLen(c));
          authorWidth = Math.max(authorWidth, author(line).length());
          dateWidth = Math.max(dateWidth, date(line).length());
          pathWidth = Math.max(pathWidth, path(line).length());
        }
        while (line + 1 < end && blame.getSourceCommit(line + 1) == c) line++;
        maxSourceLine = Math.max(maxSourceLine, blame.getSourceLine(line));
      }

      String pathFmt = MessageFormat.format(" %{0}s", valueOf(pathWidth)); // $NON-NLS-1$
      String numFmt =
          MessageFormat.format(
              " %{0}d", //$NON-NLS-1$
              valueOf(1 + (int) Math.log10(maxSourceLine + 1)));
      String lineFmt =
          MessageFormat.format(
              " %{0}d) ", //$NON-NLS-1$
              valueOf(1 + (int) Math.log10(end + 1)));
      String authorFmt =
          MessageFormat.format(
              " (%-{0}s %{1}s", //$NON-NLS-1$
              valueOf(authorWidth), valueOf(dateWidth));

      for (int line = begin; line < end; ) {
        RevCommit c = blame.getSourceCommit(line);
        String commit = abbreviate(c);
        String author = null;
        String date = null;
        if (!noAuthor) {
          author = author(line);
          date = date(line);
        }
        do {
          outw.print(commit);
          if (showSourcePath) outw.format(pathFmt, path(line));
          if (showSourceLine) outw.format(numFmt, valueOf(blame.getSourceLine(line) + 1));
          if (!noAuthor) outw.format(authorFmt, author, date);
          outw.format(lineFmt, valueOf(line + 1));
          outw.flush();
          blame.getResultContents().writeLine(outs, line);
          outs.flush();
          outw.print('\n');
        } while (++line < end && blame.getSourceCommit(line) == c);
      }
    } finally {
      reader.close();
    }
  }