Question

Un peu en arrière, je cherchais une intégrable système de contrôle de version distribuée en Java , et je pense que je l'ai trouvé dans JGit , ce qui est une implémentation pure Java de git. Cependant, il n'y a pas beaucoup de la manière d'exemples de code ou des tutoriels.

Comment puis-je utiliser JGit pour récupérer la version HEAD d'un certain fichier (comme svn cat ou hg cat whould faire)?

Je suppose que cela implique un certain tour-arbre marche et je cherche un exemple de code.

Était-ce utile?

La solution

Malheureusement, la réponse de Thilo ne fonctionne pas avec la dernière API JGit. Voici la solution que je trouve:

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)

Je souhaite qu'il était plus simple.

Autres conseils

Voici une version simplifiée de la réponse de @ morisil, en utilisant certains des concepts de Rions @directed et testé avec 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 est un objet de référentiel tel que créé dans les autres réponses.

J'ai suivi @ de Thilo et la réponse de @ morisil pour obtenir cela, compatible avec 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();

Je n'ai pas testé la version Java, mais il devrait fonctionner. Il se traduit par de

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

dans Clojure (suivant la même configuration que la partie supérieure), qui fonctionne.

figured it out par moi-même. L'API est assez bas niveau, mais il est pas trop mal:

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

J'ai commencé à écrire une bibliothèque appelée gitective qui contient de nombreuses aides pour travailler avec des blobs, engage et arbres à l'aide JGit et est MIT-licence et disponible sur GitHub.

Obtenir le contenu du fichier dans la tête engager

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

Obtenir le contenu d'un fichier sur une branche

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

Diff deux fichiers

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

D'autres exemples de services fournis sont détaillés dans le README.

Il y a quelques informations sur JGit Tutorial (mais qui est aussi ni vraiment utile, ni complète et probablement pas à jour car ils sont passés à éclipse où aucune documentation est encore disponible).

Vous pouvez lire le contenu d'un filepath donné comme suit. S'il vous plaît noter que l'ParcoursArbre peut être null si aucun chemin a été trouvé dans l'arbre donné. Donc, il faut une certaine manipulation spécifique.

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

Par exemple:

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

Cette réponse est écrit avec JGit 4.8.0.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top