From 376a741d8f2ddbd7d801067fdbf304ea3ba3a2bb Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Sat, 18 Aug 2012 00:29:45 +0200 Subject: [PATCH] Teach BranchTrackingStatus to handle tracking of local branches EGit wasn't able to decorate local branches tracking another local branch with number of commits the checked out local branch differs from the other local branch it's tracking. Bug: 376970 Change-Id: I74e932d5eacd74dbf6b0dffcfc65ba3222a8250e Signed-off-by: Matthias Sohn --- .../eclipse/jgit/lib/BranchConfigTest.java | 40 +++++++++++++++++++ .../org/eclipse/jgit/lib/BranchConfig.java | 36 ++++++++++++++++- .../jgit/lib/BranchTrackingStatus.java | 9 +++-- 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/BranchConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/BranchConfigTest.java index 1401526623..4895d3cf1a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/BranchConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/BranchConfigTest.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2011, Robin Stocker + * Copyright (C) 2012, Matthias Sohn * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -104,6 +105,45 @@ public class BranchConfigTest { assertNull(branchConfig.getRemoteTrackingBranch()); } + @Test + public void getTrackingBranchShouldReturnMergeBranchForLocalBranch() { + Config c = parse("" // + + "[remote \"origin\"]\n" + + " fetch = +refs/heads/*:refs/remotes/origin/*\n" + + "[branch \"master\"]\n" + + " remote = .\n" + + " merge = refs/heads/master\n"); + + BranchConfig branchConfig = new BranchConfig(c, "master"); + assertEquals("refs/heads/master", + branchConfig.getTrackingBranch()); + } + + @Test + public void getTrackingBranchShouldReturnNullWithoutMergeBranchForLocalBranch() { + Config c = parse("" // + + "[remote \"origin\"]\n" + + " fetch = +refs/heads/onlyone:refs/remotes/origin/onlyone\n" + + "[branch \"master\"]\n" // + + " remote = .\n"); + BranchConfig branchConfig = new BranchConfig(c, "master"); + assertNull(branchConfig.getTrackingBranch()); + } + + @Test + public void getTrackingBranchShouldHandleNormalCaseForRemoteTrackingBranch() { + Config c = parse("" // + + "[remote \"origin\"]\n" + + " fetch = +refs/heads/*:refs/remotes/origin/*\n" + + "[branch \"master\"]\n" + + " remote = origin\n" + + " merge = refs/heads/master\n"); + + BranchConfig branchConfig = new BranchConfig(c, "master"); + assertEquals("refs/remotes/origin/master", + branchConfig.getTrackingBranch()); + } + private Config parse(final String content) { final Config c = new Config(null); try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchConfig.java index ae05fd95e0..b0883e3f43 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchConfig.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2011, Robin Stocker + * Copyright (C) 2012, Matthias Sohn * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -71,8 +72,25 @@ public class BranchConfig { } /** - * @return the full remote-tracking branch name or null if it - * could not be determined + * @return the full tracking branch name or null if it could + * not be determined + */ + public String getTrackingBranch() { + String remote = getRemote(); + String mergeRef = getMergeBranch(); + if (remote == null || mergeRef == null) + return null; + + if (remote.equals(".")) + return mergeRef; + + return findRemoteTrackingBranch(remote, mergeRef); + } + + /** + * @return the full remote-tracking branch name or {@code null} if it could + * not be determined. If you also want local tracked branches use + * {@link #getTrackingBranch()} instead. */ public String getRemoteTrackingBranch() { String remote = getRemote(); @@ -80,6 +98,20 @@ public class BranchConfig { if (remote == null || mergeRef == null) return null; + return findRemoteTrackingBranch(remote, mergeRef); + } + + /** + * Finds the tracked remote tracking branch + * + * @param remote + * Remote name + * @param mergeRef + * merge Ref of the local branch tracking the remote tracking + * branch + * @return full remote tracking branch name or null + */ + private String findRemoteTrackingBranch(String remote, String mergeRef) { RemoteConfig remoteConfig; try { remoteConfig = new RemoteConfig(config, remote); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java index 4d69e602ee..7844fd819f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2011, Robin Stocker + * Copyright (C) 2012, Matthias Sohn * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -72,11 +73,11 @@ public class BranchTrackingStatus { BranchConfig branchConfig = new BranchConfig(repository.getConfig(), branchName); - String remoteTrackingBranch = branchConfig.getRemoteTrackingBranch(); - if (remoteTrackingBranch == null) + String trackingBranch = branchConfig.getTrackingBranch(); + if (trackingBranch == null) return null; - Ref tracking = repository.getRef(remoteTrackingBranch); + Ref tracking = repository.getRef(trackingBranch); if (tracking == null) return null; @@ -99,7 +100,7 @@ public class BranchTrackingStatus { int aheadCount = RevWalkUtils.count(walk, localCommit, mergeBase); int behindCount = RevWalkUtils.count(walk, trackingCommit, mergeBase); - return new BranchTrackingStatus(remoteTrackingBranch, aheadCount, behindCount); + return new BranchTrackingStatus(trackingBranch, aheadCount, behindCount); } private final String remoteTrackingBranch; -- 2.39.5