Merge branch 'stable-4.3' into stable-4.4

* stable-4.3:
  JGit v4.0.3.201509231615-r

Change-Id: I147d81a9cc9c0f9e66084897df9c88c369539db7
Signed-off-by: David Pursehouse <david.pursehouse@gmail.com>
diff --git a/.buckversion b/.buckversion
index 561a769..f5fe016 100644
--- a/.buckversion
+++ b/.buckversion
@@ -1 +1 @@
-ca8d6cbac373a690f543c5159eec0116e76187a9
+e64a2e2ada022f81e42be750b774024469551398
diff --git a/.gitignore b/.gitignore
index 6c62199..95ad174 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
-/target
+/.buckd
 /.project
 /buck-cache
 /buck-out
+/target
diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
index afa0f5c..371c66f 100644
--- a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
@@ -3,14 +3,14 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.ant.test
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Import-Package: org.apache.tools.ant,
- org.eclipse.jgit.ant.tasks;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.junit;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)",
+ org.eclipse.jgit.ant.tasks;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.junit;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)",
  org.hamcrest;version="[1.1.0,2.0.0)",
  org.junit;version="[4.0.0,5.0.0)"
diff --git a/org.eclipse.jgit.ant.test/pom.xml b/org.eclipse.jgit.ant.test/pom.xml
index fc1257d..a4f4355 100644
--- a/org.eclipse.jgit.ant.test/pom.xml
+++ b/org.eclipse.jgit.ant.test/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ant.test</artifactId>
diff --git a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
index 98da2c0..4ae7d7b 100644
--- a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
@@ -2,11 +2,11 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Bundle-Name
 Bundle-SymbolicName: org.eclipse.jgit.ant
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Import-Package: org.apache.tools.ant,
-  org.eclipse.jgit.storage.file;version="[4.3.2,4.4.0)"
+  org.eclipse.jgit.storage.file;version="[4.4.2,4.5.0)"
 Bundle-Localization: plugin
 Bundle-Vendor: %Provider-Name
-Export-Package: org.eclipse.jgit.ant.tasks;version="4.3.2";
+Export-Package: org.eclipse.jgit.ant.tasks;version="4.4.2";
  uses:="org.apache.tools.ant.types,org.apache.tools.ant"
diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml
index 6fc806f..6f21e4d 100644
--- a/org.eclipse.jgit.ant/pom.xml
+++ b/org.eclipse.jgit.ant/pom.xml
@@ -48,7 +48,7 @@
 	<parent>
 		<groupId>org.eclipse.jgit</groupId>
 		<artifactId>org.eclipse.jgit-parent</artifactId>
-		<version>4.3.2-SNAPSHOT</version>
+		<version>4.4.2-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>org.eclipse.jgit.ant</artifactId>
@@ -72,7 +72,7 @@
 		<dependency>
 			<groupId>org.apache.ant</groupId>
 			<artifactId>ant</artifactId>
-			<version>1.9.2</version>
+			<version>1.9.6</version>
 		</dependency>
 	</dependencies>
 
diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
index a185d1f..2b960ae 100644
--- a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.archive
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Vendor: %provider_name
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
@@ -12,14 +12,14 @@
  org.apache.commons.compress.compressors.bzip2;version="[1.4,2.0)",
  org.apache.commons.compress.compressors.gzip;version="[1.4,2.0)",
  org.apache.commons.compress.compressors.xz;version="[1.4,2.0)",
- org.eclipse.jgit.api;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.nls;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)",
+ org.eclipse.jgit.api;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.nls;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)",
  org.osgi.framework;version="[1.3.0,2.0.0)"
 Bundle-ActivationPolicy: lazy
 Bundle-Activator: org.eclipse.jgit.archive.FormatActivator
-Export-Package: org.eclipse.jgit.archive;version="4.3.2";
+Export-Package: org.eclipse.jgit.archive;version="4.4.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.api,
    org.apache.commons.compress.archivers,
diff --git a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
index cf164a9..b4a519c 100644
--- a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.archive - Sources
 Bundle-SymbolicName: org.eclipse.jgit.archive.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 4.3.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.archive;version="4.3.2.qualifier";roots="."
+Bundle-Version: 4.4.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.archive;version="4.4.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml
index 7b9c6ac..0df67f8 100644
--- a/org.eclipse.jgit.archive/pom.xml
+++ b/org.eclipse.jgit.archive/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.archive</artifactId>
diff --git a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
index 0872d49..200e0ce 100644
--- a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Bundle-Name
 Bundle-SymbolicName: org.eclipse.jgit.http.apache
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Bundle-Localization: plugin
 Bundle-Vendor: %Provider-Name
@@ -19,10 +19,10 @@
  org.apache.http.impl.client;version="[4.1.0,5.0.0)",
  org.apache.http.impl.client.cache;version="[4.1.0,5.0.0)",
  org.apache.http.params;version="[4.1.0,5.0.0)",
- org.eclipse.jgit.nls;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport.http;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)"
-Export-Package: org.eclipse.jgit.transport.http.apache;version="4.3.2";
+ org.eclipse.jgit.nls;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport.http;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)"
+Export-Package: org.eclipse.jgit.transport.http.apache;version="4.4.2";
   uses:="org.eclipse.jgit.transport.http,
    javax.net.ssl,
    org.apache.http.client,
diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml
index 2b0b58d..45bb22e 100644
--- a/org.eclipse.jgit.http.apache/pom.xml
+++ b/org.eclipse.jgit.http.apache/pom.xml
@@ -48,7 +48,7 @@
 	<parent>
 		<groupId>org.eclipse.jgit</groupId>
 		<artifactId>org.eclipse.jgit-parent</artifactId>
-		<version>4.3.2-SNAPSHOT</version>
+		<version>4.4.2-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>org.eclipse.jgit.http.apache</artifactId>
diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
index 848b55e..d28ac28 100644
--- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.http.server
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %provider_name
-Export-Package: org.eclipse.jgit.http.server;version="4.3.2",
- org.eclipse.jgit.http.server.glue;version="4.3.2";
+Export-Package: org.eclipse.jgit.http.server;version="4.4.2",
+ org.eclipse.jgit.http.server.glue;version="4.4.2";
   uses:="javax.servlet,javax.servlet.http",
- org.eclipse.jgit.http.server.resolver;version="4.3.2";
+ org.eclipse.jgit.http.server.resolver;version="4.4.2";
   uses:="org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.transport,
@@ -17,12 +17,12 @@
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Import-Package: javax.servlet;version="[2.5.0,3.2.0)",
  javax.servlet.http;version="[2.5.0,3.2.0)",
- org.eclipse.jgit.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.nls;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport.resolver;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)"
+ org.eclipse.jgit.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.nls;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport.resolver;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)"
diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml
index c6de937..6c5db67 100644
--- a/org.eclipse.jgit.http.server/pom.xml
+++ b/org.eclipse.jgit.http.server/pom.xml
@@ -52,7 +52,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.server</artifactId>
diff --git a/org.eclipse.jgit.http.test/.classpath b/org.eclipse.jgit.http.test/.classpath
index 2fdcc94..e1a1a64 100644
--- a/org.eclipse.jgit.http.test/.classpath
+++ b/org.eclipse.jgit.http.test/.classpath
@@ -3,5 +3,6 @@
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="src" path="tst"/>
+	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
index fefdb66..90ee569 100644
--- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.http.test
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Vendor: %provider_name
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
@@ -22,23 +22,24 @@
  org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)",
  org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)",
  org.eclipse.jetty.util.thread;version="[9.0.0,10.0.0)",
- org.eclipse.jgit.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.http.server;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.http.server.glue;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.http.server.resolver;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.junit;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.junit.http;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.nls;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport.http;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport.http.apache;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport.resolver;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)",
+ org.eclipse.jgit.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.http.server;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.http.server.glue;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.http.server.resolver;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.junit;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.junit.http;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.nls;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport.http;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport.http.apache;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport.resolver;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)",
  org.hamcrest.core;version="[1.1.0,2.0.0)",
  org.junit;version="[4.0.0,5.0.0)",
  org.junit.runner;version="[4.0.0,5.0.0)",
diff --git a/org.eclipse.jgit.http.test/pom.xml b/org.eclipse.jgit.http.test/pom.xml
index 8fc34f7..c39817f 100644
--- a/org.eclipse.jgit.http.test/pom.xml
+++ b/org.eclipse.jgit.http.test/pom.xml
@@ -51,7 +51,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.test</artifactId>
@@ -72,7 +72,6 @@
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
       <version>${project.version}</version>
-      <scope>test</scope>
     </dependency>
 
     <dependency>
@@ -111,6 +110,7 @@
   </dependencies>
 
   <build>
+    <sourceDirectory>src/</sourceDirectory>
     <testSourceDirectory>tst/</testSourceDirectory>
 
     <testResources>
diff --git a/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java b/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java
new file mode 100644
index 0000000..a1e41d1
--- /dev/null
+++ b/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016, Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.eclipse.jgit.http.test;
+
+import java.io.IOException;
+
+import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.lib.RefDatabase;
+
+/**
+ * An {@link InMemoryRepository} whose refs can be made unreadable for testing
+ * purposes.
+ */
+class RefsUnreadableInMemoryRepository extends InMemoryRepository {
+
+	private final RefsUnreadableRefDatabase refs;
+
+	private volatile boolean failing;
+
+	RefsUnreadableInMemoryRepository(DfsRepositoryDescription repoDesc) {
+		super(repoDesc);
+		refs = new RefsUnreadableRefDatabase();
+		failing = false;
+	}
+
+	@Override
+	public RefDatabase getRefDatabase() {
+		return refs;
+	}
+
+	/**
+	 * Make the ref database unable to scan its refs.
+	 * <p>
+	 * It may be useful to follow a call to startFailing with a call to
+	 * {@link RefDatabase#refresh()}, ensuring the next ref read fails.
+	 */
+	void startFailing() {
+		failing = true;
+	}
+
+	private class RefsUnreadableRefDatabase extends MemRefDatabase {
+
+		@Override
+		protected RefCache scanAllRefs() throws IOException {
+			if (failing) {
+				throw new IOException("disk failed, no refs found");
+			} else {
+				return super.scanAllRefs();
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
index 0f3d3c6..073c751 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
@@ -82,9 +82,11 @@
 import org.eclipse.jgit.errors.TransportException;
 import org.eclipse.jgit.http.server.GitServlet;
 import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.junit.TestRng;
 import org.eclipse.jgit.junit.http.AccessEvent;
+import org.eclipse.jgit.junit.http.AppServer;
 import org.eclipse.jgit.junit.http.HttpTestCase;
 import org.eclipse.jgit.lib.ConfigConstants;
 import org.eclipse.jgit.lib.Constants;
@@ -155,18 +157,7 @@
 
 		ServletContextHandler app = server.addContext("/git");
 		GitServlet gs = new GitServlet();
-		gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() {
-			public Repository open(HttpServletRequest req, String name)
-					throws RepositoryNotFoundException,
-					ServiceNotEnabledException {
-				if (!name.equals(srcName))
-					throw new RepositoryNotFoundException(name);
-
-				final Repository db = src.getRepository();
-				db.incrementOpen();
-				return db;
-			}
-		});
+		gs.setRepositoryResolver(new TestRepoResolver(src, srcName));
 		app.addServlet(new ServletHolder(gs), "/*");
 
 		ServletContextHandler broken = server.addContext("/bad");
@@ -509,6 +500,51 @@
 	}
 
 	@Test
+	public void testFetch_RefsUnreadableOnUpload() throws Exception {
+		AppServer noRefServer = new AppServer();
+		try {
+			final String repoName = "refs-unreadable";
+			RefsUnreadableInMemoryRepository badRefsRepo = new RefsUnreadableInMemoryRepository(
+					new DfsRepositoryDescription(repoName));
+			final TestRepository<Repository> repo = new TestRepository<Repository>(
+					badRefsRepo);
+
+			ServletContextHandler app = noRefServer.addContext("/git");
+			GitServlet gs = new GitServlet();
+			gs.setRepositoryResolver(new TestRepoResolver(repo, repoName));
+			app.addServlet(new ServletHolder(gs), "/*");
+			noRefServer.setUp();
+
+			RevBlob A2_txt = repo.blob("A2");
+			RevCommit A2 = repo.commit().add("A2_txt", A2_txt).create();
+			RevCommit B2 = repo.commit().parent(A2).add("A2_txt", "C2")
+					.add("B2", "B2").create();
+			repo.update(master, B2);
+
+			URIish badRefsURI = new URIish(noRefServer.getURI()
+					.resolve(app.getContextPath() + "/" + repoName).toString());
+
+			Repository dst = createBareRepository();
+			try (Transport t = Transport.open(dst, badRefsURI);
+					FetchConnection c = t.openFetch()) {
+				// We start failing here to exercise the post-advertisement
+				// upload pack handler.
+				badRefsRepo.startFailing();
+				// Need to flush caches because ref advertisement populated them.
+				badRefsRepo.getRefDatabase().refresh();
+				c.fetch(NullProgressMonitor.INSTANCE,
+						Collections.singleton(c.getRef(master)),
+						Collections.<ObjectId> emptySet());
+				fail("Successfully served ref with value " + c.getRef(master));
+			} catch (TransportException err) {
+				assertEquals("internal server error", err.getMessage());
+			}
+		} finally {
+			noRefServer.tearDown();
+		}
+	}
+
+	@Test
 	public void testPush_NotAuthorized() throws Exception {
 		final TestRepository src = createTestRepository();
 		final RevBlob Q_txt = src.blob("new text");
@@ -677,4 +713,28 @@
 		cfg.setBoolean("http", null, "receivepack", true);
 		cfg.save();
 	}
+
+	private final class TestRepoResolver
+			implements RepositoryResolver<HttpServletRequest> {
+
+		private final TestRepository<Repository> repo;
+
+		private final String repoName;
+
+		private TestRepoResolver(TestRepository<Repository> repo,
+				String repoName) {
+			this.repo = repo;
+			this.repoName = repoName;
+		}
+
+		public Repository open(HttpServletRequest req, String name)
+				throws RepositoryNotFoundException, ServiceNotEnabledException {
+			if (!name.equals(repoName))
+				throw new RepositoryNotFoundException(name);
+
+			Repository db = repo.getRepository();
+			db.incrementOpen();
+			return db;
+		}
+	}
 }
diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
index bd26ac0..c406a14 100644
--- a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.junit.http
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %provider_name
 Bundle-ActivationPolicy: lazy
@@ -20,16 +20,16 @@
  org.eclipse.jetty.util.component;version="[9.0.0,10.0.0)",
  org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)",
  org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)",
- org.eclipse.jgit.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.http.server;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.junit;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport.resolver;version="[4.3.2,4.4.0)",
+ org.eclipse.jgit.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.http.server;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.junit;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport.resolver;version="[4.4.2,4.5.0)",
  org.junit;version="[4.0.0,5.0.0)"
-Export-Package: org.eclipse.jgit.junit.http;version="4.3.2";
+Export-Package: org.eclipse.jgit.junit.http;version="4.4.2";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.junit,
    javax.servlet.http,
diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml
index 43fdb8a..201998f 100644
--- a/org.eclipse.jgit.junit.http/pom.xml
+++ b/org.eclipse.jgit.junit.http/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit.http</artifactId>
diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
index 89171bc..0202328 100644
--- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
@@ -2,27 +2,27 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.junit
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %provider_name
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
-Import-Package: org.eclipse.jgit.api;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.api.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.dircache;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.pack;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.merge;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.treewalk;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.treewalk.filter;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util.io;version="[4.3.2,4.4.0)",
+Import-Package: org.eclipse.jgit.api;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.api.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.dircache;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.merge;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.treewalk;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.treewalk.filter;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util.io;version="[4.4.2,4.5.0)",
  org.junit;version="[4.0.0,5.0.0)"
-Export-Package: org.eclipse.jgit.junit;version="4.3.2";
+Export-Package: org.eclipse.jgit.junit;version="4.4.2";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml
index bb2b677..90dd865 100644
--- a/org.eclipse.jgit.junit/pom.xml
+++ b/org.eclipse.jgit.junit/pom.xml
@@ -52,7 +52,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit</artifactId>
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
index 86b87b4..c282df0 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
@@ -406,7 +406,7 @@
 			String originalBranch = repo.getFullBranch();
 			boolean empty = repo.resolve(Constants.HEAD) == null;
 			if (!empty) {
-				if (repo.getRef(branch) == null)
+				if (repo.findRef(branch) == null)
 					git.branchCreate().setName(branch).call();
 				git.checkout().setName(branch).call();
 			}
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
index 1119e63..0a2345f 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
@@ -211,17 +211,6 @@
 		return new Date(mockSystemReader.getCurrentTime());
 	}
 
-	/**
-	 * @return current date.
-	 *
-	 * @deprecated Use {@link #getDate()} instead.
-	 */
-	@Deprecated
-	public Date getClock() {
-		// Remove once Gitiles and Gerrit are using the updated JGit.
-		return getDate();
-	}
-
 	/** @return timezone used for default identities. */
 	public TimeZone getTimeZone() {
 		return mockSystemReader.getTimeZone();
@@ -501,7 +490,7 @@
 	 */
 	public CommitBuilder amendRef(String ref) throws Exception {
 		String name = normalizeRef(ref);
-		Ref r = db.getRef(name);
+		Ref r = db.exactRef(name);
 		if (r == null)
 			throw new IOException("Not a ref: " + ref);
 		return amend(pool.parseCommit(r.getObjectId()), branch(name).commit());
@@ -586,6 +575,31 @@
 		}
 	}
 
+	/**
+	 * Delete a reference.
+	 *
+	 * @param ref
+	 *	      the name of the reference to delete. This is normalized
+	 *	      in the same way as {@link #update(String, AnyObjectId)}.
+	 * @throws Exception
+	 * @since 4.4
+	 */
+	public void delete(String ref) throws Exception {
+		ref = normalizeRef(ref);
+		RefUpdate u = db.updateRef(ref);
+		switch (u.delete()) {
+		case FAST_FORWARD:
+		case FORCED:
+		case NEW:
+		case NO_CHANGE:
+			updateServerInfo();
+			return;
+
+		default:
+			throw new IOException("Cannot delete " + ref + " " + u.getResult());
+		}
+	}
+
 	private static String normalizeRef(String ref) {
 		if (Constants.HEAD.equals(ref)) {
 			// nothing
@@ -678,7 +692,7 @@
 		RevCommit parent = commit.getParent(0);
 		pool.parseHeaders(parent);
 
-		Ref headRef = db.getRef(Constants.HEAD);
+		Ref headRef = db.exactRef(Constants.HEAD);
 		if (headRef == null)
 			throw new IOException("Missing HEAD");
 		RevCommit head = pool.parseCommit(headRef.getObjectId());
@@ -959,6 +973,15 @@
 		public RevCommit update(RevCommit to) throws Exception {
 			return TestRepository.this.update(ref, to);
 		}
+
+		/**
+		 * Delete this branch.
+		 * @throws Exception
+		 * @since 4.4
+		 */
+		public void delete() throws Exception {
+			TestRepository.this.delete(ref);
+		}
 	}
 
 	/** Helper to generate a commit. */
@@ -991,7 +1014,7 @@
 		CommitBuilder(BranchBuilder b) throws Exception {
 			branch = b;
 
-			Ref ref = db.getRef(branch.ref);
+			Ref ref = db.exactRef(branch.ref);
 			if (ref != null && ref.getObjectId() != null)
 				parent(pool.parseCommit(ref.getObjectId()));
 		}
diff --git a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
index 53d74cf..7ef63d8 100644
--- a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.lfs.server.test
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Vendor: %provider_name
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
@@ -27,11 +27,11 @@
  org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)",
  org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)",
  org.eclipse.jetty.util.thread;version="[9.0.0,10.0.0)",
- org.eclipse.jgit.junit.http;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lfs.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lfs.server.fs;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lfs.test;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)",
+ org.eclipse.jgit.junit.http;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lfs.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lfs.test;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)",
  org.hamcrest.core;version="[1.1.0,2.0.0)",
  org.junit;version="[4.0.0,5.0.0)",
  org.junit.runner;version="[4.0.0,5.0.0)",
diff --git a/org.eclipse.jgit.lfs.server.test/pom.xml b/org.eclipse.jgit.lfs.server.test/pom.xml
index 05ee6f2..bf975c0 100644
--- a/org.eclipse.jgit.lfs.server.test/pom.xml
+++ b/org.eclipse.jgit.lfs.server.test/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
index d156900..5688ea1 100644
--- a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
@@ -2,19 +2,19 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.lfs.server
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %provider_name
-Export-Package: org.eclipse.jgit.lfs.server;version="4.3.2";
+Export-Package: org.eclipse.jgit.lfs.server;version="4.4.2";
   uses:="javax.servlet.http,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.fs;version="4.3.2";
+ org.eclipse.jgit.lfs.server.fs;version="4.4.2";
   uses:="javax.servlet,
    javax.servlet.http,
    org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.internal;version="4.3.2";x-internal:=true,
- org.eclipse.jgit.lfs.server.s3;version="4.3.2";
+ org.eclipse.jgit.lfs.server.internal;version="4.4.2";x-internal:=true,
+ org.eclipse.jgit.lfs.server.s3;version="4.4.2";
   uses:="org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.lfs.lib"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
@@ -24,12 +24,12 @@
  javax.servlet.http;version="[3.1.0,4.0.0)",
  org.apache.http;version="[4.3.0,5.0.0)",
  org.apache.http.client;version="[4.3.0,5.0.0)",
- org.eclipse.jgit.annotations;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lfs.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lfs.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.nls;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport.http;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport.http.apache;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)"
+ org.eclipse.jgit.annotations;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lfs.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lfs.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.nls;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport.http;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport.http.apache;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)"
diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml
index 0a81e33..71b05ea 100644
--- a/org.eclipse.jgit.lfs.server/pom.xml
+++ b/org.eclipse.jgit.lfs.server/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server</artifactId>
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java
index 2e71c04..dd70a36 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java
@@ -147,7 +147,10 @@
 	AtomicObjectOutputStream getOutputStream(AnyLongObjectId id)
 			throws IOException {
 		Path path = getPath(id);
-		Files.createDirectories(path.getParent());
+		Path parent = path.getParent();
+		if (parent != null) {
+			Files.createDirectories(parent);
+		}
 		return new AtomicObjectOutputStream(path, id);
 	}
 
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java
index 08bb4b9..f95b605 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java
@@ -229,12 +229,12 @@
 
 	private static void addHostHeader(URL url,
 			Map<String, String> headers) {
-		String hostHeader = url.getHost();
+		StringBuilder hostHeader = new StringBuilder(url.getHost());
 		int port = url.getPort();
 		if (port > -1) {
-			hostHeader.concat(":" + Integer.toString(port)); //$NON-NLS-1$
+			hostHeader.append(":").append(port); //$NON-NLS-1$
 		}
-		headers.put("Host", hostHeader); //$NON-NLS-1$
+		headers.put("Host", hostHeader.toString()); //$NON-NLS-1$
 	}
 
 	private static String canonicalizeHeaderNames(
diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
index 173b0eb..f0ecdef 100644
--- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
@@ -2,18 +2,18 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.lfs.test
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Vendor: %provider_name
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
-Import-Package: org.eclipse.jgit.junit;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lfs.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lfs.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)",
+Import-Package: org.eclipse.jgit.junit;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lfs.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lfs.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)",
  org.hamcrest.core;version="[1.1.0,2.0.0)",
  org.junit;version="[4.0.0,5.0.0)",
  org.junit.runner;version="[4.0.0,5.0.0)",
  org.junit.runners;version="[4.0.0,5.0.0)"
-Export-Package: org.eclipse.jgit.lfs.test;version="4.3.2";x-friends:="org.eclipse.jgit.lfs.server.test"
+Export-Package: org.eclipse.jgit.lfs.test;version="4.4.2";x-friends:="org.eclipse.jgit.lfs.server.test"
 
diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml
index 8e5d28b..782c63e 100644
--- a/org.eclipse.jgit.lfs.test/pom.xml
+++ b/org.eclipse.jgit.lfs.test/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.test</artifactId>
diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
index 30baf05..77b6fce 100644
--- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
@@ -2,14 +2,14 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.lfs
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %provider_name
-Export-Package: org.eclipse.jgit.lfs.errors;version="4.3.2",
- org.eclipse.jgit.lfs.internal;version="4.3.2";x-friends:="org.eclipse.jgit.lfs.test",
- org.eclipse.jgit.lfs.lib;version="4.3.2"
+Export-Package: org.eclipse.jgit.lfs.errors;version="4.4.2",
+ org.eclipse.jgit.lfs.internal;version="4.4.2";x-friends:="org.eclipse.jgit.lfs.test",
+ org.eclipse.jgit.lfs.lib;version="4.4.2"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
-Import-Package: org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.nls;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)"
+Import-Package: org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.nls;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)"
diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml
index b0f543d..1e6fd7d 100644
--- a/org.eclipse.jgit.lfs/pom.xml
+++ b/org.eclipse.jgit.lfs/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml
index 3d13c71..5af0b63 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit"
       label="%featureName"
-      version="4.3.2.qualifier"
+      version="4.4.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
index 81a8c3b..c91a46d 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
index f2597a4..f94dce8 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.http.apache"
       label="%featureName"
-      version="4.3.2.qualifier"
+      version="4.4.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
index ca0fdca..4f1cc80 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
index 829ef0a..0014f60 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.junit"
       label="%featureName"
-      version="4.3.2.qualifier"
+      version="4.4.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml
index 6b900d4..a4c763b 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
index 829c056..4f0ada2 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.lfs"
       label="%featureName"
-      version="4.3.2.qualifier"
+      version="4.4.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
index bf96616..154df15 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
index 73a9a13..a6ae6d3 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.pgm"
       label="%featureName"
-      version="4.3.2.qualifier"
+      version="4.4.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -31,8 +31,8 @@
          version="0.0.0"/>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="4.3.0" match="equivalent"/>
-      <import feature="org.eclipse.jgit.lfs" version="4.3.0" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="4.4.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit.lfs" version="4.4.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
index 2628721..2013fc4 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml
index 4cb5cb7..cc52233 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.pgm.source"
       label="%featureName"
-      version="4.3.2.qualifier"
+      version="4.4.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml
index c5015c6..a295873 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
index 1410d68..43e15e5 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.repository</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
index 4d49aae..4f99110 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.source"
       label="%featureName"
-      version="4.3.2.qualifier"
+      version="4.4.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml
index 204026b..f737251 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
index 4e1f66f..a4ba267 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
@@ -2,4 +2,4 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: JGit Target Platform Bundle
 Bundle-SymbolicName: org.eclipse.jgit.target
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
index e506aec..f7d5622 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
-<target name="jgit-4.5" sequenceNumber="1455835295">
+<target name="jgit-4.6" sequenceNumber="1463612069">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.jetty.client" version="9.2.13.v20150730"/>
@@ -23,8 +23,8 @@
       <repository id="jetty-9.2.13" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.2.13.v20150730/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.apache.ant" version="1.9.4.v201504302020"/>
-      <unit id="org.apache.ant.source" version="1.9.4.v201504302020"/>
+      <unit id="org.apache.ant" version="1.9.6.v201510161327"/>
+      <unit id="org.apache.ant.source" version="1.9.6.v201510161327"/>
       <unit id="org.apache.commons.compress" version="1.6.0.v201310281400"/>
       <unit id="org.apache.commons.compress.source" version="1.6.0.v201310281400"/>
       <unit id="org.apache.commons.logging" version="1.1.1.v201101211721"/>
@@ -39,8 +39,8 @@
       <unit id="org.kohsuke.args4j.source" version="2.0.21.v201301150030"/>
       <unit id="org.hamcrest.core" version="1.3.0.v201303031735"/>
       <unit id="org.hamcrest.core.source" version="1.3.0.v201303031735"/>
-      <unit id="javaewah" version="0.7.9.v201401101600"/>
-      <unit id="javaewah.source" version="0.7.9.v201401101600"/>
+      <unit id="javaewah" version="0.7.9.v201605172130"/>
+      <unit id="javaewah.source" version="0.7.9.v201605172130"/>
       <unit id="org.objenesis" version="1.0.0.v201505121915"/>
       <unit id="org.objenesis.source" version="1.0.0.v201505121915"/>
       <unit id="org.mockito" version="1.8.4.v201303031500"/>
@@ -48,8 +48,8 @@
       <unit id="com.google.gson" version="2.2.4.v201311231704"/>
       <unit id="com.jcraft.jsch" version="0.1.53.v201508180515"/>
       <unit id="com.jcraft.jsch.source" version="0.1.53.v201508180515"/>
-      <unit id="org.junit" version="4.11.0.v201303080030"/>
-      <unit id="org.junit.source" version="4.11.0.v201303080030"/>
+      <unit id="org.junit" version="4.12.0.v201504281640"/>
+      <unit id="org.junit.source" version="4.12.0.v201504281640"/>
       <unit id="javax.servlet" version="3.1.0.v201410161800"/>
       <unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
       <unit id="org.tukaani.xz" version="1.3.0.v201308270617"/>
@@ -58,11 +58,11 @@
       <unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
       <unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
       <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
-      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20151204220443/repository/"/>
+      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20160518051658/repository/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
-      <repository location="http://download.eclipse.org/releases/mars/"/>
+      <repository location="http://download.eclipse.org/releases/neon/"/>
     </location>
   </locations>
 </target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
index 3963361..c784c1f 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
@@ -1,8 +1,8 @@
-target "jgit-4.5" with source configurePhase
+target "jgit-4.6" with source configurePhase
 
 include "projects/jetty-9.2.13.tpd"
-include "orbit/S20151204220443-Neon.tpd"
+include "orbit/R20160520211859-Neon.tpd"
 
-location "http://download.eclipse.org/releases/mars/" {
+location "http://download.eclipse.org/releases/neon/" {
 	org.eclipse.osgi lazy
 }
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20151204220443-Neon.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20160520211859-Neon.tpd
similarity index 82%
rename from org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20151204220443-Neon.tpd
rename to org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20160520211859-Neon.tpd
index 3afdbaa..5aca0b7 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20151204220443-Neon.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20160520211859-Neon.tpd
@@ -1,9 +1,9 @@
-target "S20151204220443-Neon" with source configurePhase
+target "R20160520211859-Neon" with source configurePhase
 // see http://download.eclipse.org/tools/orbit/downloads/
 
-location "http://download.eclipse.org/tools/orbit/downloads/drops/S20151204220443/repository/" {
-	org.apache.ant [1.9.4.v201504302020,1.9.4.v201504302020]
-	org.apache.ant.source [1.9.4.v201504302020,1.9.4.v201504302020]
+location "http://download.eclipse.org/tools/orbit/downloads/drops/R20160520211859/repository/" {
+	org.apache.ant [1.9.6.v201510161327,1.9.6.v201510161327]
+	org.apache.ant.source [1.9.6.v201510161327,1.9.6.v201510161327]
 	org.apache.commons.compress [1.6.0.v201310281400,1.6.0.v201310281400]
 	org.apache.commons.compress.source [1.6.0.v201310281400,1.6.0.v201310281400]
 	org.apache.commons.logging [1.1.1.v201101211721,1.1.1.v201101211721]
@@ -18,8 +18,8 @@
 	org.kohsuke.args4j.source [2.0.21.v201301150030,2.0.21.v201301150030]
 	org.hamcrest.core [1.3.0.v201303031735,1.3.0.v201303031735]
 	org.hamcrest.core.source [1.3.0.v201303031735,1.3.0.v201303031735]
-	javaewah [0.7.9.v201401101600,0.7.9.v201401101600]
-	javaewah.source [0.7.9.v201401101600,0.7.9.v201401101600]
+	javaewah [0.7.9.v201605172130,0.7.9.v201605172130]
+	javaewah.source [0.7.9.v201605172130,0.7.9.v201605172130]
 	org.objenesis [1.0.0.v201505121915,1.0.0.v201505121915]
 	org.objenesis.source [1.0.0.v201505121915,1.0.0.v201505121915]
 	org.mockito [1.8.4.v201303031500,1.8.4.v201303031500]
@@ -27,8 +27,8 @@
 	com.google.gson [2.2.4.v201311231704,2.2.4.v201311231704]
 	com.jcraft.jsch [0.1.53.v201508180515,0.1.53.v201508180515]
 	com.jcraft.jsch.source [0.1.53.v201508180515,0.1.53.v201508180515]
-	org.junit [4.11.0.v201303080030,4.11.0.v201303080030]
-	org.junit.source [4.11.0.v201303080030,4.11.0.v201303080030]
+	org.junit [4.12.0.v201504281640,4.12.0.v201504281640]
+	org.junit.source [4.12.0.v201504281640,4.12.0.v201504281640]
 	javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]
 	javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800]
 	org.tukaani.xz [1.3.0.v201308270617,1.3.0.v201308270617]
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
index 4696b82..cd6b4a3 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
@@ -49,7 +49,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.target</artifactId>
diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml
index 39b4be9..71b859d 100644
--- a/org.eclipse.jgit.packaging/pom.xml
+++ b/org.eclipse.jgit.packaging/pom.xml
@@ -53,15 +53,15 @@
 
   <groupId>org.eclipse.jgit</groupId>
   <artifactId>jgit.tycho.parent</artifactId>
-  <version>4.3.2-SNAPSHOT</version>
+  <version>4.4.2-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <name>JGit Tycho Parent</name>
 
   <properties>
-    <tycho-version>0.23.0</tycho-version>
+    <tycho-version>0.25.0</tycho-version>
     <tycho-extras-version>${tycho-version}</tycho-extras-version>
-    <target-platform>jgit-4.5</target-platform>
+    <target-platform>jgit-4.6</target-platform>
   </properties>
 
   <pluginRepositories>
@@ -149,7 +149,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-resources-plugin</artifactId>
-          <version>2.5</version>
+          <version>2.7</version>
           <configuration>
             <encoding>ISO-8859-1</encoding>
           </configuration>
@@ -216,12 +216,12 @@
         <plugin>
           <groupId>org.eclipse.cbi.maven.plugins</groupId>
           <artifactId>eclipse-jarsigner-plugin</artifactId>
-          <version>1.1.2</version>
+          <version>1.1.3</version>
         </plugin>
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>build-helper-maven-plugin</artifactId>
-          <version>1.9</version>
+          <version>1.10</version>
         </plugin>
       </plugins>
     </pluginManagement>
diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
index 097319d..66d010c 100644
--- a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
@@ -2,29 +2,30 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.pgm.test
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Vendor: %provider_name
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
-Import-Package: org.eclipse.jgit.api;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.api.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.diff;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.dircache;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.file;version="4.3.2",
- org.eclipse.jgit.junit;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.merge;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.pgm;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.pgm.internal;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.pgm.opt;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.treewalk;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util.io;version="[4.3.2,4.4.0)",
+Import-Package: org.eclipse.jgit.api;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.api.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.diff;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.dircache;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.file;version="4.4.2",
+ org.eclipse.jgit.junit;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.merge;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.pgm;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.pgm.internal;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.pgm.opt;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.treewalk;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util.io;version="[4.4.2,4.5.0)",
  org.hamcrest.core;bundle-version="[1.1.0,2.0.0)",
- org.junit;version="[4.4.0,5.0.0)",
+ org.junit;version="[4.11.0,5.0.0)",
+ org.junit.rules;version="[4.11.0,5.0.0)",
  org.kohsuke.args4j;version="[2.0.12,2.1.0)"
 Require-Bundle: org.tukaani.xz;bundle-version="[1.3.0,2.0.0)"
diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml
index 4225323..eeccff4 100644
--- a/org.eclipse.jgit.pgm.test/pom.xml
+++ b/org.eclipse.jgit.pgm.test/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm.test</artifactId>
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/InitTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/InitTest.java
new file mode 100644
index 0000000..c7dbc24
--- /dev/null
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/InitTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016, Rüdiger Herrmann <ruediger.herrmann@gmx.de>
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.pgm;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import java.io.File;
+
+import org.eclipse.jgit.lib.CLIRepositoryTestCase;
+import org.eclipse.jgit.lib.Constants;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class InitTest extends CLIRepositoryTestCase {
+
+	@Rule
+	public final TemporaryFolder tempFolder = new TemporaryFolder();
+
+	@Test
+	public void testInitBare() throws Exception {
+		File directory = tempFolder.getRoot();
+
+		String[] result = execute(
+				"git init '" + directory.getCanonicalPath() + "' --bare");
+
+		String[] expecteds = new String[] {
+				"Initialized empty Git repository in "
+						+ directory.getCanonicalPath(),
+				"" };
+		assertArrayEquals(expecteds, result);
+	}
+
+	@Test
+	public void testInitDirectory() throws Exception {
+		File workDirectory = tempFolder.getRoot();
+		File gitDirectory = new File(workDirectory, Constants.DOT_GIT);
+
+		String[] result = execute(
+				"git init '" + workDirectory.getCanonicalPath() + "'");
+
+		String[] expecteds = new String[] {
+				"Initialized empty Git repository in "
+						+ gitDirectory.getCanonicalPath(),
+				"" };
+		assertArrayEquals(expecteds, result);
+	}
+
+}
diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
index ab0c11b..cf2a03e 100644
--- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.pgm
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Vendor: %provider_name
 Bundle-ActivationPolicy: lazy
 Bundle-Localization: plugin
@@ -26,45 +26,45 @@
  org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)",
  org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)",
  org.eclipse.jetty.util.thread;version="[9.0.0,10.0.0)",
- org.eclipse.jgit.api;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.api.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.archive;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.awtui;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.blame;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.diff;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.dircache;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.gitrepo;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.ketch;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.pack;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.reftree;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lfs.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lfs.server;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lfs.server.fs;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lfs.server.s3;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.merge;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.nls;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.notes;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revplot;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revwalk.filter;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.storage.pack;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport.http.apache;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport.resolver;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.treewalk;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.treewalk.filter;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util.io;version="[4.3.2,4.4.0)",
+ org.eclipse.jgit.api;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.api.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.archive;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.awtui;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.blame;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.diff;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.dircache;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.gitrepo;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.ketch;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.reftree;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lfs.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lfs.server;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lfs.server.s3;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.merge;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.nls;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.notes;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revplot;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revwalk.filter;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.storage.pack;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport.http.apache;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport.resolver;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.treewalk;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.treewalk.filter;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util.io;version="[4.4.2,4.5.0)",
  org.kohsuke.args4j;version="[2.0.12,2.1.0)",
  org.kohsuke.args4j.spi;version="[2.0.15,2.1.0)"
-Export-Package: org.eclipse.jgit.console;version="4.3.2";
+Export-Package: org.eclipse.jgit.console;version="4.4.2";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.util",
- org.eclipse.jgit.pgm;version="4.3.2";
+ org.eclipse.jgit.pgm;version="4.4.2";
   uses:="org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.pgm.opt,
@@ -75,11 +75,11 @@
    org.eclipse.jgit.treewalk,
    javax.swing,
    org.eclipse.jgit.transport",
- org.eclipse.jgit.pgm.debug;version="4.3.2";
+ org.eclipse.jgit.pgm.debug;version="4.4.2";
   uses:="org.eclipse.jgit.util.io,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.pgm.internal;version="4.3.2";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test",
- org.eclipse.jgit.pgm.opt;version="4.3.2";
+ org.eclipse.jgit.pgm.internal;version="4.4.2";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test",
+ org.eclipse.jgit.pgm.opt;version="4.4.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.kohsuke.args4j.spi,
diff --git a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
index 3bbff12..aeb8b37 100644
--- a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.pgm - Sources
 Bundle-SymbolicName: org.eclipse.jgit.pgm.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 4.3.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="4.3.2.qualifier";roots="."
+Bundle-Version: 4.4.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="4.4.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml
index 8edb94a..f469cc2 100644
--- a/org.eclipse.jgit.pgm/pom.xml
+++ b/org.eclipse.jgit.pgm/pom.xml
@@ -50,7 +50,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm</artifactId>
diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
index fc412ba..abe04b8 100644
--- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
+++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
@@ -211,7 +211,6 @@
 updating=Updating {0}..{1}
 usage_Aggressive=This option will cause gc to more aggressively optimize the repository at the expense of taking much more time
 usage_bareClone=Make a bare Git repository. That is, instead of creating [DIRECTORY] and placing the administrative files in [DIRECTORY]/.git, make the [DIRECTORY] itself the $GIT_DIR.
