Frage

Ich habe es geschafft, mich mit den Grundlagen der JGIT -Datei in den Griff zu bekommen, um eine Verbindung zu einem Repos herzustellen und die Leitungsnachrichten für die Dateien hinzuzufügen, zu verbringen und sogar zu schleifen.

File gitDir = new File("/Users/myname/Sites/helloworld/.git");

RepositoryBuilder builder = new RepositoryBuilder();
Repository repository;
repository = builder.setGitDir(gitDir).readEnvironment()
        .findGitDir().build();

Git git = new Git(repository);
RevWalk walk = new RevWalk(repository);
RevCommit commit = null;

// Add all files
// AddCommand add = git.add();
// add.addFilepattern(".").call();

// Commit them
// CommitCommand commit = git.commit();
// commit.setMessage("Commiting from java").call();

Iterable<RevCommit> logs = git.log().call();
Iterator<RevCommit> i = logs.iterator();

while (i.hasNext()) {
    commit = walk.parseCommit( i.next() );
    System.out.println( commit.getFullMessage() );

}

Was ich als nächstes tun möchte, ist in der Lage, alle Commit -Nachricht für eine einzelne Datei zu erhalten und dann die einzelne Datei wieder auf eine bestimmte Referenz/einen bestimmten Zeitpunkt zurückzukehren.

War es hilfreich?

Lösung

Hier erfahren

        var tree = new TreeWalk(repository)
        tree.addTree(commit.getTree)
        commit.getParents foreach {
            parent => tree.addTree(parent.getTree)
        }
        tree.setFilter(TreeFilter.ANY_DIFF)

(Scala -Code)

Beachten Sie, dass TreeFilter.any_diff für einen einzelnen Baumwanderer arbeitet und alle in einem Root Commit verfügbaren Elemente zurückgibt.

Sie müssten dann über den Baum iterieren, um festzustellen, ob sich Ihre Datei im angegebenen Delta befindet (dies ist ziemlich einfach).

    while (tree.next)
            if (tree.getDepth == cleanPath.size) {
                // we are at the right level, do what you want
            } else {
                if (tree.isSubtree &&
                    name == cleanPath(tree.getDepth)) {
                    tree.enterSubtree
                }
            }
    }

(CleanPath ist der reine Repo -Pfad, geteilt durch '/')

Wickeln Sie diesen Code nun in eine Revwwalk.Next -Schleife und Sie werden die vom Commit geänderten Commits und Dateien ändern.

Möglicherweise möchten Sie einen anderen Filter verwenden als irgendjemand, da Any_diff wahr ist, wenn sich ein Baum unterscheidet. Dies ist ein bisschen kontraintuitiv bei einer Zusammenführung, bei der sich der Blob nicht zu allen Elternbäumen änderte. Hier ist der Kern eines All_diffs, der nur Elemente zeigt, die sich von allen Elternbäumen unterscheiden:

override def include(walker: TreeWalk): Boolean = {
    val n = walker.getTreeCount();
    if (n == 1) {
        return true;
    }
    val m = walker.getRawMode(0)
    var i = 1
    while (i < n) {
        if (walker.getRawMode(i) == m && walker.idEqual(i, 0)) {
            return false
        }
        i += 1
    }
    true
}

(Scala -Code, abgeleitet von AnyDifffilter)

Andere Tipps

Also habe ich versucht, Charliesoys Lösung zur Arbeit zu bringen, und es war meistens, aber es scheiterte für mich im folgenden Fall (vielleicht hat sich in JGIT seit diesem Beitrag etwas geändert?)

Fügen Sie Filea hinzu, begehen Sie als "Commit 1" FileB, begehen Sie als "Commit 2".

getFileVersionDateList("fileA")

Beide commit 1 und commit 2 wurden gefunden, wo ich nur erwartet hatte commit 1.

Meine Lösung war wie folgt:

List<Commit> commits = new ArrayList<Commit>();

RevWalk revWalk = new RevWalk(repository);
revWalk.setTreeFilter(
        AndTreeFilter.create(
                PathFilterGroup.createFromStrings(<relative path in question>),
                TreeFilter.ANY_DIFF)
);

RevCommit rootCommit = revWalk.parseCommit(repository.resolve(Constants.HEAD));
revWalk.sort(RevSort.COMMIT_TIME_DESC);
revWalk.markStart(rootCommit);

