Merge branch 'stable-5.1'

* stable-5.1:
  Prepare 5.1.3-SNAPSHOT builds
  EGit v5.1.2.201810061102-r
  Don't use virtual memory mapping in WindowCache on Windows

Change-Id: I0fbe5e117691a13a1e6bdbc89d690aff42a11a2f
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
diff --git a/org.eclipse.egit-feature/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit-feature/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit-feature/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit-feature/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit-feature/feature.xml b/org.eclipse.egit-feature/feature.xml
index 34a5b9a..c0f1490 100644
--- a/org.eclipse.egit-feature/feature.xml
+++ b/org.eclipse.egit-feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.egit"
       label="%featureName"
-      version="5.1.3.qualifier"
+      version="5.2.0.qualifier"
       provider-name="%providerName"
       plugin="org.eclipse.egit"
       license-feature="org.eclipse.license"
@@ -40,7 +40,7 @@
       <import plugin="org.eclipse.jsch.ui" version="1.1.100" match="compatible"/>
       <import plugin="org.eclipse.jsch.core" version="1.1.100" match="compatible"/>
       <import plugin="com.jcraft.jsch" version="0.1.37" match="compatible"/>
-      <import feature="org.eclipse.jgit" version="5.1.3" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="5.2.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.egit-feature/pom.xml b/org.eclipse.egit-feature/pom.xml
index 947582a..e620462 100644
--- a/org.eclipse.egit-feature/pom.xml
+++ b/org.eclipse.egit-feature/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.egit.feature</groupId>
diff --git a/org.eclipse.egit.core.test/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.core.test/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit.core.test/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.core.test/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.core.test/META-INF/MANIFEST.MF b/org.eclipse.egit.core.test/META-INF/MANIFEST.MF
index 7bba425..27919f3 100644
--- a/org.eclipse.egit.core.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.core.test/META-INF/MANIFEST.MF
@@ -5,7 +5,7 @@
 Automatic-Module-Name: org.eclipse.egit.core.test
 Bundle-SymbolicName: org.eclipse.egit.core.test;singleton:=true
 Fragment-Host: org.eclipse.egit.core
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
  org.eclipse.core.filesystem;bundle-version="[1.1.0,2.0.0)",
  org.eclipse.core.resources;bundle-version="[3.4.0,4.0.0)",
@@ -14,18 +14,18 @@
  org.eclipse.jdt.launching;bundle-version="[3.4.0,4.0.0)",
  org.hamcrest;bundle-version="[1.1.0,2.0.0)",
  org.junit;bundle-version="[4.3.0,5.0.0)"
-Import-Package: org.eclipse.egit.core;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.op;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.project;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.api.errors;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.attributes;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.junit;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.lib;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.treewalk;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.util;version="[5.1.3,5.2.0)",
+Import-Package: org.eclipse.egit.core;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.op;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.project;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.api.errors;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.attributes;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.junit;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.lib;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.treewalk;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.util;version="[5.2.0,5.3.0)",
  org.mockito;version="[1.8.0,1.10.0)",
  org.mockito.runners;version="[1.8.0,1.10.0)",
  org.mockito.stubbing;version="[1.8.0,1.10.0)"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Export-Package: org.eclipse.egit.core.test;version="5.1.3"
+Export-Package: org.eclipse.egit.core.test;version="5.2.0"
diff --git a/org.eclipse.egit.core.test/pom.xml b/org.eclipse.egit.core.test/pom.xml
index 21e4d96..4829834 100644
--- a/org.eclipse.egit.core.test/pom.xml
+++ b/org.eclipse.egit.core.test/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.egit.core.test</artifactId>
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/StagedChangeCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/StagedChangeCacheTest.java
index 7dc9692..34d32d1 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/StagedChangeCacheTest.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/StagedChangeCacheTest.java
@@ -231,7 +231,7 @@
 	}
 
 	@Test
