Class DiffFormatter

  • All Implemented Interfaces:
    java.lang.AutoCloseable
    Direct Known Subclasses:
    PatchIdDiffFormatter

    public class DiffFormatter
    extends java.lang.Object
    implements java.lang.AutoCloseable
    Format a Git style patch script.
    • Field Detail

      • DEFAULT_BINARY_FILE_THRESHOLD

        private static final int DEFAULT_BINARY_FILE_THRESHOLD
        See Also:
        Constant Field Values
      • noNewLine

        private static final byte[] noNewLine
      • EMPTY

        private static final byte[] EMPTY
        Magic return content indicating it is empty or no content present.
      • out

        private final java.io.OutputStream out
      • closeReader

        private boolean closeReader
      • context

        private int context
      • abbreviationLength

        private int abbreviationLength
      • binaryFileThreshold

        private int binaryFileThreshold
      • oldPrefix

        private java.lang.String oldPrefix
      • newPrefix

        private java.lang.String newPrefix
      • quotePaths

        private java.lang.Boolean quotePaths
    • Constructor Detail

      • DiffFormatter

        public DiffFormatter​(java.io.OutputStream out)
        Create a new formatter with a default level of context.
        Parameters:
        out - the stream the formatter will write line data to. This stream should have buffering arranged by the caller, as many small writes are performed to it.
    • Method Detail

      • getOutputStream

        protected java.io.OutputStream getOutputStream()
        Get output stream
        Returns:
        the stream we are outputting data to
      • setRepository

        public void setRepository​(Repository repository)
        Set the repository the formatter can load object contents from. Once a repository has been set, the formatter must be released to ensure the internal ObjectReader is able to release its resources.
        Parameters:
        repository - source repository holding referenced objects.
      • setReader

        public void setReader​(ObjectReader reader,
                              Config cfg)
        Set the repository the formatter can load object contents from.
        Parameters:
        reader - source reader holding referenced objects. Caller is responsible for closing the reader.
        cfg - config specifying diff algorithm and rename detection options.
        Since:
        4.5
      • setReader

        private void setReader​(ObjectReader reader,
                               Config cfg,
                               boolean closeReader)
      • setContext

        public void setContext​(int lineCount)
        Change the number of lines of context to display.
        Parameters:
        lineCount - number of lines of context to see before the first modification and after the last modification within a hunk of the modified file.
      • setAbbreviationLength

        public void setAbbreviationLength​(int count)
        Change the number of digits to show in an ObjectId.
        Parameters:
        count - number of digits to show in an ObjectId.
      • setDiffAlgorithm

        public void setDiffAlgorithm​(DiffAlgorithm alg)
        Set the algorithm that constructs difference output.
        Parameters:
        alg - the algorithm to produce text file differences.
        See Also:
        HistogramDiff
      • setBinaryFileThreshold

        public void setBinaryFileThreshold​(int threshold)
        Set maximum file size for text files. Files larger than this size will be treated as though they are binary and not text. Default is 52428800 .
        Parameters:
        threshold - the limit, in bytes. Files larger than this size will be assumed to be binary, even if they aren't.
      • setOldPrefix

        public void setOldPrefix​(java.lang.String prefix)
        Set the prefix applied in front of old file paths.
        Parameters:
        prefix - the prefix in front of old paths. Typically this is the standard string "a/", but may be any prefix desired by the caller. Must not be null. Use the empty string to have no prefix at all.
      • getOldPrefix

        public java.lang.String getOldPrefix()
        Get the prefix applied in front of old file paths.
        Returns:
        the prefix
        Since:
        2.0
      • setNewPrefix

        public void setNewPrefix​(java.lang.String prefix)
        Set the prefix applied in front of new file paths.
        Parameters:
        prefix - the prefix in front of new paths. Typically this is the standard string "b/", but may be any prefix desired by the caller. Must not be null. Use the empty string to have no prefix at all.
      • getNewPrefix

        public java.lang.String getNewPrefix()
        Get the prefix applied in front of new file paths.
        Returns:
        the prefix
        Since:
        2.0
      • isDetectRenames

        public boolean isDetectRenames()
        Get if rename detection is enabled
        Returns:
        true if rename detection is enabled
      • setDetectRenames

        public void setDetectRenames​(boolean on)
        Enable or disable rename detection. Before enabling rename detection the repository must be set with setRepository(Repository). Once enabled the detector can be configured away from its defaults by obtaining the instance directly from getRenameDetector() and invoking configuration.
        Parameters:
        on - if rename detection should be enabled.
      • getRenameDetector

        public RenameDetector getRenameDetector()
        Get rename detector
        Returns:
        the rename detector if rename detection is enabled
      • setProgressMonitor

        public void setProgressMonitor​(ProgressMonitor pm)
        Set the progress monitor for long running rename detection.
        Parameters:
        pm - progress monitor to receive rename detection status through.
      • setQuotePaths

        public void setQuotePaths​(boolean quote)
        Sets whether or not path names should be quoted.

        By default the setting of git config core.quotePath is active, but this can be overridden through this method.

        Parameters:
        quote - whether to quote path names
        Since:
        5.6
      • setPathFilter

        public void setPathFilter​(TreeFilter filter)
        Set the filter to produce only specific paths. If the filter is an instance of FollowFilter, the filter path will be updated during successive scan or format invocations. The updated path can be obtained from getPathFilter().
        Parameters:
        filter - the tree filter to apply.
      • getPathFilter

        public TreeFilter getPathFilter()
        Get path filter
        Returns:
        the current path filter
      • flush

        public void flush()
                   throws java.io.IOException
        Flush the underlying output stream of this formatter.
        Throws:
        java.io.IOException - the stream's own flush method threw an exception.
      • close

        public void close()

        Release the internal ObjectReader state.

        Specified by:
        close in interface java.lang.AutoCloseable
        Since:
        4.0
      • scan

        public java.util.List<DiffEntry> scan​(AnyObjectId a,
                                              AnyObjectId b)
                                       throws java.io.IOException
        Determine the differences between two trees. No output is created, instead only the file paths that are different are returned. Callers may choose to format these paths themselves, or convert them into FileHeader instances with a complete edit list by calling toFileHeader(DiffEntry).

        Either side may be null to indicate that the tree has beed added or removed. The diff will be computed against nothing.

        Parameters:
        a - the old (or previous) side or null
        b - the new (or updated) side or null
        Returns:
        the paths that are different.
        Throws:
        java.io.IOException - trees cannot be read or file contents cannot be read.
      • scan

        public java.util.List<DiffEntry> scan​(RevTree a,
                                              RevTree b)
                                       throws java.io.IOException
        Determine the differences between two trees. No output is created, instead only the file paths that are different are returned. Callers may choose to format these paths themselves, or convert them into FileHeader instances with a complete edit list by calling toFileHeader(DiffEntry).

        Either side may be null to indicate that the tree has beed added or removed. The diff will be computed against nothing.

        Parameters:
        a - the old (or previous) side or null
        b - the new (or updated) side or null
        Returns:
        the paths that are different.
        Throws:
        java.io.IOException - trees cannot be read or file contents cannot be read.
      • scan

        public java.util.List<DiffEntry> scan​(AbstractTreeIterator a,
                                              AbstractTreeIterator b)
                                       throws java.io.IOException
        Determine the differences between two trees. No output is created, instead only the file paths that are different are returned. Callers may choose to format these paths themselves, or convert them into FileHeader instances with a complete edit list by calling toFileHeader(DiffEntry).
        Parameters:
        a - the old (or previous) side.
        b - the new (or updated) side.
        Returns:
        the paths that are different.
        Throws:
        java.io.IOException - trees cannot be read or file contents cannot be read.
      • detectRenames

        private java.util.List<DiffEntry> detectRenames​(java.util.List<DiffEntry> files)
                                                 throws java.io.IOException
        Throws:
        java.io.IOException
      • isAdd

        private boolean isAdd​(java.util.List<DiffEntry> files)
      • updateFollowFilter

        private java.util.List<DiffEntry> updateFollowFilter​(java.util.List<DiffEntry> files)
      • isRename

        private static boolean isRename​(DiffEntry ent)
      • format

        public void format​(AnyObjectId a,
                           AnyObjectId b)
                    throws java.io.IOException
        Format the differences between two trees. The patch is expressed as instructions to modify a to make it b.

        Either side may be null to indicate that the tree has beed added or removed. The diff will be computed against nothing.

        Parameters:
        a - the old (or previous) side or null
        b - the new (or updated) side or null
        Throws:
        java.io.IOException - trees cannot be read, file contents cannot be read, or the patch cannot be output.
      • format

        public void format​(RevTree a,
                           RevTree b)
                    throws java.io.IOException
        Format the differences between two trees. The patch is expressed as instructions to modify a to make it b.

        Either side may be null to indicate that the tree has beed added or removed. The diff will be computed against nothing.

        Parameters:
        a - the old (or previous) side or null
        b - the new (or updated) side or null
        Throws:
        java.io.IOException - trees cannot be read, file contents cannot be read, or the patch cannot be output.
      • format

        public void format​(AbstractTreeIterator a,
                           AbstractTreeIterator b)
                    throws java.io.IOException
        Format the differences between two trees. The patch is expressed as instructions to modify a to make it b.

        Either side may be null to indicate that the tree has beed added or removed. The diff will be computed against nothing.

        Parameters:
        a - the old (or previous) side or null
        b - the new (or updated) side or null
        Throws:
        java.io.IOException - trees cannot be read, file contents cannot be read, or the patch cannot be output.
      • format

        public void format​(java.util.List<? extends DiffEntry> entries)
                    throws java.io.IOException
        Format a patch script from a list of difference entries. Requires scan(AbstractTreeIterator, AbstractTreeIterator) to have been called first.
        Parameters:
        entries - entries describing the affected files.
        Throws:
        java.io.IOException - a file's content cannot be read, or the output stream cannot be written to.
      • format

        public void format​(DiffEntry ent)
                    throws java.io.IOException
        Format a patch script for one file entry.
        Parameters:
        ent - the entry to be formatted.
        Throws:
        java.io.IOException - a file's content cannot be read, or the output stream cannot be written to.
      • quotePath

        private java.lang.String quotePath​(java.lang.String path)
      • format

        public void format​(FileHeader head,
                           RawText a,
                           RawText b)
                    throws java.io.IOException
        Format a patch script, reusing a previously parsed FileHeader.

        This formatter is primarily useful for editing an existing patch script to increase or reduce the number of lines of context within the script. All header lines are reused as-is from the supplied FileHeader.

        Parameters:
        head - existing file header containing the header lines to copy.
        a - text source for the pre-image version of the content. This must match the content of DiffEntry.getOldId().
        b - text source for the post-image version of the content. This must match the content of DiffEntry.getNewId().
        Throws:
        java.io.IOException - writing to the supplied stream failed.
      • format

        public void format​(EditList edits,
                           RawText a,
                           RawText b)
                    throws java.io.IOException
        Formats a list of edits in unified diff format
        Parameters:
        edits - some differences which have been calculated between A and B
        a - the text A which was compared
        b - the text B which was compared
        Throws:
        java.io.IOException
      • writeContextLine

        protected void writeContextLine​(RawText text,
                                        int line)
                                 throws java.io.IOException
        Output a line of context (unmodified line).
        Parameters:
        text - RawText for accessing raw data
        line - the line number within text
        Throws:
        java.io.IOException
      • isEndOfLineMissing

        private static boolean isEndOfLineMissing​(RawText text,
                                                  int line)
      • writeAddedLine

        protected void writeAddedLine​(RawText text,
                                      int line)
                               throws java.io.IOException
        Output an added line.
        Parameters:
        text - RawText for accessing raw data
        line - the line number within text
        Throws:
        java.io.IOException
      • writeRemovedLine

        protected void writeRemovedLine​(RawText text,
                                        int line)
                                 throws java.io.IOException
        Output a removed line
        Parameters:
        text - RawText for accessing raw data
        line - the line number within text
        Throws:
        java.io.IOException
      • writeHunkHeader

        protected void writeHunkHeader​(int aStartLine,
                                       int aEndLine,
                                       int bStartLine,
                                       int bEndLine)
                                throws java.io.IOException
        Output a hunk header
        Parameters:
        aStartLine - within first source
        aEndLine - within first source
        bStartLine - within second source
        bEndLine - within second source
        Throws:
        java.io.IOException
      • writeRange

        private void writeRange​(char prefix,
                                int begin,
                                int cnt)
                         throws java.io.IOException
        Throws:
        java.io.IOException
      • writeLine

        protected void writeLine​(char prefix,
                                 RawText text,
                                 int cur)
                          throws java.io.IOException
        Write a standard patch script line.
        Parameters:
        prefix - prefix before the line, typically '-', '+', ' '.
        text - the text object to obtain the line from.
        cur - line number to output.
        Throws:
        java.io.IOException - the stream threw an exception while writing to it.
      • toFileHeader

        public FileHeader toFileHeader​(DiffEntry ent)
                                throws java.io.IOException,
                                       CorruptObjectException,
                                       MissingObjectException
        Creates a FileHeader representing the given DiffEntry

        This method does not use the OutputStream associated with this DiffFormatter instance. It is therefore safe to instantiate this DiffFormatter instance with a DisabledOutputStream if this method is the only one that will be used.

        Parameters:
        ent - the DiffEntry to create the FileHeader for
        Returns:
        a FileHeader representing the DiffEntry. The FileHeader's buffer will contain only the header of the diff output. It will also contain one HunkHeader.
        Throws:
        java.io.IOException - the stream threw an exception while writing to it, or one of the blobs referenced by the DiffEntry could not be read.
        CorruptObjectException - one of the blobs referenced by the DiffEntry is corrupt.
        MissingObjectException - one of the blobs referenced by the DiffEntry is missing.
      • assertHaveReader

        private void assertHaveReader()
      • formatGitDiffFirstHeaderLine

        protected void formatGitDiffFirstHeaderLine​(java.io.ByteArrayOutputStream o,
                                                    DiffEntry.ChangeType type,
                                                    java.lang.String oldPath,
                                                    java.lang.String newPath)
                                             throws java.io.IOException
        Output the first header line
        Parameters:
        o - The stream the formatter will write the first header line to
        type - The DiffEntry.ChangeType
        oldPath - old path to the file
        newPath - new path to the file
        Throws:
        java.io.IOException - the stream threw an exception while writing to it.
      • formatHeader

        private void formatHeader​(java.io.ByteArrayOutputStream o,
                                  DiffEntry ent)
                           throws java.io.IOException
        Throws:
        java.io.IOException
      • formatIndexLine

        protected void formatIndexLine​(java.io.OutputStream o,
                                       DiffEntry ent)
                                throws java.io.IOException
        Format index line
        Parameters:
        o - the stream the formatter will write line data to
        ent - the DiffEntry to create the FileHeader for
        Throws:
        java.io.IOException - writing to the supplied stream failed.
      • formatOldNewPaths

        private void formatOldNewPaths​(java.io.ByteArrayOutputStream o,
                                       DiffEntry ent)
                                throws java.io.IOException
        Throws:
        java.io.IOException
      • findCombinedEnd

        private int findCombinedEnd​(java.util.List<Edit> edits,
                                    int i)
      • combineA

        private boolean combineA​(java.util.List<Edit> e,
                                 int i)
      • combineB

        private boolean combineB​(java.util.List<Edit> e,
                                 int i)
      • end

        private static boolean end​(Edit edit,
                                   int a,
                                   int b)