Top Description Inners Fields Constructors Methods
org.eclipse.jgit.blame

public Class BlameGenerator

extends Object
implements AutoCloseable
Class Inheritance
All Implemented Interfaces
java.lang.AutoCloseable
Static Imports
org.eclipse.jgit.lib.Constants.OBJ_BLOB, .FileMode.TYPE_FILE, .FileMode.TYPE_MASK

Generate author information for lines based on a provided file.

Applications that want a simple one-shot computation of blame for a file should use computeBlameResult() to prepare the entire result in one method call. This may block for significant time as the history of the repository must be traversed until information is gathered for every line.

Applications that want more incremental update behavior may use either the raw next() streaming approach supported by this class, or construct a org.eclipse.jgit.blame.BlameResult using org.eclipse.jgit.blame.BlameResult#create(BlameGenerator) and incrementally construct the result with org.eclipse.jgit.blame.BlameResult#computeNext().

This class is not thread-safe.

An instance of BlameGenerator can only be used once. To blame multiple files the application must create a new BlameGenerator.

During blame processing there are two files involved:

The blame algorithm is implemented by initially assigning responsibility for all lines of the result to the starting commit. A difference against the commit's ancestor is computed, and responsibility is passed to the ancestor commit for any lines that are common. The starting commit is blamed only for the lines that do not appear in the ancestor, if any. The loop repeats using the ancestor, until there are no more lines to acquire information on, or the file's creation point is discovered in history.

Nested and Inner Type Summary

Modifier and TypeClass and Description
public static class
BlameGenerator.Stats

Stats about the work done by the generator

Field Summary

Modifier and TypeField and Description
private final BlameCache
private DiffAlgorithm
private final MutableObjectId
private Candidate
outCandidate

Blame is currently assigned to this source.

private Region
private Candidate
queue

Potential candidates, sorted by commit time descending.

private ObjectReader
private int
remaining

Number of lines that still need to be discovered.

private RenameDetector
private final Repository
private final PathFilter
private RevWalk
revPool

Revision pool used to acquire commits from.

private RevFlag
SEEN

Indicates the commit was put into the queue at least once.

private final BlameGenerator.Stats
private RawTextComparator
private TreeWalk
private boolean
useCache

Blame in reverse order needs the source lines, but we don't have them in the cache.

Constructor Summary

AccessConstructor and Description
public
BlameGenerator(Repository
repository to access revision data from.
repository
,
String
initial path of the file to start scanning (relative to the repository).
path
)

Create a blame generator for the repository and path (relative to repository)

public
BlameGenerator(Repository
repository to access revision data from.
repository
,
String
initial path of the file to start scanning (relative to the repository).
path
,
BlameCache
previously calculated blames. This generator will *not* populate it, just consume it.
blameCache
)

Create a blame generator for the repository and path (relative to repository)

Method Summary

Modifier and TypeMethod and Description
private boolean
public void
close()

Implements java.lang.AutoCloseable.close.

Closes this resource, relinquishing any underlying resources.

public BlameResult

Returns:

the complete result. Null if no file exists for the given path.
computeBlameResult
()

Execute the generator in a blocking fashion until all data is ready.

private boolean
done()

private boolean
find(RevCommit commit, PathFilter path)

private DiffEntry
findRename(RevCommit parent, RevCommit commit, PathFilter path)

private static byte[]
getBytes(String path, InputStream in, long maxLength)

private List<RevCommit>
public int

Returns:

number of lines in the current region being blamed to getSourceCommit(). This is always the value of the expression getResultEnd() - getResultStart(), but also getSourceEnd() - getSourceStart().
getRegionLength
()

Get number of lines in the current region being blamed to getSourceCommit()

public RenameDetector

Returns:

the rename detector, or null if setFollowFileRenames(false).
getRenameDetector
()

Obtain the RenameDetector, allowing the application to configure its settings for rename score and breaking behavior.

public int

Returns:

rename score if a rename occurred in getSourceCommit
getRenameScore
()

Get rename score

public Repository

Returns:

repository being scanned for revision history
getRepository
()

Get repository

public RawText

Returns:

complete file contents of the result file blame is annotating. This value is accessible only after being configured and only immediately before the first call to next(). Returns null if the path does not exist.
getResultContents
()

Get complete file contents of the result file blame is annotating

public int

Returns:

one past the range of the result that getSourceCommit() has been blamed for providing. Line numbers use 0 based indexing. Because a source cannot be blamed for an empty region of the result, getResultEnd() is always at least one larger than getResultStart().
getResultEnd
()

Get one past the range of the result that getSourceCommit() has been blamed for providing

public String

Returns:

