private boolean commitIndex(Repository db, DirCache index, String author, String message)
      throws IOException, ConcurrentRefUpdateException {
    boolean success = false;

    ObjectId headId = db.resolve(BRANCH + "^{commit}");
    if (headId == null) {
      // create the branch
      createTicketsBranch(db);
      headId = db.resolve(BRANCH + "^{commit}");
    }
    try (ObjectInserter odi = db.newObjectInserter()) {
      // Create the in-memory index of the new/updated ticket
      ObjectId indexTreeId = index.writeTree(odi);

      // Create a commit object
      PersonIdent ident = new PersonIdent(author, "gitblit@localhost");
      CommitBuilder commit = new CommitBuilder();
      commit.setAuthor(ident);
      commit.setCommitter(ident);
      commit.setEncoding(Constants.ENCODING);
      commit.setMessage(message);
      commit.setParentId(headId);
      commit.setTreeId(indexTreeId);

      // Insert the commit into the repository
      ObjectId commitId = odi.insert(commit);
      odi.flush();

      try (RevWalk revWalk = new RevWalk(db)) {
        RevCommit revCommit = revWalk.parseCommit(commitId);
        RefUpdate ru = db.updateRef(BRANCH);
        ru.setNewObjectId(commitId);
        ru.setExpectedOldObjectId(headId);
        ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false);
        Result rc = ru.forceUpdate();
        switch (rc) {
          case NEW:
          case FORCED:
          case FAST_FORWARD:
            success = true;
            break;
          case REJECTED:
          case LOCK_FAILURE:
            throw new ConcurrentRefUpdateException(
                JGitText.get().couldNotLockHEAD, ru.getRef(), rc);
          default:
            throw new JGitInternalException(
                MessageFormat.format(
                    JGitText.get().updatingRefFailed, BRANCH, commitId.toString(), rc));
        }
      }
    }
    return success;
  }
Beispiel #2
0
  /**
   * Sets default values for not explicitly specified options. Then validates that all required data
   * has been provided.
   *
   * @param state the state of the repository we are working on
   * @param rw the RevWalk to use
   * @throws NoMessageException if the commit message has not been specified
   */
  private void processOptions(RepositoryState state, RevWalk rw) throws NoMessageException {
    if (committer == null) committer = new PersonIdent(repo);
    if (author == null && !amend) author = committer;
    if (allowEmpty == null)
      // JGit allows empty commits by default. Only when pathes are
      // specified the commit should not be empty. This behaviour differs
      // from native git but can only be adapted in the next release.
      // TODO(ch) align the defaults with native git
      allowEmpty = (only.isEmpty()) ? Boolean.TRUE : Boolean.FALSE;

    // when doing a merge commit parse MERGE_HEAD and MERGE_MSG files
    if (state == RepositoryState.MERGING_RESOLVED || isMergeDuringRebase(state)) {
      try {
        parents = repo.readMergeHeads();
        if (parents != null)
          for (int i = 0; i < parents.size(); i++) {
            RevObject ro = rw.parseAny(parents.get(i));
            if (ro instanceof RevTag) parents.set(i, rw.peel(ro));
          }
      } catch (IOException e) {
        throw new JGitInternalException(
            MessageFormat.format(
                JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_HEAD, e),
            e);
      }
      if (message == null) {
        try {
          message = repo.readMergeCommitMsg();
        } catch (IOException e) {
          throw new JGitInternalException(
              MessageFormat.format(
                  JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_MSG, e),
              e);
        }
      }
    } else if (state == RepositoryState.SAFE && message == null) {
      try {
        message = repo.readSquashCommitMsg();
        if (message != null) repo.writeSquashCommitMsg(null /* delete */);
      } catch (IOException e) {
        throw new JGitInternalException(
            MessageFormat.format(
                JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_MSG, e),
            e);
      }
    }
    if (message == null)
      // as long as we don't support -C option we have to have
      // an explicit message
      throw new NoMessageException(JGitText.get().commitMessageNotSpecified);
  }
Beispiel #3
0
 /**
  * Updates the file in the working tree with content and mode from an entry in the index. The new
  * content is first written to a new temporary file in the same directory as the real file. Then
  * that new file is renamed to the final filename.
  *
  * <p>TODO: this method works directly on File IO, we may need another abstraction (like
  * WorkingTreeIterator). This way we could tell e.g. Eclipse that Files in the workspace got
  * changed
  *
  * @param repo
  * @param f the file to be modified. The parent directory for this file has to exist already
  * @param entry the entry containing new mode and content
  * @param or object reader to use for checkout
  * @throws IOException
  */
 public static void checkoutEntry(
     final Repository repo, File f, DirCacheEntry entry, ObjectReader or) throws IOException {
   ObjectLoader ol = or.open(entry.getObjectId());
   File parentDir = f.getParentFile();
   parentDir.mkdirs();
   File tmpFile = File.createTempFile("._" + f.getName(), null, parentDir); // $NON-NLS-1$
   WorkingTreeOptions opt = repo.getConfig().get(WorkingTreeOptions.KEY);
   FileOutputStream rawChannel = new FileOutputStream(tmpFile);
   OutputStream channel;
   if (opt.getAutoCRLF() == AutoCRLF.TRUE) channel = new AutoCRLFOutputStream(rawChannel);
   else channel = rawChannel;
   try {
     ol.copyTo(channel);
   } finally {
     channel.close();
   }
   FS fs = repo.getFS();
   if (opt.isFileMode() && fs.supportsExecute()) {
     if (FileMode.EXECUTABLE_FILE.equals(entry.getRawMode())) {
       if (!fs.canExecute(tmpFile)) fs.setExecute(tmpFile, true);
     } else {
       if (fs.canExecute(tmpFile)) fs.setExecute(tmpFile, false);
     }
   }
   try {
     FileUtils.rename(tmpFile, f);
   } catch (IOException e) {
     throw new IOException(
         MessageFormat.format(JGitText.get().couldNotWriteFile, tmpFile.getPath(), f.getPath()));
   }
   entry.setLastModified(f.lastModified());
   if (opt.getAutoCRLF() != AutoCRLF.FALSE)
     entry.setLength(f.length()); // AutoCRLF wants on-disk-size
   else entry.setLength((int) ol.getSize());
 }
Beispiel #4
0
  /**
   * Delete file or folder
   *
   * @param f {@code File} to be deleted
   * @param options deletion options, {@code RECURSIVE} for recursive deletion of a subtree, {@code
   *     RETRY} to retry when deletion failed. Retrying may help if the underlying file system
   *     doesn't allow deletion of files being read by another thread.
   * @throws IOException if deletion of {@code f} fails. This may occur if {@code f} didn't exist
   *     when the method was called. This can therefore cause IOExceptions during race conditions
   *     when multiple concurrent threads all try to delete the same file. This exception is not
   *     thrown when IGNORE_ERRORS is set.
   */
  public static void delete(final File f, int options) throws IOException {
    if ((options & SKIP_MISSING) != 0 && !f.exists()) return;

    if ((options & RECURSIVE) != 0 && f.isDirectory()) {
      final File[] items = f.listFiles();
      if (items != null) {
        for (File c : items) delete(c, options);
      }
    }
    if (!f.delete()) {
      if ((options & RETRY) != 0 && f.exists()) {
        for (int i = 1; i < 10; i++) {
          try {
            Thread.sleep(100);
          } catch (InterruptedException e) {
            // ignore
          }
          if (f.delete()) return;
        }
      }
      if ((options & IGNORE_ERRORS) == 0)
        throw new IOException(
            MessageFormat.format(JGitText.get().deleteFileFailed, f.getAbsolutePath()));
    }
  }
