Merge branch 'stable-6.0' into stable-6.1
* stable-6.0: UploadPack: don't prematurely terminate timer in case of error Do not create reflog for remote tracking branches during clone UploadPack: do not check reachability of visible SHA1s Add missing package import javax.management to org.eclipse.jgit Change-Id: I08734ee2c8f3296d908da6a29d53ed87c4b48eb2
This commit is contained in:
commit
d01376106a
|
@ -208,6 +208,8 @@ public void flush() throws IOException {
|
||||||
log(up.getRepository(), e.getCause());
|
log(up.getRepository(), e.getCause());
|
||||||
consumeRequestBody(req);
|
consumeRequestBody(req);
|
||||||
out.close();
|
out.close();
|
||||||
|
} finally {
|
||||||
|
up.close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.eclipse.jgit.api.ListBranchCommand.ListMode;
|
import org.eclipse.jgit.api.ListBranchCommand.ListMode;
|
||||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||||
|
@ -114,6 +115,49 @@ public void testCloneRepository() throws IOException,
|
||||||
assertTagOption(git2.getRepository(), TagOpt.AUTO_FOLLOW);
|
assertTagOption(git2.getRepository(), TagOpt.AUTO_FOLLOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloneRepository_refLogForLocalRefs()
|
||||||
|
throws IOException, JGitInternalException, GitAPIException {
|
||||||
|
File directory = createTempDirectory("testCloneRepository");
|
||||||
|
CloneCommand command = Git.cloneRepository();
|
||||||
|
command.setDirectory(directory);
|
||||||
|
command.setURI(fileUri());
|
||||||
|
Git git2 = command.call();
|
||||||
|
Repository clonedRepo = git2.getRepository();
|
||||||
|
addRepoToClose(clonedRepo);
|
||||||
|
|
||||||
|
List<Ref> clonedRefs = clonedRepo.getRefDatabase().getRefs();
|
||||||
|
Stream<Ref> remoteRefs = clonedRefs.stream()
|
||||||
|
.filter(CloneCommandTest::isRemote);
|
||||||
|
Stream<Ref> localHeadsRefs = clonedRefs.stream()
|
||||||
|
.filter(CloneCommandTest::isLocalHead);
|
||||||
|
|
||||||
|
remoteRefs.forEach(ref -> assertFalse(
|
||||||
|
"Ref " + ref.getName()
|
||||||
|
+ " is remote and should not have a reflog",
|
||||||
|
hasRefLog(clonedRepo, ref)));
|
||||||
|
localHeadsRefs.forEach(ref -> assertTrue(
|
||||||
|
"Ref " + ref.getName()
|
||||||
|
+ " is local head and should have a reflog",
|
||||||
|
hasRefLog(clonedRepo, ref)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isRemote(Ref ref) {
|
||||||
|
return ref.getName().startsWith(Constants.R_REMOTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isLocalHead(Ref ref) {
|
||||||
|
return !isRemote(ref) && ref.getName().startsWith(Constants.R_HEADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasRefLog(Repository repo, Ref ref) {
|
||||||
|
try {
|
||||||
|
return repo.getReflogReader(ref.getName()).getLastEntry() != null;
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw new IllegalStateException(ioe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCloneRepositoryExplicitGitDir() throws IOException,
|
public void testCloneRepositoryExplicitGitDir() throws IOException,
|
||||||
JGitInternalException, GitAPIException {
|
JGitInternalException, GitAPIException {
|
||||||
|
|
|
@ -76,6 +76,26 @@ public void testFetch() throws Exception {
|
||||||
db.resolve(tagRef.getObjectId().getName()));
|
db.resolve(tagRef.getObjectId().getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFetchHasRefLogForRemoteRef() throws Exception {
|
||||||
|
// create an initial commit SHA1 for the default branch
|
||||||
|
ObjectId defaultBranchSha1 = remoteGit.commit()
|
||||||
|
.setMessage("initial commit").call().getId();
|
||||||
|
|
||||||
|
git.fetch().setRemote("test")
|
||||||
|
.setRefSpecs("refs/heads/*:refs/remotes/origin/*").call();
|
||||||
|
|
||||||
|
List<Ref> allFetchedRefs = git.getRepository().getRefDatabase()
|
||||||
|
.getRefs();
|
||||||
|
assertEquals(allFetchedRefs.size(), 1);
|
||||||
|
Ref remoteRef = allFetchedRefs.get(0);
|
||||||
|
|
||||||
|
assertTrue(remoteRef.getName().startsWith(Constants.R_REMOTES));
|
||||||
|
assertEquals(defaultBranchSha1, remoteRef.getObjectId());
|
||||||
|
assertNotNull(git.getRepository().getReflogReader(remoteRef.getName())
|
||||||
|
.getLastEntry());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testForcedFetch() throws Exception {
|
public void testForcedFetch() throws Exception {
|
||||||
remoteGit.commit().setMessage("commit").call();
|
remoteGit.commit().setMessage("commit").call();
|
||||||
|
|
|
@ -226,6 +226,7 @@ Export-Package: org.eclipse.jgit.annotations;version="6.1.1",
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
||||||
Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
|
Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
|
||||||
javax.crypto,
|
javax.crypto,
|
||||||
|
javax.management,
|
||||||
javax.net.ssl,
|
javax.net.ssl,
|
||||||
org.slf4j;version="[1.7.0,2.0.0)",
|
org.slf4j;version="[1.7.0,2.0.0)",
|
||||||
org.xml.sax,
|
org.xml.sax,
|
||||||
|
|
|
@ -204,8 +204,13 @@ else if (tagopt == TagOpt.FETCH_TAGS)
|
||||||
|
|
||||||
BatchRefUpdate batch = transport.local.getRefDatabase()
|
BatchRefUpdate batch = transport.local.getRefDatabase()
|
||||||
.newBatchUpdate()
|
.newBatchUpdate()
|
||||||
.setAllowNonFastForwards(true)
|
.setAllowNonFastForwards(true);
|
||||||
.setRefLogMessage("fetch", true); //$NON-NLS-1$
|
|
||||||
|
// Generate reflog only when fetching updates and not at the first clone
|
||||||
|
if (initialBranch == null) {
|
||||||
|
batch.setRefLogMessage("fetch", true); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
try (RevWalk walk = new RevWalk(transport.local)) {
|
try (RevWalk walk = new RevWalk(transport.local)) {
|
||||||
walk.setRetainBody(false);
|
walk.setRetainBody(false);
|
||||||
if (monitor instanceof BatchingProgressMonitor) {
|
if (monitor instanceof BatchingProgressMonitor) {
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
import static org.eclipse.jgit.util.RefMap.toRefMap;
|
import static org.eclipse.jgit.util.RefMap.toRefMap;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -105,7 +106,7 @@
|
||||||
/**
|
/**
|
||||||
* Implements the server side of a fetch connection, transmitting objects.
|
* Implements the server side of a fetch connection, transmitting objects.
|
||||||
*/
|
*/
|
||||||
public class UploadPack {
|
public class UploadPack implements Closeable {
|
||||||
/** Policy the server uses to validate client requests */
|
/** Policy the server uses to validate client requests */
|
||||||
public enum RequestPolicy {
|
public enum RequestPolicy {
|
||||||
/** Client may only ask for objects the server advertised a reference for. */
|
/** Client may only ask for objects the server advertised a reference for. */
|
||||||
|
@ -733,6 +734,17 @@ private boolean useProtocolV2() {
|
||||||
&& clientRequestedV2;
|
&& clientRequestedV2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (timer != null) {
|
||||||
|
try {
|
||||||
|
timer.terminate();
|
||||||
|
} finally {
|
||||||
|
timer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the upload task on the socket.
|
* Execute the upload task on the socket.
|
||||||
*
|
*
|
||||||
|
@ -780,6 +792,8 @@ public void upload(InputStream input, OutputStream output,
|
||||||
throw new UploadPackInternalServerErrorException(err);
|
throw new UploadPackInternalServerErrorException(err);
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
|
} finally {
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -789,6 +803,10 @@ public void upload(InputStream input, OutputStream output,
|
||||||
* <p>
|
* <p>
|
||||||
* If the client passed extra parameters (e.g., "version=2") through a side
|
* If the client passed extra parameters (e.g., "version=2") through a side
|
||||||
* channel, the caller must call setExtraParameters first to supply them.
|
* channel, the caller must call setExtraParameters first to supply them.
|
||||||
|
* Callers of this method should call {@link #close()} to terminate the
|
||||||
|
* internal interrupt timer thread. If the caller fails to terminate the
|
||||||
|
* thread, it will (eventually) terminate itself when the InterruptTimer
|
||||||
|
* instance is garbage collected.
|
||||||
*
|
*
|
||||||
* @param input
|
* @param input
|
||||||
* raw input to read client commands from. Caller must ensure the
|
* raw input to read client commands from. Caller must ensure the
|
||||||
|
@ -845,13 +863,6 @@ public void uploadWithExceptionPropagation(InputStream input,
|
||||||
} finally {
|
} finally {
|
||||||
msgOut = NullOutputStream.INSTANCE;
|
msgOut = NullOutputStream.INSTANCE;
|
||||||
walk.close();
|
walk.close();
|
||||||
if (timer != null) {
|
|
||||||
try {
|
|
||||||
timer.terminate();
|
|
||||||
} finally {
|
|
||||||
timer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1998,12 +2009,16 @@ private static void checkNotAdvertisedWants(UploadPack up,
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
ObjectReader reader = up.getRevWalk().getObjectReader();
|
ObjectReader reader = up.getRevWalk().getObjectReader();
|
||||||
|
Set<ObjectId> directlyVisibleObjects = refIdSet(visibleRefs);
|
||||||
|
List<ObjectId> nonTipWants = notAdvertisedWants.stream()
|
||||||
|
.filter(not(directlyVisibleObjects::contains))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
try (RevWalk walk = new RevWalk(reader)) {
|
try (RevWalk walk = new RevWalk(reader)) {
|
||||||
walk.setRetainBody(false);
|
walk.setRetainBody(false);
|
||||||
// Missing "wants" throw exception here
|
// Missing "wants" throw exception here
|
||||||
List<RevObject> wantsAsObjs = objectIdsToRevObjects(walk,
|
List<RevObject> wantsAsObjs = objectIdsToRevObjects(walk,
|
||||||
notAdvertisedWants);
|
nonTipWants);
|
||||||
List<RevCommit> wantsAsCommits = wantsAsObjs.stream()
|
List<RevCommit> wantsAsCommits = wantsAsObjs.stream()
|
||||||
.filter(obj -> obj instanceof RevCommit)
|
.filter(obj -> obj instanceof RevCommit)
|
||||||
.map(obj -> (RevCommit) obj)
|
.map(obj -> (RevCommit) obj)
|
||||||
|
@ -2063,6 +2078,10 @@ private static void checkNotAdvertisedWants(UploadPack up,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static <T> Predicate<T> not(Predicate<T> t) {
|
||||||
|
return t.negate();
|
||||||
|
}
|
||||||
|
|
||||||
static Stream<Ref> importantRefsFirst(
|
static Stream<Ref> importantRefsFirst(
|
||||||
Collection<Ref> visibleRefs) {
|
Collection<Ref> visibleRefs) {
|
||||||
Predicate<Ref> startsWithRefsHeads = ref -> ref.getName()
|
Predicate<Ref> startsWithRefsHeads = ref -> ref.getName()
|
||||||
|
|
Loading…
Reference in New Issue