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; }
/** * 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); }
/** * 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()); }
/** * 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())); } }
/** * 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(); }
/** * 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); } }
/** * 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(); } }
/** * 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); } }
/** * 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; }
/** * 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); }
/** * 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; }
/** * 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]); }
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(); }
/** * 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; }
/** * 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; }
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)); } }
/** * 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; }
@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); } }
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); } }
/** * 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; }
/** * 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$ }
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; } }
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); } }
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(); }
@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)); }
/** * 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())); }