Beispiel #5
0
  /**
   * Save the configuration as a Git text style configuration file.
   *
   * <p><b>Warning:</b> Although this method uses the traditional Git file locking approach to
   * protect against concurrent writes of the configuration file, it does not ensure that the file
   * has not been modified since the last read, which means updates performed by other objects
   * accessing the same backing file may be lost.
   *
   * @throws IOException the file could not be written.
   */
  public void save() throws IOException {
    final byte[] out;
    final String text = toText();
    if (utf8Bom) {
      final ByteArrayOutputStream bos = new ByteArrayOutputStream();
      bos.write(0xEF);
      bos.write(0xBB);
      bos.write(0xBF);
      bos.write(text.getBytes(RawParseUtils.UTF8_CHARSET.name()));
      out = bos.toByteArray();
    } else {
      out = Constants.encode(text);
    }

    final LockFile lf = new LockFile(getFile(), fs);
    if (!lf.lock()) throw new LockFailedException(getFile());
    try {
      lf.setNeedSnapshot(true);
      lf.write(out);
      if (!lf.commit())
        throw new IOException(MessageFormat.format(JGitText.get().cannotCommitWriteTo, getFile()));
    } finally {
      lf.unlock();
    }
    snapshot = lf.getCommitSnapshot();
    hash = hash(out);
    // notify the listeners
    fireConfigChangedEvent();
  }
Beispiel #6
0
 /**
  * Read the index from disk, if it has changed on disk.
  *
  * <p>This method tries to avoid loading the index if it has not changed since the last time we
  * consulted it. A missing index file will be treated as though it were present but had no file
  * entries in it.
  *
  * @throws IOException the index file is present but could not be read. This DirCache instance may
  *     not be populated correctly.
  * @throws CorruptObjectException the index file is using a format or extension that this library
  *     does not support.
  */
 public void read() throws IOException, CorruptObjectException {
   if (liveFile == null) throw new IOException(JGitText.get().dirCacheDoesNotHaveABackingFile);
   if (!liveFile.exists()) clear();
   else if (snapshot == null || snapshot.isModified(liveFile)) {
     try {
       final FileInputStream inStream = new FileInputStream(liveFile);
       try {
         clear();
         readFrom(inStream);
       } finally {
         try {
           inStream.close();
         } catch (IOException err2) {
           // Ignore any close failures.
         }
       }
     } catch (FileNotFoundException fnfe) {
       // Someone must have deleted it between our exists test
       // and actually opening the path. That's fine, its empty.
       //
       clear();
     }
     snapshot = FileSnapshot.save(liveFile);
   }
 }
Beispiel #7
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();
    }
  }
Beispiel #8
0
 /**
  * This method implements how to handle conflicts when {@link #failOnConflict} is false
  *
  * @throws CheckoutConflictException
  */
 private void cleanUpConflicts() throws CheckoutConflictException {
   // TODO: couldn't we delete unsaved worktree content here?
   for (String c : conflicts) {
     File conflict = new File(repo.getWorkTree(), c);
     if (!conflict.delete())
       throw new CheckoutConflictException(
           MessageFormat.format(JGitText.get().cannotDeleteFile, c));
     removeEmptyParents(conflict);
   }
   for (String r : removed) {
     File file = new File(repo.getWorkTree(), r);
     if (!file.delete())
       throw new CheckoutConflictException(
           MessageFormat.format(JGitText.get().cannotDeleteFile, file.getAbsolutePath()));
     removeEmptyParents(file);
   }
 }
Beispiel #9
0
 /**
  * If set to true the Commit command automatically stages files that have been modified and
  * deleted, but new files not known by the repository are not affected. This corresponds to the
  * parameter -a on the command line.
  *
  * @param all
  * @return {@code this}
  * @throws JGitInternalException in case of an illegal combination of arguments/ options
  */
 public CommitCommand setAll(boolean all) {
   checkCallable();
   if (!only.isEmpty())
     throw new JGitInternalException(
         MessageFormat.format(JGitText.get().illegalCombinationOfArguments, "--all", "--only"));
   this.all = all;
   return this;
 }
