BranchTrackingStatus.java

  1. /*
  2.  * Copyright (C) 2011, Robin Stocker <robin@nibor.org>
  3.  * Copyright (C) 2012, Matthias Sohn <matthias.sohn@sap.com> and others
  4.  *
  5.  * This program and the accompanying materials are made available under the
  6.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  7.  * https://www.eclipse.org/org/documents/edl-v10.php.
  8.  *
  9.  * SPDX-License-Identifier: BSD-3-Clause
  10.  */

  11. package org.eclipse.jgit.lib;

  12. import java.io.IOException;

  13. import org.eclipse.jgit.revwalk.RevCommit;
  14. import org.eclipse.jgit.revwalk.RevWalk;
  15. import org.eclipse.jgit.revwalk.RevWalkUtils;
  16. import org.eclipse.jgit.revwalk.filter.RevFilter;

  17. /**
  18.  * Status of a branch's relation to its remote-tracking branch.
  19.  */
  20. public class BranchTrackingStatus {

  21.     /**
  22.      * Compute the tracking status for the <code>branchName</code> in
  23.      * <code>repository</code>.
  24.      *
  25.      * @param repository
  26.      *            the git repository to compute the status from
  27.      * @param branchName
  28.      *            the local branch
  29.      * @return the tracking status, or null if it is not known
  30.      * @throws java.io.IOException
  31.      */
  32.     public static BranchTrackingStatus of(Repository repository, String branchName)
  33.             throws IOException {

  34.         String shortBranchName = Repository.shortenRefName(branchName);
  35.         String fullBranchName = Constants.R_HEADS + shortBranchName;
  36.         BranchConfig branchConfig = new BranchConfig(repository.getConfig(),
  37.                 shortBranchName);

  38.         String trackingBranch = branchConfig.getTrackingBranch();
  39.         if (trackingBranch == null)
  40.             return null;

  41.         Ref tracking = repository.exactRef(trackingBranch);
  42.         if (tracking == null)
  43.             return null;

  44.         Ref local = repository.exactRef(fullBranchName);
  45.         if (local == null)
  46.             return null;

  47.         try (RevWalk walk = new RevWalk(repository)) {

  48.             RevCommit localCommit = walk.parseCommit(local.getObjectId());
  49.             RevCommit trackingCommit = walk.parseCommit(tracking.getObjectId());

  50.             walk.setRevFilter(RevFilter.MERGE_BASE);
  51.             walk.markStart(localCommit);
  52.             walk.markStart(trackingCommit);
  53.             RevCommit mergeBase = walk.next();

  54.             walk.reset();
  55.             walk.setRevFilter(RevFilter.ALL);
  56.             int aheadCount = RevWalkUtils.count(walk, localCommit, mergeBase);
  57.             int behindCount = RevWalkUtils.count(walk, trackingCommit,
  58.                     mergeBase);

  59.             return new BranchTrackingStatus(trackingBranch, aheadCount,
  60.                     behindCount);
  61.         }
  62.     }

  63.     private final String remoteTrackingBranch;

  64.     private final int aheadCount;

  65.     private final int behindCount;

  66.     private BranchTrackingStatus(String remoteTrackingBranch, int aheadCount,
  67.             int behindCount) {
  68.         this.remoteTrackingBranch = remoteTrackingBranch;
  69.         this.aheadCount = aheadCount;
  70.         this.behindCount = behindCount;
  71.     }

  72.     /**
  73.      * Get full remote-tracking branch name
  74.      *
  75.      * @return full remote-tracking branch name
  76.      */
  77.     public String getRemoteTrackingBranch() {
  78.         return remoteTrackingBranch;
  79.     }

  80.     /**
  81.      * Get number of commits that the local branch is ahead of the
  82.      * remote-tracking branch
  83.      *
  84.      * @return number of commits that the local branch is ahead of the
  85.      *         remote-tracking branch
  86.      */
  87.     public int getAheadCount() {
  88.         return aheadCount;
  89.     }

  90.     /**
  91.      * Get number of commits that the local branch is behind of the
  92.      * remote-tracking branch
  93.      *
  94.      * @return number of commits that the local branch is behind of the
  95.      *         remote-tracking branch
  96.      */
  97.     public int getBehindCount() {
  98.         return behindCount;
  99.     }
  100. }