-	public void shouldListTwoWorkspaceChagneInFolder() throws Exception {
+	public void shouldListTwoWorkspaceChangesInFolder() throws Exception {
 		// given
 		try (Git git = new Git(db)) {
 			writeTrashFile(db, "folder/a.txt", "trash");
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/WorkingTreeChangeCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/WorkingTreeChangeCacheTest.java
index e021b1e..dfb9268 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/WorkingTreeChangeCacheTest.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/WorkingTreeChangeCacheTest.java
@@ -210,7 +210,7 @@
 	}
 
 	@Test
-	public void shouldListTwoWorkspaceChagneInFolder() throws Exception {
+	public void shouldListTwoWorkspaceChangesInFolder() throws Exception {
 		// given
 		writeTrashFile(db, "folder/a.txt", "trash");
 		writeTrashFile(db, "folder/b.txt", "trash");
@@ -231,7 +231,7 @@
 	}
 
 	@Test
-	public void shouldNotListIgnorefFile() throws Exception {
+	public void shouldNotListIgnoredFile() throws Exception {
 		// given
 		writeTrashFile(db, "a.txt", "content");
 		writeTrashFile(db, ".gitignore", "a.txt");
diff --git a/org.eclipse.egit.core/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.core/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit.core/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.core/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.core/META-INF/MANIFEST.MF b/org.eclipse.egit.core/META-INF/MANIFEST.MF
index 3c8a7a0..252abaa 100644
--- a/org.eclipse.egit.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.core/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %plugin_name
 Automatic-Module-Name: org.eclipse.egit.core
 Bundle-SymbolicName: org.eclipse.egit.core;singleton:=true
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Bundle-Activator: org.eclipse.egit.core.Activator
 Bundle-Vendor: %provider_name
 Bundle-Localization: plugin
@@ -14,7 +14,7 @@
  org.eclipse.equinox.security;bundle-version="[1.0.0,2.0.0)",
  org.eclipse.core.variables;bundle-version="[3.2.0,4.0.0)",
  org.eclipse.core.filebuffers;bundle-version="[3.5.0,4.0.0)"
-Export-Package: org.eclipse.egit.core;version="5.1.3";
+Export-Package: org.eclipse.egit.core;version="5.2.0";
   x-friends:="org.eclipse.egit.ui,
    org.eclipse.egit.ui.test,
    org.eclipse.egit.mylyn.ui,
@@ -22,16 +22,16 @@
    org.eclipse.egit.gitflow.ui,
    org.eclipse.mylyn.github.ui,
    org.eclipse.mylyn.github.core",
- org.eclipse.egit.core.attributes;version="5.1.3";uses:="org.eclipse.jgit.lib",
- org.eclipse.egit.core.internal;version="5.1.3";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.import,org.eclipse.egit.gitflow.ui",
- org.eclipse.egit.core.internal.gerrit;version="5.1.3";x-friends:="org.eclipse.egit.ui",
- org.eclipse.egit.core.internal.indexdiff;version="5.1.3";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.ui.test",
- org.eclipse.egit.core.internal.job;version="5.1.3";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.gitflow.ui,org.eclipse.egit.gitflow",
- org.eclipse.egit.core.internal.rebase;version="5.1.3";x-friends:="org.eclipse.egit.ui",
- org.eclipse.egit.core.internal.storage;version="5.1.3";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.core.test",
- org.eclipse.egit.core.internal.trace;version="5.1.3";x-internal:=true,
- org.eclipse.egit.core.internal.util;version="5.1.3";x-friends:="org.eclipse.egit.ui",
- org.eclipse.egit.core.op;version="5.1.3";
+ org.eclipse.egit.core.attributes;version="5.2.0";uses:="org.eclipse.jgit.lib",
+ org.eclipse.egit.core.internal;version="5.2.0";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.import,org.eclipse.egit.gitflow.ui",
+ org.eclipse.egit.core.internal.gerrit;version="5.2.0";x-friends:="org.eclipse.egit.ui",
+ org.eclipse.egit.core.internal.indexdiff;version="5.2.0";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.ui.test",
+ org.eclipse.egit.core.internal.job;version="5.2.0";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.gitflow.ui,org.eclipse.egit.gitflow",
+ org.eclipse.egit.core.internal.rebase;version="5.2.0";x-friends:="org.eclipse.egit.ui",
+ org.eclipse.egit.core.internal.storage;version="5.2.0";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.core.test",
+ org.eclipse.egit.core.internal.trace;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.core.internal.util;version="5.2.0";x-friends:="org.eclipse.egit.ui",
+ org.eclipse.egit.core.op;version="5.2.0";
   x-friends:="org.eclipse.egit.ui.test,
    org.eclipse.egit.ui,
    org.eclipse.egit.gitflow,
@@ -39,39 +39,39 @@
    org.eclipse.egit.gitflow.ui,
    org.eclipse.egit.github.core,
    org.eclipse.mylyn.github.ui",
- org.eclipse.egit.core.project;version="5.1.3";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.ui.test,org.eclipse.egit.gitflow.ui",
- org.eclipse.egit.core.securestorage;version="5.1.3";x-friends:="org.eclipse.egit.ui",
- org.eclipse.egit.core.storage;version="5.1.3";
+ org.eclipse.egit.core.project;version="5.2.0";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.ui.test,org.eclipse.egit.gitflow.ui",
+ org.eclipse.egit.core.securestorage;version="5.2.0";x-friends:="org.eclipse.egit.ui",
+ org.eclipse.egit.core.storage;version="5.2.0";
   uses:="org.eclipse.core.runtime,
    org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.core.resources",
- org.eclipse.egit.core.synchronize;version="5.1.3";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.ui.test",
- org.eclipse.egit.core.synchronize.dto;version="5.1.3";x-friends:="org.eclipse.egit.ui"
+ org.eclipse.egit.core.synchronize;version="5.2.0";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.ui.test",
+ org.eclipse.egit.core.synchronize.dto;version="5.2.0";x-friends:="org.eclipse.egit.ui"
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: com.jcraft.jsch;bundle-version="[0.1.37,0.2.0)",
  org.eclipse.core.net.proxy;bundle-version="[1.1.0,2.0.0)",
- org.eclipse.jgit.annotations;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.api;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.api.errors;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.attributes;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.diff;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.dircache;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.errors;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.events;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.lfs;version="[5.1.3,5.2.0)";resolution:=optional,
- org.eclipse.jgit.lib;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.merge;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.revwalk.filter;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.storage.file;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.submodule;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.transport;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.treewalk;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.util;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.util.io;version="[5.1.3,5.2.0)",
+ org.eclipse.jgit.annotations;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.api;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.api.errors;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.attributes;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.diff;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.dircache;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.errors;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.events;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.lfs;version="[5.2.0,5.3.0)";resolution:=optional,
+ org.eclipse.jgit.lib;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.merge;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.revwalk;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.revwalk.filter;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.storage.file;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.submodule;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.transport;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.treewalk;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.util;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.util.io;version="[5.2.0,5.3.0)",
  org.eclipse.jsch.core;bundle-version="[1.1.100,2.0.0)"
 Eclipse-ExtensibleAPI: true
diff --git a/org.eclipse.egit.core/pom.xml b/org.eclipse.egit.core/pom.xml
index 3ec34ff..59aa302 100644
--- a/org.eclipse.egit.core/pom.xml
+++ b/org.eclipse.egit.core/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.egit.core</artifactId>
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/CommitUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/CommitUtil.java
index b66002d..46e7418 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/CommitUtil.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/CommitUtil.java
@@ -37,7 +37,7 @@
 public class CommitUtil {
 
 	private CommitUtil() {
-		// non instanciable utility class
+		// non instantiable utility class
 	}
 
 	/**
@@ -48,7 +48,7 @@
 	 * @return a new list containing the sorted commits
 	 */
 	public static List<RevCommit> sortCommits(Collection<RevCommit> commits) {
-		Map<RevCommit, RevCommit> parentToChild = new HashMap<RevCommit, RevCommit>();
+		Map<RevCommit, RevCommit> parentToChild = new HashMap<>();
 		RevCommit firstCommit = null;
 		for (RevCommit commit : commits) {
 			RevCommit parentCommit = commit.getParent(0);
@@ -57,7 +57,7 @@
 				firstCommit = commit;
 		}
 
-		List<RevCommit> sortedCommits = new ArrayList<RevCommit>();
+		List<RevCommit> sortedCommits = new ArrayList<>();
 		sortedCommits.add(firstCommit);
 		RevCommit parentCommit = firstCommit;
 		for (;;) {
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java
index 909ad8c..a9c83b6 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java
@@ -61,6 +61,7 @@
 import org.eclipse.jgit.treewalk.WorkingTreeIterator;
 import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
 import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.FileUtils;
 import org.osgi.service.prefs.BackingStoreException;
 
 /**
@@ -141,7 +142,7 @@
 			result = ResourcesPlugin.getWorkspace().getRoot().getRawLocation()
 					.toOSString();
 		}
-		return result;
+		return FileUtils.canonicalize(new File(result)).toString();
 	}
 
 	@NonNull
@@ -183,7 +184,7 @@
 	 * <li>Tags take precedence over branches</li>
 	 * <li>Local branches take preference over remote branches</li>
 	 * <li>Newer references take precedence over older ones where time stamps
-	 * are available. Use commiter time stamp from commit if no stamp can be
+	 * are available. Use committer time stamp from commit if no stamp can be
 	 * found on the tag</li>
 	 * <li>If there are still ambiguities, the reference name with the highest
 	 * lexicographic value will be returned</li>
@@ -415,7 +416,7 @@
 		synchronized (prefs) {
 			dirString = prefs.get(PREFS_DIRECTORIES_REL, ""); //$NON-NLS-1$
 			if (dirString.equals("")) { //$NON-NLS-1$
-				dirs = migrateAbolutePaths();
+				dirs = migrateAbsolutePaths();
 			} else {
 				dirs = toDirSet(dirString);
 			}
@@ -430,7 +431,7 @@
 	 *
 	 * @return set of absolute paths of all configured git repositories
 	 */
-	private Set<String> migrateAbolutePaths() {
+	private Set<String> migrateAbsolutePaths() {
 		String dirString;
 		Set<String> dirs;
 		dirString = prefs.get(PREFS_DIRECTORIES, ""); //$NON-NLS-1$
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/RevUtils.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/RevUtils.java
index cc186b8..886bb61 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/RevUtils.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/RevUtils.java
@@ -35,7 +35,7 @@
 public class RevUtils {
 
 	private RevUtils() {
-		// non instanciable utility class
+		// non instantiable utility class
 	}
 
 	/**
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java
index 8341b33..f748960 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java
@@ -318,10 +318,9 @@
 	 * @param fileList
 	 *            the list of files/directories to lookup
 	 * @return valid projects containing one of the paths
-	 * @throws CoreException
 	 */
 	public static IProject[] getProjectsContaining(Repository repository,
-			Collection<String> fileList) throws CoreException {
+			Collection<String> fileList) {
 		if (repository == null || repository.isBare()) {
 			return new IProject[0];
 		}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BaseOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BaseOperation.java
deleted file mode 100644
index 481bf4a..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BaseOperation.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/******************************************************************************
- *  Copyright (c) 2012 GitHub Inc.
- *  All rights reserved. This program and the accompanying materials
- *  are made available under the terms of the Eclipse Public License 2.0
- *  which accompanies this distribution, and is available at
- *  https://www.eclipse.org/legal/epl-2.0/
- *
- *  SPDX-License-Identifier: EPL-2.0
- *
- *  Contributors:
- *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
- *    Stephan Hackstedt <stephan.hackstedt@googlemail.com> - Bug 477695
- *****************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.SubMonitor;
-import org.eclipse.jgit.lib.Repository;
-
-/**
- * Base operation that supports adding pre/post tasks
- */
-abstract class BaseOperation implements IEGitOperation {
-
-	protected final Repository repository;
-
-	protected Collection<PreExecuteTask> preTasks;
-
-	protected Collection<PostExecuteTask> postTasks;
-
-	BaseOperation(final Repository repository) {
-		this.repository = repository;
-	}
-
-	/**
-	 * Invoke all pre-execute tasks
-	 *
-	 * @param monitor
-	 * @throws CoreException
-	 */
-	protected void preExecute(IProgressMonitor monitor) throws CoreException {
-		synchronized (this) {
-			if (preTasks != null) {
-				SubMonitor progress = SubMonitor.convert(monitor,
-						preTasks.size());
-				for (PreExecuteTask task : preTasks)
-					task.preExecute(repository, progress.newChild(1));
-			}
-		}
-	}
-
-	/**
-	 * Invoke all post-execute tasks
-	 *
-	 * @param monitor
-	 * @throws CoreException
-	 */
-	protected void postExecute(IProgressMonitor monitor) throws CoreException {
-		synchronized (this) {
-			if (postTasks != null) {
-				SubMonitor progress = SubMonitor.convert(monitor,
-						postTasks.size());
-				for (PostExecuteTask task : postTasks)
-					task.postExecute(repository, progress.newChild(1));
-			}
-		}
-	}
-
-	/**
-	 * @param task
-	 *            to be performed before execution
-	 */
-	public synchronized void addPreExecuteTask(final PreExecuteTask task) {
-		if (preTasks == null)
-			preTasks = new ArrayList<PreExecuteTask>();
-		preTasks.add(task);
-	}
-
-	/**
-	 * @param task
-	 *            to be performed after execution
-	 */
-	public synchronized void addPostExecuteTask(PostExecuteTask task) {
-		if (postTasks == null)
-			postTasks = new ArrayList<PostExecuteTask>();
-		postTasks.add(task);
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BranchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BranchOperation.java
index 562f2b6..64eb511 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BranchOperation.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BranchOperation.java
@@ -19,9 +19,12 @@
 import java.io.IOException;
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.stream.Stream;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
@@ -33,7 +36,6 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.SubMonitor;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
 import org.eclipse.egit.core.EclipseGitProgressTransformer;
 import org.eclipse.egit.core.internal.CoreText;
 import org.eclipse.egit.core.internal.job.RuleUtil;
@@ -64,11 +66,13 @@
  * This class implements checkouts of a specific revision. A check is made that
  * this can be done without data loss.
  */
-public class BranchOperation extends BaseOperation {
+public class BranchOperation implements IEGitOperation {
 
 	private final String target;
 
-	private @NonNull CheckoutResult result = CheckoutResult.NOT_TRIED_RESULT;
+	private Repository[] repositories;
+
+	private @NonNull Map<Repository, CheckoutResult> results = new HashMap<>();
 
 	private boolean delete;
 
@@ -94,7 +98,18 @@
 	 *            them
 	 */
 	public BranchOperation(Repository repository, String target, boolean delete) {
-		super(repository);
+		this(new Repository[] { repository }, target, delete);
+	}
+
+	/**
+	 *
+	 * @param repositories
+	 * @param target
+	 * @param delete
+	 */
+	public BranchOperation(Repository[] repositories, String target,
+			boolean delete) {
+		this.repositories = repositories;
 		this.target = target;
 		this.delete = delete;
 	}
@@ -106,11 +121,28 @@
 			@Override
 			public void run(IProgressMonitor pm) throws CoreException {
 				SubMonitor progress = SubMonitor.convert(pm, 4);
-				preExecute(progress.newChild(1));
 
-				closeProjectsMissingAfterCheckout(progress);
 
-				try (Git git = new Git(repository)) {
+				for (Repository repository : repositories) {
+
+					CheckoutResult result = checkoutRepository(repository,
+							progress);
+
+					if (result.getStatus() == Status.NONDELETED) {
+						retryDelete(repository, result.getUndeletedList());
+					}
+
+					results.put(repository, result);
+				}
+				refreshAffectedProjects(progress);
+			}
+
+			public CheckoutResult checkoutRepository(Repository repo,
+					SubMonitor progress) throws CoreException {
+
+				closeProjectsMissingAfterCheckout(repo, progress);
+
+				try (Git git = new Git(repo)) {
 					CheckoutCommand co = git.checkout().setProgressMonitor(
 							new EclipseGitProgressTransformer(
 									progress.newChild(1)));
@@ -118,30 +150,23 @@
 
 					try {
 						co.call();
+						// The below exceptions are handled by the
+						// CheckoutCommand's result status which is returned
 					} catch (CheckoutConflictException e) {
-						return;
+						// ignore
 					} catch (JGitInternalException e) {
-						throw new CoreException(
-								Activator.error(e.getMessage(), e));
+						// ignore
 					} catch (GitAPIException e) {
-						throw new CoreException(
-								Activator.error(e.getMessage(), e));
-					} finally {
-						result = co.getResult();
+						// ignore
 					}
-					if (result.getStatus() == Status.NONDELETED) {
-						retryDelete(result.getUndeletedList());
-					}
-					refreshAffectedProjects(progress);
-
-					postExecute(progress.newChild(1));
+					return co.getResult();
 				}
 			}
 
-			private void closeProjectsMissingAfterCheckout(SubMonitor progress)
+			private void closeProjectsMissingAfterCheckout(Repository repo,
+					SubMonitor progress)
 					throws CoreException {
-				IProject[] missing = getMissingProjects(target, ProjectUtil
-						.getValidOpenProjects(repository));
+				IProject[] missing = getMissingProjects(repo, target);
 
 				progress.setTaskName(NLS.bind(
 						CoreText.BranchOperation_performingBranch, target));
@@ -161,14 +186,36 @@
 
 			private void refreshAffectedProjects(SubMonitor progress)
 					throws CoreException {
+
+				IProject[] refreshProjects = results.entrySet().stream() //
+					.map(this::getAffectedProjects) //
+					.flatMap(arr -> Stream.of(arr)) //
+					.distinct()
+					.toArray(IProject[]::new);
+
+				ProjectUtil.refreshValidProjects(refreshProjects, delete,
+						progress.newChild(1));
+			}
+
+			private IProject[] getAffectedProjects(
+					Entry<Repository, CheckoutResult> entry)
+			{
+				CheckoutResult result = entry.getValue();
+
+				if (result.getStatus() != Status.OK
+						&& result.getStatus() != Status.NONDELETED) {
+					// the checkout did not succeed
+					return new IProject[0];
+				}
+
+				Repository repo = entry.getKey();
 				List<String> pathsToHandle = new ArrayList<>();
 				pathsToHandle.addAll(result.getModifiedList());
 				pathsToHandle.addAll(result.getRemovedList());
 				pathsToHandle.addAll(result.getConflictList());
 				IProject[] refreshProjects = ProjectUtil
-						.getProjectsContaining(repository, pathsToHandle);
-				ProjectUtil.refreshValidProjects(refreshProjects, delete,
-						progress.newChild(1));
+						.getProjectsContaining(repo, pathsToHandle);
+				return refreshProjects;
 			}
 		};
 		// lock workspace to protect working tree changes
@@ -178,24 +225,32 @@
 
 	@Override
 	public ISchedulingRule getSchedulingRule() {
-		return RuleUtil.getRule(repository);
+		return RuleUtil.getRuleForRepositories(Arrays.asList(repositories));
 	}
 
 	/**
 	 * @return the result of the operation
 	 */
 	@NonNull
-	public CheckoutResult getResult() {
-		return result;
+	public Map<Repository, CheckoutResult> getResults() {
+		return results;
 	}
 
-	void retryDelete(List<String> pathList) {
+	/**
+	 * @param repo
+	 * @return return the result specific to a repository
+	 */
+	public CheckoutResult getResult(Repository repo) {
+		return results.get(repo);
+	}
+
+	void retryDelete(Repository repo, List<String> pathList) {
 		// try to delete, but for a short time only
 		long startTime = System.currentTimeMillis();
 		for (String path : pathList) {
 			if (System.currentTimeMillis() - startTime > 1000)
 				break;
-			File fileToDelete = new File(repository.getWorkTree(), path);
+			File fileToDelete = new File(repo.getWorkTree(), path);
 			if (fileToDelete.exists())
 				try {
 					// Only files should be passed here, thus
@@ -213,13 +268,15 @@
 	 * Compute the current projects that will be missing after the given branch
 	 * is checked out
 	 *
+	 * @param repository
 	 * @param branch
-	 * @param currentProjects
 	 * @return non-null but possibly empty array of missing projects
+	 * @throws CoreException
 	 */
-	private IProject[] getMissingProjects(String branch,
-			IProject[] currentProjects) {
-		if (delete || currentProjects.length == 0)
+	private IProject[] getMissingProjects(Repository repository,
+			String branch) throws CoreException {
+		IProject[] openProjects = ProjectUtil.getValidOpenProjects(repository);
+		if (delete || openProjects.length == 0)
 			return new IProject[0];
 
 		ObjectId targetTreeId;
@@ -234,7 +291,7 @@
 			return new IProject[0];
 
 		Map<File, IProject> locations = new HashMap<>();
-		for (IProject project : currentProjects) {
+		for (IProject project : openProjects) {
 			IPath location = project.getLocation();
 			if (location == null)
 				continue;
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriber.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriber.java
index b6f35b0..5420c1f 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriber.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriber.java
@@ -127,7 +127,13 @@
 			return new IResource[0];
 		}
 		GitSynchronizeData gsd = gsds.getData(res.getProject());
+		if (gsd == null) {
+			return new IResource[0];
+		}
 		Repository repo = gsd.getRepository();
+		if (repo == null) {
+			return new IResource[0];
+		}
 		GitSyncObjectCache repoCache = cache.get(repo);
 
 		Collection<IResource> allMembers = new ArrayList<>();
@@ -198,7 +204,7 @@
 		}
 
 		// not refreshing the workspace, locate and collect target resources
-		Map<GitSynchronizeData, Collection<String>> updateRequests = new HashMap<GitSynchronizeData, Collection<String>>();
+		Map<GitSynchronizeData, Collection<String>> updateRequests = new HashMap<>();
 		for (IResource resource : resources) {
 			IProject project = resource.getProject();
 			GitSynchronizeData data = gsds.getData(project.getName());
@@ -209,7 +215,7 @@
 				if (mapping != null) {
 					Collection<String> paths = updateRequests.get(data);
 					if (paths == null) {
-						paths = new ArrayList<String>();
+						paths = new ArrayList<>();
 						updateRequests.put(data, paths);
 					}
 
@@ -574,9 +580,9 @@
 	@Override
 	protected SyncInfo getSyncInfo(IResource local, IResourceVariant base,
 			IResourceVariant remote) throws TeamException {
-
-		Repository repo = gsds.getData(local.getProject()).getRepository();
-		return getSyncInfo(local, base, remote, repo);
+		GitSynchronizeData data = gsds.getData(local.getProject());
+		Repository repo = data != null ? data.getRepository() : null;
+		return repo != null ? getSyncInfo(local, base, remote, repo) : null;
 	}
 
 	/**
diff --git a/org.eclipse.egit.doc/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.doc/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit.doc/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.doc/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.doc/META-INF/MANIFEST.MF b/org.eclipse.egit.doc/META-INF/MANIFEST.MF
index e0ba7b1..afbe96d 100644
--- a/org.eclipse.egit.doc/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.doc/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Bundle-Name
 Bundle-SymbolicName: org.eclipse.egit.doc;singleton:=true
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Bundle-Localization: plugin
diff --git a/org.eclipse.egit.doc/pom.xml b/org.eclipse.egit.doc/pom.xml
index f6ed307..c41e343 100644
--- a/org.eclipse.egit.doc/pom.xml
+++ b/org.eclipse.egit.doc/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.egit.doc</artifactId>
diff --git a/org.eclipse.egit.gitflow-feature/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.gitflow-feature/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 0000000..2fca432
--- /dev/null
+++ b/org.eclipse.egit.gitflow-feature/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,3 @@
+#Tue Jul 19 20:11:28 CEST 2011
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
+eclipse.preferences.version=1
diff --git a/org.eclipse.egit.gitflow-feature/feature.xml b/org.eclipse.egit.gitflow-feature/feature.xml
index 125b427..308c030 100644
--- a/org.eclipse.egit.gitflow-feature/feature.xml
+++ b/org.eclipse.egit.gitflow-feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.egit.gitflow.feature"
       label="%featureName"
-      version="5.1.3.qualifier"
+      version="5.2.0.qualifier"
       provider-name="%providerName"
       plugin="org.eclipse.egit.gitflow"
       license-feature="org.eclipse.license"
@@ -26,9 +26,9 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="5.1.3" match="equivalent"/>
-      <import plugin="org.eclipse.egit.core" version="5.1.3" match="equivalent"/>
-      <import plugin="org.eclipse.egit.ui" version="5.1.3" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="5.2.0" match="equivalent"/>
+      <import plugin="org.eclipse.egit.core" version="5.2.0" match="equivalent"/>
+      <import plugin="org.eclipse.egit.ui" version="5.2.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.egit.gitflow-feature/pom.xml b/org.eclipse.egit.gitflow-feature/pom.xml
index febb50f..bdc7643 100644
--- a/org.eclipse.egit.gitflow-feature/pom.xml
+++ b/org.eclipse.egit.gitflow-feature/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.egit.feature</groupId>
diff --git a/org.eclipse.egit.gitflow.test/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.gitflow.test/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 0000000..2fca432
--- /dev/null
+++ b/org.eclipse.egit.gitflow.test/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,3 @@
+#Tue Jul 19 20:11:28 CEST 2011
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
+eclipse.preferences.version=1
diff --git a/org.eclipse.egit.gitflow.test/META-INF/MANIFEST.MF b/org.eclipse.egit.gitflow.test/META-INF/MANIFEST.MF
index d74fade..38c4788 100644
--- a/org.eclipse.egit.gitflow.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.gitflow.test/META-INF/MANIFEST.MF
@@ -3,12 +3,12 @@
 Bundle-Name: GitFlow Test
 Automatic-Module-Name: org.eclipse.egit.gitflow.test
 Bundle-SymbolicName: org.eclipse.egit.gitflow.test;singleton:=true
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Fragment-Host: org.eclipse.egit.gitflow
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.egit.core;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.test;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.junit;version="[5.1.3,5.2.0)",
+Import-Package: org.eclipse.egit.core;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.test;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.junit;version="[5.2.0,5.3.0)",
  org.hamcrest;version="[1.1.0,1.2.0)",
  org.junit.rules;version="[4.12.0,4.13.0)",
  org.junit;version="[4.3.0,5.0.0)"
diff --git a/org.eclipse.egit.gitflow.test/pom.xml b/org.eclipse.egit.gitflow.test/pom.xml
index 9f0fd59..bde7d2d 100644
--- a/org.eclipse.egit.gitflow.test/pom.xml
+++ b/org.eclipse.egit.gitflow.test/pom.xml
@@ -17,7 +17,7 @@
 	<parent>
 		<groupId>org.eclipse.egit</groupId>
 		<artifactId>egit-parent</artifactId>
-		<version>5.1.3-SNAPSHOT</version>
+		<version>5.2.0-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>org.eclipse.egit.gitflow.test</artifactId>
diff --git a/org.eclipse.egit.gitflow.ui/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.gitflow.ui/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 0000000..2fca432
--- /dev/null
+++ b/org.eclipse.egit.gitflow.ui/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,3 @@
+#Tue Jul 19 20:11:28 CEST 2011
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
+eclipse.preferences.version=1
diff --git a/org.eclipse.egit.gitflow.ui/META-INF/MANIFEST.MF b/org.eclipse.egit.gitflow.ui/META-INF/MANIFEST.MF
index a948a5b..132466e 100644
--- a/org.eclipse.egit.gitflow.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.gitflow.ui/META-INF/MANIFEST.MF
@@ -3,34 +3,34 @@
 Bundle-Name: %plugin_name
 Automatic-Module-Name: org.eclipse.egit.gitflow.ui
 Bundle-SymbolicName: org.eclipse.egit.gitflow.ui;singleton:=true
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Bundle-Activator: org.eclipse.egit.gitflow.ui.Activator
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: %provider_name
 Bundle-Localization: plugin
-Import-Package: org.eclipse.egit.core;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.internal;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.internal.job;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.op;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.project;version="[5.1.3,5.2.0)",
- org.eclipse.egit.gitflow;version="[5.1.3,5.2.0)",
- org.eclipse.egit.gitflow.op;version="[5.1.3,5.2.0)",
- org.eclipse.egit.ui;version="[5.1.3,5.2.0)",
- org.eclipse.egit.ui.internal;version="[5.1.3,5.2.0)",
- org.eclipse.egit.ui.internal.actions;version="[5.1.3,5.2.0)",
- org.eclipse.egit.ui.internal.branch;version="[5.1.3,5.2.0)",
- org.eclipse.egit.ui.internal.commit;version="[5.1.3,5.2.0)",
- org.eclipse.egit.ui.internal.rebase;version="[5.1.3,5.2.0)",
- org.eclipse.egit.ui.internal.repository.tree;version="[5.1.3,5.2.0)",
- org.eclipse.egit.ui.internal.selection;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.annotations;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.api;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.api.errors;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.lib;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.revplot;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.util;version="[5.1.3,5.2.0)"
+Import-Package: org.eclipse.egit.core;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.internal;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.internal.job;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.op;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.project;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.gitflow;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.gitflow.op;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.ui;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.ui.internal;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.ui.internal.actions;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.ui.internal.branch;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.ui.internal.commit;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.ui.internal.rebase;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.ui.internal.repository.tree;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.ui.internal.selection;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.annotations;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.api;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.api.errors;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.lib;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.revplot;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.revwalk;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.util;version="[5.2.0,5.3.0)"
 Require-Bundle: org.eclipse.core.resources;bundle-version="[3.4.0,4.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
  org.eclipse.team.ui;bundle-version="[3.4.0,4.0.0)",
@@ -40,12 +40,12 @@
  org.eclipse.core.databinding.property;bundle-version="[1.4.0,2.0.0)",
  org.eclipse.core.databinding.beans;bundle-version="[1.2.0,2.0.0)",
  org.eclipse.core.databinding;bundle-version="[1.4.0,2.0.0)"
-Export-Package: org.eclipse.egit.gitflow.ui;version="5.1.3";x-friends:="org.eclipse.egit.ui.test",
- org.eclipse.egit.gitflow.ui.internal;version="5.1.3";x-friends:="org.eclipse.egit.ui.test",
- org.eclipse.egit.gitflow.ui.internal.actions;version="5.1.3";x-friends:="org.eclipse.egit.ui.test",
- org.eclipse.egit.gitflow.ui.internal.decorators;version="5.1.3";x-internal:=true,
- org.eclipse.egit.gitflow.ui.internal.dialogs;version="5.1.3";x-internal:=true,
- org.eclipse.egit.gitflow.ui.internal.factories;version="5.1.3";x-internal:=true,
- org.eclipse.egit.gitflow.ui.internal.menu;version="5.1.3";x-internal:=true,
- org.eclipse.egit.gitflow.ui.internal.properties;version="5.1.3";x-internal:=true,
- org.eclipse.egit.gitflow.ui.internal.validation;version="5.1.3";x-internal:=true
+Export-Package: org.eclipse.egit.gitflow.ui;version="5.2.0";x-friends:="org.eclipse.egit.ui.test",
+ org.eclipse.egit.gitflow.ui.internal;version="5.2.0";x-friends:="org.eclipse.egit.ui.test",
+ org.eclipse.egit.gitflow.ui.internal.actions;version="5.2.0";x-friends:="org.eclipse.egit.ui.test",
+ org.eclipse.egit.gitflow.ui.internal.decorators;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.gitflow.ui.internal.dialogs;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.gitflow.ui.internal.factories;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.gitflow.ui.internal.menu;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.gitflow.ui.internal.properties;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.gitflow.ui.internal.validation;version="5.2.0";x-internal:=true
diff --git a/org.eclipse.egit.gitflow.ui/pom.xml b/org.eclipse.egit.gitflow.ui/pom.xml
index 137bb17..876ac8a 100644
--- a/org.eclipse.egit.gitflow.ui/pom.xml
+++ b/org.eclipse.egit.gitflow.ui/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.egit.gitflow.ui</artifactId>
diff --git a/org.eclipse.egit.gitflow/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.gitflow/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 0000000..2fca432
--- /dev/null
+++ b/org.eclipse.egit.gitflow/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,3 @@
+#Tue Jul 19 20:11:28 CEST 2011
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
+eclipse.preferences.version=1
diff --git a/org.eclipse.egit.gitflow/META-INF/MANIFEST.MF b/org.eclipse.egit.gitflow/META-INF/MANIFEST.MF
index 6d93c12..4be406e 100644
--- a/org.eclipse.egit.gitflow/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.gitflow/META-INF/MANIFEST.MF
@@ -3,22 +3,22 @@
 Bundle-Name: %plugin_name
 Automatic-Module-Name: org.eclipse.egit.gitflow
 Bundle-SymbolicName: org.eclipse.egit.gitflow;singleton:=true
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Bundle-Vendor: %provider_name
 Bundle-Activator: org.eclipse.egit.gitflow.Activator
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Bundle-ActivationPolicy: lazy
 Bundle-Localization: plugin
 Require-Bundle: org.eclipse.core.runtime,
- org.eclipse.jgit;bundle-version="[5.1.3,5.2.0)";resolution:=optional
-Export-Package: org.eclipse.egit.gitflow;version="5.1.3";
+ org.eclipse.jgit;bundle-version="[5.2.0,5.3.0)";resolution:=optional
+Export-Package: org.eclipse.egit.gitflow;version="5.2.0";
   uses:="org.osgi.framework,
    org.eclipse.jgit.transport,
    org.eclipse.core.runtime,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk",
  org.eclipse.egit.gitflow.internal;x-internal:=true,
- org.eclipse.egit.gitflow.op;version="5.1.3";
+ org.eclipse.egit.gitflow.op;version="5.2.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.core.runtime.jobs,
    org.eclipse.core.runtime,
@@ -27,12 +27,12 @@
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.lib,
    org.eclipse.egit.core.op"
-Import-Package: org.eclipse.egit.core.internal.job;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.op;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.api;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.api.errors;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.errors;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.lib;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.revwalk.filter;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.transport;version="[5.1.3,5.2.0)"
+Import-Package: org.eclipse.egit.core.internal.job;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.op;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.api;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.api.errors;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.errors;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.lib;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.revwalk;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.revwalk.filter;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.transport;version="[5.2.0,5.3.0)"
diff --git a/org.eclipse.egit.gitflow/pom.xml b/org.eclipse.egit.gitflow/pom.xml
index 77bb1b5..9c30e8e 100644
--- a/org.eclipse.egit.gitflow/pom.xml
+++ b/org.eclipse.egit.gitflow/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.egit.gitflow</artifactId>
diff --git a/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/FeatureCheckoutOperation.java b/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/FeatureCheckoutOperation.java
index 765819d..d8b6426 100644
--- a/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/FeatureCheckoutOperation.java
+++ b/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/FeatureCheckoutOperation.java
@@ -15,6 +15,7 @@
 import org.eclipse.egit.core.op.BranchOperation;
 import org.eclipse.egit.gitflow.GitFlowRepository;
 import org.eclipse.jgit.api.CheckoutResult;
+import org.eclipse.jgit.lib.Repository;
 
 /**
  * git flow feature checkout
@@ -36,10 +37,11 @@
 		String branchName = repository.getConfig().getFeatureBranchName(featureName);
 
 		boolean dontCloseProjects = false;
+		Repository gitRepo = repository.getRepository();
 		BranchOperation branchOperation = new BranchOperation(
-				repository.getRepository(), branchName, dontCloseProjects);
+				gitRepo, branchName, dontCloseProjects);
 		branchOperation.execute(monitor);
-		result = branchOperation.getResult();
+		result = branchOperation.getResult(gitRepo);
 	}
 
 	/**
diff --git a/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/FeatureTrackOperation.java b/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/FeatureTrackOperation.java
index 72d2b0b..5ad0089 100644
--- a/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/FeatureTrackOperation.java
+++ b/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/FeatureTrackOperation.java
@@ -30,6 +30,7 @@
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.lib.BranchConfig.BranchRebaseMode;
 import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.transport.FetchResult;
 import org.eclipse.osgi.util.NLS;
 
@@ -95,10 +96,11 @@
 					BranchRebaseMode.NONE);
 			createLocalBranchOperation.execute(progress.newChild(1));
 
-			BranchOperation branchOperation = new BranchOperation(
-					repository.getRepository(), newLocalBranch);
+			Repository gitRepo = repository.getRepository();
+			BranchOperation branchOperation = new BranchOperation(gitRepo,
+					newLocalBranch);
 			branchOperation.execute(progress.newChild(1));
-			CheckoutResult result = branchOperation.getResult();
+			CheckoutResult result = branchOperation.getResult(gitRepo);
 			if (!Status.OK.equals(result.getStatus())) {
 				String errorMessage = NLS.bind(
 						CoreText.FeatureTrackOperation_checkoutReturned,
diff --git a/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/GitFlowOperation.java b/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/GitFlowOperation.java
index b3c3e7c..b50fe8a 100644
--- a/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/GitFlowOperation.java
+++ b/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/GitFlowOperation.java
@@ -36,6 +36,7 @@
 import org.eclipse.jgit.api.MergeResult;
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.revwalk.RevWalkUtils;
@@ -179,18 +180,18 @@
 			}
 			SubMonitor progress = SubMonitor.convert(monitor, 2);
 			boolean dontCloseProjects = false;
-			BranchOperation branchOperation = new BranchOperation(
-					repository.getRepository(), targetBranchName,
-					dontCloseProjects);
+			Repository gitRepo = repository.getRepository();
+			BranchOperation branchOperation = new BranchOperation(gitRepo,
+					targetBranchName, dontCloseProjects);
 			branchOperation.execute(progress.newChild(1));
-			Status status = branchOperation.getResult().getStatus();
+			Status status = branchOperation.getResult(gitRepo).getStatus();
 			if (!CheckoutResult.Status.OK.equals(status)) {
 				throw new CoreException(error(NLS.bind(
 						CoreText.GitFlowOperation_unableToCheckout, branchName,
 						status.toString())));
 			}
-			MergeOperation mergeOperation = new MergeOperation(
-					repository.getRepository(), branchName);
+			MergeOperation mergeOperation = new MergeOperation(gitRepo,
+					branchName);
 			mergeOperation.setSquash(squash);
 			if (squash) {
 				mergeOperation.setCommit(true);
diff --git a/org.eclipse.egit.mylyn-feature/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.mylyn-feature/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit.mylyn-feature/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.mylyn-feature/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.mylyn-feature/feature.xml b/org.eclipse.egit.mylyn-feature/feature.xml
index 65444af..9a9dcc6 100644
--- a/org.eclipse.egit.mylyn-feature/feature.xml
+++ b/org.eclipse.egit.mylyn-feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.egit.mylyn"
       label="%featureName"
-      version="5.1.3.qualifier"
+      version="5.2.0.qualifier"
       provider-name="%providerName"
       plugin="org.eclipse.egit"
       license-feature="org.eclipse.license"
@@ -26,7 +26,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.egit" version="5.1.3" match="greaterOrEqual"/>
+      <import feature="org.eclipse.egit" version="5.2.0" match="greaterOrEqual"/>
       <import feature="org.eclipse.mylyn.team_feature" version="3.5.0" match="greaterOrEqual"/>
    </requires>
 
diff --git a/org.eclipse.egit.mylyn-feature/pom.xml b/org.eclipse.egit.mylyn-feature/pom.xml
index 93324e9..6bb3d17 100644
--- a/org.eclipse.egit.mylyn-feature/pom.xml
+++ b/org.eclipse.egit.mylyn-feature/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.egit.feature</groupId>
diff --git a/org.eclipse.egit.mylyn.ui.test/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.mylyn.ui.test/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit.mylyn.ui.test/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.mylyn.ui.test/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.mylyn.ui.test/META-INF/MANIFEST.MF b/org.eclipse.egit.mylyn.ui.test/META-INF/MANIFEST.MF
index 94d5862..be95f8d 100644
--- a/org.eclipse.egit.mylyn.ui.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.mylyn.ui.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: Git Team Provider Mylyn UI Test Fragment
 Automatic-Module-Name: org.eclipse.egit.mylyn.ui.test
 Bundle-SymbolicName: org.eclipse.egit.mylyn.ui.test
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Fragment-Host: org.eclipse.egit.mylyn.ui
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Bundle-Vendor: Eclipse.org
diff --git a/org.eclipse.egit.mylyn.ui.test/pom.xml b/org.eclipse.egit.mylyn.ui.test/pom.xml
index 60e77d3..c0108ba 100644
--- a/org.eclipse.egit.mylyn.ui.test/pom.xml
+++ b/org.eclipse.egit.mylyn.ui.test/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.egit.mylyn.ui.test</artifactId>
diff --git a/org.eclipse.egit.mylyn.ui/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.mylyn.ui/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit.mylyn.ui/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.mylyn.ui/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF b/org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF
index 6b5f90c..eaae750 100644
--- a/org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.egit.mylyn.ui
 Bundle-SymbolicName: org.eclipse.egit.mylyn.ui;singleton:=true
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Bundle-Activator: org.eclipse.egit.internal.mylyn.ui.EGitMylynUI
 Bundle-Vendor: %Bundle-Vendor
 Require-Bundle: org.eclipse.jface,
@@ -19,16 +19,16 @@
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Bundle-ActivationPolicy: lazy
 Bundle-Localization: plugin
-Export-Package: org.eclipse.egit.internal.mylyn.ui;version="5.1.3";x-friends:="org.eclipse.egit.ui.test",
- org.eclipse.egit.internal.mylyn.ui.commit;version="5.1.3";x-internal:=true
-Import-Package: org.eclipse.egit.core;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.synchronize;version="[5.1.3,5.2.0)",
- org.eclipse.egit.ui;version="[5.1.3,5.2.0)",
- org.eclipse.egit.ui.internal.commit;version="[5.1.3,5.2.0)",
- org.eclipse.egit.ui.internal.staging;version="[5.1.3,5.2.0)",
- org.eclipse.egit.ui.internal.synchronize.model;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.errors;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.lib;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.transport;version="[5.1.3,5.2.0)",
+Export-Package: org.eclipse.egit.internal.mylyn.ui;version="5.2.0";x-friends:="org.eclipse.egit.ui.test",
+ org.eclipse.egit.internal.mylyn.ui.commit;version="5.2.0";x-internal:=true
+Import-Package: org.eclipse.egit.core;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.synchronize;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.ui;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.ui.internal.commit;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.ui.internal.staging;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.ui.internal.synchronize.model;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.errors;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.lib;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.revwalk;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.transport;version="[5.2.0,5.3.0)",
  org.eclipse.ui.plugin
diff --git a/org.eclipse.egit.mylyn.ui/pom.xml b/org.eclipse.egit.mylyn.ui/pom.xml
index e4961c1..494a64a 100644
--- a/org.eclipse.egit.mylyn.ui/pom.xml
+++ b/org.eclipse.egit.mylyn.ui/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.egit.mylyn.ui</artifactId>
diff --git a/org.eclipse.egit.repository/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.repository/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit.repository/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.repository/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.repository/pom.xml b/org.eclipse.egit.repository/pom.xml
index b4ab7cf..c5ab2a0 100644
--- a/org.eclipse.egit.repository/pom.xml
+++ b/org.eclipse.egit.repository/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.egit.repository</artifactId>
diff --git a/org.eclipse.egit.source-feature/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.source-feature/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit.source-feature/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.source-feature/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.source-feature/feature.xml b/org.eclipse.egit.source-feature/feature.xml
index 56f19a2..1543e70 100644
--- a/org.eclipse.egit.source-feature/feature.xml
+++ b/org.eclipse.egit.source-feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.egit.source"
       label="%featureName"
-      version="5.1.3.qualifier"
+      version="5.2.0.qualifier"
       provider-name="%providerName"
       plugin="org.eclipse.egit"
       license-feature="org.eclipse.license"
diff --git a/org.eclipse.egit.source-feature/pom.xml b/org.eclipse.egit.source-feature/pom.xml
index a4cc6c9..13af495 100644
--- a/org.eclipse.egit.source-feature/pom.xml
+++ b/org.eclipse.egit.source-feature/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.egit.feature</groupId>
diff --git a/org.eclipse.egit.target/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.target/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit.target/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.target/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.target/META-INF/MANIFEST.MF b/org.eclipse.egit.target/META-INF/MANIFEST.MF
index cfe3482..a2569e9 100644
--- a/org.eclipse.egit.target/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.target/META-INF/MANIFEST.MF
@@ -2,5 +2,5 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: EGit Target Platform Bundle
 Bundle-SymbolicName: org.eclipse.egit.target
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/org.eclipse.egit.target/pom.xml b/org.eclipse.egit.target/pom.xml
index f048799..b08a3f8 100644
--- a/org.eclipse.egit.target/pom.xml
+++ b/org.eclipse.egit.target/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <build>
diff --git a/org.eclipse.egit.ui.importer.tests/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.ui.importer.tests/.settings/org.eclipse.mylyn.team.ui.prefs
index ce7a0f0..984263d 100644
--- a/org.eclipse.egit.ui.importer.tests/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.ui.importer.tests/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,2 +1,2 @@
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.ui.importer.tests/META-INF/MANIFEST.MF b/org.eclipse.egit.ui.importer.tests/META-INF/MANIFEST.MF
index 7f49216..8767dc5 100644
--- a/org.eclipse.egit.ui.importer.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.ui.importer.tests/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %plugin_name
 Automatic-Module-Name: org.eclipse.egit.ui.importer.tests
 Bundle-SymbolicName: org.eclipse.egit.ui.importer.tests
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Bundle-Vendor: %provider_name
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Bundle-Localization: plugin
diff --git a/org.eclipse.egit.ui.importer.tests/pom.xml b/org.eclipse.egit.ui.importer.tests/pom.xml
index b8031f1..f95ea49 100644
--- a/org.eclipse.egit.ui.importer.tests/pom.xml
+++ b/org.eclipse.egit.ui.importer.tests/pom.xml
@@ -14,7 +14,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<parent>
 		<groupId>org.eclipse.egit</groupId>
-		<version>5.1.3-SNAPSHOT</version>
+		<version>5.2.0-SNAPSHOT</version>
 		<artifactId>egit-parent</artifactId>
 	</parent>
 	<artifactId>org.eclipse.egit.ui.importer.tests</artifactId>
diff --git a/org.eclipse.egit.ui.smartimport/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.ui.smartimport/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit.ui.smartimport/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.ui.smartimport/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.ui.smartimport/META-INF/MANIFEST.MF b/org.eclipse.egit.ui.smartimport/META-INF/MANIFEST.MF
index 1a1e1af..a2933ed 100644
--- a/org.eclipse.egit.ui.smartimport/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.ui.smartimport/META-INF/MANIFEST.MF
@@ -3,14 +3,14 @@
 Bundle-Name: %fragment_name
 Automatic-Module-Name: org.eclipse.egit.ui.smartimport
 Bundle-SymbolicName: org.eclipse.egit.ui.smartimport;singleton:=true
-Fragment-Host: org.eclipse.egit.ui;bundle-version="[5.1.3,5.2.0)"
-Bundle-Version: 5.1.3.qualifier
+Fragment-Host: org.eclipse.egit.ui;bundle-version="[5.2.0,5.3.0)"
+Bundle-Version: 5.2.0.qualifier
 Bundle-Vendor: %provider_name
 Require-Bundle: org.eclipse.ui,
  org.eclipse.ui.ide;bundle-version="3.12.0"
 Bundle-Localization: fragment
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Export-Package: org.eclipse.egit.ui.internal.clone;version="5.1.3";x-internal:=true;
+Export-Package: org.eclipse.egit.ui.internal.clone;version="5.2.0";x-internal:=true;
  uses:="org.eclipse.ui,
   org.eclipse.jface.wizard,
   org.eclipse.jface.viewers"
diff --git a/org.eclipse.egit.ui.smartimport/pom.xml b/org.eclipse.egit.ui.smartimport/pom.xml
index 3eb5100..1d706aa 100644
--- a/org.eclipse.egit.ui.smartimport/pom.xml
+++ b/org.eclipse.egit.ui.smartimport/pom.xml
@@ -14,7 +14,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<parent>
 		<groupId>org.eclipse.egit</groupId>
-		<version>5.1.3-SNAPSHOT</version>
+		<version>5.2.0-SNAPSHOT</version>
 		<artifactId>egit-parent</artifactId>
 	</parent>
 	<artifactId>org.eclipse.egit.ui.smartimport</artifactId>
diff --git a/org.eclipse.egit.ui.test/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.ui.test/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit.ui.test/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.ui.test/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.ui.test/META-INF/MANIFEST.MF b/org.eclipse.egit.ui.test/META-INF/MANIFEST.MF
index 51ed0e4..e599c71 100644
--- a/org.eclipse.egit.ui.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.ui.test/META-INF/MANIFEST.MF
@@ -5,7 +5,7 @@
 Automatic-Module-Name: org.eclipse.egit.ui.test
 Bundle-SymbolicName: org.eclipse.egit.ui.test;singleton:=true
 Fragment-Host: org.eclipse.egit.ui
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Require-Bundle: org.apache.log4j;bundle-version="[1.0.0,2.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
@@ -17,22 +17,22 @@
  org.mockito;bundle-version="[1.8.0,1.10.0)",
  org.eclipse.jdt.launching;bundle-version="[3.8.0,4.0.0)"
 Import-Package: org.eclipse.core.net.proxy;bundle-version="[1.1.0,2.0.0)",
- org.eclipse.egit.core.test;version="[5.1.3,5.2.0)",
- org.eclipse.egit.gitflow;version="[5.1.3,5.2.0)",
- org.eclipse.egit.gitflow.op;version="[5.1.3,5.2.0)",
- org.eclipse.egit.gitflow.ui;version="[5.1.3,5.2.0)",
- org.eclipse.egit.gitflow.ui.internal;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.api;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.api.errors;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.attributes;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.junit;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.junit.http;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.lib;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.storage.file;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.transport;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.transport.resolver;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.util;version="[5.1.3,5.2.0)",
+ org.eclipse.egit.core.test;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.gitflow;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.gitflow.op;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.gitflow.ui;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.gitflow.ui.internal;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.api;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.api.errors;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.attributes;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.junit;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.junit.http;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.lib;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.revwalk;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.storage.file;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.transport;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.util;version="[5.2.0,5.3.0)",
  org.eclipse.swt.widgets,
  org.eclipse.swtbot.eclipse.finder,
  org.eclipse.swtbot.eclipse.finder.waits,
diff --git a/org.eclipse.egit.ui.test/pom.xml b/org.eclipse.egit.ui.test/pom.xml
index 8fbb29d..947c5ba 100644
--- a/org.eclipse.egit.ui.test/pom.xml
+++ b/org.eclipse.egit.ui.test/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.egit.ui.test</artifactId>
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/actions/SwitchToMenuTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/actions/SwitchToMenuTest.java
index 311d42a..768dc38 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/actions/SwitchToMenuTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/actions/SwitchToMenuTest.java
@@ -17,12 +17,17 @@
 import static org.mockito.Mockito.when;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.eclipse.core.expressions.EvaluationContext;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.egit.ui.JobFamilies;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.test.ContextMenuHelper;
+import org.eclipse.egit.ui.test.TestUtil;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.jgit.api.Git;
@@ -33,6 +38,7 @@
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
 import org.eclipse.ui.ISources;
 import org.eclipse.ui.handlers.IHandlerService;
 import org.eclipse.ui.services.IServiceLocator;
@@ -41,6 +47,12 @@
 
 public class SwitchToMenuTest extends LocalRepositoryTestCase {
 
+	private static final String TEAM_LABEL = util
+			.getPluginLocalizedValue("TeamMenu.label");
+
+	private static final String SWITCH_TO_LABEL_MULTIPLE = util
+			.getPluginLocalizedValue("SwitchToMenuMultiple.label");
+
 	private SwitchToMenu switchToMenu;
 
 	private IHandlerService handlerService;
@@ -152,12 +164,109 @@
 		assertTextEquals(UIText.SwitchToMenu_OtherMenuLabel, items[23]);
 	}
 
+	@Test
+	public void validateMenuEntriesForMultiSelectionWithMultipleRepositories()
+			throws Exception {
+		File gitOne = createProjectAndCommitToRepository(REPO1, PROJ1);
+		File gitTwo = createProjectAndCommitToRepository(REPO2, PROJ2);
+
+		Repository repoOne = lookupRepository(gitOne);
+		Repository repoTwo = lookupRepository(gitTwo);
+		for (int i = 0; i < SwitchToMenu.MAX_NUM_MENU_ENTRIES; i++) {
+			createBranch(repoOne, "refs/heads/change/" + i);
+			createBranch(repoTwo, "refs/heads/change/" + (i + 15));
+		}
+
+		mockMultiProjectSelection(PROJ1, PROJ2);
+
+		MenuItem[] items = fillMenu();
+		assertTextEquals("change/15", items[0]);
+		assertTextEquals("change/16", items[1]);
+		assertTextEquals("change/17", items[2]);
+		assertTextEquals("change/18", items[3]);
+		assertTextEquals("change/19", items[4]);
+		assertTextEquals("master", items[5]);
+		assertTextEquals("stable", items[6]);
+	}
+
+	@Test
+	public void validateBranchSwitchingForForMultiSelectionWithMultipleRepositories()
+			throws Exception {
+
+		File gitOne = createProjectAndCommitToRepository(REPO1, PROJ1);
+		File gitTwo = createProjectAndCommitToRepository(REPO2, PROJ2);
+		Repository repoOne = lookupRepository(gitOne);
+		Repository repoTwo = lookupRepository(gitTwo);
+
+		// Set up different branch sources
+		try (Git git = new Git(repoOne)) {
+			git.checkout().setName("master").call();
+		}
+
+		try (Git git = new Git(repoTwo)) {
+			git.checkout().setName("stable").call();
+		}
+
+		String branchName = "commonBranchAmongRepositories";
+		String branchRef = "refs/heads/" + branchName;
+		createBranch(repoOne, branchRef);
+		createBranch(repoTwo, branchRef);
+
+		assertEquals("master", repoOne.getBranch());
+		assertEquals("stable", repoTwo.getBranch());
+
+		// Multi repository Switch To
+		SWTBotTree tree = TestUtil.getExplorerTree();
+		SWTBotTree select = tree.select(tree.getAllItems());
+		ContextMenuHelper.clickContextMenu(select, TEAM_LABEL,
+				SWITCH_TO_LABEL_MULTIPLE, branchName);
+		TestUtil.joinJobs(JobFamilies.CHECKOUT);
+
+		assertEquals(branchName, repoOne.getBranch());
+		assertEquals(branchName, repoTwo.getBranch());
+	}
+
+	@Test
+	public void multipleSelectionWithMultipleRepositoriesAndNoCommonBranches()
+			throws Exception {
+		File gitOne = createProjectAndCommitToRepository(REPO1, PROJ1);
+		File gitTwo = createProjectAndCommitToRepository(REPO2, PROJ2);
+
+		try (Git git = new Git(lookupRepository(gitOne))) {
+			git.checkout().setName("stable").call();
+			git.branchDelete().setBranchNames("master").setForce(true).call();
+		}
+
+		try (Git git = new Git(lookupRepository(gitTwo))) {
+			git.branchDelete().setBranchNames("stable").setForce(true).call();
+		}
+
+		mockMultiProjectSelection(PROJ1, PROJ2);
+
+		MenuItem[] items = fillMenu();
+		assertTextEquals(UIText.SwitchToMenu_NoCommonBranchesFound, items[0]);
+
+		// delete reflog again to not confuse other tests
+		new File(gitOne, Constants.LOGS + "/" + Constants.HEAD).delete();
+		new File(gitTwo, Constants.LOGS + "/" + Constants.HEAD).delete();
+	}
+
 	private void mockSelection(ISelection selection) {
 		EvaluationContext context = new EvaluationContext(null, new Object());
 		context.addVariable(ISources.ACTIVE_MENU_SELECTION_NAME, selection);
 		when(handlerService.getCurrentState()).thenReturn(context);
 	}
 
+	private void mockMultiProjectSelection(String... projNames) {
+
+		List<IProject> projects = new ArrayList<>();
+		for (String s : projNames) {
+			projects.add(
+					ResourcesPlugin.getWorkspace().getRoot().getProject(s));
+		}
+		mockSelection(new StructuredSelection(projects));
+	}
+
 	private MenuItem[] fillMenu() {
 		final MenuItem[][] items = new MenuItem[1][];
 		Display.getDefault().syncExec(new Runnable() {
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/branch/BranchProjectTrackerTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/branch/BranchProjectTrackerTest.java
index ace9ed6..0ddda28 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/branch/BranchProjectTrackerTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/branch/BranchProjectTrackerTest.java
@@ -18,6 +18,8 @@
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
+import java.io.IOException;
+import java.util.List;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.ResourcesPlugin;
@@ -49,17 +51,20 @@
 		repository = Activator.getDefault().getRepositoryCache()
 				.lookupRepository(repoFile);
 		assertNotNull(repository);
-		BranchProjectTracker tracker = new BranchProjectTracker(repository);
 		org.eclipse.egit.ui.Activator.getDefault().getPreferenceStore()
-				.setValue(tracker.getPreference(Constants.MASTER), "");
+				.setValue(getPreferenceKey(Constants.MASTER), "");
 		org.eclipse.egit.ui.Activator.getDefault().getPreferenceStore()
-				.setValue(tracker.getPreference(BRANCH), "");
+				.setValue(getPreferenceKey(BRANCH), "");
+	}
+
+	private String getPreferenceKey(String branch) {
+		return ProjectTrackerPreferenceHelper.getPreferenceKey(repository,
+				branch);
 	}
 
 	@Test
 	public void twoProjectsWithOnlyOneOnBranch() throws Exception {
-		BranchProjectTracker tracker = new BranchProjectTracker(repository);
-		String[] paths = tracker.getProjectPaths();
+		String[] paths = getProjectPaths();
 		assertNotNull(paths);
 		assertEquals(0, paths.length);
 		assertNotNull(Git.wrap(repository).branchCreate().setName(BRANCH)
@@ -67,7 +72,7 @@
 		BranchOperationUI.checkout(repository, BRANCH).start();
 		TestUtil.joinJobs(JobFamilies.CHECKOUT);
 
-		paths = tracker.getProjectPaths(Constants.MASTER);
+		paths = getProjectPaths(Constants.MASTER);
 		assertNotNull(paths);
 		assertEquals(2, paths.length);
 
@@ -85,7 +90,7 @@
 		BranchOperationUI.checkout(repository, Constants.MASTER).start();
 		TestUtil.joinJobs(JobFamilies.CHECKOUT);
 
-		paths = tracker.getProjectPaths(BRANCH);
+		paths = getProjectPaths(BRANCH);
 		assertNotNull(paths);
 		assertEquals(1, paths.length);
 
@@ -108,4 +113,19 @@
 		assertTrue(project2.exists());
 		assertTrue(project2.isOpen());
 	}
+
+	private String[] getProjectPaths() {
+		try {
+			String branch = repository.getBranch();
+			return getProjectPaths(branch);
+		} catch (IOException e) {
+			return new String[0];
+		}
+	}
+
+	private String[] getProjectPaths(String branch) {
+		List<String> value = ProjectTrackerPreferenceHelper
+				.restoreFromPreferences(repository, branch);
+		return value.toArray(new String[0]);
+	}
 }
diff --git a/org.eclipse.egit.ui/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit.ui/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit.ui/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit.ui/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit.ui/META-INF/MANIFEST.MF b/org.eclipse.egit.ui/META-INF/MANIFEST.MF
index 7535d84..16f0643 100644
--- a/org.eclipse.egit.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.ui/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %plugin_name
 Automatic-Module-Name: org.eclipse.egit.ui
 Bundle-SymbolicName: org.eclipse.egit.ui;singleton:=true
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Bundle-Activator: org.eclipse.egit.ui.Activator
 Bundle-Vendor: %provider_name
 Bundle-Localization: plugin
@@ -30,91 +30,91 @@
  org.eclipse.ui.views;bundle-version="[3.4.0,4.0.0)"
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.egit.core;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.attributes;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.internal;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.internal.gerrit;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.internal.indexdiff;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.internal.job;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.internal.rebase;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.internal.storage;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.internal.util;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.op;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.project;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.securestorage;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.synchronize;version="[5.1.3,5.2.0)",
- org.eclipse.egit.core.synchronize.dto;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.annotations;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.api;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.api.errors;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.attributes;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.blame;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.diff;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.dircache;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.errors;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.events;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.lib;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.merge;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.notes;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.revplot;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.revwalk.filter;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.storage.file;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.submodule;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.transport;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.treewalk;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.util;version="[5.1.3,5.2.0)",
- org.eclipse.jgit.util.io;version="[5.1.3,5.2.0)"
-Export-Package: org.eclipse.egit.ui;version="5.1.3";x-friends:="org.eclipse.egit.mylyn.ui,org.eclipse.egit.gitflow.ui,org.eclipse.mylyn.github.ui",
- org.eclipse.egit.ui.internal;version="5.1.3";x-friends:="org.eclipse.egit.import,org.eclipse.egit.gitflow.ui,org.eclipse.mylyn.github.ui",
- org.eclipse.egit.ui.internal.actions;version="5.1.3";x-friends:="org.eclipse.egit.gitflow.ui",
- org.eclipse.egit.ui.internal.blame;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.branch;version="5.1.3";x-friends:="org.eclipse.egit.gitflow.ui,org.eclipse.mylyn.github.ui",
- org.eclipse.egit.ui.internal.clean;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.clone;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.commands;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.commands.shared;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.commit;version="5.1.3";x-friends:="org.eclipse.egit.mylyn.ui,org.eclipse.egit.gitflow.ui,org.eclipse.mylyn.github.ui",
- org.eclipse.egit.ui.internal.commit.command;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.components;version="5.1.3";x-friends:="org.eclipse.mylyn.github.ui",
- org.eclipse.egit.ui.internal.credentials;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.decorators;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.dialogs;version="5.1.3";x-friends:="org.eclipse.egit.gitflow.ui",
- org.eclipse.egit.ui.internal.expressions;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.factories;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.fetch;version="5.1.3";x-friends:="org.eclipse.mylyn.github.ui",
- org.eclipse.egit.ui.internal.gerrit;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.handler;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.history;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.history.command;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.importing;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.jobs;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.merge;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.operations;version="5.1.3";x-friends:="org.eclipse.egit.gitflow.ui",
- org.eclipse.egit.ui.internal.patch;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.preferences;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.provisional.wizards;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.pull;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.push;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.rebase;version="5.1.3";x-friends:="org.eclipse.egit.gitflow.ui",
- org.eclipse.egit.ui.internal.reflog;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.reflog.command;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.repository;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.repository.tree;version="5.1.3";x-friends:="org.eclipse.egit.gitflow.ui",
- org.eclipse.egit.ui.internal.repository.tree.command;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.resources;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.revision;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.search;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.selection;version="5.1.3";x-friends:="org.eclipse.egit.gitflow.ui",
- org.eclipse.egit.ui.internal.sharing;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.staging;version="5.1.3";x-friends:="org.eclipse.egit.mylyn.ui",
- org.eclipse.egit.ui.internal.stash;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.submodule;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.synchronize;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.synchronize.action;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.synchronize.compare;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.synchronize.mapping;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.synchronize.model;version="5.1.3";x-friends:="org.eclipse.egit.mylyn.ui",
- org.eclipse.egit.ui.internal.trace;version="5.1.3";x-internal:=true,
- org.eclipse.egit.ui.internal.variables;version="5.1.3";x-internal:=true
+Import-Package: org.eclipse.egit.core;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.attributes;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.internal;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.internal.gerrit;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.internal.indexdiff;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.internal.job;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.internal.rebase;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.internal.storage;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.internal.util;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.op;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.project;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.securestorage;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.synchronize;version="[5.2.0,5.3.0)",
+ org.eclipse.egit.core.synchronize.dto;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.annotations;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.api;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.api.errors;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.attributes;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.blame;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.diff;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.dircache;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.errors;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.events;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.lib;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.merge;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.notes;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.revplot;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.revwalk;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.revwalk.filter;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.storage.file;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.submodule;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.transport;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.treewalk;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.util;version="[5.2.0,5.3.0)",
+ org.eclipse.jgit.util.io;version="[5.2.0,5.3.0)"
+Export-Package: org.eclipse.egit.ui;version="5.2.0";x-friends:="org.eclipse.egit.mylyn.ui,org.eclipse.egit.gitflow.ui,org.eclipse.mylyn.github.ui",
+ org.eclipse.egit.ui.internal;version="5.2.0";x-friends:="org.eclipse.egit.import,org.eclipse.egit.gitflow.ui,org.eclipse.mylyn.github.ui",
+ org.eclipse.egit.ui.internal.actions;version="5.2.0";x-friends:="org.eclipse.egit.gitflow.ui",
+ org.eclipse.egit.ui.internal.blame;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.branch;version="5.2.0";x-friends:="org.eclipse.egit.gitflow.ui,org.eclipse.mylyn.github.ui",
+ org.eclipse.egit.ui.internal.clean;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.clone;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.commands;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.commands.shared;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.commit;version="5.2.0";x-friends:="org.eclipse.egit.mylyn.ui,org.eclipse.egit.gitflow.ui,org.eclipse.mylyn.github.ui",
+ org.eclipse.egit.ui.internal.commit.command;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.components;version="5.2.0";x-friends:="org.eclipse.mylyn.github.ui",
+ org.eclipse.egit.ui.internal.credentials;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.decorators;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.dialogs;version="5.2.0";x-friends:="org.eclipse.egit.gitflow.ui",
+ org.eclipse.egit.ui.internal.expressions;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.factories;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.fetch;version="5.2.0";x-friends:="org.eclipse.mylyn.github.ui",
+ org.eclipse.egit.ui.internal.gerrit;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.handler;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.history;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.history.command;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.importing;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.jobs;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.merge;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.operations;version="5.2.0";x-friends:="org.eclipse.egit.gitflow.ui",
+ org.eclipse.egit.ui.internal.patch;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.preferences;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.provisional.wizards;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.pull;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.push;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.rebase;version="5.2.0";x-friends:="org.eclipse.egit.gitflow.ui",
+ org.eclipse.egit.ui.internal.reflog;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.reflog.command;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.repository;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.repository.tree;version="5.2.0";x-friends:="org.eclipse.egit.gitflow.ui",
+ org.eclipse.egit.ui.internal.repository.tree.command;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.resources;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.revision;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.search;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.selection;version="5.2.0";x-friends:="org.eclipse.egit.gitflow.ui",
+ org.eclipse.egit.ui.internal.sharing;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.staging;version="5.2.0";x-friends:="org.eclipse.egit.mylyn.ui",
+ org.eclipse.egit.ui.internal.stash;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.submodule;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.synchronize;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.synchronize.action;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.synchronize.compare;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.synchronize.mapping;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.synchronize.model;version="5.2.0";x-friends:="org.eclipse.egit.mylyn.ui",
+ org.eclipse.egit.ui.internal.trace;version="5.2.0";x-internal:=true,
+ org.eclipse.egit.ui.internal.variables;version="5.2.0";x-internal:=true
diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties
index 5af78c2..ab5c53a 100644
--- a/org.eclipse.egit.ui/plugin.properties
+++ b/org.eclipse.egit.ui/plugin.properties
@@ -354,6 +354,7 @@
 RepositoriesViewContext.name= In Git Repositories View
 
 SwitchToMenu.label = S&witch To
+SwitchToMenuMultiple.label = S&witch Repositories To
 
 StashesMenu.label = &Stashes
 
@@ -463,4 +464,8 @@
 
 RebaseInteractiveOpenInCommitViewer.label=&Open in Commit Viewer
 
-InstallLfsLocalCommand.label=Enable LFS locally
\ No newline at end of file
+InstallLfsLocalCommand.label=Enable LFS locally
+
+GitSearchActionSet.label=Git Search
+GitSearchActionSet.description=Action set containing search related Git actions
+OpenCommitSearchPageAction.label=&Git...
\ No newline at end of file
diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml
index 835ca8c..52981b0 100644
--- a/org.eclipse.egit.ui/plugin.xml
+++ b/org.eclipse.egit.ui/plugin.xml
@@ -3704,40 +3704,6 @@
                visible="true">
          </separator>
          <command
-               commandId="org.eclipse.egit.ui.team.Merge"
-               icon="icons/obj16/merge.png"
-               label="%RepoViewMergeSimple.label"
-               style="push">
-            <visibleWhen
-                  checkEnabled="false">
-               <and>
-                  <count
-                        value="1">
-                  </count>
-                  <iterate>
-                     <and>
-                        <or>
-                           <instanceof
-                                 value="org.eclipse.egit.ui.internal.repository.tree.TagNode">
-                           </instanceof>
-                           <instanceof
-                                 value="org.eclipse.egit.ui.internal.repository.tree.RefNode">
-                           </instanceof>
-                        </or>
-                        <test
-                              property="GitRepository.canMerge">
-                        </test>
-                        <not>
-                           <test
-                                 property="GitRepository.isRefCheckedOut">
-                           </test>
-                        </not>
-                     </and>
-                  </iterate>
-               </and>
-            </visibleWhen>
-         </command>
-         <command
                commandId="org.eclipse.ui.edit.delete"
                label="%DeleteTagCommand.name"
                style="push">
@@ -3756,36 +3722,6 @@
             </visibleWhen>
          </command>
          <command
-               commandId="org.eclipse.egit.ui.team.Rebase"
-               label="%RebaseCommand.label"
-               style="push">
-            <visibleWhen
-                  checkEnabled="false">
-               <and>
-                  <count
-                        value="1">
-                  </count>
-                  <iterate>
-                     <and>
-                        <test
-                              property="GitRepository.canMerge">
-                        </test>
-                        <and>
-                           <instanceof
-                                 value="org.eclipse.egit.ui.internal.repository.tree.RefNode">
-                           </instanceof>
-                           <not>
-                              <test
-                                    property="GitRepository.isRefCheckedOut">
-                              </test>
-                           </not>
-                        </and>
-                     </and>
-                  </iterate>
-               </and>
-            </visibleWhen>
-         </command>
-         <command
                commandId="org.eclipse.egit.ui.team.Synchronize"
                icon="icons/obj16/synchronize.png"
                label="%RepoViewSynchronize.label"
@@ -4066,6 +4002,44 @@
             locationURI="popup:org.eclipse.egit.ui.RepositoriesView?after=repo-0">
          <menu
                icon="icons/obj16/branches_obj.png"
+               label="%SwitchToMenuMultiple.label">
+            <dynamic
+                  class="org.eclipse.egit.ui.internal.actions.SwitchToMenu"
+                  id="org.eclipse.egit.ui.switchToMenu">
+            </dynamic>
+            <visibleWhen
+                  checkEnabled="false">
+               <and>
+                  <iterate
+                        ifEmpty="false"
+                        operator="and">
+                     <and>
+                        <or>
+                           <instanceof
+                                 value="org.eclipse.egit.ui.internal.repository.tree.RepositoryNode">
+                           </instanceof>
+                           <instanceof
+                                 value="org.eclipse.egit.ui.internal.repository.tree.BranchesNode">
+                           </instanceof>
+                           <instanceof
+                                 value="org.eclipse.egit.ui.internal.repository.tree.LocalNode">
+                           </instanceof>
+                        </or>
+                        <not>
+                           <test
+                                 property="GitRepository.isBare">
+                           </test>
+                        </not>
+                     </and>
+                  </iterate>
+                  <test
+                        property="GitSelection.selectionMultipleRepositories">
+                  </test>
+               </and>
+            </visibleWhen>
+         </menu>
+         <menu
+               icon="icons/obj16/branches_obj.png"
                label="%SwitchToMenu.label">
             <dynamic
                   class="org.eclipse.egit.ui.internal.actions.SwitchToMenu"
@@ -4452,6 +4426,40 @@
          <command
                commandId="org.eclipse.egit.ui.team.Merge"
                icon="icons/obj16/merge.png"
+               label="%RepoViewMergeSimple.label"
+               style="push">
+            <visibleWhen
+                  checkEnabled="false">
+               <and>
+                  <count
+                        value="1">
+                  </count>
+                  <iterate>
+                     <and>
+                        <or>
+                           <instanceof
+                                 value="org.eclipse.egit.ui.internal.repository.tree.TagNode">
+                           </instanceof>
+                           <instanceof
+                                 value="org.eclipse.egit.ui.internal.repository.tree.RefNode">
+                           </instanceof>
+                        </or>
+                        <test
+                              property="GitRepository.canMerge">
+                        </test>
+                        <not>
+                           <test
+                                 property="GitRepository.isRefCheckedOut">
+                           </test>
+                        </not>
+                     </and>
+                  </iterate>
+               </and>
+            </visibleWhen>
+         </command>
+         <command
+               commandId="org.eclipse.egit.ui.team.Merge"
+               icon="icons/obj16/merge.png"
                label="%RepoViewMerge.label"
                style="push">
             <visibleWhen
@@ -4485,6 +4493,36 @@
          </command>
          <command
                commandId="org.eclipse.egit.ui.team.Rebase"
+               label="%RebaseCommand.label"
+               style="push">
+            <visibleWhen
+                  checkEnabled="false">
+               <and>
+                  <count
+                        value="1">
+                  </count>
+                  <iterate>
+                     <and>
+                        <test
+                              property="GitRepository.canMerge">
+                        </test>
+                        <and>
+                           <instanceof
+                                 value="org.eclipse.egit.ui.internal.repository.tree.RefNode">
+                           </instanceof>
+                           <not>
+                              <test
+                                    property="GitRepository.isRefCheckedOut">
+                              </test>
+                           </not>
+                        </and>
+                     </and>
+                  </iterate>
+               </and>
+            </visibleWhen>
+         </command>
+         <command
+               commandId="org.eclipse.egit.ui.team.Rebase"
                label="%RebaseCommand.label2"
                style="push">
             <visibleWhen
@@ -5143,6 +5181,21 @@
                   </test>
                </visibleWhen>
             </menu>
+            <menu
+                  id="egit.menu.switchMultiple"
+                  label="%SwitchToMenuMultiple.label"
+                  icon="icons/obj16/branches_obj.png">
+               <dynamic
+                     class="org.eclipse.egit.ui.internal.actions.SwitchToMenu"
+                     id="org.eclipse.egit.ui.switchToMenuMultiple">
+               </dynamic>
+               <visibleWhen
+                     checkEnabled="false">
+                  <test
+                        property="GitSelection.resourcesMultipleRepositories">
+                  </test>
+               </visibleWhen>
+            </menu>
             <separator
                   name="org.eclipse.egit.ui.AdvancedSeparator">
             </separator>
@@ -6343,7 +6396,7 @@
             class="org.eclipse.egit.ui.internal.selection.SelectionPropertyTester"
             id="org.eclipse.egit.ui.SelectionTester"
             namespace="GitSelection"
-            properties="projectsSingleRepository,projectsWithRepositories,resourcesSingleRepository,fileOrFolderInRepository,resourcesAllInRepository,selectionSingleRepository"
+            properties="projectsSingleRepository,projectsWithRepositories,resourcesSingleRepository,resourcesMultipleRepositories,fileOrFolderInRepository,resourcesAllInRepository,selectionSingleRepository,selectionMultipleRepositories"
             type="java.util.Collection">
       </propertyTester>
       <propertyTester
@@ -7027,7 +7080,20 @@
                style="push"
                toolbarPath="org.eclipse.search.searchActionSet/Search"
                tooltip="%OpenCommitAction.tooltip"/>
-       </actionSet>
+      </actionSet>
+      <actionSet
+            label="%GitSearchActionSet.label"
+            description="%GitSearchActionSet.description"
+            visible="false"
+            id="org.eclipse.egit.ui.SearchActionSet">
+         <action
+               label="%OpenCommitSearchPageAction.label"
+               icon="icons/obj16/search-commit.png"
+               class="org.eclipse.egit.ui.internal.search.OpenCommitSearchPageAction"
+               menubarPath="org.eclipse.search.menu/dialogGroup"
+               id="org.eclipse.egit.ui.actions.OpenCommitSearchPage">
+         </action>
+      </actionSet>
    </extension>
    <extension
          point="org.eclipse.ui.actionSetPartAssociations">
@@ -7054,6 +7120,36 @@
          <part
                id="org.eclipse.team.ui.GenericHistoryView">
          </part>
+         <part
+               id="org.eclipse.team.sync.views.SynchronizeView">
+         </part>
+      </actionSetPartAssociation>
+      <actionSetPartAssociation
+            targetID="org.eclipse.egit.ui.SearchActionSet">
+         <part
+               id="org.eclipse.egit.ui.RepositoriesView">
+         </part>
+         <part
+               id="org.eclipse.egit.ui.StagingView">
+         </part>
+         <part
+               id="org.eclipse.egit.ui.CompareTreeView">
+         </part>
+         <part
+               id="org.eclipse.egit.ui.ReflogView">
+         </part>
+         <part
+               id="org.eclipse.egit.ui.InteractiveRebaseView">
+         </part>
+         <part
+               id="org.eclipse.egit.ui.commitEditor">
+         </part>
+         <part
+               id="org.eclipse.team.ui.GenericHistoryView">
+         </part>
+         <part
+               id="org.eclipse.team.sync.views.SynchronizeView">
+         </part>
       </actionSetPartAssociation>
    </extension>
 
diff --git a/org.eclipse.egit.ui/pom.xml b/org.eclipse.egit.ui/pom.xml
index 6e08346..6873683 100644
--- a/org.eclipse.egit.ui/pom.xml
+++ b/org.eclipse.egit.ui/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.egit.ui</artifactId>
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/GitRepositoriesPerspectiveFactory.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/GitRepositoriesPerspectiveFactory.java
index 5ea405f..a3e0a45 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/GitRepositoriesPerspectiveFactory.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/GitRepositoriesPerspectiveFactory.java
@@ -31,34 +31,43 @@
 	public void createInitialLayout(IPageLayout layout) {
 
 		// repositories on the left hand
-		layout.addView(RepositoriesView.VIEW_ID, IPageLayout.LEFT, (float) 0.5, layout.getEditorArea());
+		layout.addView(RepositoriesView.VIEW_ID, IPageLayout.LEFT, (float) 0.3,
+				layout.getEditorArea());
 
 		IFolderLayout bottom = layout.createFolder(
 				"bottom", IPageLayout.BOTTOM, (float) 0.5, //$NON-NLS-1$
 				layout.getEditorArea());
 
 		// Views under editor area
-		bottom.addView(IPageLayout.ID_PROP_SHEET);
 		bottom.addView(IHistoryView.VIEW_ID);
 		bottom.addView(ISynchronizeView.VIEW_ID);
 		bottom.addView(StagingView.VIEW_ID);
 		bottom.addView(ReflogView.VIEW_ID);
+		bottom.addView(IPageLayout.ID_PROP_SHEET);
 
 		// place holder for Package Explorer under repositories
 		layout.addPlaceholder("org.eclipse.jdt.ui.PackageExplorer", IPageLayout.BOTTOM, (float) 0.7, RepositoriesView.VIEW_ID); //$NON-NLS-1$
 
-		// shortcut to Package Explorer
+		// Window->Show View
 		layout.addShowViewShortcut("org.eclipse.jdt.ui.PackageExplorer"); //$NON-NLS-1$
-		// shortcut to History view
 		layout.addShowViewShortcut(IHistoryView.VIEW_ID);
-		// shortcut to Synchronize view
 		layout.addShowViewShortcut(ISynchronizeView.VIEW_ID);
-		// shortcut to Staging view
 		layout.addShowViewShortcut(StagingView.VIEW_ID);
-		// shortcut to Reflog view
 		layout.addShowViewShortcut(ReflogView.VIEW_ID);
+		layout.addShowViewShortcut(RepositoriesView.VIEW_ID);
 
+		// Window->Perspective->Open
+		layout.addPerspectiveShortcut("org.eclipse.ui.resourcePerspective"); //$NON-NLS-1$
+		layout.addPerspectiveShortcut(
+				"org.eclipse.team.ui.TeamSynchronizingPerspective"); //$NON-NLS-1$
+
+		// Window->Perspective->Customize
 		layout.addActionSet("org.eclipse.egit.ui.navigation"); //$NON-NLS-1$
+		layout.addActionSet("org.eclipse.egit.ui.SearchActionSet"); //$NON-NLS-1$
+
+		// File->New
+		layout.addNewWizardShortcut(
+				"org.eclipse.egit.ui.CreateRepositoryWizard"); //$NON-NLS-1$
 	}
 
 }
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java
index 759264e..d9aafff 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java
@@ -62,7 +62,7 @@
 	 * numerous order (also known as natural order), case insensitive.
 	 *
 	 * The comparator is guaranteed to return a non-zero value if
-	 * string1.equals(String2) returns false
+	 * {@code string1.equals(string2)} returns {@code false}.
 	 */
 	public static final Comparator<String> STRING_ASCENDING_COMPARATOR = new Comparator<String>() {
 		@Override
@@ -232,7 +232,7 @@
 	/**
 	 * Assuming that the string {@code commitMessage} is a commit message,
 	 * returns the offset in the string of the footer of the commit message, if
-	 * one can found, or -1 otherwise.
+	 * one can be found, or -1 otherwise.
 	 * <p>
 	 * A footer of a commit message is defined to be the non-empty lines
 	 * following the last empty line in the commit message if they have the
@@ -277,7 +277,7 @@
 	 *
 	 * @param resources
 	 *            the collection of {@link IResource}s.
-	 * @return A comma separated list the resource names. The last element is
+	 * @return A comma separated list of the resource names. The last element is
 	 *         separated with an ampersand.
 	 */
 	public static String getResourceNames(Iterable<IResource> resources) {
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/LabelColumnComparator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/LabelColumnComparator.java
new file mode 100644
index 0000000..40a624f
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/LabelColumnComparator.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (C) 2018, Luís Copetti <lhcopetti@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal;
+
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * A lexicographical label column comparator. It depends on the
+ * {@link ColumnLabelProvider} provided by the {@link TableViewer} to retrieve
+ * the label for the given column and supports {@link #ASCENDING},
+ * {@link #DESCENDING} and also the default ordering {@link #NONE}. Clicking on
+ * the column header repeatedly alternates between the previously mentioned
+ * ordering modes.
+ */
+public class LabelColumnComparator extends ViewerComparator {
+
+	private static final int ASCENDING = SWT.DOWN;
+
+	private static final int NONE = SWT.NONE;
+
+	private static final int DESCENDING = SWT.UP;
+
+	private final TableColumn column;
+
+	private final int columnIndex;
+
+	private final TableViewer tv;
+
+	private int direction;
+
+	/**
+	 *
+	 * @param tableViewer
+	 * @param column
+	 * @param columnIndex
+	 */
+	public LabelColumnComparator(TableViewer tableViewer, TableColumn column,
+			int columnIndex) {
+		super(null);
+		this.tv = tableViewer;
+		this.column = column;
+		this.columnIndex = columnIndex;
+		column.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (tv.getComparator() == LabelColumnComparator.this) {
+					if (direction == ASCENDING) {
+						setDirection(DESCENDING);
+					} else {
+						setDirection(NONE);
+					}
+				} else {
+					setDirection(ASCENDING);
+				}
+			}
+		});
+	}
+
+	private void setDirection(int newDirection) {
+		direction = newDirection;
+		Table table = column.getParent();
+		table.setSortDirection(direction);
+		if (direction == NONE) {
+			table.setSortColumn(null);
+			tv.setComparator(null);
+		} else {
+			table.setSortColumn(column);
+			if (tv.getComparator() == this) {
+				tv.refresh();
+			} else {
+				tv.setComparator(this);
+			}
+		}
+	}
+
+	@Override
+	public int compare(Viewer viewer, Object e1, Object e2) {
+		ColumnLabelProvider labelProvider = (ColumnLabelProvider) tv
+				.getLabelProvider(columnIndex);
+		String label1 = labelProvider.getText(e1);
+		String label2 = labelProvider.getText(e2);
+		if (direction == ASCENDING) {
+			return label1.compareTo(label2);
+		} else {
+			return label2.compareTo(label1);
+		}
+	}
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
index 72b824d..061316b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
@@ -3145,6 +3145,9 @@
 	public static String BranchAction_checkingOut;
 
 	/** */
+	public static String BranchAction_checkingOutMultiple;
+
+	/** */
 	public static String BranchAction_repositoryState;
 
 	/** */
@@ -3166,6 +3169,12 @@
 	public static String BranchConfigurationDialog_UpstreamBranchLabel;
 
 	/** */
+	public static String BranchOperationUI_CheckoutError_DialogMessage;
+
+	/** */
+	public static String BranchOperationUI_CheckoutError_DialogTitle;
+
+	/** */
 	public static String BranchOperationUI_CheckoutRemoteTrackingAsLocal;
 
 	/** */
@@ -4236,6 +4245,39 @@
 	public static String MultiPullResultDialog_WindowTitle;
 
 	/** */
+	public static String MultiBranchOperationResultDialog_WindowTitle;
+
+	/** */
+	public static String MultiBranchOperationResultDialog_RepositoryColumnHeader;
+
+	/** */
+	public static String MultiBranchOperationResultDialog_CheckoutStatusColumnHeader;
+
+	/** */
+	public static String MultiBranchOperationResultDialog_DialogTitle;
+
+	/** */
+	public static String MultiBranchOperationResultDialog_DialogErrorMessage;
+
+	/** */
+	public static String MultiBranchOperationResultDialog_CheckoutResultError;
+
+	/** */
+	public static String MultiBranchOperationResultDialog_CheckoutResultNonDeleted;
+
+	/** */
+	public static String MultiBranchOperationResultDialog_CheckoutResultConflicts;
+
+	/** */
+	public static String MultiBranchOperationResultDialog_CheckoutResultOK;
+
+	/** */
+	public static String MultiBranchOperationResultDialog_CheckoutResultNotTried;
+
+	/** */
+	public static String MultiBranchOperationResultDialog_OkStatus;
+
+	/** */
 	public static String UIIcons_errorDeterminingIconBase;
 
 	/** */
@@ -5069,6 +5111,9 @@
 	public static String SwitchToMenu_NewBranchMenuLabel;
 
 	/** */
+	public static String SwitchToMenu_NoCommonBranchesFound;
+
+	/** */
 	public static String SwitchToMenu_OtherMenuLabel;
 
 	/** */
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/MergeToolActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/MergeToolActionHandler.java
index 79d2b0a..bdbfb1c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/MergeToolActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/MergeToolActionHandler.java
@@ -16,6 +16,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 
 import org.eclipse.compare.CompareEditorInput;
@@ -64,13 +65,13 @@
 		Map<Repository, Collection<String>> pathsByRepository = ResourceUtil
 				.splitPathsByRepository(Arrays.asList(paths));
 
-		Set<Repository> repos = pathsByRepository.keySet();
-
-		if (repos.size() != 1)
+		if (pathsByRepository.size() != 1)
 			return false;
 
-		Repository repo = repos.iterator().next();
-		Collection<String> selectedRepoPaths = pathsByRepository.get(repo);
+		Entry<Repository, Collection<String>> pathsEntry = pathsByRepository
+				.entrySet().iterator().next();
+		Repository repo = pathsEntry.getKey();
+		Collection<String> selectedRepoPaths = pathsEntry.getValue();
 		if (selectedRepoPaths.isEmpty())
 			return false;
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ReplaceWithOursTheirsMenu.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ReplaceWithOursTheirsMenu.java
index e0dd1c4..453f052 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ReplaceWithOursTheirsMenu.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ReplaceWithOursTheirsMenu.java
@@ -18,6 +18,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import org.eclipse.core.resources.WorkspaceJob;
 import org.eclipse.core.runtime.CoreException;
@@ -80,9 +81,10 @@
 				.splitPathsByRepository(Arrays.asList(locations));
 		if (pathsByRepository.size() == 1) {
 
-			Repository repository = pathsByRepository.keySet().iterator()
-					.next();
-			Collection<String> paths = pathsByRepository.get(repository);
+			Entry<Repository, Collection<String>> entry = pathsByRepository
+					.entrySet().iterator().next();
+			Repository repository = entry.getKey();
+			Collection<String> paths = entry.getValue();
 			if (paths.size() == 1) {
 				String path = paths.iterator().next();
 				items.addAll(createSpecificOursTheirsItems(repository, path));
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SwitchToMenu.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SwitchToMenu.java
index e8fccc3..414ccdd 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SwitchToMenu.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SwitchToMenu.java
@@ -14,11 +14,15 @@
 package org.eclipse.egit.ui.internal.actions;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Stream;
 
 import org.eclipse.egit.ui.Activator;
 import org.eclipse.egit.ui.internal.CommonUtils;
@@ -90,13 +94,39 @@
 		if (handlerService == null)
 			return;
 
-		Repository repository = SelectionUtils
-				.getRepository(handlerService.getCurrentState());
-		if (repository != null)
-			createDynamicMenu(menu, repository);
+		Repository[] repositories = SelectionUtils
+				.getRepositories(handlerService.getCurrentState());
+
+		if (repositories.length > 0) {
+			createDynamicMenu(menu, repositories);
+		}
 	}
 
-	private void createDynamicMenu(Menu menu, final Repository repository) {
+	private void createDynamicMenu(Menu menu, final Repository[] repositories) {
+
+		if (!isMultipleSelection(repositories))
+		{
+			createNewBranchMenuItem(menu, repositories[0]);
+			createSeparator(menu);
+		}
+
+		int itemCount = createMostActiveBranchesMenuItems(menu, repositories);
+
+		if (!isMultipleSelection(repositories) && itemCount > 0) {
+			createSeparator(menu);
+			createOtherMenuItem(menu, repositories[0]);
+		}
+
+		if (itemCount == 0 && isMultipleSelection(repositories)) {
+			/*
+			 * If the menu would be empty, add a disabled menuItem to inform the
+			 * user that no common branches among the selection were found
+			 */
+			createDisabledMenu(menu, UIText.SwitchToMenu_NoCommonBranchesFound);
+		}
+	}
+
+	private void createNewBranchMenuItem(Menu menu, Repository repository) {
 		MenuItem newBranch = new MenuItem(menu, SWT.PUSH);
 		newBranch.setText(UIText.SwitchToMenu_NewBranchMenuLabel);
 		newBranch.setImage(newBranchImage);
@@ -130,114 +160,173 @@
 				dlg.open();
 			}
 		});
-		createSeparator(menu);
+
+	}
+
+	private int createMostActiveBranchesMenuItems(Menu menu, Repository[] repositories)
+	{
+		int itemCount = 0;
 		try {
-			String currentBranch = repository.getFullBranch();
-			Map<String, Ref> localBranches = repository.getRefDatabase().getRefs(
-					Constants.R_HEADS);
-			TreeMap<String, Ref> sortedRefs = new TreeMap<>(
-					CommonUtils.STRING_ASCENDING_COMPARATOR);
+			List<Map<String, Ref>> activeBranches = new ArrayList<>();
 
-			// Add the MAX_NUM_MENU_ENTRIES most recently used branches first
-			ReflogReader reflogReader = repository.getReflogReader(
-					Constants.HEAD);
-			List<ReflogEntry> reflogEntries;
-			if (reflogReader == null) {
-				reflogEntries = Collections.emptyList();
-			} else {
-				reflogEntries = reflogReader.getReverseEntries();
-			}
-			for (ReflogEntry entry : reflogEntries) {
-				CheckoutEntry checkout = entry.parseCheckout();
-				if (checkout != null) {
-					Ref ref = localBranches.get(checkout.getFromBranch());
-					if (ref != null)
-						if (sortedRefs.size() < MAX_NUM_MENU_ENTRIES)
-							sortedRefs.put(checkout.getFromBranch(), ref);
-					ref = localBranches.get(checkout.getToBranch());
-					if (ref != null)
-						if (sortedRefs.size() < MAX_NUM_MENU_ENTRIES)
-							sortedRefs.put(checkout.getToBranch(), ref);
-				}
+			for (Repository repository : repositories) {
+				Map<String, Ref> branchRefMapping = getMostActiveBranches(
+						repository, MAX_NUM_MENU_ENTRIES);
+				activeBranches.add(branchRefMapping);
 			}
 
-			// Add the recently used branches to the menu, in alphabetical order
-			int itemCount = 0;
-			for (final Entry<String, Ref> entry : sortedRefs.entrySet()) {
+			Set<String> activeBranchIntersection = getBranchNameIntersection(activeBranches);
+			for (String branchName : activeBranchIntersection) {
 				itemCount++;
-				final String shortName = entry.getKey();
-				final String fullName = entry.getValue().getName();
-				createMenuItem(menu, repository, currentBranch, fullName, shortName);
-				// Do not duplicate branch names
-				localBranches.remove(shortName);
+				createMenuItemMultiple(menu, repositories,
+						branchName);
 			}
 
-			if (itemCount < MAX_NUM_MENU_ENTRIES) {
-				// A separator between recently used branches and local branches is
-				// nice but only if we have both recently used branches and other
-				// local branches
-				if (itemCount > 0 && localBranches.size() > 0)
-					createSeparator(menu);
-
-				// Now add more other branches if we have only a few branch switches
-				// Sort the remaining local branches
-				sortedRefs.clear();
-				sortedRefs.putAll(localBranches);
-				for (final Entry<String, Ref> entry : sortedRefs.entrySet()) {
-					itemCount++;
-					// protect ourselves against a huge sub-menu
-					if (itemCount > MAX_NUM_MENU_ENTRIES)
-						break;
-					final String fullName = entry.getValue().getName();
-					final String shortName = entry.getKey();
-					createMenuItem(menu, repository, currentBranch, fullName, shortName);
-				}
+			if (itemCount >= MAX_NUM_MENU_ENTRIES) {
+				return itemCount;
 			}
-			if (itemCount > 0)
+
+			List<Map<String, Ref>> localBranchMapping = new ArrayList<>();
+			for (Repository repository : repositories) {
+				Map<String, Ref> localBranches = repository.getRefDatabase()
+						.getRefs(Constants.R_HEADS);
+				localBranchMapping.add(localBranches);
+			}
+
+			// A separator between recently used branches and local branches is
+			// nice but only if we have both recently used branches and other
+			// local branches
+			Set<String> localBranchNameIntersection = getBranchNameIntersection(
+					localBranchMapping);
+			localBranchNameIntersection.removeAll(activeBranchIntersection);
+			if (itemCount > 0 && !localBranchNameIntersection.isEmpty()) {
 				createSeparator(menu);
-			MenuItem others = new MenuItem(menu, SWT.PUSH);
-			others.setText(UIText.SwitchToMenu_OtherMenuLabel);
-			others.addSelectionListener(new SelectionAdapter() {
-				@Override
-				public void widgetSelected(SelectionEvent e) {
-					CheckoutDialog dialog = new CheckoutDialog(
-							e.display.getActiveShell(), repository);
-					if (dialog.open() == Window.OK) {
-						BranchOperationUI
-								.checkout(repository, dialog.getRefName())
-								.start();
-					}
+			}
 
+			for (String localBranchName : localBranchNameIntersection) {
+				itemCount++;
+				if (itemCount > MAX_NUM_MENU_ENTRIES) {
+					break;
 				}
-			});
-		} catch (IOException e) {
+
+				createMenuItemMultiple(menu, repositories, localBranchName);
+			}
+		}
+		catch (IOException e) {
 			Activator.handleError(e.getMessage(), e, true);
 		}
+
+		return itemCount;
+	}
+
+	private Set<String> getBranchNameIntersection(
+			List<Map<String, Ref>> refMapping) {
+		Iterator<Map<String, Ref>> iterator = refMapping.iterator();
+		if (!iterator.hasNext()) {
+			return Collections.emptySet();
+		}
+
+		Set<String> intersection = new TreeSet<>(
+				CommonUtils.STRING_ASCENDING_COMPARATOR);
+		intersection.addAll(iterator.next().keySet());
+		iterator.forEachRemaining(map -> intersection.retainAll(map.keySet()));
+		return intersection;
+	}
+
+	private void createOtherMenuItem(Menu menu, Repository repository) {
+		MenuItem others = new MenuItem(menu, SWT.PUSH);
+		others.setText(UIText.SwitchToMenu_OtherMenuLabel);
+		others.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				CheckoutDialog dialog = new CheckoutDialog(
+						e.display.getActiveShell(), repository);
+				if (dialog.open() == Window.OK) {
+					BranchOperationUI.checkout(repository, dialog.getRefName())
+							.start();
+				}
+
+			}
+		});
+	}
+
+	private void createDisabledMenu(Menu menu, String text) {
+		MenuItem disabled = new MenuItem(menu, SWT.PUSH);
+		disabled.setText(text);
+		disabled.setImage(branchImage);
+		disabled.setEnabled(false);
 	}
 
 	private static MenuItem createSeparator(Menu menu) {
 		return new MenuItem(menu, SWT.SEPARATOR);
 	}
 
-	private void createMenuItem(Menu menu, final Repository repository,
-			String currentBranch, final String fullName, String shortName) {
+	private void createMenuItemMultiple(Menu menu, final Repository[] repositories, String shortName) throws IOException {
+
 		final MenuItem item = new MenuItem(menu, SWT.PUSH);
 		item.setText(shortName);
-		boolean checkedOut = currentBranch.equals(fullName);
-		if (checkedOut)
+
+		boolean allRepositoriesCheckedOut = Stream.of(repositories) //
+				.allMatch(r -> shortName.equals(getBranch(r)));
+
+		if (allRepositoriesCheckedOut)
 			item.setImage(checkedOutImage);
 		else
 			item.setImage(branchImage);
-		item.setEnabled(!checkedOut);
+		item.setEnabled(!allRepositoriesCheckedOut);
+
 		item.addSelectionListener(new SelectionAdapter() {
 			@Override
 			public void widgetSelected(SelectionEvent e) {
-				BranchOperationUI.checkout(repository, fullName)
-						.start();
+
+				BranchOperationUI.checkout(repositories, shortName).start();
 			}
 		});
 	}
 
+	private String getBranch(Repository repo) {
+		try {
+			return repo.getBranch();
+		} catch (IOException e) {
+			return ""; //$NON-NLS-1$
+		}
+	}
+
+	private Map<String, Ref> getMostActiveBranches(final Repository repository,
+			int maximumBranchCount) throws IOException {
+		Map<String, Ref> localBranches = repository.getRefDatabase()
+				.getRefs(Constants.R_HEADS);
+		Map<String, Ref> activeRefs = new HashMap<>();
+
+		ReflogReader reflogReader = repository.getReflogReader(Constants.HEAD);
+		List<ReflogEntry> reflogEntries;
+		if (reflogReader == null) {
+			return Collections.emptyMap();
+		}
+
+		reflogEntries = reflogReader.getReverseEntries();
+
+		for (ReflogEntry entry : reflogEntries) {
+			CheckoutEntry checkout = entry.parseCheckout();
+			if (checkout != null) {
+				Ref ref = localBranches.get(checkout.getFromBranch());
+				if (ref != null)
+					if (activeRefs.size() < maximumBranchCount)
+						activeRefs.put(checkout.getFromBranch(), ref);
+				ref = localBranches.get(checkout.getToBranch());
+				if (ref != null)
+					if (activeRefs.size() < maximumBranchCount)
+						activeRefs.put(checkout.getToBranch(), ref);
+			}
+		}
+
+		return activeRefs;
+	}
+
+	private boolean isMultipleSelection(Repository[] repositories) {
+		return repositories.length > 1;
+	}
+
 	@Override
 	public boolean isDynamic() {
 		return true;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java
index 4414305..fa2bf09 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java
@@ -14,7 +14,12 @@
 package org.eclipse.egit.ui.internal.branch;
 
 import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
 
 import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.resources.IWorkspaceRunnable;
@@ -49,7 +54,6 @@
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IMemento;
 import org.eclipse.ui.PlatformUI;
 
 /**
@@ -57,19 +61,36 @@
  */
 public class BranchOperationUI {
 
-	private final Repository repository;
+	private final Repository[] repositories;
 
 	private String target;
 
+	private boolean isSingleRepositoryOperation;
+
 	/**
 	 * In the case of checkout conflicts, a dialog is shown to let the user
 	 * stash, reset or commit. After that, checkout is tried again. The second
 	 * time we do checkout, we don't want to ask any questions we already asked
 	 * the first time, so this will be false then.
+	 *
+	 * This behavior is disabled when checking out multiple repositories at once
 	 */
 	private final boolean showQuestionsBeforeCheckout;
 
 	/**
+	 * Create an operation for checking out a branch on multiple repositories
+	 *
+	 * @param repositories
+	 * @param target
+	 *            a valid {@link Ref} name or commit id
+	 * @return the {@link BranchOperationUI}
+	 */
+	public static BranchOperationUI checkout(Repository[] repositories,
+			String target) {
+		return new BranchOperationUI(repositories, target, true);
+	}
+
+	/**
 	 * Create an operation for checking out a branch
 	 *
 	 * @param repository
@@ -79,7 +100,22 @@
 	 */
 	public static BranchOperationUI checkout(Repository repository,
 			String target) {
-		return new BranchOperationUI(repository, target, true);
+		return checkout(repository, target, true);
+	}
+
+	/**
+	 * Create an operation for checking out a branch
+	 *
+	 * @param repository
+	 * @param target
+	 *            a valid {@link Ref} name or commit id
+	 * @param showQuestionsBeforeCheckout
+	 * @return the {@link BranchOperationUI}
+	 */
+	public static BranchOperationUI checkout(Repository repository,
+			String target, boolean showQuestionsBeforeCheckout) {
+		return new BranchOperationUI(new Repository[] { repository }, target,
+				showQuestionsBeforeCheckout);
 	}
 
 	/**
@@ -93,55 +129,71 @@
 	}
 
 	/**
-	 * @param repository
+	 * @param repositories
 	 * @param target
 	 * @param showQuestionsBeforeCheckout
 	 */
-	private BranchOperationUI(Repository repository, String target,
+	private BranchOperationUI(Repository[] repositories, String target,
 			boolean showQuestionsBeforeCheckout) {
-		this.repository = repository;
+		this.repositories = repositories;
 		this.target = target;
-		this.showQuestionsBeforeCheckout = showQuestionsBeforeCheckout;
+		/*
+		 * We do not have support for CreateBranchWizards when performing
+		 * checkout on multiple repositories at once, thus, the
+		 * showQuestionsBeforeCheckout is forced to false in this case
+		 */
+		this.isSingleRepositoryOperation = repositories.length == 1;
+		this.showQuestionsBeforeCheckout = isSingleRepositoryOperation
+				? showQuestionsBeforeCheckout
+				: false;
 	}
 
 	private String confirmTarget(IProgressMonitor monitor) {
-		if (target != null) {
-			if (!repository.getRepositoryState().canCheckout()) {
-				PlatformUI.getWorkbench().getDisplay()
-						.asyncExec(new Runnable() {
-							@Override
-							public void run() {
-								MessageDialog.openError(getShell(),
-										UIText.BranchAction_cannotCheckout,
-										NLS.bind(
-												UIText.BranchAction_repositoryState,
-												repository.getRepositoryState()
-														.getDescription()));
-							}
-						});
-				return null;
-			}
 
-			if (LaunchFinder.shouldCancelBecauseOfRunningLaunches(repository,
-					monitor)) {
-				return null;
-			}
-
-			askForTargetIfNecessary();
+		if (target == null) {
+			return null;
 		}
+
+		Optional<Repository> invalidRepo = Stream.of(repositories) //
+				.filter(r -> !r.getRepositoryState().canCheckout()) //
+				.findFirst();
+
+		if (invalidRepo.isPresent()) {
+			PlatformUI.getWorkbench().getDisplay()
+					.asyncExec(() -> showRepositoryInInvalidStateForCheckout(
+							invalidRepo.get()));
+			return null;
+		}
+
+		Collection<Repository> repos = Arrays.asList(repositories);
+		if (LaunchFinder.shouldCancelBecauseOfRunningLaunches(repos, monitor)) {
+			return null;
+		}
+
+		askForTargetIfNecessary();
 		return target;
 	}
 
+	private void showRepositoryInInvalidStateForCheckout(Repository repo) {
+		String repoName = Activator.getDefault().getRepositoryUtil()
+				.getRepositoryName(repo);
+		String description = repo.getRepositoryState().getDescription();
+		String message = NLS.bind(UIText.BranchAction_repositoryState, repoName,
+				description);
+
+		MessageDialog.openError(getShell(), UIText.BranchAction_cannotCheckout,
+				message);
+	}
+
 	private void doCheckout(BranchOperation bop, boolean restore,
-			IProgressMonitor monitor)
-			throws CoreException {
+			IProgressMonitor monitor) throws CoreException {
 		SubMonitor progress = SubMonitor.convert(monitor, restore ? 10 : 1);
 		if (!restore) {
 			bop.execute(progress.newChild(1));
 		} else {
 			final BranchProjectTracker tracker = new BranchProjectTracker(
-					repository);
-			IMemento snapshot = tracker.snapshot();
+					repositories);
+			ProjectTrackerMemento snapshot = tracker.snapshot();
 			bop.execute(progress.newChild(7));
 			tracker.save(snapshot);
 			IWorkspaceRunnable action = new IWorkspaceRunnable() {
@@ -162,14 +214,16 @@
 	 * Starts the operation asynchronously
 	 */
 	public void start() {
+
+		if (repositories == null || repositories.length == 0) {
+			return;
+		}
+
 		target = confirmTarget(new NullProgressMonitor());
 		if (target == null) {
 			return;
 		}
-		String repoName = Activator.getDefault().getRepositoryUtil()
-				.getRepositoryName(repository);
-		String jobname = NLS.bind(UIText.BranchAction_checkingOut, repoName,
-				target);
+		String jobname = getJobName(repositories, target);
 		boolean restore = Activator.getDefault().getPreferenceStore()
 				.getBoolean(UIPreferences.CHECKOUT_PROJECT_RESTORE);
 		final CheckoutJob job = new CheckoutJob(jobname, restore);
@@ -183,6 +237,17 @@
 		job.schedule();
 	}
 
+	private static String getJobName(Repository[] repos, String target) {
+
+		if (repos.length > 1) {
+			return NLS.bind(UIText.BranchAction_checkingOutMultiple, target);
+        }
+
+		String repoName = Activator.getDefault().getRepositoryUtil()
+				.getRepositoryName(repos[0]);
+		return NLS.bind(UIText.BranchAction_checkingOut, repoName, target);
+	}
+
 	private class CheckoutJob extends Job {
 
 		private BranchOperation bop;
@@ -196,18 +261,29 @@
 
 		@Override
 		public IStatus run(IProgressMonitor monitor) {
-			bop = new BranchOperation(repository, target, !restore);
+			bop = new BranchOperation(repositories, target, !restore);
 			try {
 				doCheckout(bop, restore, monitor);
 			} catch (CoreException e) {
-				switch (bop.getResult().getStatus()) {
-				case CONFLICTS:
-				case NONDELETED:
-					break;
-				default:
-					return Activator.createErrorStatus(
-							UIText.BranchAction_branchFailed, e);
+
+				/*
+				 * For a checkout operation with multiple repositories we can
+				 * handle any error status by displaying all of them in a table.
+				 * For a single repository, though, we will stick to using a
+				 * simple message in case of an unexpected exception.
+				 */
+				if (!isSingleRepositoryOperation)
+					return Status.OK_STATUS;
+
+				CheckoutResult result = bop.getResult(repositories[0]);
+
+				if (result.getStatus() == CheckoutResult.Status.CONFLICTS || //
+						result.getStatus() == CheckoutResult.Status.NONDELETED) {
+					return Status.OK_STATUS;
 				}
+
+				return Activator
+						.createErrorStatus(UIText.BranchAction_branchFailed, e);
 			} finally {
 				GitLightweightDecorator.refresh();
 				monitor.done();
@@ -223,8 +299,8 @@
 		}
 
 		@NonNull
-		public CheckoutResult getCheckoutResult() {
-			return bop.getResult();
+		public Map<Repository, CheckoutResult> getCheckoutResult() {
+			return bop.getResults();
 		}
 	}
 
@@ -243,19 +319,25 @@
 		}
 		final boolean restore = Activator.getDefault().getPreferenceStore()
 				.getBoolean(UIPreferences.CHECKOUT_PROJECT_RESTORE);
-		BranchOperation bop = new BranchOperation(repository, target, !restore);
+		BranchOperation bop = new BranchOperation(repositories, target,
+				!restore);
 		doCheckout(bop, restore, progress.newChild(80));
-		show(bop.getResult());
+		show(bop.getResults());
 	}
 
 	private void askForTargetIfNecessary() {
-		if (target != null && showQuestionsBeforeCheckout) {
-			if (shouldShowCheckoutRemoteTrackingDialog(target))
-				target = getTargetWithCheckoutRemoteTrackingDialog();
+
+		if (target == null || //
+				!showQuestionsBeforeCheckout || //
+				!shouldShowCheckoutRemoteTrackingDialog(target)) {
+			return;
 		}
+
+		target = getTargetWithCheckoutRemoteTrackingDialog(repositories[0]);
 	}
 
-	private static boolean shouldShowCheckoutRemoteTrackingDialog(String refName) {
+	private static boolean shouldShowCheckoutRemoteTrackingDialog(
+			String refName) {
 		boolean isRemoteTrackingBranch = refName != null
 				&& refName.startsWith(Constants.R_REMOTES);
 		if (isRemoteTrackingBranch) {
@@ -272,32 +354,29 @@
 		}
 	}
 
-	private String getTargetWithCheckoutRemoteTrackingDialog() {
+	private String getTargetWithCheckoutRemoteTrackingDialog(Repository repo) {
 		final String[] dialogResult = new String[1];
-		PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
-			@Override
-			public void run() {
-				dialogResult[0] = getTargetWithCheckoutRemoteTrackingDialogInUI();
-			}
-		});
+		PlatformUI.getWorkbench().getDisplay().syncExec(
+				() -> dialogResult[0] = getTargetWithCheckoutRemoteTrackingDialogInUI(
+						repo));
+
 		return dialogResult[0];
 	}
 
-	private String getTargetWithCheckoutRemoteTrackingDialogInUI() {
+	private String getTargetWithCheckoutRemoteTrackingDialogInUI(
+			Repository repo) {
 		String[] buttons = new String[] {
 				UIText.BranchOperationUI_CheckoutRemoteTrackingAsLocal,
 				UIText.BranchOperationUI_CheckoutRemoteTrackingCommit,
 				IDialogConstants.CANCEL_LABEL };
-		MessageDialog questionDialog = new MessageDialog(
-				getShell(),
-				UIText.BranchOperationUI_CheckoutRemoteTrackingTitle,
-				null,
+		MessageDialog questionDialog = new MessageDialog(getShell(),
+				UIText.BranchOperationUI_CheckoutRemoteTrackingTitle, null,
 				UIText.BranchOperationUI_CheckoutRemoteTrackingQuestion,
 				MessageDialog.QUESTION, buttons, 0);
 		int result = questionDialog.open();
 		if (result == 0) {
 			// Check out as new local branch
-			CreateBranchWizard wizard = new CreateBranchWizard(repository,
+			CreateBranchWizard wizard = new CreateBranchWizard(repo,
 					target);
 			WizardDialog createBranchDialog = new WizardDialog(getShell(),
 					wizard);
@@ -317,30 +396,60 @@
 	}
 
 	/**
-	 * @param result
-	 *            the result to show
+	 * @param results
 	 */
-	private void show(final @NonNull CheckoutResult result) {
+	private void show(final @NonNull Map<Repository, CheckoutResult> results) {
+
+		if (allBranchOperationsSucceeded(results)) {
+
+			if (anyRepositoryIsInDetachedHeadState(results)) {
+				showDetachedHeadWarning();
+			}
+			return;
+		}
+
+		if (this.isSingleRepositoryOperation) {
+			Repository repo = repositories[0];
+			CheckoutResult result = results.get(repo);
+			handleSingleRepositoryCheckoutOperationResult(repo,
+					result);
+			return;
+		}
+
+		handleMultipleRepositoryCheckoutError(results);
+	}
+
+	private boolean allBranchOperationsSucceeded(
+			final @NonNull Map<Repository, CheckoutResult> results)
+	{
+		return results.values().stream()
+				.allMatch(r -> r.getStatus() == CheckoutResult.Status.OK);
+	}
+
+	private boolean anyRepositoryIsInDetachedHeadState(
+			final @NonNull Map<Repository, CheckoutResult> results) {
+		return results.keySet().stream()
+				.anyMatch(RepositoryUtil::isDetachedHead);
+	}
+
+	private void handleSingleRepositoryCheckoutOperationResult(Repository repository,
+			CheckoutResult result) {
+
 		if (result.getStatus() == CheckoutResult.Status.CONFLICTS) {
-			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-				@Override
-				public void run() {
-					Shell shell = PlatformUI.getWorkbench()
-							.getActiveWorkbenchWindow().getShell();
+			PlatformUI.getWorkbench().getDisplay().asyncExec(() -> {
+				Shell shell = PlatformUI.getWorkbench()
+						.getActiveWorkbenchWindow().getShell();
 					CleanupUncomittedChangesDialog cleanupUncomittedChangesDialog = new CleanupUncomittedChangesDialog(
-							shell,
-							UIText.BranchResultDialog_CheckoutConflictsTitle,
-							NLS.bind(
-									UIText.BranchResultDialog_CheckoutConflictsMessage,
-									Repository.shortenRefName(target)),
-							repository, result.getConflictList());
-					cleanupUncomittedChangesDialog.open();
-					if (cleanupUncomittedChangesDialog.shouldContinue()) {
-						BranchOperationUI op = new BranchOperationUI(repository,
-								target, false);
-						op.start();
+						shell, UIText.BranchResultDialog_CheckoutConflictsTitle,
+						NLS.bind(
+								UIText.BranchResultDialog_CheckoutConflictsMessage,
+								Repository.shortenRefName(target)),
+						repository, result.getConflictList());
+				cleanupUncomittedChangesDialog.open();
+				if (cleanupUncomittedChangesDialog.shouldContinue()) {
+					BranchOperationUI.checkout(repository, target, false)
+							.start();
 					}
-				}
 			});
 		} else if (result.getStatus() == CheckoutResult.Status.NONDELETED) {
 			// double-check if the files are still there
@@ -351,31 +460,51 @@
 					show = true;
 					break;
 				}
+
 			if (!show)
 				return;
-			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-				@Override
-				public void run() {
+
+			PlatformUI.getWorkbench().getDisplay().asyncExec(() -> {
 					Shell shell = PlatformUI.getWorkbench()
 							.getActiveWorkbenchWindow().getShell();
-					new NonDeletedFilesDialog(shell, repository, result
-							.getUndeletedList()).open();
-				}
+					new NonDeletedFilesDialog(shell, repository,
+							result.getUndeletedList()).open();
 			});
-		} else if (result.getStatus() == CheckoutResult.Status.OK) {
-			if (RepositoryUtil.isDetachedHead(repository))
-				showDetachedHeadWarning();
+		} else {
+
+			String repoName = Activator.getDefault().getRepositoryUtil()
+					.getRepositoryName(repository);
+			String message = NLS.bind(
+					UIText.BranchOperationUI_CheckoutError_DialogMessage,
+					repoName, target);
+			PlatformUI.getWorkbench().getDisplay().asyncExec(() -> {
+				Shell shell = PlatformUI.getWorkbench()
+						.getActiveWorkbenchWindow().getShell();
+				MessageDialog.openError(shell,
+						UIText.BranchOperationUI_CheckoutError_DialogTitle,
+						message);
+			});
 		}
 	}
 
+	private void handleMultipleRepositoryCheckoutError(
+			Map<Repository, CheckoutResult> results) {
+
+		PlatformUI.getWorkbench().getDisplay().asyncExec(() -> {
+			Shell shell = PlatformUI.getWorkbench()
+						.getActiveWorkbenchWindow().getShell();
+				new MultiBranchOperationResultDialog(shell, results).open();
+			}
+		);
+	}
+
 	private void showDetachedHeadWarning() {
-		PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-			@Override
-			public void run() {
+		PlatformUI.getWorkbench().getDisplay().asyncExec(() -> {
 				IPreferenceStore store = Activator.getDefault()
 						.getPreferenceStore();
 
-				if (store.getBoolean(UIPreferences.SHOW_DETACHED_HEAD_WARNING)) {
+				if (store
+						.getBoolean(UIPreferences.SHOW_DETACHED_HEAD_WARNING)) {
 					String toggleMessage = UIText.BranchResultDialog_DetachedHeadWarningDontShowAgain;
 
 					MessageDialogWithToggle dialog = new MessageDialogWithToggle(
@@ -384,16 +513,14 @@
 							UIText.BranchOperationUI_DetachedHeadTitle, null,
 							UIText.BranchOperationUI_DetachedHeadMessage,
 							MessageDialog.INFORMATION,
-							new String[] { IDialogConstants.CLOSE_LABEL },
-							0, toggleMessage, false);
+							new String[] { IDialogConstants.CLOSE_LABEL }, 0,
+							toggleMessage, false);
 					dialog.open();
 					if (dialog.getToggleState()) {
 						store.setValue(UIPreferences.SHOW_DETACHED_HEAD_WARNING,
 								false);
 					}
 				}
-			}
 		});
 	}
-
 }
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchProjectTracker.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchProjectTracker.java
index ad0c4b7..800d70b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchProjectTracker.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchProjectTracker.java
@@ -14,13 +14,14 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Stream;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
@@ -32,11 +33,9 @@
 import org.eclipse.egit.ui.Activator;
 import org.eclipse.egit.ui.internal.clone.ProjectRecord;
 import org.eclipse.egit.ui.internal.clone.ProjectUtils;
-import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jgit.annotations.NonNull;
 import org.eclipse.jgit.lib.Repository;
-import org.eclipse.ui.IMemento;
-import org.eclipse.ui.WorkbenchException;
-import org.eclipse.ui.XMLMemento;
+import org.eclipse.jgit.util.StringUtils;
 
 /**
  * Class to track which projects are imported for each branch.
@@ -51,8 +50,8 @@
  * 1. Call {@link #snapshot()} to get the current projects for the currently
  * checked out branch
  * <p>
- * 2. Call {@link #save(IMemento)} after the new branch has been successfully
- * checked out with the memento returned from step 1
+ * 2. Call {@link #save(ProjectTrackerMemento)} after the new branch has been
+ * successfully checked out with the memento returned from step 1
  * <p>
  * 3. Call {@link #restore(IProgressMonitor)} to restore the projects for the
  * newly checked out branch
@@ -60,17 +59,18 @@
  */
 class BranchProjectTracker {
 
-	private static final String PREFIX = "BranchProjectTracker_"; //$NON-NLS-1$
-
-	private static final String KEY_PROJECTS = "projects"; //$NON-NLS-1$
-
-	private static final String KEY_PROJECT = "project"; //$NON-NLS-1$
-
-	private static final String KEY_BRANCH = "branch"; //$NON-NLS-1$
-
 	private static final String REPO_ROOT = "/"; //$NON-NLS-1$
 
-	private final Repository repository;
+	private final Repository[] repositories;
+
+	/**
+	 * Create tracker for repositories
+	 *
+	 * @param repositories
+	 */
+	public BranchProjectTracker(final Repository[] repositories) {
+		this.repositories = repositories;
+	}
 
 	/**
 	 * Create tracker for repository
@@ -78,57 +78,64 @@
 	 * @param repository
 	 */
 	public BranchProjectTracker(final Repository repository) {
-		this.repository = repository;
+		this.repositories = new Repository[] { repository };
 	}
 
-	private String getBranch() {
+	private String getBranch(Repository repo) {
 		try {
-			return repository.getBranch();
+			return repo.getBranch();
 		} catch (IOException e) {
 			return null;
 		}
 	}
 
 	/**
-	 * Get preference key for branch. This will be unique to the repository and
-	 * branch.
-	 *
-	 * @param branch
-	 * @return key
-	 */
-	public String getPreference(final String branch) {
-		if (branch == null)
-			throw new IllegalArgumentException("Branch cannot be null"); //$NON-NLS-1$
-		if (branch.length() == 0)
-			throw new IllegalArgumentException("Branch cannot be empty"); //$NON-NLS-1$
-
-		return PREFIX + '_' + repository.getDirectory().getAbsolutePath() + '_'
-				+ branch;
-	}
-
-	/**
 	 * Snapshot the projects currently associated with the repository
 	 * <p>
-	 * The memento returned can be later passed to {@link #save(IMemento)} to
-	 * persist it
+	 * The memento returned can be later passed to
+	 * {@link #save(ProjectTrackerMemento)} to persist it
 	 *
-	 * @see #save(IMemento)
-	 * @return memento, will be null on failures
+	 * @see #save(ProjectTrackerMemento)
+	 * @return memento
 	 */
-	public IMemento snapshot() {
-		String branch = getBranch();
-		if (branch == null)
+	public ProjectTrackerMemento snapshot() {
+
+		ProjectTrackerMemento memento = new ProjectTrackerMemento();
+
+		Stream.of(repositories) //
+				.map(this::takeSnapshot) //
+				.filter(Objects::nonNull) //
+				.forEach(x -> memento.addSnapshot(x));
+
+		return memento;
+	}
+
+	private ProjectTrackerPreferenceSnapshot takeSnapshot(Repository repo) {
+
+		String branch = getBranch(repo);
+		if (StringUtils.isEmptyOrNull(branch))
 			return null;
 
-		IProject[] projects;
-		try {
-			projects = ProjectUtil.getValidOpenProjects(repository);
-		} catch (CoreException e) {
+		List<String> projectPaths = getAssociatedProjectsPaths(repo);
+		if (projectPaths.isEmpty()) {
 			return null;
 		}
-		XMLMemento memento = XMLMemento.createWriteRoot(KEY_PROJECTS);
-		memento.putString(KEY_BRANCH, branch);
-		final String workDir = repository.getWorkTree().getAbsolutePath();
+
+		return new ProjectTrackerPreferenceSnapshot(repo, branch,
+				projectPaths);
+	}
+
+	@NonNull
+	private List<String> getAssociatedProjectsPaths(Repository repo) {
+
+		IProject[] projects = getValidOpenProjects(repo);
+		if (projects == null) {
+			return Collections.emptyList();
+		}
+
+		List<String> projectPaths = new ArrayList<>();
+
+		final String workDir = repo.getWorkTree().getAbsolutePath();
 		for (IProject project : projects) {
 			IPath path = project.getLocation();
 			if (path == null) {
@@ -144,11 +151,18 @@
 				if (relative.length() == 0) {
 					relative = REPO_ROOT;
 				}
-				IMemento child = memento.createChild(KEY_PROJECT);
-				child.putTextData(relative);
+				projectPaths.add(relative);
 			}
 		}
-		return memento;
+		return projectPaths;
+	}
+
+	private IProject[] getValidOpenProjects(Repository repo) {
+		try {
+			return ProjectUtil.getValidOpenProjects(repo);
+		} catch (CoreException e) {
+			return null;
+		}
 	}
 
 	/**
@@ -156,69 +170,23 @@
 	 * previously returned from a call to {@link #snapshot()}.
 	 *
 	 * @see #snapshot()
-	 * @param memento
+	 * @param snapshot
 	 * @return this tracker
 	 */
-	public BranchProjectTracker save(final IMemento memento) {
-		if (!(memento instanceof XMLMemento))
-			throw new IllegalArgumentException("Invalid memento"); //$NON-NLS-1$
+	public BranchProjectTracker save(ProjectTrackerMemento snapshot) {
 
-		String branch = memento.getString(KEY_BRANCH);
-		IPreferenceStore store = Activator.getDefault().getPreferenceStore();
-		String pref = getPreference(branch);
-		StringWriter writer = new StringWriter();
-		try {
-			((XMLMemento) memento).save(writer);
-			store.setValue(pref, writer.toString());
-		} catch (IOException e) {
-			Activator.logError("Error writing branch-project associations", e); //$NON-NLS-1$
-		}
+		snapshot.getSnapshots().stream()
+				.forEach(BranchProjectTracker::savePreference);
 		return this;
 	}
 
-	/**
-	 * Load the project paths associated with the currently checked out branch.
-	 * These paths will be relative to the repository root.
-	 *
-	 * @return non-null but possibly empty array of projects
-	 */
-	public String[] getProjectPaths() {
-		String branch = getBranch();
-		if (branch == null)
-			return new String[0];
-		return getProjectPaths(branch);
-	}
+	private static void savePreference(ProjectTrackerPreferenceSnapshot snapshot) {
 
-	/**
-	 * Load the project paths associated with the given branch. These paths will
-	 * be relative to the repository root.
-	 *
-	 * @param branch
-	 * @return non-null but possibly empty array of projects
-	 */
-	public String[] getProjectPaths(final String branch) {
-		String pref = getPreference(branch);
-		String value = Activator.getDefault().getPreferenceStore()
-				.getString(pref);
-		if (value.length() == 0)
-			return new String[0];
-		XMLMemento memento;
-		try {
-			memento = XMLMemento.createReadRoot(new StringReader(value));
-		} catch (WorkbenchException e) {
-			Activator.logError("Error reading branch-project associations", e); //$NON-NLS-1$
-			return new String[0];
-		}
-		IMemento[] children = memento.getChildren(KEY_PROJECT);
-		if (children.length == 0)
-			return new String[0];
-		List<String> projects = new ArrayList<>(children.length);
-		for (int i = 0; i < children.length; i++) {
-			String path = children[i].getTextData();
-			if (path != null && path.length() > 0)
-				projects.add(path);
-		}
-		return projects.toArray(new String[0]);
+		Repository repo = snapshot.getRepository();
+		String branch = snapshot.getBranch();
+		List<String> projects = snapshot.getAssociatedProjects();
+		ProjectTrackerPreferenceHelper.saveToPreferences(repo, branch,
+				projects);
 	}
 
 	/**
@@ -228,24 +196,31 @@
 	 * @param monitor
 	 */
 	public void restore(final IProgressMonitor monitor) {
-		String branch = getBranch();
-		if (branch != null)
-			restore(branch, monitor);
+
+		for (Repository repo : repositories) {
+			String branch = getBranch(repo);
+			if (branch != null) {
+				restore(repo, branch, monitor);
+			}
+		}
 	}
 
 	/**
 	 * Restore projects associated with the given branch to the workspace
 	 *
+	 * @param repo
 	 * @param branch
 	 * @param monitor
 	 */
-	public void restore(final String branch, final IProgressMonitor monitor) {
-		String[] paths = getProjectPaths(branch);
-		if (paths.length == 0)
+	public void restore(Repository repo, final String branch,
+			final IProgressMonitor monitor) {
+		List<String> paths = ProjectTrackerPreferenceHelper
+				.restoreFromPreferences(repo, branch);
+		if (paths.size() == 0)
 			return;
 
 		Set<ProjectRecord> records = new LinkedHashSet<>();
-		File parent = repository.getWorkTree();
+		File parent = repo.getWorkTree();
 		for (String path : paths) {
 			File root;
 			if (!REPO_ROOT.equals(path)) {
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/MultiBranchOperationResultDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/MultiBranchOperationResultDialog.java
new file mode 100644
index 0000000..fc0d041
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/MultiBranchOperationResultDialog.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (C) 2018, Luís Copetti <lhcopetti@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.branch;
+
+import java.util.EnumMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.egit.core.RepositoryUtil;
+import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.LabelColumnComparator;
+import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.TableColumnLayout;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jgit.api.CheckoutResult;
+import org.eclipse.jgit.api.CheckoutResult.Status;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Presents the result of a checkout operation for multiple repositories
+ * <p>
+ */
+public class MultiBranchOperationResultDialog extends TitleAreaDialog {
+
+	private final Map<Repository, CheckoutResult> results = new LinkedHashMap<>();
+
+	private TableViewer tv;
+
+	private final RepositoryUtil utils = Activator.getDefault()
+			.getRepositoryUtil();
+
+	private EnumMap<CheckoutResult.Status, String> resultMessages;
+	/**
+	 * @param parentShell
+	 * @param results
+	 */
+	protected MultiBranchOperationResultDialog(Shell parentShell,
+			Map<Repository, CheckoutResult> results) {
+		super(parentShell);
+		setShellStyle(
+				getShellStyle() & ~SWT.APPLICATION_MODAL | SWT.SHELL_TRIM);
+		setBlockOnOpen(false);
+		this.results.putAll(results);
+
+		this.initializeResultMessages();
+	}
+
+	@Override
+	public void create() {
+		super.create();
+	}
+
+	@Override
+	protected Control createDialogArea(Composite parent) {
+		Composite main = new Composite(parent, SWT.NONE);
+		tv = new TableViewer(main, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
+		tv.setContentProvider(ArrayContentProvider.getInstance());
+		TableColumnLayout layout = new TableColumnLayout();
+		main.setLayout(layout);
+
+
+		Table table = tv.getTable();
+		TableViewerColumn tc = new TableViewerColumn(tv, SWT.NONE);
+		TableColumn col = tc.getColumn();
+		tc.setLabelProvider(new ColumnLabelProvider() {
+			@Override
+			public String getText(Object element) {
+				@SuppressWarnings("unchecked")
+				Entry<Repository, CheckoutResult> item = (Entry<Repository, CheckoutResult>) element;
+				return utils.getRepositoryName(item.getKey());
+			}
+		});
+		col.setText(
+				UIText.MultiBranchOperationResultDialog_RepositoryColumnHeader);
+		layout.setColumnData(col, new ColumnWeightData(200, 200));
+		createComparator(col, 0);
+
+		// update status
+		tc = new TableViewerColumn(tv, SWT.NONE);
+		col = tc.getColumn();
+		tc.setLabelProvider(new ColumnLabelProvider() {
+
+			@Override
+			public Image getImage(Object element) {
+
+				@SuppressWarnings("unchecked")
+				Entry<Repository, CheckoutResult> item = (Entry<Repository, CheckoutResult>) element;
+
+				if (item.getValue().getStatus() == Status.OK) {
+					return null;
+				}
+				return PlatformUI.getWorkbench().getSharedImages()
+						.getImage(ISharedImages.IMG_ELCL_STOP);
+			}
+
+			@Override
+			public String getText(Object element) {
+				@SuppressWarnings("unchecked")
+				Entry<Repository, CheckoutResult> item = (Entry<Repository, CheckoutResult>) element;
+
+				CheckoutResult.Status status = item.getValue().getStatus();
+				return getMessageForStatus(status);
+			}
+		});
+		col.setText(
+				UIText.MultiBranchOperationResultDialog_CheckoutStatusColumnHeader);
+		layout.setColumnData(col, new ColumnWeightData(200, 450));
+		createComparator(col, 1);
+
+		table.setHeaderVisible(true);
+		table.setLinesVisible(true);
+		tv.setInput(results.entrySet());
+
+		int linesToShow = Math.min(Math.max(results.size(), 5), 15);
+		int height = table.getItemHeight() * linesToShow;
+
+		GridDataFactory.fillDefaults().grab(true, true)
+				.minSize(SWT.DEFAULT, height).applyTo(main);
+
+		setTitle(UIText.MultiBranchOperationResultDialog_DialogTitle);
+		setErrorMessage(
+				UIText.MultiBranchOperationResultDialog_DialogErrorMessage);
+		return main;
+	}
+
+	@Override
+	protected void createButtonsForButtonBar(Composite parent) {
+		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
+				true);
+	}
+
+	@Override
+	protected void configureShell(Shell newShell) {
+		super.configureShell(newShell);
+		newShell.setText(UIText.MultiBranchOperationResultDialog_WindowTitle);
+	}
+
+	private LabelColumnComparator createComparator(TableColumn column,
+			int columnIndex) {
+		return new LabelColumnComparator(this.tv, column, columnIndex);
+	}
+
+	private void initializeResultMessages() {
+		this.resultMessages = new EnumMap<>(CheckoutResult.Status.class);
+
+		this.resultMessages.put(Status.OK,
+				UIText.MultiBranchOperationResultDialog_CheckoutResultOK);
+		this.resultMessages.put(Status.CONFLICTS,
+				UIText.MultiBranchOperationResultDialog_CheckoutResultConflicts);
+		this.resultMessages.put(Status.NOT_TRIED,
+				UIText.MultiBranchOperationResultDialog_CheckoutResultNotTried);
+		this.resultMessages.put(Status.NONDELETED,
+				UIText.MultiBranchOperationResultDialog_CheckoutResultNonDeleted);
+		this.resultMessages.put(Status.ERROR,
+				UIText.MultiBranchOperationResultDialog_CheckoutResultError);
+	}
+
+	private String getMessageForStatus(CheckoutResult.Status status) {
+		return this.resultMessages.getOrDefault(status, "");//$NON-NLS-1$
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/ProjectTrackerMemento.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/ProjectTrackerMemento.java
new file mode 100644
index 0000000..5a52e77
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/ProjectTrackerMemento.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2018, Luís Copetti <lhcopetti@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.branch;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ *
+ * An opaque class that can be retrieved by
+ * {@link BranchProjectTracker#snapshot()} and later saved by calling
+ * {@link BranchProjectTracker#save(ProjectTrackerMemento)}. For more
+ * information, look at the docs for {{@link BranchProjectTracker}
+ *
+ */
+class ProjectTrackerMemento {
+
+	private final Collection<ProjectTrackerPreferenceSnapshot> snapshots = new ArrayList<>();
+
+	/**
+	 * @param snapshot
+	 */
+	void addSnapshot(ProjectTrackerPreferenceSnapshot snapshot) {
+		snapshots.add(snapshot);
+	}
+
+	/**
+	 * @return the snapshot pairs previously added by
+	 *         {@link #addSnapshot(ProjectTrackerPreferenceSnapshot)}
+	 */
+	Collection<ProjectTrackerPreferenceSnapshot> getSnapshots() {
+		return snapshots;
+	}
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/ProjectTrackerPreferenceHelper.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/ProjectTrackerPreferenceHelper.java
new file mode 100644
index 0000000..fbbadcb
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/ProjectTrackerPreferenceHelper.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (C) 2018, Luís Copetti <lhcopetti@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.branch;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.eclipse.egit.ui.Activator;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.util.StringUtils;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.XMLMemento;
+
+/**
+ * A helper class to simplify storing the association between project paths and
+ * (repository + branch). This API prevents the user
+ * {@link BranchProjectTracker} from knowing where these associations are being
+ * saved. For this particular case at a {@link IPreferenceStore} using
+ * {@link XMLMemento}.
+ *
+ * <p>
+ * The usual location for the file is at:
+ * .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.egit.ui.prefs
+ * </p>
+ *
+ * <p>
+ * An example entry would be: {@code
+ * //BranchProjectTracker__/absolute/path/to/git/repository/.git_BranchName=<?xml
+ * version\="1.0"
+ * encoding\="UTF-8"?>\n<projects>\n<project>/</project>\n</projects> }
+ * </p>
+ */
+class ProjectTrackerPreferenceHelper {
+
+	private static final String PREFIX = "BranchProjectTracker_"; //$NON-NLS-1$
+
+	private static final String KEY_PROJECTS = "projects"; //$NON-NLS-1$
+
+	private static final String KEY_PROJECT = "project"; //$NON-NLS-1$
+
+	/**
+	 * @param repo
+	 * @param branch
+	 * @param projects
+	 */
+	static void saveToPreferences(Repository repo, String branch,
+			List<String> projects)
+	{
+		XMLMemento preferencesMemento = createXMLMemento(projects);
+		String preferenceKey = getPreferenceKey(repo, branch);
+		saveToPreferenceStore(preferenceKey, preferencesMemento);
+	}
+
+	private static XMLMemento createXMLMemento(List<String> projectPaths) {
+
+		XMLMemento memento = XMLMemento.createWriteRoot(KEY_PROJECTS);
+
+		projectPaths.forEach(path -> {
+			IMemento child = memento.createChild(KEY_PROJECT);
+			child.putTextData(path);
+		});
+
+		return memento;
+	}
+
+	/**
+	 * Get preference key for branch. This will be unique to the repository and
+	 * branch.
+	 *
+	 * @param repo
+	 * @param branch
+	 * @return key
+	 */
+	static String getPreferenceKey(Repository repo,
+			final String branch) {
+		return PREFIX + '_' + repo.getDirectory().getAbsolutePath() + '_'
+				+ branch;
+	}
+
+	private static void saveToPreferenceStore(String key, XMLMemento content)
+	{
+		IPreferenceStore store = Activator.getDefault().getPreferenceStore();
+		StringWriter writer = new StringWriter();
+		try {
+			content.save(writer);
+			store.setValue(key, writer.toString());
+		} catch (IOException e) {
+			Activator.logError("Error writing branch-project associations", e); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Load the project paths associated with the currently checked out branch.
+	 * These paths will be relative to the supplied repository.
+	 *
+	 * @param repo
+	 * @param branch
+	 * @return non-null but possibly empty array of projects
+	 */
+	static List<String> restoreFromPreferences(Repository repo,
+			String branch) {
+
+		String key = getPreferenceKey(repo, branch);
+		String value = Activator.getDefault().getPreferenceStore()
+				.getString(key);
+
+		if (value.length() == 0)
+			return Collections.emptyList();
+
+		XMLMemento memento;
+		try {
+			memento = XMLMemento.createReadRoot(new StringReader(value));
+		} catch (WorkbenchException e) {
+			Activator.logError("Error reading branch-project associations", e); //$NON-NLS-1$
+			return Collections.emptyList();
+		}
+		IMemento[] children = memento.getChildren(KEY_PROJECT);
+		if (children.length == 0)
+			return Collections.emptyList();
+
+		List<String> projectPaths = Stream.of(children) //
+				.map(child -> child.getTextData()) //
+				.filter(x -> !StringUtils.isEmptyOrNull(x)) //
+				.collect(Collectors.toList());
+		return projectPaths;
+	}
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/ProjectTrackerPreferenceSnapshot.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/ProjectTrackerPreferenceSnapshot.java
new file mode 100644
index 0000000..2ee297f
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/ProjectTrackerPreferenceSnapshot.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (C) 2018, Luís Copetti <lhcopetti@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.branch;
+
+import java.util.List;
+
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * Class that contains the properties that are required to be persisted and
+ * afterwards made available for the project tracking on checkout feature
+ *
+ * @see BranchProjectTracker
+ */
+class ProjectTrackerPreferenceSnapshot {
+
+	private Repository repo;
+	private String branch;
+	private List<String> associatedProjects;
+
+	/**
+	 * @param repo
+	 * @param branch
+	 * @param associatedProjects
+	 */
+	ProjectTrackerPreferenceSnapshot(Repository repo, String branch,
+			List<String> associatedProjects) {
+		this.repo = repo;
+		this.branch = branch;
+		this.associatedProjects = associatedProjects;
+	}
+
+	Repository getRepository() {
+		return repo;
+	}
+
+	String getBranch() {
+		return branch;
+	}
+
+	List<String> getAssociatedProjects() {
+		return associatedProjects;
+	}
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPanel.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPanel.java
index f5a7b09..4975f2d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPanel.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPanel.java
@@ -145,13 +145,19 @@
 	}
 
 	private static boolean isValidRefExpression(final String s) {
-		if (RefSpec.isWildcard(s)) {
-			// replace wildcard with some legal name just for checking
-			return isValidRefExpression(s.substring(0, s.length() - 1) + 'X');
-		} else
-			return Repository.isValidRefName(s)
-					|| Repository.isValidRefName(Constants.R_HEADS + s)
-					|| Repository.isValidRefName(Constants.R_TAGS + s);
+		if (s == null) {
+			return false;
+		}
+		String spec = s;
+		int i = spec.indexOf('*');
+		if (i >= 0) {
+			if (spec.indexOf('*', i + 1) >= 0) {
+				return false; // Only one '*' allowed
+			}
+			// replace wildcard by arbitrary legal character for checking
+			spec = spec.replace('*', 'X');
+		}
+		return Repository.isValidRefName(Constants.R_HEADS + spec);
 	}
 
 	private static RefSpec setRefSpecSource(final RefSpec spec, final String src) {
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/GitTraceConfigurationDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/GitTraceConfigurationDialog.java
index 386e3ab..8e03ff1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/GitTraceConfigurationDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/GitTraceConfigurationDialog.java
@@ -452,8 +452,7 @@
 						checkedKeys.add(((OptionNode) checked).getOption());
 				}
 
-				for (PluginNode plugin : optionsMap.keySet()) {
-					Properties props = optionsMap.get(plugin);
+				for (Properties props : optionsMap.values()) {
 					for (Object keyObject : props.keySet()) {
 						String key = (String) keyObject;
 						boolean isOn = options.getBooleanOption(key, false);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/UnmergedBranchDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/UnmergedBranchDialog.java
index 15c26ab..8eb14f7 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/UnmergedBranchDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/UnmergedBranchDialog.java
@@ -53,13 +53,19 @@
 	@Override
 	protected Control createCustomArea(Composite parent) {
 		Composite area = new Composite(parent, SWT.NONE);
-		area.setLayoutData(new GridData(GridData.FILL_BOTH));
 		area.setLayout(new FillLayout());
 
 		TableViewer branchesList = new TableViewer(area);
 		branchesList.setContentProvider(ArrayContentProvider.getInstance());
 		branchesList.setLabelProvider(new GitLabelProvider());
 		branchesList.setInput(nodes);
+
+		// restrict height to 20 items
+		GridData layoutData = new GridData(GridData.FILL_BOTH);
+		layoutData.heightHint = Math.min(20, nodes.size() + 1)
+				* branchesList.getTable().getItemHeight();
+		area.setLayoutData(layoutData);
+
 		return area;
 	}
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java
index 63ecd92..99a7372 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java
@@ -154,22 +154,18 @@
 		if (repository == null || repository.isBare()) {
 			return null;
 		}
-		try {
-			IPath repoRelativePath = gitPath.makeRelativeTo(
-					new Path(repository.getWorkTree().getAbsolutePath()));
-			IProject[] projects = ProjectUtil.getProjectsContaining(repository,
-					Collections.singleton(repoRelativePath.toString()));
-			if (projects.length > 0) {
-				IPath projectRelativePath = gitPath
-						.makeRelativeTo(projects[0].getLocation());
-				if (projectRelativePath.isEmpty()) {
-					return projects[0];
-				} else {
-					return projects[0].getFile(projectRelativePath);
-				}
+		IPath repoRelativePath = gitPath.makeRelativeTo(
+				new Path(repository.getWorkTree().getAbsolutePath()));
+		IProject[] projects = ProjectUtil.getProjectsContaining(repository,
+				Collections.singleton(repoRelativePath.toString()));
+		if (projects.length > 0) {
+			IPath projectRelativePath = gitPath
+					.makeRelativeTo(projects[0].getLocation());
+			if (projectRelativePath.isEmpty()) {
+				return projects[0];
+			} else {
+				return projects[0].getFile(projectRelativePath);
 			}
-		} catch (CoreException e) {
-			// Ignore and fall through
 		}
 		return root.getFile(gitPath);
 	}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
index c58e3aa..2e08d2d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
@@ -283,8 +283,10 @@
 			@Override
 			public void selectionChanged(SelectionChangedEvent event) {
 				ISelection s = event.getSelection();
-				if (s.isEmpty() || !(s instanceof IStructuredSelection))
+				if (s.isEmpty() || !(s instanceof IStructuredSelection)) {
+					copy.setEnabled(false);
 					return;
+				}
 				final IStructuredSelection iss = (IStructuredSelection) s;
 				commitToShow = (PlotCommit<?>) iss.getFirstElement();
 
@@ -355,12 +357,17 @@
 			}
 		});
 
-		menuMgr.add(new Separator(IWorkbenchActionConstants.HISTORY_GROUP));
-		menuMgr.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
-		menuMgr.add(new Separator());
-		menuMgr.add(copy);
 		Control c = getTable();
-		menuMgr.addMenuListener(manager -> c.setFocus());
+		menuMgr.setRemoveAllWhenShown(true);
+		menuMgr.addMenuListener(manager -> {
+			c.setFocus();
+			menuMgr.add(new Separator(IWorkbenchActionConstants.HISTORY_GROUP));
+			menuMgr.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+			if (copy.isEnabled()) {
+				menuMgr.add(new Separator());
+				menuMgr.add(copy);
+			}
+		});
 		c.setMenu(menuMgr.createContextMenu(c));
 	}
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java
index f1bb9e6..b7c0240 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java
@@ -709,7 +709,7 @@
 		public String toString() {
 			StringBuilder builder = new StringBuilder("Path: "); //$NON-NLS-1$
 			builder.append(getPath());
-			builder.append("regular: "); //$NON-NLS-1$
+			builder.append(", regular: "); //$NON-NLS-1$
 			builder.append(isRegularFile());
 
 			return builder.toString();
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java
index b8ab687..260acf8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java
@@ -18,6 +18,7 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import org.eclipse.compare.CompareConfiguration;
 import org.eclipse.compare.CompareEditorInput;
@@ -145,9 +146,10 @@
 						new IllegalStateException(
 								UIText.RepositoryAction_multiRepoSelection));
 			}
-			Repository repo = pathsByRepository.keySet().iterator().next();
-			List<String> filterPaths = new ArrayList<>(
-					pathsByRepository.get(repo));
+			Entry<Repository, Collection<String>> entry = pathsByRepository
+					.entrySet().iterator().next();
+			Repository repo = entry.getKey();
+			List<String> filterPaths = new ArrayList<>(entry.getValue());
 
 			if (monitor.isCanceled())
 				throw new InterruptedException();
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/AddConfigEntryDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/AddConfigEntryDialog.java
index 0afff2b..6d5b494 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/AddConfigEntryDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/AddConfigEntryDialog.java
@@ -82,9 +82,9 @@
 		Composite main = new Composite(titleParent, SWT.NONE);
 		main.setLayout(new GridLayout(2, false));
 		GridDataFactory.fillDefaults().grab(true, true).applyTo(main);
-		Label keylLabel = new Label(main, SWT.NONE);
-		keylLabel.setText(UIText.AddConfigEntryDialog_KeyLabel);
-		keylLabel.setToolTipText(UIText.AddConfigEntryDialog_ConfigKeyTooltip);
+		Label keyLabel = new Label(main, SWT.NONE);
+		keyLabel.setText(UIText.AddConfigEntryDialog_KeyLabel);
+		keyLabel.setToolTipText(UIText.AddConfigEntryDialog_ConfigKeyTooltip);
 		keyText = new Text(main, SWT.BORDER);
 		if (suggestedKey != null) {
 			keyText.setText(trimKey(suggestedKey));
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/MultiPullResultDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/MultiPullResultDialog.java
index 60125c0..35afd0c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/MultiPullResultDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/MultiPullResultDialog.java
@@ -23,6 +23,7 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.egit.core.RepositoryUtil;
 import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.LabelColumnComparator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.merge.MergeResultDialog;
 import org.eclipse.egit.ui.internal.rebase.RebaseResultDialog;
@@ -41,15 +42,11 @@
 import org.eclipse.jface.viewers.SelectionChangedEvent;
 import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerComparator;
 import org.eclipse.jgit.api.PullResult;
 import org.eclipse.jgit.api.RebaseResult;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.events.ShellAdapter;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
@@ -354,73 +351,8 @@
 		newShell.setText(UIText.MultiPullResultDialog_WindowTitle);
 	}
 
-	private ColumnComparator createComparator(TableColumn column,
+	private LabelColumnComparator createComparator(TableColumn column,
 			int columnIndex) {
-		return new ColumnComparator(column, columnIndex);
-	}
-
-	private class ColumnComparator extends ViewerComparator {
-
-		private static final int ASCENDING = SWT.DOWN;
-
-		private static final int NONE = SWT.NONE;
-
-		private static final int DESCENDING = SWT.UP;
-
-		private final TableColumn column;
-
-		private final int columnIndex;
-
-		private int direction;
-
-		public ColumnComparator(TableColumn column, int columnIndex) {
-			super(null);
-			this.column = column;
-			this.columnIndex = columnIndex;
-			column.addSelectionListener(new SelectionAdapter() {
-				@Override
-				public void widgetSelected(SelectionEvent e) {
-					if (tv.getComparator() == ColumnComparator.this) {
-						if (direction == ASCENDING) {
-							setDirection(DESCENDING);
-						} else {
-							setDirection(NONE);
-						}
-					} else {
-						setDirection(ASCENDING);
-					}
-				}
-			});
-		}
-
-		private void setDirection(int newDirection) {
-			direction = newDirection;
-			Table table = column.getParent();
-			table.setSortDirection(direction);
-			if (direction == NONE) {
-				table.setSortColumn(null);
-				tv.setComparator(null);
-			} else {
-				table.setSortColumn(column);
-				if (tv.getComparator() == this) {
-					tv.refresh();
-				} else {
-					tv.setComparator(this);
-				}
-			}
-		}
-
-		@Override
-		public int compare(Viewer viewer, Object e1, Object e2) {
-			ColumnLabelProvider labelProvider = (ColumnLabelProvider) tv
-					.getLabelProvider(columnIndex);
-			String label1 = labelProvider.getText(e1);
-			String label2 = labelProvider.getText(e2);
-			if (direction == ASCENDING) {
-				return label1.compareTo(label2);
-			} else {
-				return label2.compareTo(label1);
-			}
-		}
+		return new LabelColumnComparator(this.tv, column, columnIndex);
 	}
 }
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java
index f123ce5..738c5d0 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java
@@ -249,11 +249,6 @@
 				return null;
 			}
 
-			@Override
-			public Image getImage(Object element) {
-				return null;
-			}
-
 		});
 
 		TreeViewerColumn messageColumn = createColumn(layout,
@@ -300,6 +295,8 @@
 					return (Image) resourceManager.get(UIIcons.CHERRY_PICK);
 				if (comment.startsWith("Branch: renamed ")) //$NON-NLS-1$
 					return (Image) resourceManager.get(UIIcons.EDITCONFIG);
+				if (comment.startsWith("reset")) //$NON-NLS-1$
+					return (Image) resourceManager.get(UIIcons.RESET);
 				return null;
 			}
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/OpenCommitSearchPageAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/OpenCommitSearchPageAction.java
new file mode 100644
index 0000000..a17f6e6
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/OpenCommitSearchPageAction.java
@@ -0,0 +1,39 @@
+package org.eclipse.egit.ui.internal.search;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.search.ui.NewSearchUI;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+
+/**
+ * Opens the Search Dialog and brings the Git search page to front
+ */
+public class OpenCommitSearchPageAction implements IWorkbenchWindowActionDelegate {
+
+	private IWorkbenchWindow fWindow;
+
+	@Override
+	public void init(IWorkbenchWindow window) {
+		fWindow= window;
+	}
+
+	@Override
+	public void run(IAction action) {
+		if (fWindow == null || fWindow.getActivePage() == null) {
+			return;
+		}
+		NewSearchUI.openSearchDialog(fWindow, CommitSearchPage.ID);
+	}
+
+	@Override
+	public void selectionChanged(IAction action, ISelection selection) {
+		// do nothing since the action isn't selection dependent.
+	}
+
+	@Override
+	public void dispose() {
+		fWindow= null;
+	}
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/SelectionPropertyTester.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/SelectionPropertyTester.java
index f06310a..f580c3f 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/SelectionPropertyTester.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/SelectionPropertyTester.java
@@ -14,10 +14,13 @@
 package org.eclipse.egit.ui.internal.selection;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.eclipse.core.expressions.PropertyTester;
 import org.eclipse.core.resources.IContainer;
@@ -60,6 +63,14 @@
 			return SelectionUtils
 					.getRepository(getStructuredSelection(collection)) != null;
 
+		} else if ("resourcesMultipleRepositories".equals(property)) { //$NON-NLS-1$
+			return resourceSelectionContainsMoreThanOneRepository(collection,
+					args);
+
+		} else if ("selectionMultipleRepositories".equals(property)) { //$NON-NLS-1$
+			return selectionContainsMoreThanOneRepository(collection,
+					args);
+
 		} else if ("resourcesSingleRepository".equals(property)) { //$NON-NLS-1$
 			IStructuredSelection selection = getStructuredSelection(collection);
 
@@ -116,6 +127,32 @@
 		return false;
 	}
 
+	private boolean resourceSelectionContainsMoreThanOneRepository(
+			Collection<?> collection, Object[] args) {
+		IStructuredSelection selection = getStructuredSelection(collection);
+		IResource[] resources = SelectionUtils.getSelectedResources(selection);
+		Set<Repository> repos = Stream.of(resources) //
+				.map(SelectionPropertyTester::getRepositoryOfMapping) //
+				.collect(Collectors.toSet());
+		return testMultipleRepositoryProperties(repos, args);
+	}
+
+	private boolean selectionContainsMoreThanOneRepository(
+			Collection<?> collection, Object[] args) {
+		IStructuredSelection selection = getStructuredSelection(collection);
+		Repository[] repos = SelectionUtils.getRepositories(selection);
+		return testMultipleRepositoryProperties(Arrays.asList(repos), args);
+	}
+
+	private boolean testMultipleRepositoryProperties(
+			Collection<Repository> repos, Object[] args) {
+		if (repos.size() < 2)
+			return false;
+
+		return repos.stream().allMatch(
+				r -> SelectionPropertyTester.testRepositoryProperties(r, args));
+	}
+
 	private static @NonNull IStructuredSelection getStructuredSelection(
 			Collection<?> collection) {
 		Object firstElement = collection.iterator().next();
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
index 0cce452..3f14fbb 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
@@ -1125,13 +1125,17 @@
 BranchAction_branchFailed=Branch failed
 BranchAction_cannotCheckout=Cannot check out now
 BranchAction_checkingOut=Checking out {0} - {1}
-BranchAction_repositoryState=Repository state: {0}
+BranchAction_checkingOutMultiple=Checking out multiple repositories to {0}
+BranchAction_repositoryState=The repository {0} is not on a valid state: {1}
 BranchConfigurationDialog_BranchConfigurationTitle=Git Branch Configuration
 BranchConfigurationDialog_EditBranchConfigMessage=Edit the upstream configuration for branch {0}
 BranchConfigurationDialog_ExceptionGettingRefs=Exception getting Refs
 BranchConfigurationDialog_RemoteLabel=Rem&ote:
 BranchConfigurationDialog_SaveBranchConfigFailed=Could not save branch configuration
 BranchConfigurationDialog_UpstreamBranchLabel=Upstream &Branch:
+
+BranchOperationUI_CheckoutError_DialogTitle=Problem checking out repository
+BranchOperationUI_CheckoutError_DialogMessage=Checking out {0} - {1} has failed.
 BranchOperationUI_CheckoutRemoteTrackingAsLocal=Check out as New Local Branch
 BranchOperationUI_CheckoutRemoteTrackingCommit=Check out Commit
 BranchOperationUI_CheckoutRemoteTrackingQuestion=If you want to work on the branch, a new local branch has to be created and checked out.\n\nIf you just want to have a look at the state of the branch, the commit of the remote-tracking branch can be checked out.
@@ -1584,6 +1588,20 @@
 MultiPullResultDialog_UpdateStatusColumnHeader=Update Status
 MultiPullResultDialog_WindowTitle=Pull Result for Multiple Repositories
 
+MultiBranchOperationResultDialog_OkStatus=OK
+MultiBranchOperationResultDialog_RepositoryColumnHeader=Repository
+MultiBranchOperationResultDialog_WindowTitle=Branch Operation for Multiple Repositories
+MultiBranchOperationResultDialog_CheckoutStatusColumnHeader=Checkout Status
+
+MultiBranchOperationResultDialog_DialogTitle=Problems checking out multiple repositories
+MultiBranchOperationResultDialog_DialogErrorMessage=Some of the repositories were not checked out
+
+MultiBranchOperationResultDialog_CheckoutResultError=An exception occurred during checkout
+MultiBranchOperationResultDialog_CheckoutResultNonDeleted=Checkout succeeded but some files could not be deleted
+MultiBranchOperationResultDialog_CheckoutResultConflicts=Operation has not completed because of conflicts
+MultiBranchOperationResultDialog_CheckoutResultOK=Checkout completed normally
+MultiBranchOperationResultDialog_CheckoutResultNotTried=The operation was not executed
+
 CommitFileDiffViewer_CanNotOpenCompareEditorTitle=Cannot Open Compare Editor
 CommitFileDiffViewer_CompareMenuLabel=Compare with Previous &Version
 CommitFileDiffViewer_CompareWorkingDirectoryMenuLabel=Compare with &Working Tree
@@ -1826,6 +1844,7 @@
 SquashHandler_JobName=Squashing {0} Commits
 SwitchToMenu_NewBranchMenuLabel=&New Branch...
 SwitchToMenu_OtherMenuLabel=&Other...
+SwitchToMenu_NoCommonBranchesFound=No common branches found
 GitActionContributor_ExpandAll=Expand All
 GitActionContributor_Push=Push
 GitActionContributor_Pull=Pull
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/variables/GitTemplateVariableResolver.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/variables/GitTemplateVariableResolver.java
index ac0a7d9..5b8dbe9 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/variables/GitTemplateVariableResolver.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/variables/GitTemplateVariableResolver.java
@@ -10,18 +10,20 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.variables;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.List;
 
 import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.egit.core.AdapterUtils;
 import org.eclipse.egit.core.project.RepositoryMapping;
 import org.eclipse.egit.ui.Activator;
-import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContext;
-import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContext;
 import org.eclipse.jface.text.templates.TemplateContext;
 import org.eclipse.jface.text.templates.TemplateVariable;
 import org.eclipse.jface.text.templates.TemplateVariableResolver;
+import org.eclipse.jgit.annotations.Nullable;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.lib.StoredConfig;
 
@@ -140,23 +142,41 @@
 	 *            the current template context.
 	 * @return the current project
 	 */
+	@Nullable
 	protected static IProject getProject(TemplateContext context) {
-		IProject project = null;
+		// We can't use instanceof here because of the compiler error on 4.10
+		// platform saying that TemplateContext is always IAdaptable
+		if (IAdaptable.class.isInstance(context)) {
+			return AdapterUtils.adapt(context, IProject.class);
+		}
+		// Note: block below can be removed after EGit minimum target platform
+		// will be 4.10, see bug 539095 for details
 		if (Activator.hasJavaPlugin()) {
-			if (context instanceof CodeTemplateContext) {
-				IJavaProject javaProject = ((CodeTemplateContext) context)
-						.getJavaProject();
-				if (javaProject != null) {
-					project = javaProject.getProject();
+			boolean hasPublicMethod = context.getClass().getSimpleName()
+					.equals("CodeTemplateContext"); //$NON-NLS-1$
+			try {
+				Method method;
+				if (hasPublicMethod) {
+					// CodeTemplateContext has public getJavaProject() method
+					method = context.getClass().getMethod("getJavaProject"); //$NON-NLS-1$
+				} else {
+					// JavaContext inherits from CompilationUnitContext which
+					// has protected getJavaProject() method
+					method = context.getClass().getSuperclass()
+							.getDeclaredMethod("getJavaProject"); //$NON-NLS-1$
+					method.setAccessible(true);
 				}
-			} else if (context instanceof CompilationUnitContext) {
-				ICompilationUnit cu = ((CompilationUnitContext) context)
-						.getCompilationUnit();
-				if (cu != null) {
-					project = cu.getJavaProject().getProject();
+				Object result = method.invoke(context);
+				if (result instanceof IJavaProject) {
+					IJavaProject javaProject = (IJavaProject) result;
+					return javaProject.getProject();
 				}
+			} catch (NoSuchMethodException | SecurityException
+					| IllegalAccessException | IllegalArgumentException
+					| InvocationTargetException e) {
+				return null;
 			}
 		}
-		return project;
+		return null;
 	}
 }
diff --git a/org.eclipse.egit/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.egit/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949..2fca432 100644
--- a/org.eclipse.egit/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.egit/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
 #Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
 eclipse.preferences.version=1
diff --git a/org.eclipse.egit/META-INF/MANIFEST.MF b/org.eclipse.egit/META-INF/MANIFEST.MF
index 298c52c..ad5cfe5 100644
--- a/org.eclipse.egit/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.egit;singleton:=true
-Bundle-Version: 5.1.3.qualifier
+Bundle-Version: 5.2.0.qualifier
 Bundle-Vendor: %provider_name
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
diff --git a/org.eclipse.egit/pom.xml b/org.eclipse.egit/pom.xml
index 9d3c2c5..ce9a179 100644
--- a/org.eclipse.egit/pom.xml
+++ b/org.eclipse.egit/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.egit</groupId>
     <artifactId>egit-parent</artifactId>
-    <version>5.1.3-SNAPSHOT</version>
+    <version>5.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.egit</artifactId>
diff --git a/pom.xml b/pom.xml
index 6d69d4b..9edd5bc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
 
   <groupId>org.eclipse.egit</groupId>
   <artifactId>egit-parent</artifactId>
-  <version>5.1.3-SNAPSHOT</version>
+  <version>5.2.0-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <name>EGit Parent</name>
@@ -60,7 +60,7 @@
   </licenses>
 
   <properties>
-    <egit-version>5.1.3-SNAPSHOT</egit-version>
+    <egit-version>5.2.0-SNAPSHOT</egit-version>
     <tycho-version>1.2.0</tycho-version>
     <tycho-extras-version>${tycho-version}</tycho-extras-version>
     <jboss-tycho-plugins-version>1.1.0</jboss-tycho-plugins-version>
diff --git a/tools/oomph/EGit.setup b/tools/oomph/EGit.setup
index 8d1728f..c8fbcf5 100644
--- a/tools/oomph/EGit.setup
+++ b/tools/oomph/EGit.setup
@@ -105,15 +105,6 @@
       xsi:type="pde:APIBaselineTask"
       name="EGit"
       activate="false"
-      version="4.10.0"
-      location="${workspace.location/../api.baseline/4.10.0}"
-      remoteURI="http://download.eclipse.org/egit/updates-4.10/org.eclipse.egit.repository-4.10.0.201712302008-r.zip">
-    <description>EGit 4.10.0 API baseline; to be used with branch stable-4.11</description>
-  </setupTask>
-  <setupTask
-      xsi:type="pde:APIBaselineTask"
-      name="EGit"
-      activate="false"
       version="4.11.0"
       location="${workspace.location/../api.baseline/4.11.0}"
       remoteURI="http://download.eclipse.org/egit/updates-4.11/org.eclipse.egit.repository-4.11.0.201803080745-r.zip">
@@ -122,10 +113,19 @@
   <setupTask
       xsi:type="pde:APIBaselineTask"
       name="EGit"
+      activate="false"
       version="5.0.0"
       location="${workspace.location/../api.baseline/5.0.0}"
       remoteURI="http://download.eclipse.org/egit/updates-5.0/org.eclipse.egit.repository-5.0.0.201806131550-r.zip">
-    <description>EGit 5.0.0 API baseline; to be used with branch master</description>
+    <description>EGit 5.0.0 API baseline; to be used with branch stable-5.1</description>
+  </setupTask>
+  <setupTask
+      xsi:type="pde:APIBaselineTask"
+      name="EGit"
+      version="5.1.1"
+      location="${workspace.location/../api.baseline/5.1.1}"
+      remoteURI="http://download.eclipse.org/egit/updates-5.1.1/org.eclipse.egit.repository-5.1.1.201809181055-r.zip">
+    <description>EGit 5.1.1 API baseline; to be used with branch master</description>
   </setupTask>
   <stream name="master"
       label="Workspace setup for branch master">