path file path being processed
getResultPath
()

Get result path

public int

Returns:

first line of the result that getSourceCommit() has been blamed for providing. Line numbers use 0 based indexing.
getResultStart
()

Get first line of the result that getSourceCommit() has been blamed for providing

public PersonIdent

Returns:

current author being blamed
getSourceAuthor
()

Get source author

public RevCommit

Returns:

current revision being blamed.
getSourceCommit
()

Get the revision blamed for the current region.

public PersonIdent

Returns:

current committer being blamed
getSourceCommitter
()

Get source committer

public RawText

Returns:

complete contents of the source file blamed for the current output region. This is the contents of getSourcePath() within getSourceCommit(). The source contents is temporarily available as an artifact of the blame algorithm. Most applications will want the result contents for display to users.
getSourceContents
()

Get complete contents of the source file blamed for the current output region

public int

Returns:

one past the range of the source data that has been blamed for the current region. This is line number of where the region was added during getSourceCommit() in file getSourcePath().
getSourceEnd
()

Get one past the range of the source data that has been blamed for the current region

This value is not reliable when the generator is reusing cached values.

public String

Returns:

path of the file being blamed
getSourcePath
()

Get source path

public int

Returns:

first line of the source data that has been blamed for the current region. This is line number of where the region was added during getSourceCommit() in file getSourcePath().
getSourceStart
()

Get first line of the source data that has been blamed for the current region

This value is not reliable when the generator is reusing cached values.

public BlameGenerator.Stats

Returns:

the stats of this generator
getStats
()

Stats about this generator

private void
initRevPool(boolean reverse)

private static final boolean
isFile(int rawMode)

private static boolean
public RevFlag

Returns:

the newly allocated flag.
newFlag
(String
unique name of the flag in the blame context.
name
)

Allocate a new RevFlag for use by the caller.

public boolean

Returns:

true if the generator has found a region's source. The getSource* and getResultStart(), getResultEnd() methods can be used to inspect the region found. False if there are no more regions to describe.
next
()

Step the blame algorithm one iteration.

private Candidate
pop()

public BlameGenerator

Returns:

this
prepareHead
()

Pushes HEAD, index, and working tree as appropriate for blaming the file given in the constructor BlameGenerator(Repository, String) against HEAD.

private boolean
private boolean
public BlameGenerator

Returns:

this
push
(String
description of the blob revision, such as "Working Tree".
description
,
byte[]
contents of the file.
contents
)

Push a candidate blob onto the generator's traversal stack.

public BlameGenerator

Returns:

this
push
(String
description of the blob revision, such as "Working Tree".
description
,
RawText
contents of the file.
contents
)

Push a candidate blob onto the generator's traversal stack.

public BlameGenerator

Returns:

this
push
(String
description of the blob revision, such as "Working Tree".
description
,
AnyObjectId
may be a commit or a blob.
id
)

Push a candidate object onto the generator's traversal stack.

private void
private void
push(Candidate toInsert)

private boolean
public BlameGenerator

Returns:

this
reverse
(AnyObjectId
oldest commit to traverse from. The result file will be loaded from this commit's tree.
start
,
AnyObjectId
most recent commit to stop traversal at. Usually an active branch tip, tag, or HEAD.
end
)

Configure the generator to compute reverse blame (history of deletes).

public BlameGenerator

Returns:

this
reverse
(AnyObjectId
oldest commit to traverse from. The result file will be loaded from this commit's tree.
start
,
Collection<? extends ObjectId>
most recent commits to stop traversal at. Usually an active branch tip, tag, or HEAD.
end
)

Configure the generator to compute reverse blame (history of deletes).

private boolean
public BlameGenerator

Returns:

this
setDiffAlgorithm
(DiffAlgorithm algorithm)

Difference algorithm to use when comparing revisions.

public BlameGenerator

Returns:

this
setFollowFileRenames
(boolean
enable following.
follow
)

Enable (or disable) following file renames, on by default.

public BlameGenerator

Returns:

this
setTextComparator
(RawTextComparator comparator)

Text comparator to use when comparing revisions.

public void
setUseCache(boolean
should this generator use the cache.
useCache
)

Enable/disable the use of cache (if present).

private boolean
split(Candidate parent, Candidate source)

private boolean
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

blameCacheback to summary
private final BlameCache blameCache
diffAlgorithmback to summary
private DiffAlgorithm diffAlgorithm
idBufback to summary
private final MutableObjectId idBuf
outCandidateback to summary
private Candidate outCandidate

Blame is currently assigned to this source.

outRegionback to summary
private Region outRegion
queueback to summary
private Candidate queue

Potential candidates, sorted by commit time descending.

readerback to summary
private ObjectReader reader
remainingback to summary
private int remaining

Number of lines that still need to be discovered.

renameDetectorback to summary
private RenameDetector renameDetector
repositoryback to summary
private final Repository repository
resultPathback to summary
private final PathFilter resultPath
revPoolback to summary
private RevWalk revPool

Revision pool used to acquire commits from.

SEENback to summary
private RevFlag SEEN

Indicates the commit was put into the queue at least once.

statsback to summary
private final BlameGenerator.Stats stats
textComparatorback to summary
private RawTextComparator textComparator
treeWalkback to summary
private TreeWalk treeWalk
useCacheback to summary
private boolean useCache

Blame in reverse order needs the source lines, but we don't have them in the cache. We need to ignore the cache in that case.

Constructor Detail

BlameGeneratorback to summary
public BlameGenerator(Repository repository, String path)

Create a blame generator for the repository and path (relative to repository)

Parameters
repository:Repository

repository to access revision data from.

path:String

initial path of the file to start scanning (relative to the repository).

BlameGeneratorback to summary
public BlameGenerator(Repository repository, String path, BlameCache blameCache)

Create a blame generator for the repository and path (relative to repository)

Parameters
repository:Repository

repository to access revision data from.

path:String

initial path of the file to start scanning (relative to the repository).

blameCache:BlameCache

previously calculated blames. This generator will *not* populate it, just consume it.

Since
7.2

Method Detail

blameEntireRegionOnParentback to summary
private boolean blameEntireRegionOnParent(Candidate n, RevCommit parent)
closeback to summary
public void close()

Implements java.lang.AutoCloseable.close.

Doc from java.lang.AutoCloseable.close.

Closes this resource, relinquishing any underlying resources. This method is invoked automatically on objects managed by the try-with-resources statement.

Release the current blame session.

Annotations
@Override
Since
4.0
computeBlameResultback to summary
public BlameResult computeBlameResult() throws IOException

Execute the generator in a blocking fashion until all data is ready.

Returns:BlameResult

the complete result. Null if no file exists for the given path.

Exceptions
IOException:
the repository cannot be read.
doneback to summary
private boolean done()
findback to summary
private boolean find(RevCommit commit, PathFilter path) throws IOException
findRenameback to summary
private DiffEntry findRename(RevCommit parent, RevCommit commit, PathFilter path) throws IOException
getBytesback to summary
private static byte[] getBytes(String path, InputStream in, long maxLength) throws IOException
getHeadsback to summary
private List<RevCommit> getHeads(Repository repo, ObjectId head) throws NoWorkTreeException, IOException
getRegionLengthback to summary
public int getRegionLength()

Get number of lines in the current region being blamed to getSourceCommit()

Returns:int

number of lines in the current region being blamed to getSourceCommit(). This is always the value of the expression getResultEnd() - getResultStart(), but also getSourceEnd() - getSourceStart().

getRenameDetectorback to summary
public RenameDetector getRenameDetector()

Obtain the RenameDetector, allowing the application to configure its settings for rename score and breaking behavior.

Returns:RenameDetector

the rename detector, or null if setFollowFileRenames(false).

Annotations
@Nullable
getRenameScoreback to summary
public int getRenameScore()

Get rename score

Returns:int

rename score if a rename occurred in getSourceCommit

getRepositoryback to summary
public Repository getRepository()

Get repository

Returns:Repository

repository being scanned for revision history

getResultContentsback to summary
public RawText getResultContents() throws IOException

Get complete file contents of the result file blame is annotating

Returns:RawText

complete file contents of the result file blame is annotating. This value is accessible only after being configured and only immediately before the first call to next(). Returns null if the path does not exist.

Exceptions
IOException:
repository cannot be read.
IllegalStateException:
next() has already been invoked.
getResultEndback to summary
public int getResultEnd()

Get one past the range of the result that getSourceCommit() has been blamed for providing

Returns:int

one past the range of the result that getSourceCommit() has been blamed for providing. Line numbers use 0 based indexing. Because a source cannot be blamed for an empty region of the result, getResultEnd() is always at least one larger than getResultStart().

getResultPathback to summary
public String getResultPath()

Get result path

Returns:String

path file path being processed

getResultStartback to summary
public int getResultStart()

Get first line of the result that getSourceCommit() has been blamed for providing

Returns:int

first line of the result that getSourceCommit() has been blamed for providing. Line numbers use 0 based indexing.

getSourceAuthorback to summary
public PersonIdent getSourceAuthor()

Get source author

Returns:PersonIdent

current author being blamed

getSourceCommitback to summary
public RevCommit getSourceCommit()