-usage_branches=Set branch field in .gitmodules
 usage_Blame=Show what revision and author last modified each line
 usage_CommandLineClientForamazonsS3Service=Command line client for Amazon's S3 service
 usage_CommitAll=commit all modified and deleted files
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
index bf6ee3a..5f3740c 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
@@ -169,7 +169,7 @@
 			if (rename) {
 				String src, dst;
 				if (otherBranch == null) {
-					final Ref head = db.getRef(Constants.HEAD);
+					final Ref head = db.exactRef(Constants.HEAD);
 					if (head != null && head.isSymbolic()) {
 						src = head.getLeaf().getName();
 					} else {
@@ -178,7 +178,7 @@
 					dst = branch;
 				} else {
 					src = branch;
-					final Ref old = db.getRef(src);
+					final Ref old = db.findRef(src);
 					if (old == null)
 						throw die(MessageFormat.format(CLIText.get().doesNotExist, src));
 					if (!old.getName().startsWith(Constants.R_HEADS))
@@ -204,7 +204,7 @@
 				} else {
 					startBranch = Constants.HEAD;
 				}
-				Ref startRef = db.getRef(startBranch);
+				Ref startRef = db.findRef(startBranch);
 				ObjectId startAt = db.resolve(startBranch + "^0"); //$NON-NLS-1$
 				if (startRef != null) {
 					startBranch = startRef.getName();
@@ -243,7 +243,7 @@
 	}
 
 	private void list() throws Exception {
-		Ref head = db.getRef(Constants.HEAD);
+		Ref head = db.exactRef(Constants.HEAD);
 		// This can happen if HEAD is stillborn
 		if (head != null) {
 			String current = head.getLeaf().getName();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java
index 38d8d70..2cfbd86 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java
@@ -95,7 +95,7 @@
 					commitCmd.setOnly(p);
 			commitCmd.setAmend(amend);
 			commitCmd.setAll(all);
-			Ref head = db.getRef(Constants.HEAD);
+			Ref head = db.exactRef(Constants.HEAD);
 			if (head == null) {
 				throw die(CLIText.get().onBranchToBeBorn);
 			}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java
index b3e73b5..a7bee7f 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java
@@ -4,6 +4,7 @@
  * Copyright (C) 2010, Robin Rosenberg <robin.rosenberg@dewire.com>
  * Copyright (C) 2010, Sasa Zivkov <sasa.zivkov@sap.com>
  * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
+ * Copyright (C) 2016, Rüdiger Herrmann <ruediger.herrmann@gmx.de>
  * and other copyright owners as documented in the project's IP log.
  *
  * This program and the accompanying materials are made available
@@ -54,6 +55,7 @@
 import org.eclipse.jgit.api.InitCommand;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.pgm.internal.CLIText;
+import org.kohsuke.args4j.Argument;
 import org.kohsuke.args4j.Option;
 
 @Command(common = true, usage = "usage_CreateAnEmptyGitRepository")
@@ -61,6 +63,9 @@
 	@Option(name = "--bare", usage = "usage_CreateABareRepository")
 	private boolean bare;
 
+	@Argument(index = 0, metaVar = "metaVar_directory")
+	private String directory;
+
 	@Override
 	protected final boolean requiresRepository() {
 		return false;
@@ -70,8 +75,12 @@
 	protected void run() throws Exception {
 		InitCommand command = Git.init();
 		command.setBare(bare);
-		if (gitdir != null)
+		if (gitdir != null) {
 			command.setDirectory(new File(gitdir));
+		}
+		if (directory != null) {
+			command.setDirectory(new File(directory));
+		}
 		Repository repository = command.call().getRepository();
 		outw.println(MessageFormat.format(
 				CLIText.get().initializedEmptyGitRepositoryIn, repository
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java
index 6947cdd..62e7728 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java
@@ -228,7 +228,7 @@
 	}
 
 	private void addNoteMap(String notesRef) throws IOException {
-		Ref notes = db.getRef(notesRef);
+		Ref notes = db.exactRef(notesRef);
 		if (notes == null)
 			return;
 		RevCommit notesCommit = argWalk.parseCommit(notes.getObjectId());
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
index e739b58..485efc5 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
@@ -114,7 +114,7 @@
 		}
 
 		// determine the other revision we want to merge with HEAD
-		final Ref srcRef = db.getRef(ref);
+		final Ref srcRef = db.findRef(ref);
 		final ObjectId src = db.resolve(ref + "^{commit}"); //$NON-NLS-1$
 		if (src == null)
 			throw die(MessageFormat.format(
@@ -209,7 +209,7 @@
 	}
 
 	private Ref getOldHead() throws IOException {
-		Ref oldHead = db.getRef(Constants.HEAD);
+		Ref oldHead = db.exactRef(Constants.HEAD);
 		if (oldHead == null) {
 			throw die(CLIText.get().onBranchToBeBorn);
 		}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java
index ea59527..bec5003 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java
@@ -58,16 +58,12 @@
 	@Argument(required = true, metaVar = "metaVar_path", usage = "usage_pathToXml")
 	private String path;
 
-	@Option(name = "--record-remote-branch", usage = "usage_branches")
-	private boolean branches;
-
 	@Override
 	protected void run() throws Exception {
 		new RepoCommand(db)
 			.setURI(uri)
 			.setPath(path)
 			.setGroups(groups)
-			.setRecordRemoteBranch(branches)
 			.call();
 	}
 }
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java
index c5986b0..6892c99 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java
@@ -63,6 +63,7 @@
 import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.pgm.internal.CLIText;
 import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler;
 import org.eclipse.jgit.revwalk.RevCommit;
@@ -81,8 +82,7 @@
 
 	private final DateFormat fmt;
 
-	private final DiffFormatter diffFmt = new DiffFormatter( //
-			new BufferedOutputStream(System.out));
+	private DiffFormatter diffFmt;
 
 	@Argument(index = 0, metaVar = "metaVar_object")
 	private String objectName;
@@ -165,6 +165,12 @@
 		fmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy ZZZZZ", Locale.US); //$NON-NLS-1$
 	}
 
+	@Override
+	protected void init(final Repository repository, final String gitDir) {
+		super.init(repository, gitDir);
+		diffFmt = new DiffFormatter(new BufferedOutputStream(outs));
+	}
+
 	@SuppressWarnings("boxing")
 	@Override
 	protected void run() throws Exception {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
index 6a63221..de3df80 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
@@ -204,7 +204,7 @@
 	private void printLongStatus(org.eclipse.jgit.api.Status status)
 			throws IOException {
 		// Print current branch name
-		final Ref head = db.getRef(Constants.HEAD);
+		final Ref head = db.exactRef(Constants.HEAD);
 		if (head != null && head.isSymbolic()) {
 			String branch = Repository.shortenRefName(head.getLeaf().getName());
 			outw.println(CLIText.formatLine(MessageFormat.format(
diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
index 4c47ce5..12620de 100644
--- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -2,55 +2,56 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.test
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %provider_name
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Import-Package: com.googlecode.javaewah;version="[0.7.9,0.8.0)",
- org.eclipse.jgit.api;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.api.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.attributes;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.awtui;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.blame;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.diff;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.dircache;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.events;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.fnmatch;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.gitrepo;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.hooks;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.ignore;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.ignore.internal;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.pack;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.internal.storage.reftree;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.junit;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.merge;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.nls;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.notes;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.patch;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.pgm;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.pgm.internal;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revplot;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revwalk.filter;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.storage.file;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.storage.pack;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.submodule;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport.http;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport.resolver;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.treewalk;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.treewalk.filter;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util.io;version="[4.3.2,4.4.0)",
+ org.eclipse.jgit.api;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.api.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.attributes;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.awtui;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.blame;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.diff;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.dircache;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.events;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.fnmatch;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.gitrepo;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.hooks;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.ignore;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.ignore.internal;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.internal.storage.reftree;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.junit;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.merge;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.nls;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.notes;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.patch;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.pgm;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.pgm.internal;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revplot;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revwalk.filter;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.storage.file;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.storage.pack;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.submodule;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport.http;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport.resolver;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.treewalk;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.treewalk.filter;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util.io;version="[4.4.2,4.5.0)",
  org.hamcrest;version="[1.1.0,2.0.0)",
  org.junit;version="[4.4.0,5.0.0)",
  org.junit.experimental.theories;version="[4.4.0,5.0.0)",
+ org.junit.rules;version="[4.11.0,5.0.0)",
  org.junit.runner;version="[4.4.0,5.0.0)",
  org.junit.runners;version="[4.11.0,5.0.0)",
  org.slf4j;version="[1.7.2,2.0.0)"
diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml
index a52ac4c..81a3b09 100644
--- a/org.eclipse.jgit.test/pom.xml
+++ b/org.eclipse.jgit.test/pom.xml
@@ -52,7 +52,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.test</artifactId>
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M1.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M1.patch
new file mode 100644
index 0000000..395bd4c
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M1.patch
@@ -0,0 +1,9 @@
+diff --git a/M1 b/M1
+new file mode 100755
+index 0000000..de98044
+--- /dev/null
++++ b/M1
+@@ -0,0 +1,3 @@
++a
++b
++c
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M1_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M1_PostImage
new file mode 100644
index 0000000..de98044
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M1_PostImage
@@ -0,0 +1,3 @@
+a
+b
+c
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2.patch
new file mode 100644
index 0000000..b56ca08
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2.patch
@@ -0,0 +1,10 @@
+diff --git a/M2 b/M2
+old mode 100644
+new mode 100755
+index 0000000..de98044
+--- a/M2
++++ b/M2
+@@ -1,3 +1,1 @@
+ a
+-b
+-c
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2_PostImage
new file mode 100644
index 0000000..7898192
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2_PostImage
@@ -0,0 +1 @@
+a
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2_PreImage
new file mode 100644
index 0000000..de98044
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2_PreImage
@@ -0,0 +1,3 @@
+a
+b
+c
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3.patch
new file mode 100644
index 0000000..ee53605
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3.patch
@@ -0,0 +1,10 @@
+diff --git a/M3 b/M3
+old mode 100755
+new mode 100644
+index 0000000..de98044
+--- a/M3
++++ b/M3
+@@ -1,1 +1,3 @@
+ a
++b
++c
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3_PostImage
new file mode 100644
index 0000000..de98044
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3_PostImage
@@ -0,0 +1,3 @@
+a
+b
+c
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3_PreImage
new file mode 100755
index 0000000..7898192
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3_PreImage
@@ -0,0 +1 @@
+a
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
index f2b5b3b..172807c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
@@ -44,6 +44,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.io.ByteArrayOutputStream;
@@ -157,6 +158,33 @@
 	}
 
 	@Test
+	public void testAddM1() throws Exception {
+		ApplyResult result = init("M1", false, true);
+		assertEquals(1, result.getUpdatedFiles().size());
+		assertTrue(result.getUpdatedFiles().get(0).canExecute());
+		checkFile(new File(db.getWorkTree(), "M1"),
+				b.getString(0, b.size(), false));
+	}
+
+	@Test
+	public void testModifyM2() throws Exception {
+		ApplyResult result = init("M2", true, true);
+		assertEquals(1, result.getUpdatedFiles().size());
+		assertTrue(result.getUpdatedFiles().get(0).canExecute());
+		checkFile(new File(db.getWorkTree(), "M2"),
+				b.getString(0, b.size(), false));
+	}
+
+	@Test
+	public void testModifyM3() throws Exception {
+		ApplyResult result = init("M3", true, true);
+		assertEquals(1, result.getUpdatedFiles().size());
+		assertFalse(result.getUpdatedFiles().get(0).canExecute());
+		checkFile(new File(db.getWorkTree(), "M3"),
+				b.getString(0, b.size(), false));
+	}
+
+	@Test
 	public void testModifyX() throws Exception {
 		ApplyResult result = init("X");
 		assertEquals(1, result.getUpdatedFiles().size());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
index 9d87f0c..8a07118 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
@@ -68,6 +68,7 @@
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.lib.RefUpdate;
 import org.eclipse.jgit.lib.RefUpdate.Result;
+import org.eclipse.jgit.lib.ReflogEntry;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.revwalk.RevCommit;
@@ -436,6 +437,36 @@
 		}
 	}
 
+	@Test
+	public void testReflogs() throws Exception {
+		try (Git git = new Git(db)) {
+			writeTrashFile("f", "1");
+			git.add().addFilepattern("f").call();
+			git.commit().setMessage("c1").call();
+			writeTrashFile("f", "2");
+			git.commit().setMessage("c2").setAll(true).setReflogComment(null)
+					.call();
+			writeTrashFile("f", "3");
+			git.commit().setMessage("c3").setAll(true)
+					.setReflogComment("testRl").call();
+
+			db.getReflogReader(Constants.HEAD).getReverseEntries();
+
+			assertEquals("testRl;commit (initial): c1;", reflogComments(
+					db.getReflogReader(Constants.HEAD).getReverseEntries()));
+			assertEquals("testRl;commit (initial): c1;", reflogComments(
+					db.getReflogReader(db.getBranch()).getReverseEntries()));
+		}
+	}
+
+	private static String reflogComments(List<ReflogEntry> entries) {
+		StringBuffer b = new StringBuffer();
+		for (ReflogEntry e : entries) {
+			b.append(e.getComment()).append(";");
+		}
+		return b.toString();
+	}
+
 	@Test(expected = WrongRepositoryStateException.class)
 	public void commitAmendOnInitialShouldFail() throws Exception {
 		try (Git git = new Git(db)) {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java
index 34432c5..1310625 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java
@@ -53,7 +53,9 @@
 import org.eclipse.jgit.junit.RepositoryTestCase;
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.merge.MergeStrategy;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.filter.RevFilter;
 import org.junit.Test;
 
 public class LogCommandTest extends RepositoryTestCase {
@@ -210,4 +212,81 @@
 		assertEquals("commit#2", commit.getShortMessage());
 		assertFalse(log.hasNext());
 	}
+
+	@Test
+	public void logOnlyMergeCommits() throws Exception {
+		setCommitsAndMerge();
+		Git git = Git.wrap(db);
+
+		Iterable<RevCommit> commits = git.log().all().call();
+		Iterator<RevCommit> i = commits.iterator();
+		RevCommit commit = i.next();
+		assertEquals("merge s0 with m1", commit.getFullMessage());
+		commit = i.next();
+		assertEquals("s0", commit.getFullMessage());
+		commit = i.next();
+		assertEquals("m1", commit.getFullMessage());
+		commit = i.next();
+		assertEquals("m0", commit.getFullMessage());
+		assertFalse(i.hasNext());
+
+		commits = git.log().setRevFilter(RevFilter.ONLY_MERGES).call();
+		i = commits.iterator();
+		commit = i.next();
+		assertEquals("merge s0 with m1", commit.getFullMessage());
+		assertFalse(i.hasNext());
+	}
+
+	@Test
+	public void logNoMergeCommits() throws Exception {
+		setCommitsAndMerge();
+		Git git = Git.wrap(db);
+
+		Iterable<RevCommit> commits = git.log().all().call();
+		Iterator<RevCommit> i = commits.iterator();
+		RevCommit commit = i.next();
+		assertEquals("merge s0 with m1", commit.getFullMessage());
+		commit = i.next();
+		assertEquals("s0", commit.getFullMessage());
+		commit = i.next();
+		assertEquals("m1", commit.getFullMessage());
+		commit = i.next();
+		assertEquals("m0", commit.getFullMessage());
+		assertFalse(i.hasNext());
+
+		commits = git.log().setRevFilter(RevFilter.NO_MERGES).call();
+		i = commits.iterator();
+		commit = i.next();
+		assertEquals("m1", commit.getFullMessage());
+		commit = i.next();
+		assertEquals("s0", commit.getFullMessage());
+		commit = i.next();
+		assertEquals("m0", commit.getFullMessage());
+		assertFalse(i.hasNext());
+	}
+
+	private void setCommitsAndMerge() throws Exception {
+		Git git = Git.wrap(db);
+		writeTrashFile("file1", "1\n2\n3\n4\n");
+		git.add().addFilepattern("file1").call();
+		RevCommit masterCommit0 = git.commit().setMessage("m0").call();
+
+		createBranch(masterCommit0, "refs/heads/side");
+		checkoutBranch("refs/heads/side");
+
+		writeTrashFile("file2", "1\n2\n3\n4\n5\n6\n7\n8\n");
+		git.add().addFilepattern("file2").call();
+		RevCommit c = git.commit().setMessage("s0").call();
+
+		checkoutBranch("refs/heads/master");
+
+		writeTrashFile("file3", "1\n2\n");
+		git.add().addFilepattern("file3").call();
+		git.commit().setMessage("m1").call();
+
+		git.merge().include(c.getId())
+				.setStrategy(MergeStrategy.RESOLVE)
+				.setMessage("merge s0 with m1").call();
+	}
+
 }
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java
index ff7066e..a526fda 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java
@@ -58,6 +58,7 @@
 import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
 import org.eclipse.jgit.api.MergeResult.MergeStatus;
 import org.eclipse.jgit.api.errors.NoHeadException;
+import org.eclipse.jgit.junit.JGitTestUtil;
 import org.eclipse.jgit.junit.RepositoryTestCase;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
@@ -185,6 +186,40 @@
 	}
 
 	@Test
+	public void testPullWithUntrackedStash() throws Exception {
+		target.pull().call();
+
+		// change the source file
+		writeToFile(sourceFile, "Source change");
+		source.add().addFilepattern("SomeFile.txt").call();
+		source.commit().setMessage("Source change in remote").call();
+
+		// write untracked file
+		writeToFile(new File(dbTarget.getWorkTree(), "untracked.txt"),
+				"untracked");
+		RevCommit stash = target.stashCreate().setIndexMessage("message here")
+				.setIncludeUntracked(true).call();
+		assertNotNull(stash);
+		assertTrue(target.status().call().isClean());
+
+		// pull from source
+		assertTrue(target.pull().call().isSuccessful());
+		assertEquals("[SomeFile.txt, mode:100644, content:Source change]",
+				indexState(dbTarget, CONTENT));
+		assertFalse(JGitTestUtil.check(dbTarget, "untracked.txt"));
+		assertEquals("Source change",
+				JGitTestUtil.read(dbTarget, "SomeFile.txt"));
+
+		// apply the stash
+		target.stashApply().setStashRef(stash.getName()).call();
+		assertEquals("[SomeFile.txt, mode:100644, content:Source change]",
+				indexState(dbTarget, CONTENT));
+		assertEquals("untracked", JGitTestUtil.read(dbTarget, "untracked.txt"));
+		assertEquals("Source change",
+				JGitTestUtil.read(dbTarget, "SomeFile.txt"));
+	}
+
+	@Test
 	public void testPullLocalConflict() throws Exception {
 		target.branchCreate().setName("basedOnMaster").setStartPoint(
 				"refs/heads/master").setUpstreamMode(SetupUpstreamMode.TRACK)
@@ -576,4 +611,4 @@
 				fis.close();
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
index 40d8458..a4a699e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
@@ -157,6 +157,34 @@
 	}
 
 	@Test
+	public void testHardResetWithConflicts_DoOverWriteUntrackedFile()
+			throws JGitInternalException,
+			AmbiguousObjectException, IOException, GitAPIException {
+		setupRepository();
+		git.rm().setCached(true).addFilepattern("a.txt").call();
+		assertTrue(new File(db.getWorkTree(), "a.txt").exists());
+		git.reset().setMode(ResetType.HARD).setRef(Constants.HEAD)
+				.call();
+		assertTrue(new File(db.getWorkTree(), "a.txt").exists());
+		assertEquals("content", read(new File(db.getWorkTree(), "a.txt")));
+	}
+
+	@Test
+	public void testHardResetWithConflicts_DoDeleteFileFolderConflicts()
+			throws JGitInternalException,
+			AmbiguousObjectException, IOException, GitAPIException {
+		setupRepository();
+		writeTrashFile("d/c.txt", "x");
+		git.add().addFilepattern("d/c.txt").call();
+		FileUtils.delete(new File(db.getWorkTree(), "d"), FileUtils.RECURSIVE);
+		writeTrashFile("d", "y");
+
+		git.reset().setMode(ResetType.HARD).setRef(Constants.HEAD)
+				.call();
+		assertFalse(new File(db.getWorkTree(), "d").exists());
+	}
+
+	@Test
 	public void testResetToNonexistingHEAD() throws JGitInternalException,
 			AmbiguousObjectException, IOException, GitAPIException {
 
@@ -568,7 +596,7 @@
 	 * @throws IOException
 	 */
 	private void assertSameAsHead(Ref ref) throws IOException {
-		Ref headRef = db.getRef(Constants.HEAD);
+		Ref headRef = db.exactRef(Constants.HEAD);
 		assertEquals(headRef.getName(), ref.getName());
 		assertEquals(headRef.getObjectId(), ref.getObjectId());
 	}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
index 2cec34b..ccd15d0 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
@@ -44,6 +44,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.BufferedReader;
@@ -743,14 +744,107 @@
 				FileBasedConfig c = new FileBasedConfig(gitmodules,
 						FS.DETECTED);
 				c.load();
-				assertEquals("standard branches work", "master",
+				assertEquals("Recording remote branches should work for short branch descriptions", "master",
 						c.getString("submodule", "with-branch", "branch"));
-				assertEquals("long branches work", "refs/heads/master",
+				assertEquals("Recording remote branches should work for full ref specs", "refs/heads/master",
 						c.getString("submodule", "with-long-branch", "branch"));
 			}
 		}
 	}
 
+
+	@Test
+	public void testRecordSubmoduleLabels() throws Exception {
+		try (
+				Repository remoteDb = createBareRepository();
+				Repository tempDb = createWorkRepository()) {
+			StringBuilder xmlContent = new StringBuilder();
+			xmlContent
+				.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
+				.append("<manifest>")
+				.append("<remote name=\"remote1\" fetch=\".\" />")
+				.append("<default revision=\"master\" remote=\"remote1\" />")
+				.append("<project path=\"test\" ")
+					.append("revision=\"master\" ")
+					.append("name=\"").append(notDefaultUri).append("\" ")
+					.append("groups=\"a1,a2\" />")
+				.append("</manifest>");
+			JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
+				xmlContent.toString());
+
+			RepoCommand command = new RepoCommand(remoteDb);
+			command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
+				.setURI(rootUri)
+				.setRecordSubmoduleLabels(true)
+				.call();
+			// Clone it
+			File directory = createTempDirectory("testBareRepo");
+			try (Repository localDb = Git.cloneRepository()
+					.setDirectory(directory)
+					.setURI(remoteDb.getDirectory().toURI().toString()).call()
+					.getRepository();) {
+				// The .gitattributes file should exist
+				File gitattributes = new File(localDb.getWorkTree(),
+					".gitattributes");
+				assertTrue("The .gitattributes file should exist",
+						gitattributes.exists());
+				try (BufferedReader reader = new BufferedReader(
+						new FileReader(gitattributes));) {
+					String content = reader.readLine();
+					assertEquals(".gitattributes content should be as expected",
+						"/test a1 a2", content);
+				}
+			}
+		}
+	}
+
+	@Test
+	public void testRecordShallowRecommendation() throws Exception {
+		try (
+				Repository remoteDb = createBareRepository();
+				Repository tempDb = createWorkRepository()) {
+			StringBuilder xmlContent = new StringBuilder();
+			xmlContent
+				.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
+				.append("<manifest>")
+				.append("<remote name=\"remote1\" fetch=\".\" />")
+				.append("<default revision=\"master\" remote=\"remote1\" />")
+				.append("<project path=\"shallow-please\" ")
+					.append("name=\"").append(defaultUri).append("\" ")
+					.append("clone-depth=\"1\" />")
+				.append("<project path=\"non-shallow\" ")
+					.append("name=\"").append(defaultUri).append("\" />")
+				.append("</manifest>");
+			JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
+				xmlContent.toString());
+
+			RepoCommand command = new RepoCommand(remoteDb);
+			command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
+				.setURI(rootUri)
+				.setRecommendShallow(true)
+				.call();
+			// Clone it
+			File directory = createTempDirectory("testBareRepo");
+			try (Repository localDb = Git.cloneRepository()
+					.setDirectory(directory)
+					.setURI(remoteDb.getDirectory().toURI().toString()).call()
+					.getRepository();) {
+				// The .gitmodules file should exist
+				File gitmodules = new File(localDb.getWorkTree(),
+						".gitmodules");
+				assertTrue("The .gitmodules file should exist",
+						gitmodules.exists());
+				FileBasedConfig c = new FileBasedConfig(gitmodules,
+						FS.DETECTED);
+				c.load();
+				assertEquals("Recording shallow configuration should work", "true",
+						c.getString("submodule", "shallow-please", "shallow"));
+				assertNull("Recording non shallow configuration should work",
+						c.getString("submodule", "non-shallow", "shallow"));
+			}
+		}
+	}
+
 	@Test
 	public void testRemoteRevision() throws Exception {
 		StringBuilder xmlContent = new StringBuilder();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
index 11a0924..74790f7 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
@@ -45,6 +45,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
@@ -97,6 +98,7 @@
 		assertEquals(0, db.getObjectDatabase().listPacks().size());
 
 		ObjectReader reader = ins.newReader();
+		assertSame(ins, reader.getCreatedFromInserter());
 		assertEquals("foo", readString(reader.open(id1)));
 		assertEquals("bar", readString(reader.open(id2)));
 		assertEquals(0, db.getObjectDatabase().listPacks().size());
@@ -118,6 +120,7 @@
 		assertEquals(0, db.getObjectDatabase().listPacks().size());
 
 		ObjectReader reader = ins.newReader();
+		assertSame(ins, reader.getCreatedFromInserter());
 		assertTrue(Arrays.equals(data, readStream(reader.open(id1))));
 		assertEquals(0, db.getObjectDatabase().listPacks().size());
 		ins.flush();
@@ -136,6 +139,7 @@
 		assertEquals(1, db.getObjectDatabase().listPacks().size());
 
 		ObjectReader reader = ins.newReader();
+		assertSame(ins, reader.getCreatedFromInserter());
 		assertEquals("foo", readString(reader.open(id1)));
 		assertEquals("bar", readString(reader.open(id2)));
 		assertEquals(1, db.getObjectDatabase().listPacks().size());
@@ -154,6 +158,7 @@
 		assertFalse(abbr1.equals(abbr2));
 
 		ObjectReader reader = ins.newReader();
+		assertSame(ins, reader.getCreatedFromInserter());
 		Collection<ObjectId> objs;
 		objs = reader.resolve(AbbreviatedObjectId.fromString(abbr1));
 		assertEquals(1, objs.size());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java
index 48ea13b..ea8dfa2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java
@@ -45,11 +45,14 @@
 
 import static java.lang.Integer.valueOf;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.concurrent.BrokenBarrierException;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CyclicBarrier;
@@ -81,6 +84,17 @@
 	}
 
 	@Test
+	public void emptyRefDirectoryDeleted() throws Exception {
+		String ref = "dir/ref";
+		tr.branch(ref).commit().create();
+		String name = repo.findRef(ref).getName();
+		Path dir = repo.getDirectory().toPath().resolve(name).getParent();
+
+		gc.packRefs();
+		assertFalse(Files.exists(dir));
+	}
+
+	@Test
 	public void concurrentOnlyOneWritesPackedRefs() throws Exception {
 		RevBlob a = tr.blob("a");
 		tr.lightweightTag("t", a);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
index 6238a35..aebbafe 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
@@ -48,6 +48,11 @@
 
 package org.eclipse.jgit.lib;
 
+import static java.util.concurrent.TimeUnit.DAYS;
+import static java.util.concurrent.TimeUnit.HOURS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -56,26 +61,41 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
 import java.text.MessageFormat;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 
 import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
 import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.junit.MockSystemReader;
 import org.eclipse.jgit.merge.MergeConfig;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
 import org.eclipse.jgit.util.FS;
 import org.eclipse.jgit.util.SystemReader;
 import org.junit.After;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
 
 /**
  * Test reading of git config
  */
 public class ConfigTest {
 
+	@Rule
+	public ExpectedException expectedEx = ExpectedException.none();
+
+	@Rule
+	public TemporaryFolder tmp = new TemporaryFolder();
+
 	@After
 	public void tearDown() {
 		SystemReader.setInstance(null);
@@ -739,6 +759,102 @@
 				c.getStringList("a", null, "x"));
 	}
 
+	@Test
+	public void testReadMultipleValuesForName() throws ConfigInvalidException {
+		Config c = parse("[foo]\nbar=false\nbar=true\n");
+		assertTrue(c.getBoolean("foo", "bar", false));
+	}
+
+	@Test
+	public void testIncludeInvalidName() throws ConfigInvalidException {
+		expectedEx.expect(ConfigInvalidException.class);
+		expectedEx.expectMessage(JGitText.get().invalidLineInConfigFile);
+		parse("[include]\nbar\n");
+	}
+
+	@Test
+	public void testIncludeNoValue() throws ConfigInvalidException {
+		expectedEx.expect(ConfigInvalidException.class);
+		expectedEx.expectMessage(JGitText.get().invalidLineInConfigFile);
+		parse("[include]\npath\n");
+	}
+
+	@Test
+	public void testIncludeEmptyValue() throws ConfigInvalidException {
+		expectedEx.expect(ConfigInvalidException.class);
+		expectedEx.expectMessage(JGitText.get().invalidLineInConfigFile);
+		parse("[include]\npath=\n");
+	}
+
+	@Test
+	public void testIncludeValuePathNotFound() throws ConfigInvalidException {
+		// we do not expect an exception, included path not found are ignored
+		String notFound = "/not/found";
+		Config parsed = parse("[include]\npath=" + notFound + "\n");
+		assertEquals(1, parsed.getSections().size());
+		assertEquals(notFound, parsed.getString("include", null, "path"));
+	}
+
+	@Test
+	public void testIncludeValuePathWithTilde() throws ConfigInvalidException {
+		// we do not expect an exception, included path not supported are
+		// ignored
+		String notSupported = "~/someFile";
+		Config parsed = parse("[include]\npath=" + notSupported + "\n");
+		assertEquals(1, parsed.getSections().size());
+		assertEquals(notSupported, parsed.getString("include", null, "path"));
+	}
+
+	@Test
+	public void testIncludeValuePathRelative() throws ConfigInvalidException {
+		// we do not expect an exception, included path not supported are
+		// ignored
+		String notSupported = "someRelativeFile";
+		Config parsed = parse("[include]\npath=" + notSupported + "\n");
+		assertEquals(1, parsed.getSections().size());
+		assertEquals(notSupported, parsed.getString("include", null, "path"));
+	}
+
+	@Test
+	public void testIncludeTooManyRecursions() throws IOException {
+		File config = tmp.newFile("config");
+		String include = "[include]\npath=" + config.toPath() + "\n";
+		Files.write(config.toPath(), include.getBytes());
+		FileBasedConfig fbConfig = new FileBasedConfig(null, config,
+				FS.DETECTED);
+		try {
+			fbConfig.load();
+			fail();
+		} catch (ConfigInvalidException cie) {
+			assertEquals(JGitText.get().tooManyIncludeRecursions,
+					cie.getCause().getMessage());
+		}
+	}
+
+	@Test
+	public void testInclude() throws IOException, ConfigInvalidException {
+		File config = tmp.newFile("config");
+		File more = tmp.newFile("config.more");
+		File other = tmp.newFile("config.other");
+
+		String fooBar = "[foo]\nbar=true\n";
+		String includeMore = "[include]\npath=" + more.toPath() + "\n";
+		String includeOther = "path=" + other.toPath() + "\n";
+		String fooPlus = fooBar + includeMore + includeOther;
+		Files.write(config.toPath(), fooPlus.getBytes());
+
+		String fooMore = "[foo]\nmore=bar\n";
+		Files.write(more.toPath(), fooMore.getBytes());
+
+		String otherMore = "[other]\nmore=bar\n";
+		Files.write(other.toPath(), otherMore.getBytes());
+
+		Config parsed = parse("[include]\npath=" + config.toPath() + "\n");
+		assertTrue(parsed.getBoolean("foo", "bar", false));
+		assertEquals("bar", parsed.getString("foo", null, "more"));
+		assertEquals("bar", parsed.getString("other", null, "more"));
+	}
+
 	private static void assertReadLong(long exp) throws ConfigInvalidException {
 		assertReadLong(exp, String.valueOf(exp));
 	}
@@ -760,4 +876,93 @@
 		c.fromText(content);
 		return c;
 	}
+
+	@Test
+	public void testTimeUnit() throws ConfigInvalidException {
+		assertEquals(0, parseTime("0", MILLISECONDS));
+		assertEquals(2, parseTime("2ms", MILLISECONDS));
+		assertEquals(200, parseTime("200 milliseconds", MILLISECONDS));
+
+		assertEquals(0, parseTime("0s", SECONDS));
+		assertEquals(2, parseTime("2s", SECONDS));
+		assertEquals(231, parseTime("231sec", SECONDS));
+		assertEquals(1, parseTime("1second", SECONDS));
+		assertEquals(300, parseTime("300 seconds", SECONDS));
+
+		assertEquals(2, parseTime("2m", MINUTES));
+		assertEquals(2, parseTime("2min", MINUTES));
+		assertEquals(1, parseTime("1 minute", MINUTES));
+		assertEquals(10, parseTime("10 minutes", MINUTES));
+
+		assertEquals(5, parseTime("5h", HOURS));
+		assertEquals(5, parseTime("5hr", HOURS));
+		assertEquals(1, parseTime("1hour", HOURS));
+		assertEquals(48, parseTime("48hours", HOURS));
+
+		assertEquals(5, parseTime("5 h", HOURS));
+		assertEquals(5, parseTime("5 hr", HOURS));
+		assertEquals(1, parseTime("1 hour", HOURS));
+		assertEquals(48, parseTime("48 hours", HOURS));
+		assertEquals(48, parseTime("48 \t \r hours", HOURS));
+
+		assertEquals(4, parseTime("4d", DAYS));
+		assertEquals(1, parseTime("1day", DAYS));
+		assertEquals(14, parseTime("14days", DAYS));
+
+		assertEquals(7, parseTime("1w", DAYS));
+		assertEquals(7, parseTime("1week", DAYS));
+		assertEquals(14, parseTime("2w", DAYS));
+		assertEquals(14, parseTime("2weeks", DAYS));
+
+		assertEquals(30, parseTime("1mon", DAYS));
+		assertEquals(30, parseTime("1month", DAYS));
+		assertEquals(60, parseTime("2mon", DAYS));
+		assertEquals(60, parseTime("2months", DAYS));
+
+		assertEquals(365, parseTime("1y", DAYS));
+		assertEquals(365, parseTime("1year", DAYS));
+		assertEquals(365 * 2, parseTime("2years", DAYS));
+	}
+
+	private long parseTime(String value, TimeUnit unit)
+			throws ConfigInvalidException {
+		Config c = parse("[a]\na=" + value + "\n");
+		return c.getTimeUnit("a", null, "a", 0, unit);
+	}
+
+	@Test
+	public void testTimeUnitDefaultValue() throws ConfigInvalidException {
+		// value not present
+		assertEquals(20, parse("[a]\na=0\n").getTimeUnit("a", null, "b", 20,
+				MILLISECONDS));
+		// value is empty
+		assertEquals(20, parse("[a]\na=\" \"\n").getTimeUnit("a", null, "a", 20,
+				MILLISECONDS));
+
+		// value is not numeric
+		assertEquals(20, parse("[a]\na=test\n").getTimeUnit("a", null, "a", 20,
+				MILLISECONDS));
+	}
+
+	@Test
+	public void testTimeUnitInvalid() throws ConfigInvalidException {
+		expectedEx.expect(IllegalArgumentException.class);
+		expectedEx
+				.expectMessage("Invalid time unit value: a.a=1 monttthhh");
+		parseTime("1 monttthhh", DAYS);
+	}
+
+	@Test
+	public void testTimeUnitInvalidWithSection() throws ConfigInvalidException {
+		Config c = parse("[a \"b\"]\na=1 monttthhh\n");
+		expectedEx.expect(IllegalArgumentException.class);
+		expectedEx.expectMessage("Invalid time unit value: a.b.a=1 monttthhh");
+		c.getTimeUnit("a", "b", "a", 0, DAYS);
+	}
+
+	@Test
+	public void testTimeUnitNegative() throws ConfigInvalidException {
+		expectedEx.expect(IllegalArgumentException.class);
+		parseTime("-1", MILLISECONDS);
+	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
index 5578c03..fbe7dd0 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
@@ -798,6 +798,7 @@
 			fail("didn't get the expected exception");
 		} catch (CheckoutConflictException e) {
 			assertConflict("foo");
+			assertEquals("foo", e.getConflictingFiles()[0]);
 			assertWorkDir(mkmap("foo", "bar", "other", "other"));
 			assertIndex(mk("other"));
 		}
@@ -885,6 +886,7 @@
 			assertWorkDir(mkmap("a", "a", "b/c", "b/c", "d", "d", "e/f",
 					"e/f", "e/g", "e/g3"));
 			assertConflict("e/g");
+			assertEquals("e/g", e.getConflictingFiles()[0]);
 		}
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheConfigTest.java
new file mode 100644
index 0000000..52cc9fb
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheConfigTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2016 Ericsson
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.lib;
+
+import static org.eclipse.jgit.lib.RepositoryCacheConfig.AUTO_CLEANUP_DELAY;
+import static org.eclipse.jgit.lib.RepositoryCacheConfig.NO_CLEANUP;
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RepositoryCacheConfigTest {
+
+	private RepositoryCacheConfig config;
+
+	@Before
+	public void setUp() {
+		config = new RepositoryCacheConfig();
+	}
+
+	@Test
+	public void testDefaultValues() {
+		assertEquals(TimeUnit.HOURS.toMillis(1), config.getExpireAfter());
+		assertEquals(config.getExpireAfter() / 10, config.getCleanupDelay());
+	}
+
+	@Test
+	public void testCleanupDelay() {
+		config.setCleanupDelay(TimeUnit.HOURS.toMillis(1));
+		assertEquals(TimeUnit.HOURS.toMillis(1), config.getCleanupDelay());
+	}
+
+	@Test
+	public void testAutoCleanupDelay() {
+		config.setExpireAfter(TimeUnit.MINUTES.toMillis(20));
+		config.setCleanupDelay(AUTO_CLEANUP_DELAY);
+		assertEquals(TimeUnit.MINUTES.toMillis(20), config.getExpireAfter());
+		assertEquals(config.getExpireAfter() / 10, config.getCleanupDelay());
+	}
+
+	@Test
+	public void testAutoCleanupDelayShouldBeMax10minutes() {
+		config.setExpireAfter(TimeUnit.HOURS.toMillis(10));
+		assertEquals(TimeUnit.HOURS.toMillis(10), config.getExpireAfter());
+		assertEquals(TimeUnit.MINUTES.toMillis(10), config.getCleanupDelay());
+	}
+
+	@Test
+	public void testDisabledCleanupDelay() {
+		config.setCleanupDelay(NO_CLEANUP);
+		assertEquals(NO_CLEANUP, config.getCleanupDelay());
+	}
+
+	@Test
+	public void testFromConfig() throws ConfigInvalidException {
+		Config otherConfig = new Config();
+		otherConfig.fromText("[core]\nrepositoryCacheExpireAfter=1000\n"
+				+ "repositoryCacheCleanupDelay=500");
+		config.fromConfig(otherConfig);
+		assertEquals(1000, config.getExpireAfter());
+		assertEquals(500, config.getCleanupDelay());
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java
index a1cec2d..6bea320 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java
@@ -195,17 +195,81 @@
 		assertEquals(0, ((Repository) db).useCnt.get());
 	}
 
-	public void testRepositoryUnregisteringWhenClosing() throws Exception {
+	@Test
+	public void testRepositoryNotUnregisteringWhenClosing() throws Exception {
 		FileKey loc = FileKey.exact(db.getDirectory(), db.getFS());
 		Repository d2 = RepositoryCache.open(loc);
 		assertEquals(1, d2.useCnt.get());
 		assertThat(RepositoryCache.getRegisteredKeys(),
 				hasItem(FileKey.exact(db.getDirectory(), db.getFS())));
 		assertEquals(1, RepositoryCache.getRegisteredKeys().size());
-
 		d2.close();
-
 		assertEquals(0, d2.useCnt.get());
-		assertEquals(0, RepositoryCache.getRegisteredKeys().size());
+		assertEquals(1, RepositoryCache.getRegisteredKeys().size());
+		assertTrue(RepositoryCache.isCached(d2));
+	}
+
+	@Test
+	public void testRepositoryUnregisteringWhenExpired() throws Exception {
+		Repository repoA = createBareRepository();
+		Repository repoB = createBareRepository();
+		Repository repoC = createBareRepository();
+		RepositoryCache.register(repoA);
+		RepositoryCache.register(repoB);
+		RepositoryCache.register(repoC);
+
+		assertEquals(3, RepositoryCache.getRegisteredKeys().size());
+		assertTrue(RepositoryCache.isCached(repoA));
+		assertTrue(RepositoryCache.isCached(repoB));
+		assertTrue(RepositoryCache.isCached(repoC));
+
+		// fake that repoA was closed more than 1 hour ago (default expiration
+		// time)
+		repoA.close();
+		repoA.closedAt.set(System.currentTimeMillis() - 65 * 60 * 1000);
+		// close repoB but this one will not be expired
+		repoB.close();
+
+		assertEquals(3, RepositoryCache.getRegisteredKeys().size());
+		assertTrue(RepositoryCache.isCached(repoA));
+		assertTrue(RepositoryCache.isCached(repoB));
+		assertTrue(RepositoryCache.isCached(repoC));
+
+		RepositoryCache.clearExpired();
+
+		assertEquals(2, RepositoryCache.getRegisteredKeys().size());
+		assertFalse(RepositoryCache.isCached(repoA));
+		assertTrue(RepositoryCache.isCached(repoB));
+		assertTrue(RepositoryCache.isCached(repoC));
+	}
+
+	@Test
+	public void testReconfigure() throws InterruptedException {
+		RepositoryCache.register(db);
+		assertTrue(RepositoryCache.isCached(db));
+		db.close();
+		assertTrue(RepositoryCache.isCached(db));
+
+		// Actually, we would only need to validate that
+		// WorkQueue.getExecutor().scheduleWithFixedDelay is called with proper
+		// values but since we do not have a mock library, we test
+		// reconfiguration from a black box perspective. I.e. reconfigure
+		// expireAfter and cleanupDelay to 1 ms and wait until the Repository
+		// is evicted to prove that reconfiguration worked.
+		RepositoryCacheConfig config = new RepositoryCacheConfig();
+		config.setExpireAfter(1);
+		config.setCleanupDelay(1);
+		config.install();
+
+		// Instead of using a fixed waiting time, start with small and increase:
+		// sleep 1, 2, 4, 8, 16, ..., 1024 ms
+		// This wait will time out after 2048 ms
+		for (int i = 0; i <= 10; i++) {
+			Thread.sleep(1 << i);
+			if (!RepositoryCache.isCached(db)) {
+				return;
+			}
+		}
+		fail("Repository should have been evicted from cache");
 	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java
index 1515a07..19181f5 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java
@@ -89,12 +89,54 @@
 
 	@Test
 	public void testToExternalStringTrimsNameAndEmail() throws Exception {
-		PersonIdent personIdent = new PersonIdent("  A U Thor  ",
-				"  author@example.com  ");
+		PersonIdent personIdent = new PersonIdent(" \u0010A U Thor  ",
+				"  author@example.com \u0009");
+
+		assertEquals(" \u0010A U Thor  ", personIdent.getName());
+		assertEquals("  author@example.com \u0009", personIdent.getEmailAddress());
 
 		String externalString = personIdent.toExternalString();
-
 		assertTrue(externalString.startsWith("A U Thor <author@example.com>"));
 	}
 
+	@Test
+	public void testToExternalStringTrimsAllWhitespace() {
+		String ws = "  \u0001 \n ";
+		PersonIdent personIdent = new PersonIdent(ws, ws);
+		assertEquals(ws, personIdent.getName());
+		assertEquals(ws, personIdent.getEmailAddress());
+
+		String externalString = personIdent.toExternalString();
+		assertTrue(externalString.startsWith(" <>"));
+	}
+
+	@Test
+	public void testToExternalStringTrimsOtherBadCharacters() {
+		String name = " Foo\r\n<Bar> ";
+		String email = " Baz>\n\u1234<Quux ";
+		PersonIdent personIdent = new PersonIdent(name, email);
+		assertEquals(name, personIdent.getName());
+		assertEquals(email, personIdent.getEmailAddress());
+
+		String externalString = personIdent.toExternalString();
+		assertTrue(externalString.startsWith("Foo\rBar <Baz\u1234Quux>"));
+	}
+
+	@Test
+	public void testEmptyNameAndEmail() {
+		PersonIdent personIdent = new PersonIdent("", "");
+		assertEquals("", personIdent.getName());
+		assertEquals("", personIdent.getEmailAddress());
+
+		String externalString = personIdent.toExternalString();
+		assertTrue(externalString.startsWith(" <>"));
+	}
+
+	@Test
+	public void testAppendSanitized() {
+		StringBuilder r = new StringBuilder();
+		PersonIdent.appendSanitized(r, " Baz>\n\u1234<Quux ");
+		assertEquals("Baz\u1234Quux", r.toString());
+	}
 }
+
diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
index db339e0..4d864d6 100644
--- a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
@@ -3,14 +3,14 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit.ui
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Vendor: %provider_name
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
-Export-Package: org.eclipse.jgit.awtui;version="4.3.2"
-Import-Package: org.eclipse.jgit.errors;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.lib;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.nls;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revplot;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.transport;version="[4.3.2,4.4.0)",
- org.eclipse.jgit.util;version="[4.3.2,4.4.0)"
+Export-Package: org.eclipse.jgit.awtui;version="4.4.2"
+Import-Package: org.eclipse.jgit.errors;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.lib;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.nls;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revplot;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.transport;version="[4.4.2,4.5.0)",
+ org.eclipse.jgit.util;version="[4.4.2,4.5.0)"
diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml
index fdd6dad..a8d9b5d 100644
--- a/org.eclipse.jgit.ui/pom.xml
+++ b/org.eclipse.jgit.ui/pom.xml
@@ -52,7 +52,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ui</artifactId>
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
index c0dbc77..bacfb33 100644
--- a/org.eclipse.jgit/.settings/.api_filters
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -1,5 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <component id="org.eclipse.jgit" version="2">
+    <resource path="META-INF/MANIFEST.MF">
+        <filter id="924844039">
+            <message_arguments>
+                <message_argument value="4.4.1"/>
+                <message_argument value="4.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
     <resource path="src/org/eclipse/jgit/attributes/AttributesNode.java" type="org.eclipse.jgit.attributes.AttributesNode">
         <filter comment="moved to new AttributesManager" id="338792546">
             <message_arguments>
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF
index f94c22c..82b27bf 100644
--- a/org.eclipse.jgit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/MANIFEST.MF
@@ -2,12 +2,12 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.jgit
-Bundle-Version: 4.3.2.qualifier
+Bundle-Version: 4.4.2.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %provider_name
 Bundle-ActivationPolicy: lazy
-Export-Package: org.eclipse.jgit.annotations;version="4.3.2",
- org.eclipse.jgit.api;version="4.3.2";
+Export-Package: org.eclipse.jgit.annotations;version="4.4.2",
+ org.eclipse.jgit.api;version="4.4.2";
   uses:="org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.diff,
@@ -21,47 +21,50 @@
    org.eclipse.jgit.submodule,
    org.eclipse.jgit.transport,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.api.errors;version="4.3.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors",
- org.eclipse.jgit.attributes;version="4.3.2",
- org.eclipse.jgit.blame;version="4.3.2";
+ org.eclipse.jgit.api.errors;version="4.4.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors",
+ org.eclipse.jgit.attributes;version="4.4.2",
+ org.eclipse.jgit.blame;version="4.4.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.diff",
- org.eclipse.jgit.diff;version="4.3.2";
+ org.eclipse.jgit.diff;version="4.4.2";
   uses:="org.eclipse.jgit.patch,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.util",
- org.eclipse.jgit.dircache;version="4.3.2";
+ org.eclipse.jgit.dircache;version="4.4.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util,
    org.eclipse.jgit.events,
    org.eclipse.jgit.attributes",
- org.eclipse.jgit.errors;version="4.3.2";
+ org.eclipse.jgit.errors;version="4.4.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.internal.storage.pack,
    org.eclipse.jgit.transport,
    org.eclipse.jgit.dircache",
- org.eclipse.jgit.events;version="4.3.2";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.fnmatch;version="4.3.2",
- org.eclipse.jgit.gitrepo;version="4.3.2";
+ org.eclipse.jgit.events;version="4.4.2";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.fnmatch;version="4.4.2",
+ org.eclipse.jgit.gitrepo;version="4.4.2";
   uses:="org.eclipse.jgit.api,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.xml.sax.helpers,
    org.xml.sax",
- org.eclipse.jgit.gitrepo.internal;version="4.3.2";x-internal:=true,
- org.eclipse.jgit.hooks;version="4.3.2";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.ignore;version="4.3.2",
- org.eclipse.jgit.ignore.internal;version="4.3.2";x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal;version="4.3.2";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test",
- org.eclipse.jgit.internal.ketch;version="4.3.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.dfs;version="4.3.2";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.server",
- org.eclipse.jgit.internal.storage.file;version="4.3.2";
+ org.eclipse.jgit.gitrepo.internal;version="4.4.2";x-internal:=true,
+ org.eclipse.jgit.hooks;version="4.4.2";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.ignore;version="4.4.2",
+ org.eclipse.jgit.ignore.internal;version="4.4.2";x-friends:="org.eclipse.jgit.test",
+ org.eclipse.jgit.internal;version="4.4.2";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test",
+ org.eclipse.jgit.internal.ketch;version="4.4.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.internal.storage.dfs;version="4.4.2";
+  x-friends:="org.eclipse.jgit.test,
+   org.eclipse.jgit.http.server,
+   org.eclipse.jgit.http.test",
+ org.eclipse.jgit.internal.storage.file;version="4.4.2";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.junit,
    org.eclipse.jgit.junit.http,
@@ -69,9 +72,9 @@
    org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.pgm,
    org.eclipse.jgit.pgm.test",
- org.eclipse.jgit.internal.storage.pack;version="4.3.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.reftree;version="4.3.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.lib;version="4.3.2";
+ org.eclipse.jgit.internal.storage.pack;version="4.4.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.internal.storage.reftree;version="4.4.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.lib;version="4.4.2";
   uses:="org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.util,
@@ -81,32 +84,32 @@
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.transport,
    org.eclipse.jgit.submodule",
- org.eclipse.jgit.merge;version="4.3.2";
+ org.eclipse.jgit.merge;version="4.4.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.dircache,
    org.eclipse.jgit.api",
- org.eclipse.jgit.nls;version="4.3.2",
- org.eclipse.jgit.notes;version="4.3.2";
+ org.eclipse.jgit.nls;version="4.4.2",
+ org.eclipse.jgit.notes;version="4.4.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.patch;version="4.3.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff",
- org.eclipse.jgit.revplot;version="4.3.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk",
- org.eclipse.jgit.revwalk;version="4.3.2";
+ org.eclipse.jgit.patch;version="4.4.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff",
+ org.eclipse.jgit.revplot;version="4.4.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk",
+ org.eclipse.jgit.revwalk;version="4.4.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.revwalk.filter",
- org.eclipse.jgit.revwalk.filter;version="4.3.2";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util",
- org.eclipse.jgit.storage.file;version="4.3.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util",
- org.eclipse.jgit.storage.pack;version="4.3.2";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.submodule;version="4.3.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk",
- org.eclipse.jgit.transport;version="4.3.2";
+ org.eclipse.jgit.revwalk.filter;version="4.4.2";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util",
+ org.eclipse.jgit.storage.file;version="4.4.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util",
+ org.eclipse.jgit.storage.pack;version="4.4.2";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.submodule;version="4.4.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk",
+ org.eclipse.jgit.transport;version="4.4.2";
   uses:="org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.internal.storage.pack,
@@ -118,22 +121,22 @@
    org.eclipse.jgit.transport.http,
    org.eclipse.jgit.errors,
    org.eclipse.jgit.storage.pack",
- org.eclipse.jgit.transport.http;version="4.3.2";uses:="javax.net.ssl",
- org.eclipse.jgit.transport.resolver;version="4.3.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport",
- org.eclipse.jgit.treewalk;version="4.3.2";
+ org.eclipse.jgit.transport.http;version="4.4.2";uses:="javax.net.ssl",
+ org.eclipse.jgit.transport.resolver;version="4.4.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport",
+ org.eclipse.jgit.treewalk;version="4.4.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.util,
    org.eclipse.jgit.dircache",
- org.eclipse.jgit.treewalk.filter;version="4.3.2";uses:="org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util;version="4.3.2";
+ org.eclipse.jgit.treewalk.filter;version="4.4.2";uses:="org.eclipse.jgit.treewalk",
+ org.eclipse.jgit.util;version="4.4.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.transport.http,
    org.eclipse.jgit.storage.file,
    org.ietf.jgss",
- org.eclipse.jgit.util.io;version="4.3.2"
+ org.eclipse.jgit.util.io;version="4.4.2"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Require-Bundle: com.jcraft.jsch;bundle-version="[0.1.37,0.2.0)"
 Import-Package: com.googlecode.javaewah;version="[0.7.9,0.8.0)",
diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
index 3bf02b7..b0365c7 100644
--- a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit - Sources
 Bundle-SymbolicName: org.eclipse.jgit.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 4.3.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit;version="4.3.2.qualifier";roots="."
+Bundle-Version: 4.4.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit;version="4.4.2.qualifier";roots="."
diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml
index 40d15c8..77bfba1 100644
--- a/org.eclipse.jgit/pom.xml
+++ b/org.eclipse.jgit/pom.xml
@@ -53,7 +53,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>4.3.2-SNAPSHOT</version>
+    <version>4.4.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit</artifactId>
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 992e10b..21fbaa4 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -21,6 +21,7 @@
 atLeastOnePatternIsRequired=At least one pattern is required.
 atLeastTwoFiltersNeeded=At least two filters needed.
 atomicPushNotSupported=Atomic push not supported.
+atomicRefUpdatesNotSupported=Atomic ref updates not supported
 authenticationNotSupported=authentication not supported
 badBase64InputCharacterAt=Bad Base64 input character at {0} : {1} (decimal)
 badEntryDelimiter=Bad entry delimiter
@@ -184,6 +185,7 @@
 corruptObjectTruncatedInName=truncated in name
 corruptObjectTruncatedInObjectId=truncated in object id
 corruptObjectZeroId=entry points to null SHA-1
+corruptUseCnt=close() called when useCnt is already zero
 couldNotCheckOutBecauseOfConflicts=Could not check out because of conflicts
 couldNotDeleteLockFileShouldNotHappen=Could not delete lock file. Should not happen
 couldNotDeleteTemporaryIndexFileShouldNotHappen=Could not delete temporary index file. Should not happen
@@ -313,6 +315,8 @@
 indexSignatureIsInvalid=Index signature is invalid: {0}
 indexWriteException=Modified index could not be written
 initFailedBareRepoDifferentDirs=When initializing a bare repo with directory {0} and separate git-dir {1} specified both folders must point to the same location
+initFailedDirIsNoDirectory=Cannot set directory to ''{0}'' which is not a directory
+initFailedGitDirIsNoDirectory=Cannot set git-dir to ''{0}'' which is not a directory
 initFailedNonBareRepoSameDirs=When initializing a non-bare repo with directory {0} and separate git-dir {1} specified both folders should not point to the same location
 inMemoryBufferLimitExceeded=In-memory buffer limit exceeded
 inputDidntMatchLength=Input did not match supplied length. {0} bytes are missing.
@@ -357,6 +361,8 @@
 invalidStageForPath=Invalid stage {0} for path {1}
 invalidTagOption=Invalid tag option: {0}
 invalidTimeout=Invalid timeout: {0}
+invalidTimeUnitValue2=Invalid time unit value: {0}.{1}={2}
+invalidTimeUnitValue3=Invalid time unit value: {0}.{1}.{2}={3}
 invalidURL=Invalid URL {0}
 invalidWildcards=Invalid wildcards {0}
 invalidRefSpec=Invalid refspec {0}
@@ -591,6 +597,7 @@
 tagOnRepoWithoutHEADCurrentlyNotSupported=Tag on repository without HEAD currently not supported
 theFactoryMustNotBeNull=The factory must not be null
 timerAlreadyTerminated=Timer already terminated
+tooManyIncludeRecursions=Too many recursions; circular includes in config file(s)?
 topologicalSortRequired=Topological sort required.
 transactionAborted=transaction aborted
 transportExceptionBadRef=Empty ref: {0}: {1}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java
index 9cf8881..4235e37 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java
@@ -87,7 +87,7 @@
 		RevCommit notesCommit = null;
 		try (RevWalk walk = new RevWalk(repo);
 				ObjectInserter inserter = repo.newObjectInserter()) {
-			Ref ref = repo.getRef(notesRef);
+			Ref ref = repo.findRef(notesRef);
 			// if we have a notes ref, use it
 			if (ref != null) {
 				notesCommit = walk.parseCommit(ref.getObjectId());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
index 8fbf839..d74e991 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
@@ -58,6 +58,7 @@
 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
 import org.eclipse.jgit.diff.RawText;
 import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.patch.FileHeader;
 import org.eclipse.jgit.patch.HunkHeader;
@@ -260,6 +261,8 @@
 		FileWriter fw = new FileWriter(f);
 		fw.write(sb.toString());
 		fw.close();
+
+		getRepository().getFS().setExecute(f, fh.getNewMode() == FileMode.EXECUTABLE_FILE);
 	}
 
 	private static boolean isChanged(List<String> ol, List<String> nl) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
index 6c80289..65508ef 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
@@ -223,7 +223,7 @@
 				}
 			}
 
-			Ref headRef = repo.getRef(Constants.HEAD);
+			Ref headRef = repo.exactRef(Constants.HEAD);
 			if (headRef == null) {
 				// TODO Git CLI supports checkout from unborn branch, we should
 				// also allow this
@@ -242,7 +242,7 @@
 								JGitText.get().checkoutUnexpectedResult,
 								r.name()));
 					this.status = CheckoutResult.NOT_TRIED_RESULT;
-					return repo.getRef(Constants.HEAD);
+					return repo.exactRef(Constants.HEAD);
 				}
 				branch = getStartPointObjectId();
 			} else {
@@ -277,7 +277,7 @@
 			} finally {
 				dc.unlock();
 			}
-			Ref ref = repo.getRef(name);
+			Ref ref = repo.findRef(name);
 			if (ref != null && !ref.getName().startsWith(Constants.R_HEADS))
 				ref = null;
 			String toName = Repository.shortenRefName(name);
@@ -289,7 +289,7 @@
 				updateResult = refUpdate.link(ref.getName());
 			else if (orphan) {
 				updateResult = refUpdate.link(getBranchName());
-				ref = repo.getRef(Constants.HEAD);
+				ref = repo.exactRef(Constants.HEAD);
 			} else {
 				refUpdate.setNewObjectId(newCommit);
 				updateResult = refUpdate.forceUpdate();
@@ -519,7 +519,7 @@
 					.get().branchNameInvalid, name == null ? "<null>" : name)); //$NON-NLS-1$
 
 		if (orphan) {
-			Ref refToCheck = repo.getRef(getBranchName());
+			Ref refToCheck = repo.exactRef(getBranchName());
 			if (refToCheck != null)
 				throw new RefAlreadyExistsException(MessageFormat.format(
 						JGitText.get().refAlreadyExists, name));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
index d6e930a..e82a697 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
@@ -126,7 +126,7 @@
 		try (RevWalk revWalk = new RevWalk(repo)) {
 
 			// get the head commit
-			Ref headRef = repo.getRef(Constants.HEAD);
+			Ref headRef = repo.exactRef(Constants.HEAD);
 			if (headRef == null)
 				throw new NoHeadException(
 						JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
index 2ac8729..ff15fd0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
@@ -155,6 +155,7 @@
 		command.setBare(bare);
 		if (directory == null && gitDir == null)
 			directory = new File(u.getHumanishName(), Constants.DOT_GIT);
+		validateDirs(directory, gitDir, bare);
 		if (directory != null && directory.exists()
 				&& directory.listFiles().length != 0)
 			throw new JGitInternalException(MessageFormat.format(
@@ -511,6 +512,15 @@
 	private static void validateDirs(File directory, File gitDir, boolean bare)
 			throws IllegalStateException {
 		if (directory != null) {
+			if (directory.exists() && !directory.isDirectory()) {
+				throw new IllegalStateException(MessageFormat.format(
+						JGitText.get().initFailedDirIsNoDirectory, directory));
+			}
+			if (gitDir != null && gitDir.exists() && !gitDir.isDirectory()) {
+				throw new IllegalStateException(MessageFormat.format(
+						JGitText.get().initFailedGitDirIsNoDirectory,
+						gitDir));
+			}
 			if (bare) {
 				if (gitDir != null && !gitDir.equals(directory))
 					throw new IllegalStateException(MessageFormat.format(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
index 0abb8ba..561319c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
@@ -124,6 +124,8 @@
 
 	private String reflogComment;
 
+	private boolean useDefaultReflogMessage = true;
+
 	/**
 	 * Setting this option bypasses the pre-commit and commit-msg hooks.
 	 */
@@ -193,7 +195,7 @@
 				}
 			}
 
-			Ref head = repo.getRef(Constants.HEAD);
+			Ref head = repo.exactRef(Constants.HEAD);
 			if (head == null)
 				throw new NoHeadException(
 						JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported);
@@ -258,7 +260,7 @@
 				RevCommit revCommit = rw.parseCommit(commitId);
 				RefUpdate ru = repo.updateRef(Constants.HEAD);
 				ru.setNewObjectId(commitId);
-				if (reflogComment != null) {
+				if (!useDefaultReflogMessage) {
 					ru.setRefLogMessage(reflogComment, false);
 				} else {
 					String prefix = amend ? "commit (amend): " //$NON-NLS-1$
@@ -790,10 +792,13 @@
 	 * Override the message written to the reflog
 	 *
 	 * @param reflogComment
+	 *            the comment to be written into the reflog or <code>null</code>
+	 *            to specify that no reflog should be written
 	 * @return {@code this}
 	 */
 	public CommitCommand setReflogComment(String reflogComment) {
 		this.reflogComment = reflogComment;
+		useDefaultReflogMessage = false;
 		return this;
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java
index a664660..69d82bc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java
@@ -125,7 +125,7 @@
 		checkCallable();
 		processOptions();
 		try (RevWalk revWalk = new RevWalk(repo)) {
-			Ref refToCheck = repo.getRef(name);
+			Ref refToCheck = repo.findRef(name);
 			boolean exists = refToCheck != null
 					&& refToCheck.getName().startsWith(Constants.R_HEADS);
 			if (!force && exists)
@@ -135,7 +135,7 @@
 			ObjectId startAt = getStartPointObjectId();
 			String startPointFullName = null;
 			if (startPoint != null) {
-				Ref baseRef = repo.getRef(startPoint);
+				Ref baseRef = repo.findRef(startPoint);
 				if (baseRef != null)
 					startPointFullName = baseRef.getName();
 			}
@@ -207,7 +207,7 @@
 						.get().createBranchUnexpectedResult, updateResult
 						.name()));
 
-			Ref result = repo.getRef(name);
+			Ref result = repo.findRef(name);
 			if (result == null)
 				throw new JGitInternalException(
 						JGitText.get().createBranchFailedUnknownReason);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java
index 61beb2f..ecc1ce5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java
@@ -114,7 +114,7 @@
 					for (String branchName : branchNames) {
 						if (branchName == null)
 							continue;
-						Ref currentRef = repo.getRef(branchName);
+						Ref currentRef = repo.findRef(branchName);
 						if (currentRef == null)
 							continue;
 
@@ -130,7 +130,7 @@
 			for (String branchName : branchNames) {
 				if (branchName == null)
 					continue;
-				Ref currentRef = repo.getRef(branchName);
+				Ref currentRef = repo.findRef(branchName);
 				if (currentRef == null)
 					continue;
 				String fullName = currentRef.getName();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java
index ae511c6..3aeec48 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java
@@ -90,7 +90,7 @@
 			for (String tagName : tags) {
 				if (tagName == null)
 					continue;
-				Ref currentRef = repo.getRef(tagName);
+				Ref currentRef = repo.findRef(tagName);
 				if (currentRef == null)
 					continue;
 				String fullName = currentRef.getName();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java
index 904c74f..efcfd16 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java
@@ -108,7 +108,7 @@
 			Collection<Ref> refs = new ArrayList<Ref>();
 
 			// Also return HEAD if it's detached
-			Ref head = repo.getRef(Constants.HEAD);
+			Ref head = repo.exactRef(Constants.HEAD);
 			if (head != null && head.getLeaf().getName().equals(Constants.HEAD))
 				refs.add(head);
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java
index 796ac79..ff963ed 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java
@@ -82,7 +82,7 @@
 		List<Note> notes = new ArrayList<Note>();
 		NoteMap map = NoteMap.newEmptyMap();
 		try (RevWalk walk = new RevWalk(repo)) {
-			Ref ref = repo.getRef(notesRef);
+			Ref ref = repo.findRef(notesRef);
 			// if we have a notes ref, use it
 			if (ref != null) {
 				RevCommit notesCommit = walk.parseCommit(ref.getObjectId());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
index 9690f79..bb1a738 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
@@ -65,6 +65,7 @@
 import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.revwalk.filter.AndRevFilter;
 import org.eclipse.jgit.revwalk.filter.MaxCountRevFilter;
+import org.eclipse.jgit.revwalk.filter.RevFilter;
 import org.eclipse.jgit.revwalk.filter.SkipRevFilter;
 import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
 import org.eclipse.jgit.treewalk.filter.PathFilter;
@@ -104,6 +105,8 @@
 
 	private boolean startSpecified = false;
 
+	private RevFilter revFilter;
+
 	private final List<PathFilter> pathFilters = new ArrayList<PathFilter>();
 
 	private int maxCount = -1;
@@ -156,6 +159,11 @@
 						e);
 			}
 		}
+
+		if (this.revFilter != null) {
+			walk.setRevFilter(this.revFilter);
+		}
+
 		setCallable(false);
 		return walk;
 	}
@@ -342,4 +350,21 @@
 					, start), e);
 		}
 	}
+
+
+	/**
+	 * Sets a filter for the <code>LogCommand</code>.
+	 *
+	 *
+	 * @param aFilter
+	 *            the filter that this instance of <code>LogCommand</code>
+	 *            should use
+	 * @return {@code this}
+	 * @since 4.4
+	 */
+	public LogCommand setRevFilter(RevFilter aFilter) {
+		checkCallable();
+		this.revFilter = aFilter;
+		return this;
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
index bfe90a3..38b1097 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
@@ -231,7 +231,7 @@
 		RevWalk revWalk = null;
 		DirCacheCheckout dco = null;
 		try {
-			Ref head = repo.getRef(Constants.HEAD);
+			Ref head = repo.exactRef(Constants.HEAD);
 			if (head == null)
 				throw new NoHeadException(
 						JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
index f5b82bd..0a49f78 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
@@ -55,6 +55,7 @@
 import org.eclipse.jgit.api.errors.InvalidRemoteException;
 import org.eclipse.jgit.api.errors.JGitInternalException;
 import org.eclipse.jgit.errors.NotSupportedException;
+import org.eclipse.jgit.errors.TooLargeObjectInPackException;
 import org.eclipse.jgit.errors.TooLargePackException;
 import org.eclipse.jgit.errors.TransportException;
 import org.eclipse.jgit.internal.JGitText;
@@ -130,7 +131,7 @@
 				refSpecs.addAll(config.getPushRefSpecs());
 			}
 			if (refSpecs.isEmpty()) {
-				Ref head = repo.getRef(Constants.HEAD);
+				Ref head = repo.exactRef(Constants.HEAD);
 				if (head != null && head.isSymbolic())
 					refSpecs.add(new RefSpec(head.getLeaf().getName()));
 			}
@@ -160,6 +161,9 @@
 				} catch (TooLargePackException e) {
 					throw new org.eclipse.jgit.api.errors.TooLargePackException(
 							e.getMessage(), e);
+				} catch (TooLargeObjectInPackException e) {
+					throw new org.eclipse.jgit.api.errors.TooLargeObjectInPackException(
+							e.getMessage(), e);
 				} catch (TransportException e) {
 					throw new org.eclipse.jgit.api.errors.TransportException(
 							e.getMessage(), e);
@@ -344,7 +348,7 @@
 		} else {
 			Ref src;
 			try {
-				src = repo.getRef(nameOrSpec);
+				src = repo.findRef(nameOrSpec);
 			} catch (IOException e) {
 				throw new JGitInternalException(
 						JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
index 643ec7a..2d6a76b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
@@ -419,7 +419,7 @@
 
 	private void updateStashRef(ObjectId commitId, PersonIdent refLogIdent,
 			String refLogMessage) throws IOException {
-		Ref currentRef = repo.getRef(Constants.R_STASH);
+		Ref currentRef = repo.exactRef(Constants.R_STASH);
 		RefUpdate refUpdate = repo.updateRef(Constants.R_STASH);
 		refUpdate.setNewObjectId(commitId);
 		refUpdate.setRefLogIdent(refLogIdent);
@@ -750,7 +750,7 @@
 
 	private void resetSoftToParent() throws IOException,
 			GitAPIException, CheckoutConflictException {
-		Ref ref = repo.getRef(Constants.ORIG_HEAD);
+		Ref ref = repo.exactRef(Constants.ORIG_HEAD);
 		ObjectId orig_head = ref == null ? null : ref.getObjectId();
 		try {
 			// we have already commited the cherry-picked commit.
@@ -1207,7 +1207,7 @@
 	}
 
 	private Ref getHead() throws IOException, RefNotFoundException {
-		Ref head = repo.getRef(Constants.HEAD);
+		Ref head = repo.exactRef(Constants.HEAD);
 		if (head == null || head.getObjectId() == null)
 			throw new RefNotFoundException(MessageFormat.format(
 					JGitText.get().refNotResolved, Constants.HEAD));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java
index a526c27..1c4880c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java
@@ -85,7 +85,7 @@
 				ObjectInserter inserter = repo.newObjectInserter()) {
 			NoteMap map = NoteMap.newEmptyMap();
 			RevCommit notesCommit = null;
-			Ref ref = repo.getRef(notesRef);
+			Ref ref = repo.exactRef(notesRef);
 			// if we have a notes ref, use it
 			if (ref != null) {
 				notesCommit = walk.parseCommit(ref.getObjectId());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java
index 0731dd4..044a486 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java
@@ -107,11 +107,11 @@
 		try {
 			String fullOldName;
 			String fullNewName;
-			if (repo.getRef(newName) != null)
+			if (repo.findRef(newName) != null)
 				throw new RefAlreadyExistsException(MessageFormat.format(
 						JGitText.get().refAlreadyExists1, newName));
 			if (oldName != null) {
-				Ref ref = repo.getRef(oldName);
+				Ref ref = repo.findRef(oldName);
 				if (ref == null)
 					throw new RefNotFoundException(MessageFormat.format(
 							JGitText.get().refNotResolved, oldName));
@@ -186,7 +186,7 @@
 				repoConfig.save();
 			}
 
-			Ref resultRef = repo.getRef(newName);
+			Ref resultRef = repo.findRef(newName);
 			if (resultRef == null)
 				throw new JGitInternalException(
 						JGitText.get().renameBranchFailedUnknownReason);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
index 4c91e6c..e385a5d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
@@ -171,7 +171,7 @@
 				// reset [commit] -- paths
 				resetIndexForPaths(commitTree);
 				setCallable(false);
-				return repo.getRef(Constants.HEAD);
+				return repo.exactRef(Constants.HEAD);
 			}
 
 			final Ref result;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
index 8015773..9d79ed0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
@@ -129,7 +129,7 @@
 		try (RevWalk revWalk = new RevWalk(repo)) {
 
 			// get the head commit
-			Ref headRef = repo.getRef(Constants.HEAD);
+			Ref headRef = repo.exactRef(Constants.HEAD);
 			if (headRef == null)
 				throw new NoHeadException(
 						JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java
index 82db881..168ea51 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java
@@ -79,7 +79,7 @@
 		NoteMap map = NoteMap.newEmptyMap();
 		RevCommit notesCommit = null;
 		try (RevWalk walk = new RevWalk(repo)) {
-			Ref ref = repo.getRef(notesRef);
+			Ref ref = repo.exactRef(notesRef);
 			// if we have a notes ref, use it
 			if (ref != null) {
 				notesCommit = walk.parseCommit(ref.getObjectId());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java
index 1699b9f..b8ee1ec 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java
@@ -223,8 +223,13 @@
 					ResolveMerger untrackedMerger = (ResolveMerger) strategy
 							.newMerger(repo, true);
 					untrackedMerger.setCommitNames(new String[] {
-							"stashed HEAD", "HEAD", "untracked files" }); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
-					untrackedMerger.setBase(stashHeadCommit);
+							"null", "HEAD", "untracked files" }); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+					// There is no common base for HEAD & untracked files
+					// because the commit for untracked files has no parent. If
+					// we use stashHeadCommit as common base (as in the other
+					// merges) we potentially report conflicts for files
+					// which are not even member of untracked files commit
+					untrackedMerger.setBase(null);
 					boolean ok = untrackedMerger.merge(headCommit,
 							untrackedCommit);
 					if (ok)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java
index ef32ac9..ee9b7fc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java
@@ -206,7 +206,7 @@
 			String refLogMessage) throws IOException {
 		if (ref == null)
 			return;
-		Ref currentRef = repo.getRef(ref);
+		Ref currentRef = repo.findRef(ref);
 		RefUpdate refUpdate = repo.updateRef(ref);
 		refUpdate.setNewObjectId(commitId);
 		refUpdate.setRefLogIdent(refLogIdent);
@@ -220,7 +220,7 @@
 
 	private Ref getHead() throws GitAPIException {
 		try {
-			Ref head = repo.getRef(Constants.HEAD);
+			Ref head = repo.exactRef(Constants.HEAD);
 			if (head == null || head.getObjectId() == null)
 				throw new NoHeadException(JGitText.get().headRequiredToStash);
 			return head;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java
index f6903be..6e1d0f2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java
@@ -118,7 +118,7 @@
 
 	private Ref getRef() throws GitAPIException {
 		try {
-			return repo.getRef(R_STASH);
+			return repo.exactRef(R_STASH);
 		} catch (IOException e) {
 			throw new InvalidRefNameException(MessageFormat.format(
 					JGitText.get().cannotRead, R_STASH), e);
@@ -236,7 +236,7 @@
 		updateRef(stashRef, entryId);
 
 		try {
-			Ref newStashRef = repo.getRef(R_STASH);
+			Ref newStashRef = repo.exactRef(R_STASH);
 			return newStashRef != null ? newStashRef.getObjectId() : null;
 		} catch (IOException e) {
 			throw new InvalidRefNameException(MessageFormat.format(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java
index 59a83aa..aedc9a6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java
@@ -81,7 +81,7 @@
 		checkCallable();
 
 		try {
-			if (repo.getRef(Constants.R_STASH) == null)
+			if (repo.exactRef(Constants.R_STASH) == null)
 				return Collections.emptyList();
 		} catch (IOException e) {
 			throw new InvalidRefNameException(MessageFormat.format(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java
index e7fe71a..024f0be 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java
@@ -101,7 +101,7 @@
 	 * @throws IOException
 	 */
 	protected String getHeadBranch(final Repository subRepo) throws IOException {
-		Ref head = subRepo.getRef(Constants.HEAD);
+		Ref head = subRepo.exactRef(Constants.HEAD);
 		if (head != null && head.isSymbolic())
 			return Repository.shortenRefName(head.getLeaf().getName());
 		else
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java
index ca98ced..39dd42c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java
@@ -184,7 +184,7 @@
 		switch (updateResult) {
 		case NEW:
 		case FORCED:
-			return repo.getRef(refName);
+			return repo.exactRef(refName);
 		case LOCK_FAILURE:
 			throw new ConcurrentRefUpdateException(
 					JGitText.get().couldNotLockHEAD, tagRef.getRef(),
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/TooLargeObjectInPackException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/TooLargeObjectInPackException.java
new file mode 100644
index 0000000..08c25c2
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/TooLargeObjectInPackException.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2016, Matthias Sohn <matthias.sohn@sap.com> and
+ * other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v1.0 which accompanies this
+ * distribution, is reproduced below, and is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.eclipse.jgit.api.errors;
+
+/**
+ * Exception thrown when the server rejected a too large pack
+ *
+ * @since 4.4
+ */
+public class TooLargeObjectInPackException extends TransportException {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * @param msg
+	 *            message describing the transport failure.
+	 */
+	public TooLargeObjectInPackException(String msg) {
+		super(msg);
+	}
+
+	/**
+	 * @param msg
+	 *            message describing the transport exception.
+	 * @param cause
+	 *            why the transport failed.
+	 */
+	public TooLargeObjectInPackException(String msg, Throwable cause) {
+		super(msg, cause);
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
index fc4cc90..12ceb74 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
@@ -354,8 +354,16 @@
 				// The index entry is missing
 				if (f != null && !FileMode.TREE.equals(f.getEntryFileMode())
 						&& !f.isEntryIgnored()) {
-					// don't overwrite an untracked and not ignored file
-					conflicts.add(walk.getPathString());
+					if (failOnConflict) {
+						// don't overwrite an untracked and not ignored file
+						conflicts.add(walk.getPathString());
+					} else {
+						// failOnConflict is false. Putting something to conflicts
+						// would mean we delete it. Instead we want the mergeCommit
+						// content to be checked out.
+						update(m.getEntryPathString(), m.getEntryObjectId(),
+								m.getEntryFileMode());
+					}
 				} else
 					update(m.getEntryPathString(), m.getEntryObjectId(),
 						m.getEntryFileMode());
@@ -390,6 +398,9 @@
 			if (f != null) {
 				// There is a file/folder for that path in the working tree
 				if (walk.isDirectoryFileConflict()) {
+					// We put it in conflicts. Even if failOnConflict is false
+					// this would cause the path to be deleted. Thats exactly what
+					// we want in this situation
 					conflicts.add(walk.getPathString());
 				} else {
 					// No file/folder conflict exists. All entries are files or
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/CheckoutConflictException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CheckoutConflictException.java
index db29f3f..b6010b6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/CheckoutConflictException.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CheckoutConflictException.java
@@ -56,6 +56,8 @@
 public class CheckoutConflictException extends IOException {
 	private static final long serialVersionUID = 1L;
 
+	private final String[] conflicting;
+
 	/**
 	 * Construct a CheckoutConflictException for the specified file
 	 *
@@ -63,6 +65,7 @@
 	 */
 	public CheckoutConflictException(String file) {
 		super(MessageFormat.format(JGitText.get().checkoutConflictWithFile, file));
+		conflicting = new String[] { file };
 	}
 
 	/**
@@ -72,6 +75,16 @@
 	 */
 	public CheckoutConflictException(String[] files) {
 		super(MessageFormat.format(JGitText.get().checkoutConflictWithFiles, buildList(files)));
+		conflicting = files;
+	}
+
+	/**
+	 * @return the relative paths of the conflicting files (relative to the
+	 *         working directory root).
+	 * @since 4.4
+	 */
+	public String[] getConflictingFiles() {
+		return conflicting;
 	}
 
 	private static String buildList(String[] files) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/TooLargeObjectInPackException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TooLargeObjectInPackException.java
index 79515fc..b5b1af5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/TooLargeObjectInPackException.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TooLargeObjectInPackException.java
@@ -43,13 +43,13 @@
 
 package org.eclipse.jgit.errors;
 
-import java.io.IOException;
 import java.text.MessageFormat;
 
 import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.transport.URIish;
 
 /** Thrown when PackParser finds an object larger than a predefined limit */
-public class TooLargeObjectInPackException extends IOException {
+public class TooLargeObjectInPackException extends TransportException {
 	private static final long serialVersionUID = 1L;
 
 	/**
@@ -79,4 +79,17 @@
 		super(MessageFormat.format(JGitText.get().receivePackObjectTooLarge2,
 				Long.valueOf(objectSize), Long.valueOf(maxObjectSizeLimit)));
 	}
+
+	/**
+	 * Construct a too large object in pack exception.
+	 *
+	 * @param uri
+	 *            URI used for transport
+	 * @param s
+	 *            message
+	 * @since 4.4
+	 */
+	public TooLargeObjectInPackException(URIish uri, String s) {
+		super(uri.setPass(null) + ": " + s); //$NON-NLS-1$
+	}
 }
\ No newline at end of file
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
index 796b422..2370ae1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
@@ -192,6 +192,8 @@
 					attributes.getValue("revision"), //$NON-NLS-1$
 					attributes.getValue("remote"), //$NON-NLS-1$
 					attributes.getValue("groups")); //$NON-NLS-1$
+			currentProject.setRecommendShallow(
+				attributes.getValue("clone-depth")); //$NON-NLS-1$
 		} else if ("remote".equals(qName)) { //$NON-NLS-1$
 			String alias = attributes.getValue("alias"); //$NON-NLS-1$
 			String fetch = attributes.getValue("fetch"); //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
index ee937f5..ca976a1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -53,6 +53,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.eclipse.jgit.annotations.Nullable;
 import org.eclipse.jgit.api.Git;
@@ -110,6 +111,8 @@
 	private String branch;
 	private String targetBranch = Constants.HEAD;
 	private boolean recordRemoteBranch = false;
+	private boolean recordSubmoduleLabels = false;
+	private boolean recordShallowSubmodules = false;
 	private PersonIdent author;
 	private RemoteReader callback;
 	private InputStream inputStream;
@@ -345,6 +348,36 @@
 	}
 
 	/**
+	 * Set whether the labels field should be recorded as a label in
+	 * .gitattributes.
+	 * <p>
+	 * Not implemented for non-bare repositories.
+	 *
+	 * @param enable Whether to record the labels in the .gitattributes
+	 * @return this command
+	 * @since 4.4
+	 */
+	public RepoCommand setRecordSubmoduleLabels(boolean enable) {
+		this.recordSubmoduleLabels = enable;
+		return this;
+	}
+
+	/**
+	 * Set whether the clone-depth field should be recorded as a shallow
+	 * recommendation in .gitmodules.
+	 * <p>
+	 * Not implemented for non-bare repositories.
+	 *
+	 * @param enable Whether to record the shallow recommendation.
+	 * @return this command
+	 * @since 4.4
+	 */
+	public RepoCommand setRecommendShallow(boolean enable) {
+		this.recordShallowSubmodules = enable;
+		return this;
+	}
+
+	/**
 	 * The progress monitor associated with the clone operation. By default,
 	 * this is set to <code>NullProgressMonitor</code>
 	 *
@@ -452,7 +485,9 @@
 					addSubmodule(proj.getUrl(),
 							proj.getPath(),
 							proj.getRevision(),
-							proj.getCopyFiles());
+							proj.getCopyFiles(),
+							proj.getGroups(),
+							proj.getRecommendShallow());
 				}
 			} catch (GitAPIException | IOException e) {
 				throw new ManifestErrorException(e);
@@ -472,6 +507,7 @@
 			ObjectInserter inserter = repo.newObjectInserter();
 			try (RevWalk rw = new RevWalk(repo)) {
 				Config cfg = new Config();
+				StringBuilder attributes = new StringBuilder();
 				for (RepoProject proj : bareProjects) {
 					String name = proj.getPath();
 					String nameUri = proj.getName();
@@ -492,6 +528,27 @@
 							cfg.setString("submodule", name, "branch", //$NON-NLS-1$ //$NON-NLS-2$
 									proj.getRevision());
 						}
+
+						if (recordShallowSubmodules && proj.getRecommendShallow() != null) {
+							// The shallow recommendation is losing information.
+							// As the repo manifests stores the recommended
+							// depth in the 'clone-depth' field, while
+							// git core only uses a binary 'shallow = true/false'
+							// hint, we'll map any depth to 'shallow = true'
+							cfg.setBoolean("submodule", name, "shallow", //$NON-NLS-1$ //$NON-NLS-2$
+									true);
+						}
+					}
+					if (recordSubmoduleLabels) {
+						StringBuilder rec = new StringBuilder();
+						rec.append("/"); //$NON-NLS-1$
+						rec.append(name);
+						for (String group : proj.getGroups()) {
+							rec.append(" "); //$NON-NLS-1$
+							rec.append(group);
+						}
+						rec.append("\n"); //$NON-NLS-1$
+						attributes.append(rec.toString());
 					}
 					cfg.setString("submodule", name, "path", name); //$NON-NLS-1$ //$NON-NLS-2$
 					cfg.setString("submodule", name, "url", nameUri); //$NON-NLS-1$ //$NON-NLS-2$
@@ -522,6 +579,16 @@
 				dcEntry.setFileMode(FileMode.REGULAR_FILE);
 				builder.add(dcEntry);
 
+				if (recordSubmoduleLabels) {
+					// create a new DirCacheEntry for .gitattributes file.
+					final DirCacheEntry dcEntryAttr = new DirCacheEntry(Constants.DOT_GIT_ATTRIBUTES);
+					ObjectId attrId = inserter.insert(Constants.OBJ_BLOB,
+							attributes.toString().getBytes(Constants.CHARACTER_ENCODING));
+					dcEntryAttr.setObjectId(attrId);
+					dcEntryAttr.setFileMode(FileMode.REGULAR_FILE);
+					builder.add(dcEntryAttr);
+				}
+
 				builder.finish();
 				ObjectId treeId = index.writeTree(inserter);
 
@@ -575,9 +642,10 @@
 	}
 
 	private void addSubmodule(String url, String name, String revision,
-			List<CopyFile> copyfiles) throws GitAPIException, IOException {
+			List<CopyFile> copyfiles, Set<String> groups, String recommendShallow)
+			throws GitAPIException, IOException {
 		if (repo.isBare()) {
-			RepoProject proj = new RepoProject(url, name, revision, null, null);
+			RepoProject proj = new RepoProject(url, name, revision, null, groups, recommendShallow);
 			proj.addCopyFiles(copyfiles);
 			bareProjects.add(proj);
 		} else {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
index f6d1209..d29f6c0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
@@ -70,6 +70,7 @@
 	private final String remote;
 	private final Set<String> groups;
 	private final List<CopyFile> copyfiles;
+	private String recommendShallow;
 	private String url;
 	private String defaultRevision;
 
@@ -134,10 +135,14 @@
 	 * @param remote
 	 *            name of the remote definition
 	 * @param groups
-	 *            comma separated group list
+	 *            set of groups
+	 * @param recommendShallow
+	 *            recommendation for shallowness
+	 * @since 4.4
 	 */
 	public RepoProject(String name, String path, String revision,
-			String remote, String groups) {
+			String remote, Set<String> groups,
+			String recommendShallow) {
 		if (name == null) {
 			throw new NullPointerException();
 		}
@@ -148,13 +153,31 @@
 			this.path = name;
 		this.revision = revision;
 		this.remote = remote;
-		this.groups = new HashSet<String>();
-		if (groups != null && groups.length() > 0)
-			this.groups.addAll(Arrays.asList(groups.split(","))); //$NON-NLS-1$
+		this.groups = groups;
+		this.recommendShallow = recommendShallow;
 		copyfiles = new ArrayList<CopyFile>();
 	}
 
 	/**
+	 * @param name
+	 *            the relative path to the {@code remote}
+	 * @param path
+	 *            the relative path to the super project
+	 * @param revision
+	 *            a SHA-1 or branch name or tag name
+	 * @param remote
+	 *            name of the remote definition
+	 * @param groups
+	 *            comma separated group list
+	 */
+	public RepoProject(String name, String path, String revision,
+			String remote, String groups) {
+		this(name, path, revision, remote, new HashSet<String>(), null);
+		if (groups != null && groups.length() > 0)
+			this.setGroups(groups);
+	}
+
+	/**
 	 * Set the url of the sub repo.
 	 *
 	 * @param url
@@ -166,6 +189,20 @@
 	}
 
 	/**
+	 * Set the url of the sub repo.
+	 *
+	 * @param groups
+	 *            comma separated group list
+	 * @return this for chaining.
+	 * @since 4.4
+	 */
+	public RepoProject setGroups(String groups) {
+		this.groups.clear();
+		this.groups.addAll(Arrays.asList(groups.split(","))); //$NON-NLS-1$
+		return this;
+	}
+
+	/**
 	 * Set the default revision for the sub repo.
 	 *
 	 * @param defaultRevision
@@ -241,6 +278,37 @@
 	}
 
 	/**
+	 * Return the set of groups.
+	 *
+	 * @return a Set of groups.
+	 * @since 4.4
+	 */
+	public Set<String> getGroups() {
+		return groups;
+	}
+
+	/**
+	 * Return the recommendation for shallowness.
+	 *
+	 * @return the String of "clone-depth"
+	 * @since 4.4
+	 */
+	public String getRecommendShallow() {
+		return recommendShallow;
+	}
+
+	/**
+	 * Sets the recommendation for shallowness.
+	 *
+	 * @param recommendShallow
+	 *            recommendation for shallowness
+	 * @since 4.4
+	 */
+	public void setRecommendShallow(String recommendShallow) {
+		this.recommendShallow = recommendShallow;
+	}
+
+	/**
 	 * Add a copy file configuration.
 	 *
 	 * @param copyfile
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index 7740a2b..b7ef085 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -80,6 +80,7 @@
 	/***/ public String atLeastOnePatternIsRequired;
 	/***/ public String atLeastTwoFiltersNeeded;
 	/***/ public String atomicPushNotSupported;
+	/***/ public String atomicRefUpdatesNotSupported;
 	/***/ public String authenticationNotSupported;
 	/***/ public String badBase64InputCharacterAt;
 	/***/ public String badEntryDelimiter;
@@ -244,6 +245,7 @@
 	/***/ public String corruptObjectTruncatedInObjectId;
 	/***/ public String corruptObjectZeroId;
 	/***/ public String corruptPack;
+	/***/ public String corruptUseCnt;
 	/***/ public String couldNotCheckOutBecauseOfConflicts;
 	/***/ public String couldNotDeleteLockFileShouldNotHappen;
 	/***/ public String couldNotDeleteTemporaryIndexFileShouldNotHappen;
@@ -372,6 +374,8 @@
 	/***/ public String indexSignatureIsInvalid;
 	/***/ public String indexWriteException;
 	/***/ public String initFailedBareRepoDifferentDirs;
+	/***/ public String initFailedDirIsNoDirectory;
+	/***/ public String initFailedGitDirIsNoDirectory;
 	/***/ public String initFailedNonBareRepoSameDirs;
 	/***/ public String inMemoryBufferLimitExceeded;
 	/***/ public String inputDidntMatchLength;
@@ -415,6 +419,8 @@
 	/***/ public String invalidStageForPath;
 	/***/ public String invalidTagOption;
 	/***/ public String invalidTimeout;
+	/***/ public String invalidTimeUnitValue2;
+	/***/ public String invalidTimeUnitValue3;
 	/***/ public String invalidURL;
 	/***/ public String invalidWildcards;
 	/***/ public String invalidRefSpec;
@@ -651,6 +657,7 @@
 	/***/ public String transactionAborted;
 	/***/ public String theFactoryMustNotBeNull;
 	/***/ public String timerAlreadyTerminated;
+	/***/ public String tooManyIncludeRecursions;
 	/***/ public String topologicalSortRequired;
 	/***/ public String transportExceptionBadRef;
 	/***/ public String transportExceptionEmptyRef;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
index 33be3b1..dc91a70 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
@@ -241,7 +241,12 @@
 		if (!addl.isEmpty()) {
 			List<Ref> all = new ArrayList<>(refs.size() + addl.size());
 			all.addAll(refs);
-			all.addAll(addl);
+			// add additional refs which start with refs/
+			for (Ref r : addl) {
+				if (r.getName().startsWith(Constants.R_REFS)) {
+					all.add(r);
+				}
+			}
 			return all;
 		}
 		return refs;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
index e5ae980..f5673e8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
@@ -601,6 +601,11 @@
 		}
 
 		@Override
+		public ObjectInserter getCreatedFromInserter() {
+			return DfsInserter.this;
+		}
+
+		@Override
 		public void close() {
 			ctx.close();
 		}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
index 96f1d54..4eabb03 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
@@ -1189,7 +1189,7 @@
 		}
 	}
 
-	private boolean isCorrupt(long offset) {
+	boolean isCorrupt(long offset) {
 		LongList list = corruptObjects;
 		if (list == null)
 			return false;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
index 1665c2c..66421e2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
@@ -476,7 +476,7 @@
 		PackIndex idx = pack.getPackIndex(this);
 		for (ObjectToPack otp : objects) {
 			long p = idx.findOffset(otp);
-			if (0 < p) {
+			if (0 < p && !pack.isCorrupt(p)) {
 				otp.setOffset(p);
 				tmp.add((DfsObjectToPack) otp);
 			}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java
index b312835..de18ead 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java
@@ -252,11 +252,20 @@
 		}
 	}
 
-	private class MemRefDatabase extends DfsRefDatabase {
+	/**
+	 * A ref database storing all refs in-memory.
+	 * <p>
+	 * This class is protected (and not private) to facilitate testing using
+	 * subclasses of InMemoryRepository.
+	 */
+    protected class MemRefDatabase extends DfsRefDatabase {
 		private final ConcurrentMap<String, Ref> refs = new ConcurrentHashMap<String, Ref>();
 		private final ReadWriteLock lock = new ReentrantReadWriteLock(true /* fair */);
 
-		MemRefDatabase() {
+		/**
+		 * Initialize a new in-memory ref database.
+		 */
+		protected MemRefDatabase() {
 			super(InMemoryRepository.this);
 		}
 
@@ -271,7 +280,7 @@
 				@Override
 				public void execute(RevWalk walk, ProgressMonitor monitor)
 						throws IOException {
-					if (performsAtomicTransactions()) {
+					if (performsAtomicTransactions() && isAtomic()) {
 						try {
 							lock.writeLock().lock();
 							batch(getCommands());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
index b02efed..53fd37e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
@@ -491,7 +491,7 @@
 	 * @throws IOException the ref could not be accessed.
 	 */
 	public ReflogReader getReflogReader(String refName) throws IOException {
-		Ref ref = getRef(refName);
+		Ref ref = findRef(refName);
 		if (ref != null)
 			return new ReflogReaderImpl(this, ref.getName());
 		return null;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
index 9cdb753..c998ebe 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
@@ -655,8 +655,12 @@
 	}
 
 	/**
-	 * Returns a collection of all refs and additional refs (e.g. FETCH_HEAD,
-	 * MERGE_HEAD, ...)
+	 * Returns a collection of all refs and additional refs.
+	 *
+	 * Additional refs which don't start with "refs/" are not returned because
+	 * they should not save objects from being garbage collected. Examples for
+	 * such references are ORIG_HEAD, MERGE_HEAD, FETCH_HEAD and
+	 * CHERRY_PICK_HEAD.
 	 *
 	 * @return a collection of refs pointing to live objects.
 	 * @throws IOException
@@ -668,7 +672,12 @@
 		if (!addl.isEmpty()) {
 			List<Ref> all = new ArrayList<>(refs.size() + addl.size());
 			all.addAll(refs);
-			all.addAll(addl);
+			// add additional refs which start with refs/
+			for (Ref r : addl) {
+				if (r.getName().startsWith(Constants.R_REFS)) {
+					all.add(r);
+				}
+			}
 			return all;
 		}
 		return refs;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
index fb41172..9820e0e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
@@ -136,7 +136,7 @@
 
 	@Override
 	public ObjectReader newReader() {
-		return new WindowCursor(db);
+		return new WindowCursor(db, this);
 	}
 
 	@Override
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
index 4bb2982..e5ca736 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
@@ -688,7 +688,7 @@
 							newLoose = curLoose.remove(idx);
 						} while (!looseRefs.compareAndSet(curLoose, newLoose));
 						int levels = levelsIn(refName) - 2;
-						delete(fileFor(refName), levels);
+						delete(refFile, levels, rLck);
 					}
 				} finally {
 					rLck.unlock();
@@ -1062,13 +1062,24 @@
 	}
 
 	static void delete(final File file, final int depth) throws IOException {
-		if (!file.delete() && file.isFile())
-			throw new IOException(MessageFormat.format(JGitText.get().fileCannotBeDeleted, file));
+		delete(file, depth, null);
+	}
 
+	private static void delete(final File file, final int depth, LockFile rLck)
+			throws IOException {
+		if (!file.delete() && file.isFile()) {
+			throw new IOException(MessageFormat.format(
+					JGitText.get().fileCannotBeDeleted, file));
+		}
+
+		if (rLck != null) {
+			rLck.unlock(); // otherwise cannot delete dir below
+		}
 		File dir = file.getParentFile();
 		for (int i = 0; i < depth; ++i) {
-			if (!dir.delete())
+			if (!dir.delete()) {
 				break; // ignore problem here
+			}
 			dir = dir.getParentFile();
 		}
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
index a555e10..a2c0561 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
@@ -53,6 +53,7 @@
 import java.util.zip.DataFormatException;
 import java.util.zip.Inflater;
 
+import org.eclipse.jgit.annotations.Nullable;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.errors.StoredObjectRepresentationNotAvailableException;
@@ -69,6 +70,7 @@
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.InflaterCache;
 import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.lib.ObjectReader;
 import org.eclipse.jgit.lib.ProgressMonitor;
@@ -84,10 +86,20 @@
 
 	private DeltaBaseCache baseCache;
 
+	@Nullable
+	private final ObjectInserter createdFromInserter;
+
 	final FileObjectDatabase db;
 
 	WindowCursor(FileObjectDatabase db) {
 		this.db = db;
+		this.createdFromInserter = null;
+	}
+
+	WindowCursor(FileObjectDatabase db,
+			@Nullable ObjectDirectoryInserter createdFromInserter) {
+		this.db = db;
+		this.createdFromInserter = createdFromInserter;
 	}
 
 	DeltaBaseCache getDeltaBaseCache() {
@@ -329,6 +341,12 @@
 		return WindowCache.getStreamFileThreshold();
 	}
 
+	@Override
+	@Nullable
+	public ObjectInserter getCreatedFromInserter() {
+		return createdFromInserter;
+	}
+
 	/** Release the current window cursor. */
 	@Override
 	public void close() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java
index a55a9f5..1cccd79 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java
@@ -98,8 +98,12 @@
 				}
 				if (c.getType() == UPDATE_NONFASTFORWARD) {
 					c.setResult(REJECTED_NONFASTFORWARD);
-					ReceiveCommand.abort(getCommands());
-					return;
+					if (isAtomic()) {
+						ReceiveCommand.abort(getCommands());
+						return;
+					} else {
+						continue;
+					}
 				}
 			}
 			todo.add(new Command(rw, c));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
index d7e9308..35cadd3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
@@ -89,6 +89,9 @@
 	/** Push certificate associated with this update. */
 	private PushCertificate pushCert;
 
+	/** Whether updates should be atomic. */
+	private boolean atomic;
+
 	/**
 	 * Initialize a new batch update.
 	 *
@@ -98,6 +101,7 @@
 	protected BatchRefUpdate(RefDatabase refdb) {
 		this.refdb = refdb;
 		this.commands = new ArrayList<ReceiveCommand>();
+		this.atomic = refdb.performsAtomicTransactions();
 	}
 
 	/**
@@ -200,6 +204,36 @@
 	}
 
 	/**
+	 * Request that all updates in this batch be performed atomically.
+	 * <p>
+	 * When atomic updates are used, either all commands apply successfully, or
+	 * none do. Commands that might have otherwise succeeded are rejected with
+	 * {@code REJECTED_OTHER_REASON}.
+	 * <p>
+	 * This method only works if the underlying ref database supports atomic
+	 * transactions, i.e. {@link RefDatabase#performsAtomicTransactions()} returns
+	 * true. Calling this method with true if the underlying ref database does not
+	 * support atomic transactions will cause all commands to fail with {@code
+	 * REJECTED_OTHER_REASON}.
+	 *
+	 * @param atomic whether updates should be atomic.
+	 * @return {@code this}
+	 * @since 4.4
+	 */
+	public BatchRefUpdate setAtomic(boolean atomic) {
+		this.atomic = atomic;
+		return this;
+	}
+
+	/**
+	 * @return atomic whether updates should be atomic.
+	 * @since 4.4
+	 */
+	public boolean isAtomic() {
+		return atomic;
+	}
+
+	/**
 	 * Set a push certificate associated with this update.
 	 * <p>
 	 * This usually includes commands to update the refs in this batch, but is not
@@ -271,6 +305,10 @@
 	 * <p>
 	 * The default implementation of this method performs a sequential reference
 	 * update over each reference.
+	 * <p>
+	 * Implementations must respect the atomicity requirements of the underlying
+	 * database as described in {@link #setAtomic(boolean)} and {@link
+	 * RefDatabase#performsAtomicTransactions()}.
 	 *
 	 * @param walk
 	 *            a RevWalk to parse tags in case the storage system wants to
@@ -284,6 +322,17 @@
 	 */
 	public void execute(RevWalk walk, ProgressMonitor monitor)
 			throws IOException {
+
+		if (atomic && !refdb.performsAtomicTransactions()) {
+			for (ReceiveCommand c : commands) {
+				if (c.getResult() == NOT_ATTEMPTED) {
+					c.setResult(REJECTED_OTHER_REASON,
+							JGitText.get().atomicRefUpdatesNotSupported);
+				}
+			}
+			return;
+		}
+
 		monitor.beginTask(JGitText.get().updatingReferences, commands.size());
 		List<ReceiveCommand> commands2 = new ArrayList<ReceiveCommand>(
 				commands.size());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java
index 39856c0..a3859ab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java
@@ -43,55 +43,11 @@
 
 package org.eclipse.jgit.lib;
 
-import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.TimeUnit;
 
 /** ProgressMonitor that batches update events. */
 public abstract class BatchingProgressMonitor implements ProgressMonitor {
-	private static final ScheduledThreadPoolExecutor alarmQueue;
-
-	static final Object alarmQueueKiller;
-
-	static {
-		// To support garbage collection, start our thread but
-		// swap out the thread factory. When our class is GC'd
-		// the alarmQueueKiller will finalize and ask the executor
-		// to shutdown, ending the worker.
-		//
-		int threads = 1;
-		alarmQueue = new ScheduledThreadPoolExecutor(threads,
-				new ThreadFactory() {
-					private final ThreadFactory baseFactory = Executors
-							.defaultThreadFactory();
-
-					public Thread newThread(Runnable taskBody) {
-						Thread thr = baseFactory.newThread(taskBody);
-						thr.setName("JGit-AlarmQueue"); //$NON-NLS-1$
-						thr.setDaemon(true);
-						return thr;
-					}
-				});
-		alarmQueue.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
-		alarmQueue.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
-		alarmQueue.prestartAllCoreThreads();
-
-		// Now that the threads are running, its critical to swap out
-		// our own thread factory for one that isn't in the ClassLoader.
-		// This allows the class to GC.
-		//
-		alarmQueue.setThreadFactory(Executors.defaultThreadFactory());
-
-		alarmQueueKiller = new Object() {
-			@Override
-			protected void finalize() {
-				alarmQueue.shutdownNow();
-			}
-		};
-	}
-
 	private long delayStartTime;
 
 	private TimeUnit delayStartUnit = TimeUnit.MILLISECONDS;
@@ -219,7 +175,7 @@
 
 		void delay(long time, TimeUnit unit) {
 			display = false;
-			timerFuture = alarmQueue.schedule(this, time, unit);
+			timerFuture = WorkQueue.getExecutor().schedule(this, time, unit);
 		}
 
 		public void run() {
@@ -254,7 +210,8 @@
 
 		private void restartTimer() {
 			display = false;
-			timerFuture = alarmQueue.schedule(this, 1, TimeUnit.SECONDS);
+			timerFuture = WorkQueue.getExecutor().schedule(this, 1,
+					TimeUnit.SECONDS);
 		}
 
 		void end(BatchingProgressMonitor pm) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java
index 7d52991..8958ce7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java
@@ -80,8 +80,7 @@
 			throws ConfigInvalidException {
 		super(base);
 		final String decoded;
-		if (blob.length >= 3 && blob[0] == (byte) 0xEF
-				&& blob[1] == (byte) 0xBB && blob[2] == (byte) 0xBF) {
+		if (isUtf8(blob)) {
 			decoded = RawParseUtils.decode(RawParseUtils.UTF8_CHARSET,
 					blob, 3, blob.length);
 		} else {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java
index 1525e5b..d4fccf9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java
@@ -79,11 +79,11 @@
 		if (trackingBranch == null)
 			return null;
 
-		Ref tracking = repository.getRef(trackingBranch);
+		Ref tracking = repository.exactRef(trackingBranch);
 		if (tracking == null)
 			return null;
 
-		Ref local = repository.getRef(fullBranchName);
+		Ref local = repository.exactRef(fullBranchName);
 		if (local == null)
 			return null;
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
index e48386d..1e1d147 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
@@ -51,12 +51,18 @@
 
 package org.eclipse.jgit.lib;
 
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.events.ConfigChangedEvent;
@@ -64,6 +70,8 @@
 import org.eclipse.jgit.events.ListenerHandle;
 import org.eclipse.jgit.events.ListenerList;
 import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.util.IO;
+import org.eclipse.jgit.util.RawParseUtils;
 import org.eclipse.jgit.util.StringUtils;
 
 
@@ -75,6 +83,7 @@
 	private static final long KiB = 1024;
 	private static final long MiB = 1024 * KiB;
 	private static final long GiB = 1024 * MiB;
+	private static final int MAX_DEPTH = 10;
 
 	/** the change listeners */
 	private final ListenerList listeners = new ListenerList();
@@ -485,6 +494,123 @@
 	}
 
 	/**
+	 * Parse a numerical time unit, such as "1 minute", from the configuration.
+	 *
+	 * @param section
+	 *            section the key is in.
+	 * @param subsection
+	 *            subsection the key is in, or null if not in a subsection.
+	 * @param name
+	 *            the key name.
+	 * @param defaultValue
+	 *            default value to return if no value was present.
+	 * @param wantUnit
+	 *            the units of {@code defaultValue} and the return value, as
+	 *            well as the units to assume if the value does not contain an
+	 *            indication of the units.
+	 * @return the value, or {@code defaultValue} if not set, expressed in
+	 *         {@code units}.
+	 * @since 4.4
+	 */
+	public long getTimeUnit(String section, String subsection, String name,
+			long defaultValue, TimeUnit wantUnit) {
+		String valueString = getString(section, subsection, name);
+
+		if (valueString == null) {
+			return defaultValue;
+		}
+
+		String s = valueString.trim();
+		if (s.length() == 0) {
+			return defaultValue;
+		}
+
+		if (s.startsWith("-")/* negative */) { //$NON-NLS-1$
+			throw notTimeUnit(section, subsection, name, valueString);
+		}
+
+		Matcher m = Pattern.compile("^(0|[1-9][0-9]*)\\s*(.*)$") //$NON-NLS-1$
+				.matcher(valueString);
+		if (!m.matches()) {
+			return defaultValue;
+		}
+
+		String digits = m.group(1);
+		String unitName = m.group(2).trim();
+
+		TimeUnit inputUnit;
+		int inputMul;
+
+		if (unitName.isEmpty()) {
+			inputUnit = wantUnit;
+			inputMul = 1;
+
+		} else if (match(unitName, "ms", "milliseconds")) { //$NON-NLS-1$ //$NON-NLS-2$
+			inputUnit = TimeUnit.MILLISECONDS;
+			inputMul = 1;
+
+		} else if (match(unitName, "s", "sec", "second", "seconds")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+			inputUnit = TimeUnit.SECONDS;
+			inputMul = 1;
+
+		} else if (match(unitName, "m", "min", "minute", "minutes")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+			inputUnit = TimeUnit.MINUTES;
+			inputMul = 1;
+
+		} else if (match(unitName, "h", "hr", "hour", "hours")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+			inputUnit = TimeUnit.HOURS;
+			inputMul = 1;
+
+		} else if (match(unitName, "d", "day", "days")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			inputUnit = TimeUnit.DAYS;
+			inputMul = 1;
+
+		} else if (match(unitName, "w", "week", "weeks")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			inputUnit = TimeUnit.DAYS;
+			inputMul = 7;
+
+		} else if (match(unitName, "mon", "month", "months")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			inputUnit = TimeUnit.DAYS;
+			inputMul = 30;
+
+		} else if (match(unitName, "y", "year", "years")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			inputUnit = TimeUnit.DAYS;
+			inputMul = 365;
+
+		} else {
+			throw notTimeUnit(section, subsection, name, valueString);
+		}
+
+		try {
+			return wantUnit.convert(Long.parseLong(digits) * inputMul,
+					inputUnit);
+		} catch (NumberFormatException nfe) {
+			throw notTimeUnit(section, subsection, unitName, valueString);
+		}
+	}
+
+	private static boolean match(final String a, final String... cases) {
+		for (final String b : cases) {
+			if (b != null && b.equalsIgnoreCase(a)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private IllegalArgumentException notTimeUnit(String section,
+			String subsection, String name, String valueString) {
+		if (subsection != null) {
+			return new IllegalArgumentException(
+					MessageFormat.format(JGitText.get().invalidTimeUnitValue3,
+							section, subsection, name, valueString));
+		}
+		return new IllegalArgumentException(
+				MessageFormat.format(JGitText.get().invalidTimeUnitValue2,
+						section, name, valueString));
+	}
+
+	/**
 	 * @param section
 	 *            section to search for.
 	 * @return set of all subsections of specified section within this
@@ -633,12 +759,13 @@
 	private String getRawString(final String section, final String subsection,
 			final String name) {
 		String[] lst = getRawStringList(section, subsection, name);
-		if (lst != null)
-			return lst[0];
-		else if (baseConfig != null)
+		if (lst != null) {
+			return lst[lst.length - 1];
+		} else if (baseConfig != null) {
 			return baseConfig.getRawString(section, subsection, name);
-		else
+		} else {
 			return null;
+		}
 	}
 
 	private String[] getRawStringList(String section, String subsection,
@@ -855,7 +982,8 @@
 	 *
 	 * <pre>
 	 * [section &quot;subsection&quot;]
-	 *         name = value
+	 *         name = value1
+	 *         name = value2
 	 * </pre>
 	 *
 	 * @param section
@@ -1025,6 +1153,15 @@
 	 *             made to {@code this}.
 	 */
 	public void fromText(final String text) throws ConfigInvalidException {
+		state.set(newState(fromTextRecurse(text, 1)));
+	}
+
+	private List<ConfigLine> fromTextRecurse(final String text, int depth)
+			throws ConfigInvalidException {
+		if (depth > MAX_DEPTH) {
+			throw new ConfigInvalidException(
+					JGitText.get().tooManyIncludeRecursions);
+		}
 		final List<ConfigLine> newEntries = new ArrayList<ConfigLine>();
 		final StringReader in = new StringReader(text);
 		ConfigLine last = null;
@@ -1083,11 +1220,44 @@
 				} else
 					e.value = readValue(in, false, -1);
 
+				if (e.section.equals("include")) { //$NON-NLS-1$
+					addIncludedConfig(newEntries, e, depth);
+				}
 			} else
 				throw new ConfigInvalidException(JGitText.get().invalidLineInConfigFile);
 		}
 
-		state.set(newState(newEntries));
+		return newEntries;
+	}
+
+	private void addIncludedConfig(final List<ConfigLine> newEntries,
+			ConfigLine line, int depth) throws ConfigInvalidException {
+		if (!line.name.equals("path") || //$NON-NLS-1$
+				line.value == null || line.value.equals(MAGIC_EMPTY_VALUE)) {
+			throw new ConfigInvalidException(
+					JGitText.get().invalidLineInConfigFile);
+		}
+		File path = new File(line.value);
+		try {
+			byte[] bytes = IO.readFully(path);
+			String decoded;
+			if (isUtf8(bytes)) {
+				decoded = RawParseUtils.decode(RawParseUtils.UTF8_CHARSET,
+						bytes, 3, bytes.length);
+			} else {
+				decoded = RawParseUtils.decode(bytes);
+			}
+			newEntries.addAll(fromTextRecurse(decoded, depth + 1));
+		} catch (FileNotFoundException fnfe) {
+			if (path.exists()) {
+				throw new ConfigInvalidException(MessageFormat
+						.format(JGitText.get().cannotReadFile, path), fnfe);
+			}
+		} catch (IOException ioe) {
+			throw new ConfigInvalidException(
+					MessageFormat.format(JGitText.get().cannotReadFile, path),
+					ioe);
+		}
 	}
 
 	private ConfigSnapshot newState() {
@@ -1107,6 +1277,19 @@
 		state.set(newState());
 	}
 
+	/**
+	 * Check if bytes should be treated as UTF-8 or not.
+	 *
+	 * @param bytes
+	 *            the bytes to check encoding for.
+	 * @return true if bytes should be treated as UTF-8, false otherwise.
+	 * @since 4.4
+	 */
+	protected boolean isUtf8(final byte[] bytes) {
+		return bytes.length >= 3 && bytes[0] == (byte) 0xEF
+				&& bytes[1] == (byte) 0xBB && bytes[2] == (byte) 0xBF;
+	}
+
 	private static String readSectionName(final StringReader in)
 			throws ConfigInvalidException {
 		final StringBuilder name = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
index d9da65f..4c51279 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
@@ -143,7 +143,18 @@
 		}
 
 		public ObjectReader newReader() {
-			return delegate().newReader();
+			final ObjectReader dr = delegate().newReader();
+			return new ObjectReader.Filter() {
+				@Override
+				protected ObjectReader delegate() {
+					return dr;
+				}
+
+				@Override
+				public ObjectInserter getCreatedFromInserter() {
+					return ObjectInserter.Filter.this;
+				}
+			};
 		}
 
 		public void flush() throws IOException {
@@ -398,6 +409,9 @@
 	 * visible to the repository. The returned reader should only be used from
 	 * the same thread as the inserter. Objects written by this inserter may not
 	 * be visible to {@code this.newReader().newReader()}.
+	 * <p>
+	 * The returned reader should return this inserter instance from {@link
+	 * ObjectReader#getCreatedFromInserter()}.
 	 *
 	 * @since 3.5
 	 * @return reader for any object, including an object recently inserted by
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
index 77cfb03..b23145d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
@@ -50,6 +50,7 @@
 import java.util.List;
 import java.util.Set;
 
+import org.eclipse.jgit.annotations.Nullable;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.internal.storage.pack.ObjectReuseAsIs;
@@ -422,6 +423,17 @@
 	}
 
 	/**
+	 * @return the {@link ObjectInserter} from which this reader was created
+	 *         using {@code inserter.newReader()}, or null if this reader was not
+	 *         created from an inserter.
+	 * @since 4.4
+	 */
+	@Nullable
+	public ObjectInserter getCreatedFromInserter() {
+		return null;
+	}
+
+	/**
 	 * Release any resources used by this reader.
 	 * <p>
 	 * A reader that has been released can be used again, but may need to be
@@ -431,4 +443,108 @@
 	 */
 	@Override
 	public abstract void close();
+
+	/**
+	 * Wraps a delegate ObjectReader.
+	 *
+	 * @since 4.4
+	 */
+	public static abstract class Filter extends ObjectReader {
+		/**
+		 * @return delegate ObjectReader to handle all processing.
+		 * @since 4.4
+		 */
+		protected abstract ObjectReader delegate();
+
+		@Override
+		public ObjectReader newReader() {
+			return delegate().newReader();
+		}
+
+		@Override
+		public AbbreviatedObjectId abbreviate(AnyObjectId objectId)
+				throws IOException {
+			return delegate().abbreviate(objectId);
+		}
+
+		@Override
+		public AbbreviatedObjectId abbreviate(AnyObjectId objectId, int len)
+				throws IOException {
+			return delegate().abbreviate(objectId, len);
+		}
+
+		@Override
+		public Collection<ObjectId> resolve(AbbreviatedObjectId id)
+				throws IOException {
+			return delegate().resolve(id);
+		}
+
+		@Override
+		public boolean has(AnyObjectId objectId) throws IOException {
+			return delegate().has(objectId);
+		}
+
+		@Override
+		public boolean has(AnyObjectId objectId, int typeHint) throws IOException {
+			return delegate().has(objectId, typeHint);
+		}
+
+		@Override
+		public ObjectLoader open(AnyObjectId objectId)
+				throws MissingObjectException, IOException {
+			return delegate().open(objectId);
+		}
+
+		@Override
+		public ObjectLoader open(AnyObjectId objectId, int typeHint)
+				throws MissingObjectException, IncorrectObjectTypeException,
+				IOException {
+			return delegate().open(objectId, typeHint);
+		}
+
+		@Override
+		public Set<ObjectId> getShallowCommits() throws IOException {
+			return delegate().getShallowCommits();
+		}
+
+		@Override
+		public <T extends ObjectId> AsyncObjectLoaderQueue<T> open(
+				Iterable<T> objectIds, boolean reportMissing) {
+			return delegate().open(objectIds, reportMissing);
+		}
+
+		@Override
+		public long getObjectSize(AnyObjectId objectId, int typeHint)
+				throws MissingObjectException, IncorrectObjectTypeException,
+				IOException {
+			return delegate().getObjectSize(objectId, typeHint);
+		}
+
+		@Override
+		public <T extends ObjectId> AsyncObjectSizeQueue<T> getObjectSize(
+				Iterable<T> objectIds, boolean reportMissing) {
+			return delegate().getObjectSize(objectIds, reportMissing);
+		}
+
+		@Override
+		public void setAvoidUnreachableObjects(boolean avoid) {
+			delegate().setAvoidUnreachableObjects(avoid);
+		}
+
+		@Override
+		public BitmapIndex getBitmapIndex() throws IOException {
+			return delegate().getBitmapIndex();
+		}
+
+		@Override
+		@Nullable
+		public ObjectInserter getCreatedFromInserter() {
+			return delegate().getCreatedFromInserter();
+		}
+
+		@Override
+		public void close() {
+			delegate().close();
+		}
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java
index 2ecc60c..e08a985 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java
@@ -111,6 +111,44 @@
 		r.append(offsetMins);
 	}
 
+	/**
+	 * Sanitize the given string for use in an identity and append to output.
+	 * <p>
+	 * Trims whitespace from both ends and special characters {@code \n < >} that
+	 * interfere with parsing; appends all other characters to the output.
+	 * Analogous to the C git function {@code strbuf_addstr_without_crud}.
+	 *
+	 * @param r
+	 *            string builder to append to.
+	 * @param str
+	 *            input string.
+	 * @since 4.4
+	 */
+	public static void appendSanitized(StringBuilder r, String str) {
+		// Trim any whitespace less than \u0020 as in String#trim().
+		int i = 0;
+		while (i < str.length() && str.charAt(i) <= ' ') {
+			i++;
+		}
+		int end = str.length();
+		while (end > i && str.charAt(end - 1) <= ' ') {
+			end--;
+		}
+
+		for (; i < end; i++) {
+			char c = str.charAt(i);
+			switch (c) {
+				case '\n':
+				case '<':
+				case '>':
+					continue;
+				default:
+					r.append(c);
+					break;
+			}
+		}
+	}
+
 	private final String name;
 
 	private final String emailAddress;
@@ -217,7 +255,12 @@
 	}
 
 	/**
-	 * Construct a {@link PersonIdent}
+	 * Construct a {@link PersonIdent}.
+	 * <p>
+	 * Whitespace in the name and email is preserved for the lifetime of this
+	 * object, but are trimmed by {@link #toExternalString()}. This means that
+	 * parsing the result of {@link #toExternalString()} may not return an
+	 * equivalent instance.
 	 *
 	 * @param aName
 	 * @param aEmailAddress
@@ -276,6 +319,9 @@
 		return tzOffset;
 	}
 
+	/**
+	 * Hashcode is based only on the email address and timestamp.
+	 */
 	public int hashCode() {
 		int hc = getEmailAddress().hashCode();
 		hc *= 31;
@@ -300,9 +346,9 @@
 	 */
 	public String toExternalString() {
 		final StringBuilder r = new StringBuilder();
-		r.append(getName().trim());
+		appendSanitized(r, getName());
 		r.append(" <"); //$NON-NLS-1$
-		r.append(getEmailAddress().trim());
+		appendSanitized(r, getEmailAddress());
 		r.append("> "); //$NON-NLS-1$
 		r.append(when / 1000);
 		r.append(' ');
@@ -328,3 +374,4 @@
 		return r.toString();
 	}
 }
+
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
index c0c3862..517c8aa 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
@@ -207,8 +207,25 @@
 	}
 
 	/**
-	 * @return if the database performs {@code newBatchUpdate()} as an atomic
-	 *         transaction.
+	 * Whether the database is capable of performing batch updates as atomic
+	 * transactions.
+	 * <p>
+	 * If true, by default {@link BatchRefUpdate} instances will perform updates
+	 * atomically, meaning either all updates will succeed, or all updates will
+	 * fail. It is still possible to turn off this behavior on a per-batch basis
+	 * by calling {@code update.setAtomic(false)}.
+	 * <p>
+	 * If false, {@link BatchRefUpdate} instances will never perform updates
+	 * atomically, and calling {@code update.setAtomic(true)} will cause the
+	 * entire batch to fail with {@code REJECTED_OTHER_REASON}.
+	 * <p>
+	 * This definition of atomicity is stronger than what is provided by
+	 * {@link org.eclipse.jgit.transport.ReceivePack}. {@code ReceivePack} will
+	 * attempt to reject all commands if it knows in advance some commands may
+	 * fail, even if the storage layer does not support atomic transactions. Here,
+	 * atomicity applies even in the case of unforeseeable errors.
+	 *
+	 * @return whether transactions are atomic by default.
 	 * @since 3.6
 	 */
 	public boolean performsAtomicTransactions() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
index ba0dea3..7ec2499 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
@@ -63,6 +63,7 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
 
 import org.eclipse.jgit.annotations.NonNull;
 import org.eclipse.jgit.annotations.Nullable;
@@ -93,6 +94,8 @@
 import org.eclipse.jgit.util.RawParseUtils;
 import org.eclipse.jgit.util.SystemReader;
 import org.eclipse.jgit.util.io.SafeBufferedOutputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Represents a Git repository.
@@ -103,6 +106,8 @@
  * This class is thread-safe.
  */
 public abstract class Repository implements AutoCloseable {
+	private static Logger LOG = LoggerFactory.getLogger(Repository.class);
+
 	private static final ListenerList globalListeners = new ListenerList();
 
 	/** @return the global listener list observing all events in this JVM. */
@@ -113,6 +118,8 @@
 	/** Use counter */
 	final AtomicInteger useCnt = new AtomicInteger(1);
 
+	final AtomicLong closedAt = new AtomicLong();
+
 	/** Metadata directory holding the repository's critical files. */
 	private final File gitDir;
 
@@ -863,9 +870,24 @@
 
 	/** Decrement the use count, and maybe close resources. */
 	public void close() {
-		if (useCnt.decrementAndGet() == 0) {
-			doClose();
-			RepositoryCache.unregister(this);
+		int newCount = useCnt.decrementAndGet();
+		if (newCount == 0) {
+			if (RepositoryCache.isCached(this)) {
+				closedAt.set(System.currentTimeMillis());
+			} else {
+				doClose();
+			}
+		} else if (newCount == -1) {
+			// should not happen, only log when useCnt became negative to
+			// minimize number of log entries
+			LOG.warn(JGitText.get().corruptUseCnt);
+			if (LOG.isDebugEnabled()) {
+				IllegalStateException e = new IllegalStateException();
+				LOG.debug("", e); //$NON-NLS-1$
+			}
+			if (RepositoryCache.isCached(this)) {
+				closedAt.set(System.currentTimeMillis());
+			}
 		}
 	}
 
@@ -898,7 +920,7 @@
 	 * This is essentially the same as doing:
 	 *
 	 * <pre>
-	 * return getRef(Constants.HEAD).getTarget().getName()
+	 * return exactRef(Constants.HEAD).getTarget().getName()
 	 * </pre>
 	 *
 	 * Except when HEAD is detached, in which case this method returns the
@@ -912,7 +934,7 @@
 	 */
 	@Nullable
 	public String getFullBranch() throws IOException {
-		Ref head = getRef(Constants.HEAD);
+		Ref head = exactRef(Constants.HEAD);
 		if (head == null) {
 			return null;
 		}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java
index 22b5fcd..29ef084 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java
@@ -52,17 +52,26 @@
 import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
+import org.eclipse.jgit.annotations.NonNull;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.eclipse.jgit.internal.storage.file.FileRepository;
 import org.eclipse.jgit.util.FS;
 import org.eclipse.jgit.util.IO;
 import org.eclipse.jgit.util.RawParseUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /** Cache of active {@link Repository} instances. */
 public class RepositoryCache {
 	private static final RepositoryCache cache = new RepositoryCache();
 
+	private final static Logger LOG = LoggerFactory
+			.getLogger(RepositoryCache.class);
+
 	/**
 	 * Open an existing repository, reusing a cached instance if possible.
 	 * <p>
@@ -138,10 +147,10 @@
 	 * @param db
 	 *            repository to unregister.
 	 */
-	public static void close(final Repository db) {
+	public static void close(@NonNull final Repository db) {
 		if (db.getDirectory() != null) {
 			FileKey key = FileKey.exact(db.getDirectory(), db.getFS());
-			cache.unregisterAndCloseRepository(key);
+			cache.unregisterAndCloseRepository(key, db);
 		}
 	}
 
@@ -187,20 +196,69 @@
 		return cache.getKeys();
 	}
 
+	static boolean isCached(@NonNull Repository repo) {
+		File gitDir = repo.getDirectory();
+		if (gitDir == null) {
+			return false;
+		}
+		FileKey key = new FileKey(gitDir, repo.getFS());
+		Reference<Repository> repoRef = cache.cacheMap.get(key);
+		return repoRef != null && repoRef.get() == repo;
+	}
+
 	/** Unregister all repositories from the cache. */
 	public static void clear() {
 		cache.clearAll();
 	}
 
+	static void clearExpired() {
+		cache.clearAllExpired();
+	}
+
+	static void reconfigure(RepositoryCacheConfig repositoryCacheConfig) {
+		cache.configureEviction(repositoryCacheConfig);
+	}
+
 	private final ConcurrentHashMap<Key, Reference<Repository>> cacheMap;
 
 	private final Lock[] openLocks;
 
+	private ScheduledFuture<?> cleanupTask;
+
+	private volatile long expireAfter;
+
 	private RepositoryCache() {
 		cacheMap = new ConcurrentHashMap<Key, Reference<Repository>>();
 		openLocks = new Lock[4];
-		for (int i = 0; i < openLocks.length; i++)
+		for (int i = 0; i < openLocks.length; i++) {
 			openLocks[i] = new Lock();
+		}
+		configureEviction(new RepositoryCacheConfig());
+	}
+
+	private void configureEviction(
+			RepositoryCacheConfig repositoryCacheConfig) {
+		expireAfter = repositoryCacheConfig.getExpireAfter();
+		ScheduledThreadPoolExecutor scheduler = WorkQueue.getExecutor();
+		synchronized (scheduler) {
+			if (cleanupTask != null) {
+				cleanupTask.cancel(false);
+			}
+			long delay = repositoryCacheConfig.getCleanupDelay();
+			if (delay == RepositoryCacheConfig.NO_CLEANUP) {
+				return;
+			}
+			cleanupTask = scheduler.scheduleWithFixedDelay(new Runnable() {
+				@Override
+				public void run() {
+					try {
+						cache.clearAllExpired();
+					} catch (Throwable e) {
+						LOG.error(e.getMessage(), e);
+					}
+				}
+			}, delay, delay, TimeUnit.MILLISECONDS);
+		}
 	}
 
 	@SuppressWarnings("resource")
@@ -239,10 +297,20 @@
 		return oldRef != null ? oldRef.get() : null;
 	}
 
-	private void unregisterAndCloseRepository(final Key location) {
-		Repository oldDb = unregisterRepository(location);
-		if (oldDb != null) {
-			oldDb.close();
+	private boolean isExpired(Repository db) {
+		return db != null && db.useCnt.get() == 0
+			&& (System.currentTimeMillis() - db.closedAt.get() > expireAfter);
+	}
+
+	private void unregisterAndCloseRepository(final Key location,
+			Repository db) {
+		synchronized (lockFor(location)) {
+			if (isExpired(db)) {
+				Repository oldDb = unregisterRepository(location);
+				if (oldDb != null) {
+					oldDb.close();
+				}
+			}
 		}
 	}
 
@@ -250,6 +318,15 @@
 		return new ArrayList<Key>(cacheMap.keySet());
 	}
 
+	private void clearAllExpired() {
+		for (Reference<Repository> ref : cacheMap.values()) {
+			Repository db = ref.get();
+			if (isExpired(db)) {
+				RepositoryCache.close(db);
+			}
+		}
+	}
+
 	private void clearAll() {
 		for (int stage = 0; stage < 2; stage++) {
 			for (Iterator<Map.Entry<Key, Reference<Repository>>> i = cacheMap
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCacheConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCacheConfig.java
new file mode 100644
index 0000000..428dea3
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCacheConfig.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2016 Ericsson
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.eclipse.jgit.lib;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Configuration parameters for JVM-wide repository cache used by JGit.
+ *
+ * @since 4.4
+ */
+public class RepositoryCacheConfig {
+
+	/**
+	 * Set cleanupDelayMillis to this value in order to switch off time-based
+	 * cache eviction. The JVM can still expire cache entries when heap memory
+	 * runs low.
+	 */
+	public static final long NO_CLEANUP = 0;
+
+	/**
+	 * Set cleanupDelayMillis to this value in order to auto-set it to minimum
+	 * of 1/10 of expireAfterMillis and 10 minutes
+	 */
+	public static final long AUTO_CLEANUP_DELAY = -1;
+
+	private long expireAfterMillis;
+
+	private long cleanupDelayMillis;
+
+	/** Create a default configuration. */
+	public RepositoryCacheConfig() {
+		expireAfterMillis = TimeUnit.HOURS.toMillis(1);
+		cleanupDelayMillis = AUTO_CLEANUP_DELAY;
+	}
+
+	/**
+	 * @return the time an unused repository should expired and be evicted from
+	 *         the RepositoryCache in milliseconds. <b>Default is 1 hour.</b>
+	 */
+	public long getExpireAfter() {
+		return expireAfterMillis;
+	}
+
+	/**
+	 * @param expireAfterMillis
+	 *            the time an unused repository should expired and be evicted
+	 *            from the RepositoryCache in milliseconds.
+	 */
+	public void setExpireAfter(long expireAfterMillis) {
+		this.expireAfterMillis = expireAfterMillis;
+	}
+
+	/**
+	 * @return the delay between the periodic cleanup of expired repository in
+	 *         milliseconds. <b>Default is minimum of 1/10 of expireAfterMillis
+	 *         and 10 minutes</b>
+	 */
+	public long getCleanupDelay() {
+		if (cleanupDelayMillis < 0) {
+			return Math.min(expireAfterMillis / 10,
+					TimeUnit.MINUTES.toMillis(10));
+		}
+		return cleanupDelayMillis;
+	}
+
+	/**
+	 * @param cleanupDelayMillis
+	 *            the delay between the periodic cleanup of expired repository
+	 *            in milliseconds. Set it to {@link #AUTO_CLEANUP_DELAY} to
+	 *            automatically derive cleanup delay from expireAfterMillis.
+	 *            <p>
+	 *            Set it to {@link #NO_CLEANUP} in order to switch off cache
+	 *            expiration.
+	 *            <p>
+	 *            If cache expiration is switched off the JVM still can evict
+	 *            cache entries when the JVM is running low on available heap
+	 *            memory.
+	 */
+	public void setCleanupDelay(long cleanupDelayMillis) {
+		this.cleanupDelayMillis = cleanupDelayMillis;
+	}
+
+	/**
+	 * Update properties by setting fields from the configuration.
+	 * <p>
+	 * If a property is not defined in the configuration, then it is left
+	 * unmodified.
+	 *
+	 * @param config
+	 *            configuration to read properties from.
+	 * @return {@code this}.
+	 */
+	public RepositoryCacheConfig fromConfig(Config config) {
+		setExpireAfter(
+				config.getTimeUnit("core", null, "repositoryCacheExpireAfter", //$NON-NLS-1$//$NON-NLS-2$
+						getExpireAfter(), TimeUnit.MILLISECONDS));
+		setCleanupDelay(
+				config.getTimeUnit("core", null, "repositoryCacheCleanupDelay", //$NON-NLS-1$ //$NON-NLS-2$
+						AUTO_CLEANUP_DELAY, TimeUnit.MILLISECONDS));
+		return this;
+	}
+
+	/**
+	 * Install this configuration as the live settings.
+	 * <p>
+	 * The new configuration is applied immediately.
+	 */
+	public void install() {
+		RepositoryCache.reconfigure(this);
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java
new file mode 100644
index 0000000..9735d19
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008-2016, Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.lib;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+
+/**
+ * Simple work queue to run tasks in the background
+ */
+class WorkQueue {
+	private static final ScheduledThreadPoolExecutor executor;
+
+	static final Object executorKiller;
+
+	static {
+		// To support garbage collection, start our thread but
+		// swap out the thread factory. When our class is GC'd
+		// the executorKiller will finalize and ask the executor
+		// to shutdown, ending the worker.
+		//
+		int threads = 1;
+		executor = new ScheduledThreadPoolExecutor(threads,
+				new ThreadFactory() {
+					private final ThreadFactory baseFactory = Executors
+							.defaultThreadFactory();
+
+					public Thread newThread(Runnable taskBody) {
+						Thread thr = baseFactory.newThread(taskBody);
+						thr.setName("JGit-WorkQueue"); //$NON-NLS-1$
+						thr.setDaemon(true);
+						return thr;
+					}
+				});
+		executor.setRemoveOnCancelPolicy(true);
+		executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
+		executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+		executor.prestartAllCoreThreads();
+
+		// Now that the threads are running, its critical to swap out
+		// our own thread factory for one that isn't in the ClassLoader.
+		// This allows the class to GC.
+		//
+		executor.setThreadFactory(Executors.defaultThreadFactory());
+
+		executorKiller = new Object() {
+			@Override
+			protected void finalize() {
+				executor.shutdownNow();
+			}
+		};
+	}
+
+	static ScheduledThreadPoolExecutor getExecutor() {
+		return executor;
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java
index 2a5cb2b..14a98a1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java
@@ -82,6 +82,7 @@
  * <b>Merge filters:</b>
  * <ul>
  * <li>Skip all merges: {@link #NO_MERGES}.</li>
+ * <li>Skip all non-merges: {@link #ONLY_MERGES}</li>
  * </ul>
  *
  * <p>
@@ -143,6 +144,37 @@
 		}
 	}
 
+	/**
+	 * Filter including only merge commits, excluding all commits with less than
+	 * two parents (thread safe).
+	 *
+	 * @since 4.4
+	 */
+	public static final RevFilter ONLY_MERGES = new OnlyMergesFilter();
+
+	private static final class OnlyMergesFilter extends RevFilter {
+
+		@Override
+		public boolean include(RevWalk walker, RevCommit c) {
+			return c.getParentCount() >= 2;
+		}
+
+		@Override
+		public RevFilter clone() {
+			return this;
+		}
+
+		@Override
+		public boolean requiresCommitBody() {
+			return false;
+		}
+
+		@Override
+		public String toString() {
+			return "ONLY_MERGES"; //$NON-NLS-1$
+		}
+	}
+
 	/** Excludes commits with more than one parent (thread safe). */
 	public static final RevFilter NO_MERGES = new NoMergesFilter();
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java
index 702fd70..4b4822c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java
@@ -147,8 +147,7 @@
 					snapshot = newSnapshot;
 			} else {
 				final String decoded;
-				if (in.length >= 3 && in[0] == (byte) 0xEF
-						&& in[1] == (byte) 0xBB && in[2] == (byte) 0xBF) {
+				if (isUtf8(in)) {
 					decoded = RawParseUtils.decode(RawParseUtils.UTF8_CHARSET,
 							in, 3, in.length);
 					utf8Bom = true;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
index 6263d4b..5b9e8d9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
@@ -264,7 +264,7 @@
 
 		String remoteName = null;
 		// Look up remote URL associated wit HEAD ref
-		Ref ref = parent.getRef(Constants.HEAD);
+		Ref ref = parent.exactRef(Constants.HEAD);
 		if (ref != null) {
 			if (ref.isSymbolic())
 				ref = ref.getLeaf();
@@ -704,7 +704,7 @@
 		if (subRepo == null)
 			return null;
 		try {
-			Ref head = subRepo.getRef(Constants.HEAD);
+			Ref head = subRepo.exactRef(Constants.HEAD);
 			return head != null ? head.getLeaf().getName() : null;
 		} finally {
 			subRepo.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
index 963de35..9b8ba80 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
@@ -57,6 +57,7 @@
 import org.eclipse.jgit.errors.NoRemoteRepositoryException;
 import org.eclipse.jgit.errors.NotSupportedException;
 import org.eclipse.jgit.errors.PackProtocolException;
+import org.eclipse.jgit.errors.TooLargeObjectInPackException;
 import org.eclipse.jgit.errors.TooLargePackException;
 import org.eclipse.jgit.errors.TransportException;
 import org.eclipse.jgit.internal.JGitText;
@@ -328,12 +329,16 @@
 		if (!unpackLine.startsWith("unpack ")) //$NON-NLS-1$
 			throw new PackProtocolException(uri, MessageFormat.format(JGitText.get().unexpectedReportLine, unpackLine));
 		final String unpackStatus = unpackLine.substring("unpack ".length()); //$NON-NLS-1$
-		if (unpackStatus.startsWith("error Pack exceeds the limit of")) //$NON-NLS-1$
+		if (unpackStatus.startsWith("error Pack exceeds the limit of")) {//$NON-NLS-1$
 			throw new TooLargePackException(uri,
 					unpackStatus.substring("error ".length())); //$NON-NLS-1$
-		if (!unpackStatus.equals("ok")) //$NON-NLS-1$
+		} else if (unpackStatus.startsWith("error Object too large")) {//$NON-NLS-1$
+			throw new TooLargeObjectInPackException(uri,
+					unpackStatus.substring("error ".length())); //$NON-NLS-1$
+		} else if (!unpackStatus.equals("ok")) { //$NON-NLS-1$
 			throw new TransportException(uri, MessageFormat.format(
 					JGitText.get().errorOccurredDuringUnpackingOnTheRemoteEnd, unpackStatus));
+		}
 
 		String refLine;
 		while ((refLine = pckIn.readString()) != PacketLineIn.END) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
index a20e652..b5f9e2f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
@@ -176,6 +176,12 @@
 	/** Should an incoming transfer permit non-fast-forward requests? */
 	private boolean allowNonFastForwards;
 
+	/**
+	 * Should the requested ref updates be performed as a single atomic
+	 * transaction?
+	 */
+	private boolean atomic;
+
 	private boolean allowOfsDelta;
 	private boolean allowQuiet = true;
 
@@ -607,6 +613,25 @@
 		allowNonFastForwards = canRewind;
 	}
 
+	/**
+	 * @return true if the client's commands should be performed as a single
+	 *         atomic transaction.
+	 * @since 4.4
+	 */
+	public boolean isAtomic() {
+		return atomic;
+	}
+
+	/**
+	 * @param atomic
+	 *            true to perform the client's commands as a single atomic
+	 *            transaction.
+	 * @since 4.4
+	 */
+	public void setAtomic(boolean atomic) {
+		this.atomic = atomic;
+	}
+
 	/** @return identity of the user making the changes in the reflog. */
 	public PersonIdent getRefLogIdent() {
 		return refLogIdent;
@@ -1483,6 +1508,7 @@
 
 		BatchRefUpdate batch = db.getRefDatabase().newBatchUpdate();
 		batch.setAllowNonFastForwards(isAllowNonFastForwards());
+		batch.setAtomic(isAtomic());
 		batch.setRefLogIdent(getRefLogIdent());
 		batch.setRefLogMessage("push", true); //$NON-NLS-1$
 		batch.addCommand(toApply);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
index 6ed9bc8..f61e93f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -201,6 +201,8 @@
 
 			if (unpackError == null) {
 				boolean atomic = isCapabilityEnabled(CAPABILITY_ATOMIC);
+				setAtomic(atomic);
+
 				validateCommands();
 				if (atomic && anyRejects())
 					failPendingCommands();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
index 9e6d1f6..862b3bd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
@@ -629,7 +629,7 @@
 
 		for (final RefSpec spec : procRefs) {
 			String srcSpec = spec.getSource();
-			final Ref srcRef = db.getRef(srcSpec);
+			final Ref srcRef = db.findRef(srcSpec);
 			if (srcRef != null)
 				srcSpec = srcRef.getName();
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
index 8b642bb..e49ee87 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -82,6 +82,7 @@
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ProgressMonitor;
 import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefDatabase;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.AsyncRevObjectQueue;
 import org.eclipse.jgit.revwalk.DepthWalk;
@@ -704,22 +705,22 @@
 		return statistics;
 	}
 
-	private Map<String, Ref> getAdvertisedOrDefaultRefs() {
+	private Map<String, Ref> getAdvertisedOrDefaultRefs() throws IOException {
 		if (refs == null)
-			setAdvertisedRefs(null);
+			setAdvertisedRefs(db.getRefDatabase().getRefs(RefDatabase.ALL));
 		return refs;
 	}
 
 	private void service() throws IOException {
-		if (biDirectionalPipe)
-			sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut));
-		else if (requestValidator instanceof AnyRequestValidator)
-			advertised = Collections.emptySet();
-		else
-			advertised = refIdSet(getAdvertisedOrDefaultRefs().values());
-
 		boolean sendPack;
 		try {
+			if (biDirectionalPipe)
+				sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut));
+			else if (requestValidator instanceof AnyRequestValidator)
+				advertised = Collections.emptySet();
+			else
+				advertised = refIdSet(getAdvertisedOrDefaultRefs().values());
+
 			recvWants();
 			if (wantIds.isEmpty()) {
 				preUploadHook.onBeginNegotiateRound(this, wantIds, 0);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
index 779b10e..b4f12f4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
@@ -122,7 +122,7 @@
 							.defaultCharset().name()))) {
 				if (p.waitFor() == 0) {
 					String s = lineRead.readLine();
-					if (s.matches("0?\\d{3}")) { //$NON-NLS-1$
+					if (s != null && s.matches("0?\\d{3}")) { //$NON-NLS-1$
 						return Integer.parseInt(s, 8);
 					}
 				}
diff --git a/pom.xml b/pom.xml
index 1ff91cd..d38d156 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,7 +51,7 @@
   <groupId>org.eclipse.jgit</groupId>
   <artifactId>org.eclipse.jgit-parent</artifactId>
   <packaging>pom</packaging>
-  <version>4.3.2-SNAPSHOT</version>
+  <version>4.4.2-SNAPSHOT</version>
 
   <name>JGit - Parent</name>
   <url>${jgit-url}</url>
@@ -188,14 +188,15 @@
 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-
     <maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
     <bundle-manifest>${project.build.directory}/META-INF/MANIFEST.MF</bundle-manifest>
+    <!-- set JDK_HOME to JAVA_HOME path of JDK7 installation in order to compile against JDK 7 class library -->
+    <JDK_HOME>${JAVA_HOME}</JDK_HOME>
 
     <jgit-last-release-version>4.2.0.201601211800-r</jgit-last-release-version>
     <jsch-version>0.1.53</jsch-version>
     <javaewah-version>0.7.9</javaewah-version>
-    <junit-version>4.11</junit-version>
+    <junit-version>4.12</junit-version>
     <test-fork-count>1C</test-fork-count>
     <args4j-version>2.0.15</args4j-version>
     <commons-compress-version>1.6</commons-compress-version>
@@ -206,8 +207,8 @@
     <httpclient-version>4.3.6</httpclient-version>
     <slf4j-version>1.7.2</slf4j-version>
     <log4j-version>1.2.15</log4j-version>
-    <maven-javadoc-plugin-version>2.10.1</maven-javadoc-plugin-version>
-    <tycho-extras-version>0.23.0</tycho-extras-version>
+    <maven-javadoc-plugin-version>2.10.3</maven-javadoc-plugin-version>
+    <tycho-extras-version>0.25.0</tycho-extras-version>
     <gson-version>2.2.4</gson-version>
 
     <!-- Properties to enable jacoco code coverage analysis -->
@@ -259,23 +260,26 @@
 
         <plugin>
           <artifactId>maven-compiler-plugin</artifactId>
-          <version>3.2</version>
+          <version>3.5.1</version>
           <configuration>
             <encoding>UTF-8</encoding>
             <source>1.7</source>
             <target>1.7</target>
+            <compilerArguments>
+              <bootclasspath>${JDK_HOME}${file.separator}jre${file.separator}lib${file.separator}rt.jar${path.separator}${JDK_HOME}${file.separator}jre${file.separator}lib${file.separator}jsse.jar${path.separator}${JDK_HOME}${file.separator}jre${file.separator}lib${file.separator}jce.jar</bootclasspath>
+            </compilerArguments>
           </configuration>
         </plugin>
 
         <plugin>
           <artifactId>maven-clean-plugin</artifactId>
-          <version>2.6.1</version>
+          <version>3.0.0</version>
         </plugin>
 
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-shade-plugin</artifactId>
-          <version>2.3</version>
+          <version>2.4.3</version>
         </plugin>
 
         <plugin>
@@ -293,7 +297,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-source-plugin</artifactId>
-          <version>2.4</version>
+          <version>3.0.0</version>
         </plugin>
 
         <plugin>
@@ -305,7 +309,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-surefire-plugin</artifactId>
-          <version>2.18.1</version>
+          <version>2.19.1</version>
           <configuration>
             <forkCount>${test-fork-count}</forkCount>
             <reuseForks>true</reuseForks>
@@ -315,13 +319,13 @@
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>build-helper-maven-plugin</artifactId>
-          <version>1.9</version>
+          <version>1.10</version>
         </plugin>
 
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>findbugs-maven-plugin</artifactId>
-          <version>3.0.0</version>
+          <version>3.0.3</version>
           <configuration>
             <findbugsXmlOutput>true</findbugsXmlOutput>
             <failOnError>false</failOnError>
@@ -338,7 +342,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-pmd-plugin</artifactId>
-          <version>3.4</version>
+          <version>3.6</version>
           <configuration>
             <sourceEncoding>utf-8</sourceEncoding>
             <minimumTokens>100</minimumTokens>
@@ -358,7 +362,7 @@
         <plugin>
           <groupId>org.eclipse.cbi.maven.plugins</groupId>
           <artifactId>eclipse-jarsigner-plugin</artifactId>
-          <version>1.1.2</version>
+          <version>1.1.3</version>
         </plugin>
         <plugin>
           <groupId>org.eclipse.tycho.extras</groupId>
@@ -373,24 +377,24 @@
         <plugin>
           <groupId>org.jacoco</groupId>
           <artifactId>jacoco-maven-plugin</artifactId>
-          <version>0.7.1.201405082137</version>
+          <version>0.7.6.201602180812</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-site-plugin</artifactId>
-          <version>3.4</version>
+          <version>3.5.1</version>
           <dependencies>
             <dependency><!-- add support for ssh/scp -->
               <groupId>org.apache.maven.wagon</groupId>
               <artifactId>wagon-ssh</artifactId>
-              <version>2.7</version>
+              <version>2.10</version>
             </dependency>
           </dependencies>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-surefire-report-plugin</artifactId>
-          <version>2.18.1</version>
+          <version>2.19.1</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
@@ -400,7 +404,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-project-info-reports-plugin</artifactId>
-          <version>2.8</version>
+          <version>2.9</version>
         </plugin>
       </plugins>
     </pluginManagement>
@@ -453,6 +457,7 @@
         <configuration>
           <encoding>${project.build.sourceEncoding}</encoding>
           <quiet>true</quiet>
+          <excludePackageNames>org.eclipse.jgit.http.test</excludePackageNames>
           <links>
             <link>http://docs.oracle.com/javase/7/docs/api</link>
           </links>
@@ -525,12 +530,12 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>findbugs-maven-plugin</artifactId>
-        <version>3.0.0</version>
+        <version>3.0.3</version>
       </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-report-plugin</artifactId>
-        <version>2.18.1</version>
+        <version>2.19.1</version>
         <configuration>
           <aggregate>true</aggregate>
           <alwaysGenerateSurefireReport>false</alwaysGenerateSurefireReport>
diff --git a/tools/release.sh b/tools/release.sh
index 7adb375..d180bdf 100755
--- a/tools/release.sh
+++ b/tools/release.sh
@@ -47,6 +47,5 @@
 git tag -sf -m "$MSG" $1
 
 # run the build
-mvn clean install
+mvn clean install -T 1C
 mvn clean install -f org.eclipse.jgit.packaging/pom.xml
-