2016-04-19 7 views
1

Я пытаюсь реализовать RevFilter для использования через RevWalk#setRevFilter(). В следующем, что я пробовал:Как определить «промежуточный» JGit RevFilter?

private class InBetweenRevFilter extends RevFilter { 

    private AnyObjectId end; 
    private AnyObjectId begin; 

    public InBetweenRevFilter(AnyObjectId begin, AnyObjectId end) { 
     this.begin = begin; 
     this.end = end; 
    } 

    @Override 
    public RevFilter clone() { 
     return this; 
    } 

    @Override 
    public boolean include(RevWalk walker, RevCommit c) 
      throws StopWalkException, MissingObjectException, 
      IncorrectObjectTypeException, IOException { 
     RevCommit from = walker.parseCommit(begin); 
     RevCommit to = walker.parseCommit(end); 
     return (walker.isMergedInto(from, c) && walker.isMergedInto(c, to)); 
    } 
} 

Результат фильтра должен быть коммит толкнул после begin и перед end. Проблема в том, что когда я устанавливаю этот фильтр, RevWalk.next() возвращает только фиксацию, помеченную как начальную точку с RevWalk.markStart(RevCommit c). В дальнейшем, я покажу шоу, как я пытался использовать фильтр:

RevWalk walk = new RevWalk(getRepository()); 
    RevCommit beginCommit = walk.parseCommit(getRepository().resolve(start)); 
    RevCommit endCommit = walk.parseCommit(getRepository().resolve(end)); 
    walk.setRevFilter(new InBetweenRevFilter(beginCommit.getId(), endCommit.getId())); 
    walk.markStart(endCommit); 
    for (RevCommit rev : walk) { 
     System.out.println(rev.getFullMessage()); 
    } 
    walk.close(); 

В этом примере, только сообщение от endCommit напечатанного в консоли. Есть ли другой способ сделать это? Или, что я пропущу или сделал не так?

+0

Сейчас я использую рекурсию, чтобы ходить по дереву в качестве временного решения. Но я хотел бы более сложный. Любая помощь будет оценена по достоинству. –

ответ

0

Это было мое решение, но кажется,

public List<RevCommit> between(String start, String end) throws Exception { 
    RevWalk walk = new RevWalk(getRepository()); 
    RevCommit beginCommit = walk.parseCommit(getRepository().resolve(start)); 
    RevCommit endCommit = walk.parseCommit(getRepository().resolve(end)); 
    walk.close(); 
    return commitsBetween(beginCommit, endCommit); 
} 

private List<RevCommit> commitsBetween(RevCommit begin, RevCommit end) throws Exception { 
    List<RevCommit> commits = new LinkedList<>(); 
    RevWalk walk = new RevWalk(getRepository()); 
    RevCommit parent = walk.parseCommit(end.getParent(0).getId()); 

    if (parent.getName().equals(begin.getName())) { 
     commits.add(end); 
     walk.close(); 
     return commits; 
    } else { 
     commits.add(end); 
     commits.addAll(commitsBetween(begin, parent)); 
     walk.close(); 
     return commits; 
    } 
} 

UPDATE: Я получил эту answer в форуме EGit/JGit, который так же просто, как ответ на @ centic в.

RevCommit begin = getBeginCommit(); 
RevCommit end = getEndCommit(); 

try (RevWalk rw = new RevWalk(getRepository())) { 
    rw.markStart(rw.lookupCommit(begin)); 
    rw.markUninteresting(rw.lookupCommit(end)); 
    for (RevCommit curr; (curr = rw.next()) != null;) 
     System.out.println("Inspecting entry: " + curr.getShortMessage()); 
} 
2

Я только что опубликовал фрагмент на jgit-cookbook, который показывает один из способов сделать это:

В принципе, вы можете начать прогулку по одному совершить и запустить прогулку, пока вы не найдете второй или коммиты на ветке выбежать ,

Обратите внимание, что вы возвращаетесь вовремя вовремя, так как Git хранит ссылки между фиксациями, то есть мы начинаем с «до», который является новым фиксатором, и ходим до тех пор, пока мы не достигнем «от».

 String from = "3408efc41a51555d488d30d8a91ea560c5e13311"; 
     String to = "7228de6ebe2a3087118562414061af4e189624c0"; 

     // a RevWalk allows to walk over commits based on some filtering that is defined 
     try (RevWalk walk = new RevWalk(repository)) { 
      RevCommit commit = walk.parseCommit(repository.resolve(to)); 

      System.out.println("Walking all commits starting at " + to + " until we find " + from); 
      walk.markStart(commit); 
      int count = 0; 
      for (RevCommit rev : walk) { 
       System.out.println("Commit: " + rev); 
       count++; 

       if(rev.getId().getName().equals(from)) { 
        System.out.println("Found from, stopping walk"); 
        break; 
       } 
      } 
      System.out.println(count); 

      walk.dispose(); 
     } 
+0

Я также разместил здесь свое решение. Хотя вам кажется, что проще, чем мой с точки зрения использования JGIT API, знаете, что каждый из обоих ответов имеет лучшую производительность? Я принимаю твое. –