public class BlameGenerator extends Object implements AutoCloseable
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 BlameResult
using BlameResult.create(BlameGenerator)
and
incrementally construct the result with 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.
Constructor and Description |
---|
BlameGenerator(Repository repository,
String path)
Create a blame generator for the repository and path (relative to
repository)
|
Modifier and Type | Method and Description |
---|---|
void |
close()
Release the current blame session.
|
BlameResult |
computeBlameResult()
Execute the generator in a blocking fashion until all data is ready.
|
int |
getRegionLength() |
RenameDetector |
getRenameDetector()
Obtain the RenameDetector if
setFollowFileRenames(true) . |
int |
getRenameScore() |
Repository |
getRepository() |
RawText |
getResultContents() |
int |
getResultEnd() |
String |
getResultPath() |
int |
getResultStart() |
PersonIdent |
getSourceAuthor() |
RevCommit |
getSourceCommit()
Get the revision blamed for the current region.
|
PersonIdent |
getSourceCommitter() |
RawText |
getSourceContents() |
int |
getSourceEnd() |
String |
getSourcePath() |
int |
getSourceStart() |
RevFlag |
newFlag(String name)
Allocate a new RevFlag for use by the caller.
|
boolean |
next()
Step the blame algorithm one iteration.
|
BlameGenerator |
push(String description,
AnyObjectId id)
Push a candidate object onto the generator's traversal stack.
|
BlameGenerator |
push(String description,
byte[] contents)
Push a candidate blob onto the generator's traversal stack.
|
BlameGenerator |
push(String description,
RawText contents)
Push a candidate blob onto the generator's traversal stack.
|
BlameGenerator |
reverse(AnyObjectId start,
AnyObjectId end)
Configure the generator to compute reverse blame (history of deletes).
|
BlameGenerator |
reverse(AnyObjectId start,
Collection<? extends ObjectId> end)
Configure the generator to compute reverse blame (history of deletes).
|
BlameGenerator |
setDiffAlgorithm(DiffAlgorithm algorithm)
Difference algorithm to use when comparing revisions.
|
BlameGenerator |
setFollowFileRenames(boolean follow)
Enable (or disable) following file renames, on by default.
|
BlameGenerator |
setTextComparator(RawTextComparator comparator)
Text comparator to use when comparing revisions.
|
public BlameGenerator(Repository repository, String path)
repository
- repository to access revision data from.path
- initial path of the file to start scanning (relative to the
repository).public Repository getRepository()
public String getResultPath()
public BlameGenerator setDiffAlgorithm(DiffAlgorithm algorithm)
algorithm
- this
public BlameGenerator setTextComparator(RawTextComparator comparator)
comparator
- this
public BlameGenerator setFollowFileRenames(boolean follow)
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
.
follow
- enable following.this
public RenameDetector getRenameDetector()
setFollowFileRenames(true)
.public BlameGenerator push(String description, byte[] contents) throws IOException
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).
description
- description of the blob revision, such as "Working Tree".contents
- contents of the file.this
IOException
- the repository cannot be read.public BlameGenerator push(String description, RawText contents) throws IOException
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).
description
- description of the blob revision, such as "Working Tree".contents
- contents of the file.this
IOException
- the repository cannot be read.public BlameGenerator push(String description, AnyObjectId id) throws IOException
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).
description
- description of the blob revision, such as "Working Tree".id
- may be a commit or a blob.this
IOException
- the repository cannot be read.public BlameGenerator reverse(AnyObjectId start, AnyObjectId end) throws IOException
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
BlameResult
as it filters these duplicate sources and only
remembers the first (oldest) deletion.
start
- oldest commit to traverse from. The result file will be loaded
from this commit's tree.end
- most recent commit to stop traversal at. Usually an active
branch tip, tag, or HEAD.this
IOException
- the repository cannot be read.public BlameGenerator reverse(AnyObjectId start, Collection<? extends ObjectId> end) throws IOException
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
BlameResult
as it filters these duplicate sources and only
remembers the first (oldest) deletion.
start
- oldest commit to traverse from. The result file will be loaded
from this commit's tree.end
- most recent commits to stop traversal at. Usually an active
branch tip, tag, or HEAD.this
IOException
- the repository cannot be read.public RevFlag newFlag(String name)
name
- unique name of the flag in the blame context.public BlameResult computeBlameResult() throws IOException
IOException
- the repository cannot be read.public boolean next() throws IOException
getResultStart()
, getResultEnd()
methods
can be used to inspect the region found. False if there are no
more regions to describe.IOException
- repository cannot be read.public RevCommit getSourceCommit()
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).
public PersonIdent getSourceAuthor()
public PersonIdent getSourceCommitter()
public String getSourcePath()
public int getRenameScore()
getSourceCommit()
.public int getSourceStart()
getSourceCommit()
in file
getSourcePath()
.public int getSourceEnd()
getSourceCommit()
in file
getSourcePath()
.public int getResultStart()
getSourceCommit()
has been
blamed for providing. Line numbers use 0 based indexing.public int getResultEnd()
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()
.public int getRegionLength()
getSourceCommit()
. This is always the value of the
expression getResultEnd() - getResultStart()
, but also
getSourceEnd() - getSourceStart()
.public RawText getSourceContents()
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.public RawText getResultContents() throws IOException
next()
. Returns
null if the path does not exist.IOException
- repository cannot be read.IllegalStateException
- next()
has already been invoked.public void close()
close
in interface AutoCloseable
Copyright © 2015 Eclipse JGit Project. All rights reserved.