Beispiel #10
0
  /**
   * Sets default values for not explicitly specified options. Then validates that all required data
   * has been provided.
   *
   * @param state the state of the repository we are working on
   * @param rw the RevWalk to use
   * @throws NoMessageException if the commit message has not been specified
   */
  private void processOptions(RepositoryState state, RevWalk rw) throws NoMessageException {
    if (committer == null) committer = new PersonIdent(repo);
    if (author == null && !amend) author = committer;

    // when doing a merge commit parse MERGE_HEAD and MERGE_MSG files
    if (state == RepositoryState.MERGING_RESOLVED || isMergeDuringRebase(state)) {
      try {
        parents = repo.readMergeHeads();
        if (parents != null)
          for (int i = 0; i < parents.size(); i++) {
            RevObject ro = rw.parseAny(parents.get(i));
            if (ro instanceof RevTag) parents.set(i, rw.peel(ro));
          }
      } catch (IOException e) {
        throw new JGitInternalException(
            MessageFormat.format(
                JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_HEAD, e),
            e);
      }
      if (message == null) {
        try {
          message = repo.readMergeCommitMsg();
        } catch (IOException e) {
          throw new JGitInternalException(
              MessageFormat.format(
                  JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_MSG, e),
              e);
        }
      }
    } else if (state == RepositoryState.SAFE && message == null) {
      try {
        message = repo.readSquashCommitMsg();
        if (message != null) repo.writeSquashCommitMsg(null /* delete */);
      } catch (IOException e) {
        throw new JGitInternalException(
            MessageFormat.format(
                JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_MSG, e),
            e);
      }
    }
    if (message == null)
      // as long as we don't support -C option we have to have
      // an explicit message
      throw new NoMessageException(JGitText.get().commitMessageNotSpecified);
  }
Beispiel #11
0
 /**
  * Push a candidate blob onto the generator's traversal stack.
  *
  * <p>Candidates should be pushed in history order from oldest-to-newest. Applications should push
  * the starting commit first, then the index revision (if the index is interesting), and finally
  * the working tree copy (if the working tree is interesting).
  *
  * @param description description of the blob revision, such as "Working Tree".
  * @param contents contents of the file.
  * @return {@code this}
  * @throws IOException the repository cannot be read.
  */
 public BlameGenerator push(String description, RawText contents) throws IOException {
   if (description == null) description = JGitText.get().blameNotCommittedYet;
   BlobCandidate c = new BlobCandidate(description, resultPath);
   c.sourceText = contents;
   c.regionList = new Region(0, 0, contents.size());
   remaining = contents.size();
   push(c);
   return this;
 }
Beispiel #12
0
  /**
   * Construct a new substring pattern.
   *
   * @param patternText text to locate. This should be a literal string, as no meta-characters are
   *     supported by this implementation. The string may not be the empty string.
   */
  public RawSubStringPattern(final String patternText) {
    if (patternText.length() == 0)
      throw new IllegalArgumentException(JGitText.get().cannotMatchOnEmptyString);
    needleString = patternText;

    final byte[] b = Constants.encode(patternText);
    needle = new byte[b.length];
    for (int i = 0; i < b.length; i++) needle[i] = lc(b[i]);
  }
Beispiel #13
0
  private RefList<Ref> parsePackedRefs(final BufferedReader br) throws IOException {
    RefList.Builder<Ref> all = new RefList.Builder<Ref>();
    Ref last = null;
    boolean peeled = false;
    boolean needSort = false;

    String p;
    while ((p = br.readLine()) != null) {
      if (p.charAt(0) == '#') {
        if (p.startsWith(PACKED_REFS_HEADER)) {
          p = p.substring(PACKED_REFS_HEADER.length());
          peeled = p.contains(PACKED_REFS_PEELED);
        }
        continue;
      }

      if (p.charAt(0) == '^') {
        if (last == null) throw new IOException(JGitText.get().peeledLineBeforeRef);

        ObjectId id = ObjectId.fromString(p.substring(1));
        last = new ObjectIdRef.PeeledTag(PACKED, last.getName(), last.getObjectId(), id);
        all.set(all.size() - 1, last);
        continue;
      }

      int sp = p.indexOf(' ');
      if (sp < 0) {
        throw new IOException(
            MessageFormat.format(
                JGitText.get().packedRefsCorruptionDetected, packedRefsFile.getAbsolutePath()));
      }
      ObjectId id = ObjectId.fromString(p.substring(0, sp));
      String name = copy(p, sp + 1, p.length());
      ObjectIdRef cur;
      if (peeled) cur = new ObjectIdRef.PeeledNonTag(PACKED, name, id);
      else cur = new ObjectIdRef.Unpeeled(PACKED, name, id);
      if (last != null && RefComparator.compareTo(last, cur) > 0) needSort = true;
      all.add(cur);
      last = cur;
    }

    if (needSort) all.sort();
    return all.toRefList();
  }
