سؤال

منذ الظهر كنت أبحث عن نظام تحكم الإصدار الموزع الموزع في جافاوأعتقد أنني قد وجدت ذلك جي جي جي, ، وهو تطبيق جافا النقي لجيت. ومع ذلك، لا يوجد الكثير في طريقة نموذج التعليمات البرمجية أو البرامج التعليمية.

كيف يمكنني استخدام JGIT لاسترداد إصدار الرأس من ملف معين (تماما مثل svn cat أو hg cat هل تفعل)؟

أفترض أن هذا ينطوي على بعض المشي الشجرة وأبحث عن عينة من التعليمات البرمجية.

هل كانت مفيدة؟

المحلول

لسوء الحظ، لا تعمل إجابة 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)

أتمنى لو كان أبسط.

نصائح أخرى

إليك إصدار أبسط من إجابة @ Morisil، وذلك باستخدام بعض المفاهيم من الضحك واختباره مع 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 هو كائن مستودع كما تم إنشاؤه في الإجابات الأخرى.

لقد تابعت الإجابة @ Thilo's و @ 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 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();

لقد بدأت في كتابة مكتبة تسمى gittective. يحتوي ذلك على العديد من المساعدين للعمل مع النقطات والتنزف والأشجار باستخدام JGIT ويتم ترخيص معهد ماساتشوستس للتكنولوجيا والمتاحة على 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");

فرق اثنين من الملفات

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

مزيد من الأمثلة على المرافق المقدمة مفصلة في التمهيدي.

هناك بعض المعلومات في JGIT Tutorial. (ولكن هذا أيضا ليس مفيدا حقا ولا يكتمل وربما قديمة منذ أن تحولت إلى كسوف حيث لا توجد وثائق متاحة بعد).

يمكنك قراءة محتوى FilePath المعطى على النحو التالي. يرجى أن تدرك أن therewalk يمكن أن يكون باطل إذا لم يتم العثور على مسار في الشجرة المحددة. لذلك يتطلب بعض المناولة المحددة.

public String readFile(RevCommit commit, String filepath) throws IOException {
    try (TreeWalk walk = TreeWalk.forPath(repo, filepath, commit.getTree())) {
        if (walk != null) {
            byte[] bytes = repo.open(walk.getObjectId(0)).getBytes();
            return new String(bytes, StandardCharsets.UTF_8);
        } else {
            throw new IllegalArgumentException("No path found.");
        }
    }
}

علي سبيل المثال:

ObjectId head = repo.resolve(Constants.HEAD);
RevCommit last = repo.parseCommit(head);
readFile(last, "docs/README.md")

تتم كتابة هذه الإجابة مع JGIT 4.8.0.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top