for (RevCommit revCommit : revWalk) {
    commits.add(new GitCommit(getRepository(), revCommit));
}

Die Verwendung des Logcommand ist noch einfacher und sieht so aus:

List<Commit> commitsList = new ArrayList<Commit>();

Git git = new Git(repository);
LogCommand logCommand = git.log()
        .add(git.getRepository().resolve(Constants.HEAD))
        .addPath(<relative path in question>);

for (RevCommit revCommit : logCommand.call()) {
    commitsList.add(new GitCommit(this, revCommit));
}

Offensichtlich würden Sie auch nach Bedarf die Commit -Daten usw. überprüfen.

Der allgemeine Ansatz mit Git, um die Geschichte einer bestimmten Datei zu finden die Geschichte für einen ganzen Subtree finden). Fungieren Sie also im Wesentlichen als Filter für die Revisions -Ausgabe des Revision Walker.

Die JGIT -Dokumentation scheint ... spärlich. Sie sollten jedoch in der Lage sein, einen Revtree zu erhalten, der jedem Revcommit entspricht, und wenn Sie dies mit jedem Pfadsegment notwendigerweise durchgehen, werden in der Reihe zu einer terminalen Objekt -ID.

Araqnid ist richtig, so habe ich eine Liste von Daten erhalten, an denen jedes Datum in Bezug auf Commits die fragliche Datei enthielt ...

Anschließend können Sie die Datei von einem bestimmten Commit abrufen, wie Sie den Namen der Datei und das Datum des Commits haben. Siehe die beiden folgenden Methoden.

Hinweis: Dieser Code befindet sich in einer.

byte[] getAnyPreviousVersionFileBytes(String relativeFilePath, Date date) {

    byte[] bytes = null
    try {

        RevWalk revWalk = new RevWalk(repository)
        ObjectId headId = repository.resolve(Constants.HEAD);
        RevCommit root = revWalk.parseCommit(headId);

        revWalk.sort(RevSort.COMMIT_TIME_DESC);
        revWalk.markStart(root);

        for (RevCommit revCommit: revWalk) {

            // if date matches then walk the tree in this commit
            if (new Date(revCommit.commitTime * 1000L) == date) {

                TreeWalk treeWalk = TreeWalk.forPath(repository, relativeFilePath, revCommit.getTree())

                if (treeWalk != null) {
                    treeWalk.setRecursive(true)
                    CanonicalTreeParser canonicalTreeParser = treeWalk.getTree(0, CanonicalTreeParser)

                    while (!canonicalTreeParser.eof()) {

                        // if the filename matches, we have a match, so set teh byte array to return
                        if (canonicalTreeParser.getEntryPathString() == relativeFilePath) {
                            ObjectLoader objectLoader = repository.open(canonicalTreeParser.getEntryObjectId())
                            bytes = objectLoader.bytes
                        }
                        canonicalTreeParser.next(1)
                    }
                }
            }

        }

    }
    catch (Exception e) {
        throw new JgitException(e)
    }
    return bytes
}

List<Date> getFileVersionDateList(String relativeFilePath) {

    List<Date> versions = new LinkedList<Date>()
    try {

        RevWalk revWalk = new RevWalk(repository)
        ObjectId headId = repository.resolve(Constants.HEAD);
        RevCommit root = revWalk.parseCommit(headId);

        revWalk.sort(RevSort.COMMIT_TIME_DESC);
        revWalk.markStart(root);

        for (RevCommit revCommit: revWalk) {

            TreeWalk treeWalk = TreeWalk.forPath(repository, relativeFilePath, revCommit.getTree())

            if (treeWalk != null) {
                treeWalk.setRecursive(true)
                CanonicalTreeParser canonicalTreeParser = treeWalk.getTree(0, CanonicalTreeParser)

                while (!canonicalTreeParser.eof()) {
                    // if the filename matches, we have a match, so add the date of this commit to the list
                    if (canonicalTreeParser.getEntryPathString() == relativeFilePath) {
                        versions.add(new Date(revCommit.commitTime * 1000L))
                    }
                    canonicalTreeParser.next(1)
                }
            }
        }
    }
    catch (Exception e) {
        throw new JgitException(e)
    }

    return versions
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top