Beispiel #14
0
 /**
  * Try to establish an update lock on the cache file.
  *
  * @return true if the lock is now held by the caller; false if it is held by someone else.
  * @throws IOException the output file could not be created. The caller does not hold the lock.
  */
 public boolean lock() throws IOException {
   if (liveFile == null) throw new IOException(JGitText.get().dirCacheDoesNotHaveABackingFile);
   final LockFile tmp = new LockFile(liveFile, fs);
   if (tmp.lock()) {
     tmp.setNeedStatInformation(true);
     myLock = tmp;
     return true;
   }
   return false;
 }
Beispiel #15
0
 /**
  * Set the output stream for a selected hook script executed by this command (pre-commit,
  * commit-msg, post-commit). If not set it defaults to {@code System.out}.
  *
  * @param hookName name of the hook to set the output stream for
  * @param hookStdOut the output stream to use for the selected hook
  * @return {@code this}
  * @since 4.5
  */
 public CommitCommand setHookOutputStream(String hookName, PrintStream hookStdOut) {
   if (!(PreCommitHook.NAME.equals(hookName)
       || CommitMsgHook.NAME.equals(hookName)
       || PostCommitHook.NAME.equals(hookName))) {
     throw new IllegalArgumentException(
         MessageFormat.format(JGitText.get().illegalHookName, hookName));
   }
   hookOutRedirect.put(hookName, hookStdOut);
   return this;
 }
Beispiel #16
0
 private static byte[] read(Repository db, AnyObjectId treeish, String path)
     throws MissingObjectException, IncorrectObjectTypeException, IOException {
   try (ObjectReader or = db.newObjectReader()) {
     TreeWalk tree = TreeWalk.forPath(or, path, asTree(or, treeish));
     if (tree == null)
       throw new FileNotFoundException(
           MessageFormat.format(JGitText.get().entryNotFoundByPath, path));
     return read(or, tree.getObjectId(0));
   }
 }
Beispiel #17
0
 /**
  * Commit dedicated path only
  *
  * <p>This method can be called several times to add multiple paths. Full file paths are supported
  * as well as directory paths; in the latter case this commits all files/ directories below the
  * specified path.
  *
  * @param only path to commit
  * @return {@code this}
  */
 public CommitCommand setOnly(String only) {
   checkCallable();
   if (all)
     throw new JGitInternalException(
         MessageFormat.format(JGitText.get().illegalCombinationOfArguments, "--only", "--all"));
   String o = only.endsWith("/") ? only.substring(0, only.length() - 1) : only;
   // ignore duplicates
   if (!this.only.contains(o)) this.only.add(o);
   return this;
 }
Beispiel #18
0
 @Test
 public void testInvalidType() {
   try {
     checker.check(Constants.OBJ_BAD, new byte[0]);
     fail("Did not throw CorruptObjectException");
   } catch (CorruptObjectException e) {
     final String m = e.getMessage();
     assertEquals(
         MessageFormat.format(JGitText.get().corruptObjectInvalidType2, Constants.OBJ_BAD), m);
   }
 }
Beispiel #19
0
 private boolean isMergeDuringRebase(RepositoryState state) {
   if (state != RepositoryState.REBASING_INTERACTIVE && state != RepositoryState.REBASING_MERGE)
     return false;
   try {
     return repo.readMergeHeads() != null;
   } catch (IOException e) {
     throw new JGitInternalException(
         MessageFormat.format(
             JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_HEAD, e),
         e);
   }
 }
Beispiel #20
0
  /**
   * Create a new stream to write side band packets.
   *
   * @param chan channel number to prefix all packets with, so the remote side can demultiplex the
   *     stream and get back the original data. Must be in the range [1, 255].
   * @param sz maximum size of a data packet within the stream. The remote side needs to agree to
   *     the packet size to prevent buffer overflows. Must be in the range [HDR_SIZE + 1, MAX_BUF).
   * @param os stream that the packets are written onto. This stream should be attached to a
   *     SideBandInputStream on the remote side.
   */
  public SideBandOutputStream(final int chan, final int sz, final OutputStream os) {
    if (chan <= 0 || chan > 255)
      throw new IllegalArgumentException(
          MessageFormat.format(JGitText.get().channelMustBeInRange1_255, Integer.valueOf(chan)));
    if (sz <= HDR_SIZE)
      throw new IllegalArgumentException(
          MessageFormat.format(
              JGitText.get().packetSizeMustBeAtLeast,
              Integer.valueOf(sz),
              Integer.valueOf(HDR_SIZE)));
    else if (MAX_BUF < sz)
      throw new IllegalArgumentException(
          MessageFormat.format(
              JGitText.get().packetSizeMustBeAtMost,
              Integer.valueOf(sz),
              Integer.valueOf(MAX_BUF)));

    out = os;
    buffer = new byte[sz];
    buffer[4] = (byte) chan;
    cnt = HDR_SIZE;
  }
Beispiel #21
0
 /**
  * Load the configuration as a Git text style configuration file.
  *
  * <p>If the file does not exist, this configuration is cleared, and thus behaves the same as
  * though the file exists, but is empty.
  *
  * @throws IOException the file could not be read (but does exist).
  * @throws ConfigInvalidException the file is not a properly formatted configuration file.
  */
 @Override
 public void load() throws IOException, ConfigInvalidException {
   final FileSnapshot oldSnapshot = snapshot;
   final FileSnapshot newSnapshot = FileSnapshot.save(getFile());
   try {
     final byte[] in = IO.readFully(getFile());
     final ObjectId newHash = hash(in);
     if (hash.equals(newHash)) {
       if (oldSnapshot.equals(newSnapshot)) oldSnapshot.setClean(newSnapshot);
       else snapshot = newSnapshot;
     } else {
       final String decoded;
       if (in.length >= 3
           && in[0] == (byte) 0xEF
           && in[1] == (byte) 0xBB
           && in[2] == (byte) 0xBF) {
         decoded = RawParseUtils.decode(RawParseUtils.UTF8_CHARSET, in, 3, in.length);
         utf8Bom = true;
       } else {
         decoded = RawParseUtils.decode(in);
       }
       fromText(decoded);
       snapshot = newSnapshot;
       hash = newHash;
     }
   } catch (FileNotFoundException noFile) {
     clear();
     snapshot = newSnapshot;
   } catch (IOException e) {
     final IOException e2 =
         new IOException(MessageFormat.format(JGitText.get().cannotReadFile, getFile()));
     e2.initCause(e);
     throw e2;
   } catch (ConfigInvalidException e) {
     throw new ConfigInvalidException(
         MessageFormat.format(JGitText.get().cannotReadFile, getFile()), e);
   }
 }
  @Test
  public void testPush_UnpackError_TruncatedPack() throws Exception {
    StringBuilder sb = new StringBuilder();
    sb.append(ObjectId.zeroId().name());
    sb.append(' ');
    sb.append(a_blob.name());
    sb.append(' ');
    sb.append("refs/objects/A");
    sb.append('\0');
    sb.append("report-status");

    ByteArrayOutputStream reqbuf = new ByteArrayOutputStream();
    PacketLineOut reqpck = new PacketLineOut(reqbuf);
    reqpck.writeString(sb.toString());
    reqpck.end();

    packHeader(reqbuf, 1);

    byte[] reqbin = reqbuf.toByteArray();

    URL u = new URL(remoteURI.toString() + "/git-receive-pack");
    HttpURLConnection c = (HttpURLConnection) u.openConnection();
    try {
      c.setRequestMethod("POST");
      c.setDoOutput(true);
      c.setRequestProperty("Content-Type", GitSmartHttpTools.RECEIVE_PACK_REQUEST_TYPE);
      c.setFixedLengthStreamingMode(reqbin.length);
      OutputStream out = c.getOutputStream();
      try {
        out.write(reqbin);
      } finally {
        out.close();
      }

      assertEquals(200, c.getResponseCode());
      assertEquals(GitSmartHttpTools.RECEIVE_PACK_RESULT_TYPE, c.getContentType());

      InputStream rawin = c.getInputStream();
      try {
        PacketLineIn pckin = new PacketLineIn(rawin);
        assertEquals("unpack error " + JGitText.get().packfileIsTruncated, pckin.readString());
        assertEquals("ng refs/objects/A n/a (unpacker error)", pckin.readString());
        assertSame(PacketLineIn.END, pckin.readString());
      } finally {
        rawin.close();
      }
    } finally {
      c.disconnect();
    }
  }
  private void writeBitmaps(PackBitmapIndexBuilder bitmaps) throws IOException {
    int bitmapCount = 0;
    for (StoredEntry entry : bitmaps.getCompressedBitmaps()) {
      writeBitmapEntry(entry);
      bitmapCount++;
    }

    int expectedBitmapCount = bitmaps.getBitmapCount();
    if (expectedBitmapCount != bitmapCount)
      throw new IOException(
          MessageFormat.format(
              JGitText.get().expectedGot,
              String.valueOf(expectedBitmapCount),
              String.valueOf(bitmapCount)));
  }
  /**
   * Construct a new pattern matching filter.
   *
   * @param pattern text of the pattern. Callers may want to surround their pattern with ".*" on
   *     either end to allow matching in the middle of the string.
   * @param innerString should .* be wrapped around the pattern of ^ and $ are missing? Most users
   *     will want this set.
   * @param rawEncoding should {@link #forceToRaw(String)} be applied to the pattern before
   *     compiling it?
   * @param flags flags from {@link Pattern} to control how matching performs.
   */
  protected PatternMatchRevFilter(
      String pattern, final boolean innerString, final boolean rawEncoding, final int flags) {
    if (pattern.length() == 0)
      throw new IllegalArgumentException(JGitText.get().cannotMatchOnEmptyString);
    patternText = pattern;

    if (innerString) {
      if (!pattern.startsWith("^") && !pattern.startsWith(".*")) // $NON-NLS-1$ //$NON-NLS-2$
      pattern = ".*" + pattern; // $NON-NLS-1$
      if (!pattern.endsWith("$") && !pattern.endsWith(".*")) // $NON-NLS-1$ //$NON-NLS-2$
      pattern = pattern + ".*"; // $NON-NLS-1$
    }
    final String p = rawEncoding ? forceToRaw(pattern) : pattern;
    compiledPattern = Pattern.compile(p, flags).matcher(""); // $NON-NLS-1$
  }
