後來我一直在尋找embeddable distributed version control system in Java, ,我想我已經在JGit中找到它了,它是純粹的git實現。 但是,示例代碼或教程沒有多少內容。如何在JGit中「貓」一個文件?
如何使用JGit檢索某個文件的HEAD版本(就像svn cat
或hg cat
)?
我想這涉及到一些rev-tree-walking,並且正在尋找代碼示例。
後來我一直在尋找embeddable distributed version control system in Java, ,我想我已經在JGit中找到它了,它是純粹的git實現。 但是,示例代碼或教程沒有多少內容。如何在JGit中「貓」一個文件?
如何使用JGit檢索某個文件的HEAD版本(就像svn cat
或hg cat
)?
我想這涉及到一些rev-tree-walking,並且正在尋找代碼示例。
不幸的是,Thilo的答案不適用於最新的JGit API。這裏是我找到的解決方案:
File repoDir = new File("test-git");
// open the repository
Repository repository = new Repository(repoDir);
// find the HEAD
ObjectId lastCommitId = repository.resolve(Constants.HEAD);
// now we have to get the commit
RevWalk revWalk = new RevWalk(repository);
RevCommit commit = revWalk.parseCommit(lastCommitId);
// and using commit's tree find the path
RevTree tree = commit.getTree();
TreeWalk treeWalk = new TreeWalk(repository);
treeWalk.addTree(tree);
treeWalk.setRecursive(true);
treeWalk.setFilter(PathFilter.create(path));
if (!treeWalk.next()) {
return null;
}
ObjectId objectId = treeWalk.getObjectId(0);
ObjectLoader loader = repository.open(objectId);
// and then one can use either
InputStream in = loader.openStream()
// or
loader.copyTo(out)
我希望它更簡單。
有一些信息在JGit Tutorial(但也沒有真正的幫助也沒有完整,可能已經過時,因爲他們切換到eclipse沒有文檔可用)。
自己弄明白了。該API是相當低級的,但它不是太糟糕:
File repoDir = new File("test-git/.git");
// open the repository
Repository repo = new Repository(repoDir);
// find the HEAD
Commit head = repo.mapCommit(Constants.HEAD);
// retrieve the tree in HEAD
Tree tree = head.getTree();
// find a file (as a TreeEntry, which contains the blob object id)
TreeEntry entry = tree.findBlobMember("b/test.txt");
// use the blob id to read the file's data
byte[] data = repo.openBlob(entry.getId()).getBytes();
這似乎是當前JGit版本的過時示例。 API已經改變了一點,要小心。 – 2011-03-24 18:33:49
@Jonathan Dumaine:如有必要,請更新帖子(你知道如何) – Thilo 2011-03-25 02:29:31
我已經開始編寫一個名爲gitective的庫,其中包含許多使用JGit處理Blob,提交和樹的幫助程序,並且已獲得MIT許可並可在GitHub上獲得。在頭文件的
獲取內容提交
Repository repo = new FileRepository("/repos/project/.git");
String content = BlobUtils.getHeadContent(repo, "src/Buffer.java");
分支上獲取文件的內容
Repository repo = new FileRepository("/repos/project/.git");
String content = BlobUtils.getContent(repo, "master", "src/Buffer.java");
DIFF兩個文件
Repository repo = new FileRepository("/repos/project/.git");
ObjectId current = BlobUtils.getId(repo, "master", "Main.java");
ObjectId previous = BlobUtils.getId(repo, "master~1", "Main.java");
Collection<Edit> edit = BlobUtils.diff(repo, previous, current);
更多的實用程序示例詳見README。
它看起來不錯。如果我還沒有寫我的jGit項目,我肯定會使用它。 – 2013-07-25 21:58:18
我跟着@蒂洛的和@ morisil的回答得到這個,兼容JGit 1.2.0:
File repoDir = new File("test-git/.git");
// open the repository
Repository repo = new Repository(repoDir);
// find the HEAD
Commit head = repo.mapCommit(Constants.HEAD);
// retrieve the tree in HEAD
Tree tree = head.getTree();
// 1.2.0 api version here
// find a file (as a TreeEntry, which contains the blob object id)
TreeWalk treewalk = TreeWalk.forPath(repo, "b/test.txt", tree);
// use the blob id to read the file's data
byte[] data = repo.open(treewalk.getObjectId(0)).getBytes();
我沒有測試的Java版本,但它應該工作。它翻譯自
(.getBytes (.open repo (.getObjectId (TreeWalk/forPath repo "b/test.txt" tree) 0)))
在clojure(遵循與頂部相同的設置),它工作。
工程太棒了!我直接去了file:'FileOutputStream fileOS = new FileOutputStream(path);如果(treewalk!= null){repo.open(treewalk.getObjectId(0))。copyTo(fileOS);}'然後'fileOS.close;' – 2013-10-09 07:53:15
更多的Java問題應該在Clojure中得到解答。 – user12341234 2017-10-13 13:27:52
這裏的@ morisil的回答的一個簡化版本,使用一些從@directed笑的概念,並與JGit 2.2.0測試:
private String fetchBlob(String revSpec, String path) throws MissingObjectException, IncorrectObjectTypeException,
IOException {
// Resolve the revision specification
final ObjectId id = this.repo.resolve(revSpec);
// Makes it simpler to release the allocated resources in one go
ObjectReader reader = this.repo.newObjectReader();
try {
// Get the commit object for that revision
RevWalk walk = new RevWalk(reader);
RevCommit commit = walk.parseCommit(id);
// Get the revision's file tree
RevTree tree = commit.getTree();
// .. and narrow it down to the single file's path
TreeWalk treewalk = TreeWalk.forPath(reader, path, tree);
if (treewalk != null) {
// use the blob id to read the file's data
byte[] data = reader.open(treewalk.getObjectId(0)).getBytes();
return new String(data, "utf-8");
} else {
return "";
}
} finally {
reader.release();
}
}
repo
是在其他的答案中創建一個資源庫對象。
看起來不錯,除了在返回類型爲String時返回getBytes()。請注意,您還必須在'walk'和'treeWalk'上調用'release'來釋放資源。爲了只需要這樣做一次,調用ObjectReader reader = repo.newObjectReader()並將其傳遞給Revwalk和Treewalk,而不是存儲庫。然後在finally塊中調用'reader.release()'。 – robinst 2013-08-16 13:03:35
@robinst:非常感謝您指出 - 修復它。 – creinig 2013-09-03 11:07:57
RevWalk也需要發佈,將調用移至'newObjectReader'並改爲使用'new RevWalk(reader)'。 – robinst 2013-09-04 11:02:56
開發人員很快就可以在郵件列表上找到答案:https://dev.eclipse.org/mailman/listinfo/egit-dev。我建議你試試看。 – 2009-11-07 16:44:04