Get the revision blamed for the current region.

The source commit may be null if the line was blamed to an uncommitted revision, such as the working tree copy, or during a reverse blame if the line survives to the end revision (e.g. the branch tip).

Returns:RevCommit

current revision being blamed.

getSourceCommitterback to summary
public PersonIdent getSourceCommitter()

Get source committer

Returns:PersonIdent

current committer being blamed

getSourceContentsback to summary
public RawText getSourceContents()

Get complete contents of the source file blamed for the current output region

Returns:RawText

complete contents of the source file blamed for the current output region. This is the contents of getSourcePath() within getSourceCommit(). The source contents is temporarily available as an artifact of the blame algorithm. Most applications will want the result contents for display to users.

getSourceEndback to summary
public int getSourceEnd()

Get one past the range of the source data that has been blamed for the current region

This value is not reliable when the generator is reusing cached values. Cache doesn't keep the source lines, the returned value is based on the result and can be off if the region moved in previous commits.

Returns:int

one past the range of the source data that has been blamed for the current region. This is line number of where the region was added during getSourceCommit() in file getSourcePath().

getSourcePathback to summary
public String getSourcePath()

Get source path

Returns:String

path of the file being blamed

getSourceStartback to summary
public int getSourceStart()

Get first line of the source data that has been blamed for the current region

This value is not reliable when the generator is reusing cached values. Cache doesn't keep the source lines, the returned value is based on the result and can be off if the region moved in previous commits.

Returns:int

first line of the source data that has been blamed for the current region. This is line number of where the region was added during getSourceCommit() in file getSourcePath().

getStatsback to summary
public BlameGenerator.Stats getStats()

Stats about this generator

Returns:BlameGenerator.Stats

the stats of this generator

Since
7.2
initRevPoolback to summary
private void initRevPool(boolean reverse)
isFileback to summary
private static final boolean isFile(int rawMode)
isRenameback to summary
private static boolean isRename(DiffEntry ent)
newFlagback to summary
public RevFlag newFlag(String name)

Allocate a new RevFlag for use by the caller.

Parameters
name:String

unique name of the flag in the blame context.

Returns:RevFlag

the newly allocated flag.

Since
3.4
nextback to summary
public boolean next() throws IOException

Step the blame algorithm one iteration.

Returns:boolean

true if the generator has found a region's source. The getSource* and getResultStart(), getResultEnd() methods can be used to inspect the region found. False if there are no more regions to describe.

Exceptions
IOException:
repository cannot be read.
popback to summary
private Candidate pop()
prepareHeadback to summary
public BlameGenerator prepareHead() throws NoHeadException, IOException

Pushes HEAD, index, and working tree as appropriate for blaming the file given in the constructor BlameGenerator(Repository, String) against HEAD. Includes special handling in case the file is in conflict state from an unresolved merge conflict.

Returns:BlameGenerator

this

Exceptions
NoHeadException:
if the repository has no HEAD
IOException:
if an error occurs
Since
5.6
processMergeback to summary
private boolean processMerge(Candidate n) throws IOException
processOneback to summary
private boolean processOne(Candidate n) throws IOException
pushback to summary
public BlameGenerator push(String description, byte[] contents) throws IOException

Push a candidate blob onto the generator's traversal stack.

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).

Parameters
description:String

description of the blob revision, such as "Working Tree".

contents:byte[]

contents of the file.

Returns:BlameGenerator

this

Exceptions
IOException:
the repository cannot be read.
pushback to summary
public BlameGenerator push(String description, RawText contents) throws IOException

Push a candidate blob onto the generator's traversal stack.

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).

Parameters
description:String

description of the blob revision, such as "Working Tree".

contents:RawText

contents of the file.

Returns:BlameGenerator

this

Exceptions
IOException:
the repository cannot be read.
pushback to summary
public BlameGenerator push(String description, AnyObjectId id) throws IOException

Push a candidate object onto the generator's traversal stack.

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).

Parameters
description:String

description of the blob revision, such as "Working Tree".

id:AnyObjectId

may be a commit or a blob.

Returns:BlameGenerator

this

Exceptions
IOException:
the repository cannot be read.
pushback to summary
private void push(Candidate.BlobCandidate toInsert)
pushback to summary
private void push(Candidate toInsert)
resultback to summary
private boolean result(Candidate n) throws IOException
reverseback to summary
public BlameGenerator reverse(AnyObjectId start, AnyObjectId end) throws IOException

Configure the generator to compute reverse blame (history of deletes).

This method is expensive as it immediately runs a RevWalk over the history spanning the expression start..end (end being more recent than start) and then performs the equivalent operation as push(String, AnyObjectId) to begin blame traversal from the commit named by start walking forwards through history until end blaming line deletions.