Beispiel #25
0
 private void skipOptionalExtension(
     final InputStream in, final MessageDigest md, final byte[] hdr, long sz) throws IOException {
   final byte[] b = new byte[4096];
   while (0 < sz) {
     int n = in.read(b, 0, (int) Math.min(b.length, sz));
     if (n < 0) {
       throw new EOFException(
           MessageFormat.format(
               JGitText.get().shortReadOfOptionalDIRCExtensionExpectedAnotherBytes,
               formatExtensionName(hdr),
               Long.valueOf(sz)));
     }
     md.update(b, 0, n);
     sz -= n;
   }
 }
Beispiel #26
0
  private static void delete(final File file, final int depth, LockFile rLck) throws IOException {
    if (!file.delete() && file.isFile()) {
      throw new IOException(MessageFormat.format(JGitText.get().fileCannotBeDeleted, file));
    }

    if (rLck != null) {
      rLck.unlock(); // otherwise cannot delete dir below
    }
    File dir = file.getParentFile();
    for (int i = 0; i < depth; ++i) {
      if (!dir.delete()) {
        break; // ignore problem here
      }
      dir = dir.getParentFile();
    }
  }
 private void commit() throws CoreException {
   Git git = new Git(repo);
   try {
     CommitCommand commitCommand = git.commit();
     setAuthorAndCommitter(commitCommand);
     commitCommand.setAmend(amending).setMessage(message).setInsertChangeId(createChangeId);
     if (!commitIndex) for (String path : commitFileList) commitCommand.setOnly(path);
     commit = commitCommand.call();
   } catch (JGitInternalException e) {
     if ("No changes".equals(JGitText.get().emptyCommit)) {
       ifNoChanges = true;
     }
   } catch (Exception e) {
     throw new CoreException("An internal error occurred", e);
   }
 }
