Wie kann man eine Datei in JGit „kategorisieren“?

Lesezeit: 6 Minuten

Wie kann man eine Datei in JGit „kategorisieren
Thilo

Vor einiger Zeit suchte ich nach einem integrierbaren verteilten Versionskontrollsystem in Java, und ich glaube, ich habe es gefunden JGit, die eine reine Java-Implementierung von git ist. Es gibt jedoch nicht viel Beispielcode oder Tutorials.

Wie kann ich JGit verwenden, um die HEAD-Version einer bestimmten Datei abzurufen (genau wie svn cat oder hg cat wer tun)?

Ich nehme an, dies beinhaltet ein gewisses Rev-Tree-Walking und suche nach einem Codebeispiel.

Wie kann man eine Datei in JGit „kategorisieren
Morisil

Leider funktioniert Thilos Antwort nicht mit der neuesten JGit-API. Hier ist die Lösung, die ich gefunden habe:

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)

Ich wünschte, es wäre einfacher.

  • Wer in aller Welt hat diese API entwickelt?

    – Joch

    19. April 2012 um 22:59 Uhr

  • Wissen Sie, was der n-te Wert von treeWalk.getObjectId(nth) bewirkt? (dh in welchen Fällen übergeben wir einen Wert größer als 0 an treeWalk.getObjectId?)

    – Dinis Cruz

    15. Juli 2013 um 22:50 Uhr

  • @DinisCruz TreeWalk kann über mehr als einen Baum laufen (indem man ruft addTree mehrmals). In diesem Fall können Sie verwenden getObjectId(N) um die Objekt-ID von Baum N zu erhalten (die je nach Baum gleich oder unterschiedlich sein kann).

    – Robinst

    16. August 2013 um 13:07 Uhr

  • In Creinigs Antwort erfahren Sie, wie Sie dies ein wenig vereinfachen können, indem Sie verwenden TreeWalk.forPath.

    – Robinst

    16. August 2013 um 13:10 Uhr

  • Wie kann ich die Ausgabe von speichern loader in eine Variable?

    – Evgenij Reznik

    26. August 2014 um 22:31 Uhr

1647276488 513 Wie kann man eine Datei in JGit „kategorisieren
kräuseln

Hier ist eine einfachere Version von @morisils Antwort, die einige der Konzepte von @directed laughs verwendet und mit JGit 2.2.0 getestet wurde:

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.close();
    }
}

repo ist ein Repository-Objekt, wie es in den anderen Antworten erstellt wurde.

  • Sieht gut aus, außer dass getBytes() zurückgegeben wird, während der Rückgabetyp String ist. Beachten Sie, dass Sie auch anrufen müssen release an walk und treeWalk zum Freigeben von Ressourcen. Um das erst einmal machen zu müssen, rufen Sie an ObjectReader reader = repo.newObjectReader() und übergeben Sie diese an Revwalk und Treewalk anstelle des Repositorys. Dann ruf an reader.release() in einem Endgültig-Block.

    – Robinst

    16. August 2013 um 13:03 Uhr

  • RevWalk muss auch freigegeben werden, verschieben Sie den Anruf nach newObjectReader auf und verwenden new RevWalk(reader) stattdessen.

    – Robinst

    4. September 2013 um 11:02 Uhr

  • Ein weiterer Kommentar (sorry :)), this.repo.open sollte auch ersetzt werden durch reader.open.

    – Robinst

    4. September 2013 um 13:48 Uhr

  • @robinst: Behoben. Und Sie können die Antwort nach Bedarf bearbeiten;)

    – kräuseln

    5. September 2013 um 7:16 Uhr

Ich bin der Antwort von @Thilo und @morisil gefolgt, um dies zu erhalten, kompatibel mit 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();

Ich habe die Java-Version nicht getestet, aber es sollte funktionieren. Es übersetzt aus

(.getBytes (.open repo (.getObjectId (TreeWalk/forPath repo "b/test.txt" tree) 0)))

in Clojure (nach dem gleichen Aufbau wie der obere Abschnitt), was funktioniert.

  • Funktioniert super! Ich ging direkt zur Datei: FileOutputStream fileOS = new FileOutputStream(path); if (treewalk != null){repo.open(treewalk.getObjectId(0)).copyTo(fileOS);} dann fileOS.close;

    – Mark Mikofski

    9. Oktober 2013 um 7:53 Uhr

  • Weitere Java-Fragen sollten in Clojure beantwortet werden.

    – Benutzer12341234

    13. Oktober 2017 um 13:27 Uhr

Habe es selbst herausgefunden. Die API ist ziemlich niedrig, aber es ist nicht so schlimm:

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

Ich habe angefangen, eine Bibliothek namens zu schreiben gitektiv das viele Helfer für die Arbeit mit Blobs, Commits und Bäumen mit JGit enthält und MIT-lizenziert und auf GitHub verfügbar ist.

Holen Sie sich den Inhalt der Datei im HEAD-Commit

Repository repo = new FileRepository("/repos/project/.git");
String content = BlobUtils.getHeadContent(repo, "src/Buffer.java");

Holen Sie sich den Inhalt einer Datei in einem Zweig

Repository repo = new FileRepository("/repos/project/.git");
String content = BlobUtils.getContent(repo, "master", "src/Buffer.java");

Diff zwei Dateien

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

Weitere Beispiele für bereitgestellte Dienstprogramme finden Sie in der Liesmich.

  • Es sieht gut aus. Wenn ich mein jGit-Projekt nicht bereits geschrieben hätte, hätte ich dies definitiv verwendet.

    – Jason Wheeler

    25. Juli 2013 um 21:58 Uhr

1647276489 663 Wie kann man eine Datei in JGit „kategorisieren
Zittern

Es gibt einige Infos unter JGit-Tutorial (Aber das ist auch weder wirklich hilfreich noch vollständig und wahrscheinlich veraltet, seit sie auf gewechselt haben Finsternis wo noch keine Dokumentation verfügbar ist).

  • Es sieht gut aus. Wenn ich mein jGit-Projekt nicht bereits geschrieben hätte, hätte ich dies definitiv verwendet.

    – Jason Wheeler

    25. Juli 2013 um 21:58 Uhr

1647276490 35 Wie kann man eine Datei in JGit „kategorisieren
Mincong Huang

Sie können den Inhalt eines bestimmten Dateipfads wie folgt lesen. Bitte beachten Sie, dass der TreeWalk sein kann Null wenn im angegebenen Baum kein Pfad gefunden wurde. Es erfordert also eine spezielle Handhabung.

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.");
        }
    }
}

Zum Beispiel:

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

Diese Antwort wurde mit JGit 4.8.0 geschrieben.

1002410cookie-checkWie kann man eine Datei in JGit „kategorisieren“?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy