Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EGit » redundand file revisions when iterating over branches
redundand file revisions when iterating over branches [message #492473] Tue, 20 October 2009 10:47 Go to next message
Eclipse User
Originally posted by: hillner.informatik.uni-leipzig.de

Hello,

while iterating over all branches of a repository and extracting all the
revisions of one file I get redundand versions of the file in different
branches.
These branches may have cloned the file and updated it from the master
branch or another but I need each version of a file only once (in the branch
where the file was created/modified).
See my code below.

(I'm checking out each branch and loop over all RevCommits of the RevWalk.
From the RevCommit I get the ObjectId of the file revision and then I just
get the string out of the blob.)
How can I filter the revisions for a result like that which you get using
the command "gitk --all filepath"?
There each file revision is displayed only once at the graph.



public class GitFileHistory {
private Repository repo;
private RevWalk walk;
private String fileRelativePath;
private Vector<Tupel<ObjectId,String>> fileRevisionIds = new
Vector<Tupel<ObjectId,String>>();
private String currentBranch;


public GitFileHistory(File originalFile, Repository repo) throws
IOException {
this.repo = repo;
fileRelativePath =
FileUtility.getRelativePath(originalFile.getAbsoluteFile(),
this.repo.getWorkDir()).replace(File.separator, "/");
loadBranch("refs/heads/master");
for (String refName : getAllBranchNames()) {
if(refName.equals("HEAD"))
continue;
loadBranch(refName);
walk = buildWalk();
fileRevisionIds.addAll(buildRevisions());
}
loadBranch("refs/heads/master");
this.repo.close();
}

private RevWalk buildWalk() {
RevWalk walk = new RevWalk(repo);
walk.sort(RevSort.COMMIT_TIME_DESC, true);
walk.sort(RevSort.BOUNDARY, true);
walk.setTreeFilter(AndTreeFilter.create(PathFilterGroup.crea teFromStrings(Collections.singleton(fileRelativePath)),
TreeFilter.ANY_DIFF));
return walk;
}

private Vector<Tupel<ObjectId,String>> buildRevisions() throws IOException
{
Vector<Tupel<ObjectId,String>> result = new
Vector<Tupel<ObjectId,String>>();
AnyObjectId headID = repo.resolve(Constants.HEAD);
if(headID == null) {
System.err.println("NULL - headID");
return null;
}

walk.markStart(walk.parseCommit(headID));

for (RevCommit revCommit : walk) {
TreeWalk fileWalker = TreeWalk.forPath(repo, fileRelativePath,
revCommit.asCommit(walk).getTreeId());
if(fileWalker != null) {
result.add(new Tupel<ObjectId,
String>(fileWalker.getObjectId(0),currentBranch));
}
}

return result;
}

public Vector<Tupel<String,String>> getFileRevisions() throws IOException {
Vector<Tupel<String,String>> result = new Vector<Tupel<String,String>>();
ObjectDatabase db = repo.getObjectDatabase();
for (Tupel<ObjectId,String> t : fileRevisionIds) {
byte[] buffer = db.openObject(new WindowCursor(), t.getO1()).getBytes();
RawCharSequence seq = new RawCharSequence(buffer, 0, buffer.length);
result.add(new Tupel<String, String>(seq.toString(), t.getO2()));
}
return result;
}

private List<String> getAllBranchNames() {
return new ArrayList<String>(repo.getAllRefs().keySet());
}

private void loadBranch(String refName) throws IOException {
Commit commit = repo.mapCommit(refName);
Tree tree = commit.getTree();
GitIndex index = repo.getIndex();
WorkDirCheckout co = new WorkDirCheckout(repo, repo.getWorkDir(), index,
tree);
index.write();
repo.writeSymref(Constants.HEAD, refName);
currentBranch = refName;
}

public int countBranches() {
HashSet<String> branches = new HashSet<String>();
for (Tupel<ObjectId,String> t : fileRevisionIds) {
branches.add(t.getO2());
}
return branches.size();
}
}
Re: redundand file revisions when iterating over branches [message #493950 is a reply to message #492473] Wed, 28 October 2009 11:18 Go to previous messageGo to next message
Shawn O. Pearce is currently offline Shawn O. Pearce
Messages: 82
Registered: July 2009
Member
Stanley Hillner wrote:
> How can I filter the revisions for a result like that which you get
> using the command "gitk --all filepath"?

Behave like --all does, that is, feed all branches into a single RevWalk
rather than creating a unique RevWalk for each branch.

> private Vector<Tupel<ObjectId,String>> buildRevisions() throws
> IOException {
> Vector<Tupel<ObjectId,String>> result = new
> Vector<Tupel<ObjectId,String>>();
> AnyObjectId headID = repo.resolve(Constants.HEAD);
> if(headID == null) {
> System.err.println("NULL - headID");
> return null;
> }
>
> walk.markStart(walk.parseCommit(headID));

Here, instead of feeding only HEAD, feed all branches:

for (Ref ref : repo.getRefs())
walk.markStart(walk.parseCommit(ref.getObjectId());


> for (RevCommit revCommit : walk) {
> TreeWalk fileWalker = TreeWalk.forPath(repo,
> fileRelativePath, revCommit.asCommit(walk).getTreeId());

Here its better to say "revCommit.getTree()" for that last argument.
Its faster as you avoid reparsing the commit data.
Re: redundand file revisions when iterating over branches [message #499233 is a reply to message #493950] Fri, 20 November 2009 09:13 Go to previous message
Eclipse User
Originally posted by: hillner.informatik.uni-leipzig.de

Hello,

sorry this late answer but there was no reply before I started to implement
my own version of this --all behaviour.
I think this works, thanks a lot.

"Shawn Pearce" <spearce@spearce.org> schrieb im Newsbeitrag
news:hc9nc4$fl$2@build.eclipse.org...
> Stanley Hillner wrote:
>> How can I filter the revisions for a result like that which you get using
>> the command "gitk --all filepath"?
>
> Behave like --all does, that is, feed all branches into a single RevWalk
> rather than creating a unique RevWalk for each branch.
>
>> private Vector<Tupel<ObjectId,String>> buildRevisions() throws
>> IOException {
>> Vector<Tupel<ObjectId,String>> result = new
>> Vector<Tupel<ObjectId,String>>();
>> AnyObjectId headID = repo.resolve(Constants.HEAD);
>> if(headID == null) {
>> System.err.println("NULL - headID");
>> return null;
>> }
>>
>> walk.markStart(walk.parseCommit(headID));
>
> Here, instead of feeding only HEAD, feed all branches:
>
> for (Ref ref : repo.getRefs())
> walk.markStart(walk.parseCommit(ref.getObjectId());
>
>
>> for (RevCommit revCommit : walk) {
>> TreeWalk fileWalker = TreeWalk.forPath(repo,
>> fileRelativePath, revCommit.asCommit(walk).getTreeId());
>
> Here its better to say "revCommit.getTree()" for that last argument. Its
> faster as you avoid reparsing the commit data.
Re: redundand file revisions when iterating over branches [message #575542 is a reply to message #492473] Wed, 28 October 2009 11:18 Go to previous message
Shawn O. Pearce is currently offline Shawn O. Pearce
Messages: 82
Registered: July 2009
Member
Stanley Hillner wrote:
> How can I filter the revisions for a result like that which you get
> using the command "gitk --all filepath"?

Behave like --all does, that is, feed all branches into a single RevWalk
rather than creating a unique RevWalk for each branch.

> private Vector<Tupel<ObjectId,String>> buildRevisions() throws
> IOException {
> Vector<Tupel<ObjectId,String>> result = new
> Vector<Tupel<ObjectId,String>>();
> AnyObjectId headID = repo.resolve(Constants.HEAD);
> if(headID == null) {
> System.err.println("NULL - headID");
> return null;
> }
>
> walk.markStart(walk.parseCommit(headID));

Here, instead of feeding only HEAD, feed all branches:

for (Ref ref : repo.getRefs())
walk.markStart(walk.parseCommit(ref.getObjectId());


> for (RevCommit revCommit : walk) {
> TreeWalk fileWalker = TreeWalk.forPath(repo,
> fileRelativePath, revCommit.asCommit(walk).getTreeId());

Here its better to say "revCommit.getTree()" for that last argument.
Its faster as you avoid reparsing the commit data.
Re: redundand file revisions when iterating over branches [message #575729 is a reply to message #493950] Fri, 20 November 2009 09:13 Go to previous message
Eclipse User
Originally posted by: hillner.informatik.uni-leipzig.de

Hello,

sorry this late answer but there was no reply before I started to implement
my own version of this --all behaviour.
I think this works, thanks a lot.

"Shawn Pearce" <spearce@spearce.org> schrieb im Newsbeitrag
news:hc9nc4$fl$2@build.eclipse.org...
> Stanley Hillner wrote:
>> How can I filter the revisions for a result like that which you get using
>> the command "gitk --all filepath"?
>
> Behave like --all does, that is, feed all branches into a single RevWalk
> rather than creating a unique RevWalk for each branch.
>
>> private Vector<Tupel<ObjectId,String>> buildRevisions() throws
>> IOException {
>> Vector<Tupel<ObjectId,String>> result = new
>> Vector<Tupel<ObjectId,String>>();
>> AnyObjectId headID = repo.resolve(Constants.HEAD);
>> if(headID == null) {
>> System.err.println("NULL - headID");
>> return null;
>> }
>>
>> walk.markStart(walk.parseCommit(headID));
>
> Here, instead of feeding only HEAD, feed all branches:
>
> for (Ref ref : repo.getRefs())
> walk.markStart(walk.parseCommit(ref.getObjectId());
>
>
>> for (RevCommit revCommit : walk) {
>> TreeWalk fileWalker = TreeWalk.forPath(repo,
>> fileRelativePath, revCommit.asCommit(walk).getTreeId());
>
> Here its better to say "revCommit.getTree()" for that last argument. Its
> faster as you avoid reparsing the commit data.
Previous Topic:Jgit/Egit vs Git missing functionalities?
Next Topic:Author / Commiter Preference Settings / Last inputed values
Goto Forum:
  


Current Time: Tue Jul 29 08:55:18 EDT 2014

Powered by FUDForum. Page generated in 0.02502 seconds