DiffCommand.java
- /*
- * Copyright (C) 2011, Tomasz Zarna <Tomasz.Zarna@pl.ibm.com> and others
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Distribution License v. 1.0 which is available at
- * https://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- package org.eclipse.jgit.api;
- import static org.eclipse.jgit.lib.Constants.HEAD;
- import java.io.BufferedOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.util.List;
- import org.eclipse.jgit.api.errors.GitAPIException;
- import org.eclipse.jgit.api.errors.JGitInternalException;
- import org.eclipse.jgit.api.errors.NoHeadException;
- import org.eclipse.jgit.diff.DiffEntry;
- import org.eclipse.jgit.diff.DiffFormatter;
- import org.eclipse.jgit.dircache.DirCacheIterator;
- import org.eclipse.jgit.internal.JGitText;
- import org.eclipse.jgit.lib.NullProgressMonitor;
- import org.eclipse.jgit.lib.ObjectId;
- import org.eclipse.jgit.lib.ObjectReader;
- import org.eclipse.jgit.lib.ProgressMonitor;
- import org.eclipse.jgit.lib.Repository;
- import org.eclipse.jgit.treewalk.AbstractTreeIterator;
- import org.eclipse.jgit.treewalk.CanonicalTreeParser;
- import org.eclipse.jgit.treewalk.FileTreeIterator;
- import org.eclipse.jgit.treewalk.filter.TreeFilter;
- import org.eclipse.jgit.util.io.NullOutputStream;
- /**
- * Show changes between commits, commit and working tree, etc.
- *
- * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-diff.html"
- * >Git documentation about diff</a>
- */
- public class DiffCommand extends GitCommand<List<DiffEntry>> {
- private AbstractTreeIterator oldTree;
- private AbstractTreeIterator newTree;
- private boolean cached;
- private TreeFilter pathFilter = TreeFilter.ALL;
- private boolean showNameAndStatusOnly;
- private boolean showNameOnly;
- private OutputStream out;
- private int contextLines = -1;
- private String sourcePrefix;
- private String destinationPrefix;
- private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;
- /**
- * Constructor for DiffCommand
- *
- * @param repo
- * a {@link org.eclipse.jgit.lib.Repository} object.
- */
- protected DiffCommand(Repository repo) {
- super(repo);
- }
- private DiffFormatter getDiffFormatter() {
- return out != null && !showNameAndStatusOnly && !showNameOnly
- ? new DiffFormatter(new BufferedOutputStream(out))
- : new DiffFormatter(NullOutputStream.INSTANCE);
- }
- /**
- * {@inheritDoc}
- * <p>
- * Executes the {@code Diff} command with all the options and parameters
- * collected by the setter methods (e.g. {@link #setCached(boolean)} of this
- * class. Each instance of this class should only be used for one invocation
- * of the command. Don't call this method twice on an instance.
- */
- @Override
- public List<DiffEntry> call() throws GitAPIException {
- try (DiffFormatter diffFmt = getDiffFormatter()) {
- diffFmt.setRepository(repo);
- diffFmt.setProgressMonitor(monitor);
- if (cached) {
- if (oldTree == null) {
- ObjectId head = repo.resolve(HEAD + "^{tree}"); //$NON-NLS-1$
- if (head == null)
- throw new NoHeadException(JGitText.get().cannotReadTree);
- CanonicalTreeParser p = new CanonicalTreeParser();
- try (ObjectReader reader = repo.newObjectReader()) {
- p.reset(reader, head);
- }
- oldTree = p;
- }
- newTree = new DirCacheIterator(repo.readDirCache());
- } else {
- if (oldTree == null) {
- oldTree = new DirCacheIterator(repo.readDirCache());
- }
- if (newTree == null) {
- newTree = new FileTreeIterator(repo);
- }
- }
- diffFmt.setPathFilter(pathFilter);
- List<DiffEntry> result = diffFmt.scan(oldTree, newTree);
- if (showNameAndStatusOnly || showNameOnly) {
- return result;
- }
- if (contextLines >= 0) {
- diffFmt.setContext(contextLines);
- }
- if (destinationPrefix != null) {
- diffFmt.setNewPrefix(destinationPrefix);
- }
- if (sourcePrefix != null) {
- diffFmt.setOldPrefix(sourcePrefix);
- }
- diffFmt.format(result);
- diffFmt.flush();
- return result;
- } catch (IOException e) {
- throw new JGitInternalException(e.getMessage(), e);
- }
- }
- /**
- * Whether to view the changes staged for the next commit
- *
- * @param cached
- * whether to view the changes staged for the next commit
- * @return this instance
- */
- public DiffCommand setCached(boolean cached) {
- this.cached = cached;
- return this;
- }
- /**
- * Set path filter
- *
- * @param pathFilter
- * parameter, used to limit the diff to the named path
- * @return this instance
- */
- public DiffCommand setPathFilter(TreeFilter pathFilter) {
- this.pathFilter = pathFilter;
- return this;
- }
- /**
- * Set old tree
- *
- * @param oldTree
- * the previous state
- * @return this instance
- */
- public DiffCommand setOldTree(AbstractTreeIterator oldTree) {
- this.oldTree = oldTree;
- return this;
- }
- /**
- * Set new tree
- *
- * @param newTree
- * the updated state
- * @return this instance
- */
- public DiffCommand setNewTree(AbstractTreeIterator newTree) {
- this.newTree = newTree;
- return this;
- }
- /**
- * Set whether to return only names and status of changed files
- *
- * @param showNameAndStatusOnly
- * whether to return only names and status of changed files
- * @return this instance
- */
- public DiffCommand setShowNameAndStatusOnly(boolean showNameAndStatusOnly) {
- this.showNameAndStatusOnly = showNameAndStatusOnly;
- return this;
- }
- /**
- * Set whether to return only names of changed files
- *
- * @param showNameOnly
- * whether to return only names files
- * @return this instance
- * @since 6.4
- */
- public DiffCommand setShowNameOnly(boolean showNameOnly) {
- this.showNameOnly = showNameOnly;
- return this;
- }
- /**
- * Set output stream
- *
- * @param out
- * the stream to write line data
- * @return this instance
- */
- public DiffCommand setOutputStream(OutputStream out) {
- this.out = out;
- return this;
- }
- /**
- * Set number of context lines instead of the usual three.
- *
- * @param contextLines
- * the number of context lines
- * @return this instance
- */
- public DiffCommand setContextLines(int contextLines) {
- this.contextLines = contextLines;
- return this;
- }
- /**
- * Set the given source prefix instead of "a/".
- *
- * @param sourcePrefix
- * the prefix
- * @return this instance
- */
- public DiffCommand setSourcePrefix(String sourcePrefix) {
- this.sourcePrefix = sourcePrefix;
- return this;
- }
- /**
- * Set the given destination prefix instead of "b/".
- *
- * @param destinationPrefix
- * the prefix
- * @return this instance
- */
- public DiffCommand setDestinationPrefix(String destinationPrefix) {
- this.destinationPrefix = destinationPrefix;
- return this;
- }
- /**
- * The progress monitor associated with the diff operation. By default, this
- * is set to <code>NullProgressMonitor</code>
- *
- * @see NullProgressMonitor
- * @param monitor
- * a progress monitor
- * @return this instance
- */
- public DiffCommand setProgressMonitor(ProgressMonitor monitor) {
- if (monitor == null) {
- monitor = NullProgressMonitor.INSTANCE;
- }
- this.monitor = monitor;
- return this;
- }
- }