Beispiel #28
0
  String getScriptText(Charset[] charsetGuess) {
    if (getHunks().isEmpty()) {
      // If we have no hunks then we can safely assume the entire
      // patch is a binary style patch, or a meta-data only style
      // patch. Either way the encoding of the headers should be
      // strictly 7-bit US-ASCII and the body is either 7-bit ASCII
      // (due to the base 85 encoding used for a BinaryHunk) or is
      // arbitrary noise we have chosen to ignore and not understand
      // (e.g. the message "Binary files ... differ").
      //
      return extractBinaryString(buf, startOffset, endOffset);
    }

    if (charsetGuess != null && charsetGuess.length != getParentCount() + 1)
      throw new IllegalArgumentException(
          MessageFormat.format(
              JGitText.get().expectedCharacterEncodingGuesses,
              Integer.valueOf(getParentCount() + 1)));

    if (trySimpleConversion(charsetGuess)) {
      Charset cs = charsetGuess != null ? charsetGuess[0] : null;
      if (cs == null) cs = Constants.CHARSET;
      try {
        return decodeNoFallback(cs, buf, startOffset, endOffset);
      } catch (CharacterCodingException cee) {
        // Try the much slower, more-memory intensive version which
        // can handle a character set conversion patch.
      }
    }

    final StringBuilder r = new StringBuilder(endOffset - startOffset);

    // Always treat the headers as US-ASCII; Git file names are encoded
    // in a C style escape if any character has the high-bit set.
    //
    final int hdrEnd = getHunks().get(0).getStartOffset();
    for (int ptr = startOffset; ptr < hdrEnd; ) {
      final int eol = Math.min(hdrEnd, nextLF(buf, ptr));
      r.append(extractBinaryString(buf, ptr, eol));
      ptr = eol;
    }

    final String[] files = extractFileLines(charsetGuess);
    final int[] offsets = new int[files.length];
    for (final HunkHeader h : getHunks()) h.extractFileLines(r, files, offsets);
    return r.toString();
  }
Beispiel #29
0
 @Override
 public String toString() {
   boolean first = true;
   StringBuilder commits = new StringBuilder();
   for (ObjectId commit : mergedCommits) {
     if (!first) commits.append(", ");
     else first = false;
     commits.append(ObjectId.toString(commit));
   }
   return MessageFormat.format(
       JGitText.get().mergeUsingStrategyResultedInDescription,
       commits,
       ObjectId.toString(base),
       mergeStrategy.getName(),
       mergeStatus,
       (description == null ? "" : ", " + description));
 }
Beispiel #30
0
  /**
   * Start this daemon on a background thread.
   *
   * @throws IOException the server socket could not be opened.
   * @throws IllegalStateException the daemon is already running.
   */
  public synchronized void start() throws IOException {
    if (acceptThread != null) throw new IllegalStateException(JGitText.get().daemonAlreadyRunning);

    final ServerSocket listenSock =
        new ServerSocket(
            myAddress != null ? myAddress.getPort() : 0,
            BACKLOG,
            myAddress != null ? myAddress.getAddress() : null);
    myAddress = (InetSocketAddress) listenSock.getLocalSocketAddress();

    run.set(true);
    acceptSocket = listenSock;
    acceptThread =
        new Thread(processors, "Git-Daemon-Accept") {
          public void run() {
            while (isRunning()) {
              try {
                startClient(listenSock.accept());
              } catch (InterruptedIOException e) {
                // Test again to see if we should keep accepting.
              } catch (IOException e) {
                break;
              }
            }

            try {
              listenSock.close();
            } catch (IOException err) {
              //
            } finally {
              acceptSocket = null;
              acceptThread = null;
            }
          }
        };
    acceptThread.start();

    logger.info(
        MessageFormat.format(
            "Git Daemon is listening on {0}:{1,number,0}",
            myAddress.getAddress().getHostAddress(), myAddress.getPort()));
  }