public Result applyPatch()

in org.eclipse.jgit/src/org/eclipse/jgit/patch/PatchApplier.java [186:296]


	public Result applyPatch(InputStream patchInput)
			throws PatchFormatException, PatchApplyException {
		Result result = new Result();
		Patch p = new Patch();
		try (InputStream inStream = patchInput) {
			p.parse(inStream);

			if (!p.getErrors().isEmpty()) {
				throw new PatchFormatException(p.getErrors());
			}

			DirCache dirCache = inCore() ? DirCache.read(reader, beforeTree)
					: repo.lockDirCache();

			DirCacheBuilder dirCacheBuilder = dirCache.builder();
			Set<String> modifiedPaths = new HashSet<>();
			for (FileHeader fh : p.getFiles()) {
				ChangeType type = fh.getChangeType();
				switch (type) {
				case ADD: {
					File f = getFile(fh.getNewPath());
					if (f != null) {
						try {
							FileUtils.mkdirs(f.getParentFile(), true);
							FileUtils.createNewFile(f);
						} catch (IOException e) {
							throw new PatchApplyException(MessageFormat.format(
									JGitText.get().createNewFileFailed, f), e);
						}
					}
					apply(fh.getNewPath(), dirCache, dirCacheBuilder, f, fh);
				}
					break;
				case MODIFY:
					apply(fh.getOldPath(), dirCache, dirCacheBuilder,
							getFile(fh.getOldPath()), fh);
					break;
				case DELETE:
					if (!inCore()) {
						File old = getFile(fh.getOldPath());
						if (!old.delete())
							throw new PatchApplyException(MessageFormat.format(
									JGitText.get().cannotDeleteFile, old));
					}
					break;
				case RENAME: {
					File src = getFile(fh.getOldPath());
					File dest = getFile(fh.getNewPath());

					if (!inCore()) {
						/*
						 * this is odd: we rename the file on the FS, but
						 * apply() will write a fresh stream anyway, which will
						 * overwrite if there were hunks in the patch.
						 */
						try {
							FileUtils.mkdirs(dest.getParentFile(), true);
							FileUtils.rename(src, dest,
									StandardCopyOption.ATOMIC_MOVE);
						} catch (IOException e) {
							throw new PatchApplyException(MessageFormat.format(
									JGitText.get().renameFileFailed, src, dest),
									e);
						}
					}
					String pathWithOriginalContent = inCore() ?
							fh.getOldPath() : fh.getNewPath();
					apply(pathWithOriginalContent, dirCache, dirCacheBuilder, dest, fh);
					break;
				}
				case COPY: {
					File dest = getFile(fh.getNewPath());
					if (!inCore()) {
						File src = getFile(fh.getOldPath());
						FileUtils.mkdirs(dest.getParentFile(), true);
						Files.copy(src.toPath(), dest.toPath());
					}
					apply(fh.getOldPath(), dirCache, dirCacheBuilder, dest, fh);
					break;
				}
				}
				if (fh.getChangeType() != ChangeType.DELETE)
					modifiedPaths.add(fh.getNewPath());
				if (fh.getChangeType() != ChangeType.COPY
						&& fh.getChangeType() != ChangeType.ADD)
					modifiedPaths.add(fh.getOldPath());
			}

			// We processed the patch. Now add things that weren't changed.
			for (int i = 0; i < dirCache.getEntryCount(); i++) {
				DirCacheEntry dce = dirCache.getEntry(i);
				if (!modifiedPaths.contains(dce.getPathString())
						|| dce.getStage() != DirCacheEntry.STAGE_0)
					dirCacheBuilder.add(dce);
			}

			if (inCore())
				dirCacheBuilder.finish();
			else if (!dirCacheBuilder.commit()) {
				throw new IndexWriteException();
			}

			result.treeId = dirCache.writeTree(inserter);
			result.paths = modifiedPaths.stream().sorted()
					.collect(Collectors.toList());
		} catch (IOException e) {
			throw new PatchApplyException(MessageFormat.format(
					JGitText.get().patchApplyException, e.getMessage()), e);
		}
		return result;
	}