A reverse blame may produce multiple sources for the same result line, each of these is a descendant commit that removed the line, typically this occurs when the same deletion appears in multiple side branches such as due to a cherry-pick. Applications relying on reverse should use org.eclipse.jgit.blame.BlameResult as it filters these duplicate sources and only remembers the first (oldest) deletion.

Parameters
start:AnyObjectId

oldest commit to traverse from. The result file will be loaded from this commit's tree.

end:AnyObjectId

most recent commit to stop traversal at. Usually an active branch tip, tag, or HEAD.

Returns:BlameGenerator

this

Exceptions
IOException:
the repository cannot be read.
reverseback to summary
public BlameGenerator reverse(AnyObjectId start, Collection<? extends ObjectId> end) throws IOException

Configure the generator to compute reverse blame (history of deletes).

This method is expensive as it immediately runs a RevWalk over the history spanning the expression start..end (end being more recent than start) and then performs the equivalent operation as push(String, AnyObjectId) to begin blame traversal from the commit named by start walking forwards through history until end blaming line deletions.

A reverse blame may produce multiple sources for the same result line, each of these is a descendant commit that removed the line, typically this occurs when the same deletion appears in multiple side branches such as due to a cherry-pick. Applications relying on reverse should use org.eclipse.jgit.blame.BlameResult as it filters these duplicate sources and only remembers the first (oldest) deletion.

Parameters
start:AnyObjectId

oldest commit to traverse from. The result file will be loaded from this commit's tree.

end:Collection<? extends ObjectId>

most recent commits to stop traversal at. Usually an active branch tip, tag, or HEAD.

Returns:BlameGenerator

this

Exceptions
IOException:
the repository cannot be read.
reverseResultback to summary
private boolean reverseResult(Candidate parent, Candidate source) throws IOException
setDiffAlgorithmback to summary
public BlameGenerator setDiffAlgorithm(DiffAlgorithm algorithm)

Difference algorithm to use when comparing revisions.

Parameters
algorithm:DiffAlgorithm

a org.eclipse.jgit.diff.DiffAlgorithm

Returns:BlameGenerator

this

setFollowFileRenamesback to summary
public BlameGenerator setFollowFileRenames(boolean follow)

Enable (or disable) following file renames, on by default.

If true renames are followed using the standard FollowFilter behavior used by RevWalk (which matches git log --follow in the C implementation). This is not the same as copy/move detection as implemented by the C implementation's of git blame -M -C.

Parameters
follow:boolean

enable following.

Returns:BlameGenerator

this

setTextComparatorback to summary
public BlameGenerator setTextComparator(RawTextComparator comparator)

Text comparator to use when comparing revisions.

Parameters
comparator:RawTextComparator

a org.eclipse.jgit.diff.RawTextComparator

Returns:BlameGenerator

this

setUseCacheback to summary
public void setUseCache(boolean useCache)

Enable/disable the use of cache (if present). Enabled by default.

If caller need source line numbers, the generator cannot use the cache (source lines are not there). Use this method to disable the cache in that case.

Parameters
useCache:boolean

should this generator use the cache.

Since
7.2
splitback to summary
private boolean split(Candidate parent, Candidate source) throws IOException
splitBlameWithParentback to summary
private boolean splitBlameWithParent(Candidate n, RevCommit parent) throws IOException
org.eclipse.jgit.blame back to summary

public Class BlameGenerator.Stats

extends Object
Class Inheritance

Stats about the work done by the generator
Since
7.2

Field Summary

Modifier and TypeField and Description
private boolean
private int
candidatesVisited

Candidates taken from the queue

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
public int

Returns:

number of candidates taken from the queue
getCandidatesVisited
()

Number of candidates taken from the queue

The generator could signal it's done without exhausting all candidates if there is no more remaining lines or the last visited candidate is found in the cache.

public boolean

Returns:

true if we used results from the cache
isCacheHit
()

The generator found a blamed version in the cache

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

cacheHitback to summary
private boolean cacheHit
candidatesVisitedback to summary
private int candidatesVisited

Candidates taken from the queue

Constructor Detail

Statsback to summary
public Stats()

Method Detail

getCandidatesVisitedback to summary
public int getCandidatesVisited()

Number of candidates taken from the queue

The generator could signal it's done without exhausting all candidates if there is no more remaining lines or the last visited candidate is found in the cache.

Returns:int

number of candidates taken from the queue

isCacheHitback to summary
public boolean isCacheHit()

The generator found a blamed version in the cache

Returns:boolean

true if we used results from the cache