From 446a7096ef01c0e3bb56736403d91b125b2ee6ba Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Wed, 14 Feb 2018 18:23:03 +0100 Subject: [PATCH] RepoCommand: persist unreadable submodules in .gitmodules In cases where a manifest file mixes different remotes, a Gerrit server process may not have access to all remotes, and won't be able to produce a full submodule tree. Preserving this information in .gitmodules will let downstream clients reconstruct the full tree. Signed-off-by: Han-Wen Nienhuys Change-Id: I52f5d3f288e771dca0af2b4dd3f3fa0f940dcf15 --- .../eclipse/jgit/gitrepo/RepoCommandTest.java | 77 +++++++++++-------- .../org/eclipse/jgit/gitrepo/RepoCommand.java | 59 +++++++------- 2 files changed, 73 insertions(+), 63 deletions(-) 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 9afb58ecf..2df34df30 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 @@ -213,8 +213,7 @@ public class RepoCommandTest extends RepositoryTestCase { repos.put("platform/base", child); RevCommit commit = cmd - .setInputStream(new ByteArrayInputStream( - xmlContent.toString().getBytes(UTF_8))) + .setInputStream(new ByteArrayInputStream(xmlContent.toString().getBytes(UTF_8))) .setRemoteReader(repos) .setURI("platform/") .setTargetURI("platform/superproject") @@ -236,6 +235,49 @@ public class RepoCommandTest extends RepositoryTestCase { child.close(); dest.close(); } + @Test + public void recordUnreachableRemotes() throws Exception { + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("\n") + .append("") + .append("") + .append("") + .append("") + .append(""); + + Repository dest = Git.cloneRepository() + .setURI(db.getDirectory().toURI().toString()) + .setDirectory(createUniqueTestGitDir(true)).setBare(true).call() + .getRepository(); + + assertTrue(dest.isBare()); + + RevCommit commit = new RepoCommand(dest) + .setInputStream(new ByteArrayInputStream( + xmlContent.toString().getBytes(UTF_8))) + .setRemoteReader(new IndexedRepos()) + .setURI("platform/") + .setTargetURI("platform/superproject") + .setRecordRemoteBranch(true) + .setIgnoreRemoteFailures(true) + .setRecordSubmoduleLabels(true) + .call(); + + String idStr = commit.getId().name() + ":" + ".gitmodules"; + ObjectId modId = dest.resolve(idStr); + + try (ObjectReader reader = dest.newObjectReader()) { + byte[] bytes = reader.open(modId).getCachedBytes(Integer.MAX_VALUE); + Config base = new Config(); + BlobBasedConfig cfg = new BlobBasedConfig(base, bytes); + String subUrl = cfg.getString("submodule", "base", "url"); + assertEquals(subUrl, "https://host.com/platform/base"); + } + + dest.close(); + } + + @Test public void gerritSetup() throws Exception { @@ -814,37 +856,6 @@ public class RepoCommandTest extends RepositoryTestCase { assertEquals("submodule content should be as expected", "master world", content); } - - @Test - public void testNonDefaultRemotes() throws Exception { - StringBuilder xmlContent = new StringBuilder(); - xmlContent.append("\n") - .append("") - .append("") - .append("") - .append("") - .append("") - .append("") - .append(""); - - Repository localDb = createWorkRepository(); - JGitTestUtil.writeTrashFile( - localDb, "manifest.xml", xmlContent.toString()); - RepoCommand command = new RepoCommand(localDb); - command - .setPath(localDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri) - .call(); - File file = new File(localDb.getWorkTree(), "foo/hello.txt"); - assertTrue("We should have foo", file.exists()); - file = new File(localDb.getWorkTree(), "bar/world.txt"); - assertTrue("We should have bar", file.exists()); - } - @Test public void testRemoteAlias() throws Exception { StringBuilder xmlContent = new StringBuilder(); 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 10bd6005b..24651b9b6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java @@ -543,10 +543,7 @@ public class RepoCommand extends GitCommand { objectId = ObjectId.fromString(proj.getRevision()); } else { objectId = callback.sha1(nameUri, proj.getRevision()); - if (objectId == null) { - if (ignoreRemoteFailures) { - continue; - } + if (objectId == null && !ignoreRemoteFailures) { throw new RemoteUnavailableException(nameUri); } if (recordRemoteBranch) { @@ -585,38 +582,40 @@ public class RepoCommand extends GitCommand { cfg.setString("submodule", path, "url", submodUrl.toString()); //$NON-NLS-1$ //$NON-NLS-2$ // create gitlink - DirCacheEntry dcEntry = new DirCacheEntry(path); - dcEntry.setObjectId(objectId); - dcEntry.setFileMode(FileMode.GITLINK); - builder.add(dcEntry); - - for (CopyFile copyfile : proj.getCopyFiles()) { - byte[] src = callback.readFile( - nameUri, proj.getRevision(), copyfile.src); - objectId = inserter.insert(Constants.OBJ_BLOB, src); - dcEntry = new DirCacheEntry(copyfile.dest); + if (objectId != null) { + DirCacheEntry dcEntry = new DirCacheEntry(path); dcEntry.setObjectId(objectId); - dcEntry.setFileMode(FileMode.REGULAR_FILE); + dcEntry.setFileMode(FileMode.GITLINK); builder.add(dcEntry); - } - for (LinkFile linkfile : proj.getLinkFiles()) { - String link; - if (linkfile.dest.contains("/")) { //$NON-NLS-1$ - link = FileUtils.relativizeGitPath( + + for (CopyFile copyfile : proj.getCopyFiles()) { + byte[] src = callback.readFile( + nameUri, proj.getRevision(), copyfile.src); + objectId = inserter.insert(Constants.OBJ_BLOB, src); + dcEntry = new DirCacheEntry(copyfile.dest); + dcEntry.setObjectId(objectId); + dcEntry.setFileMode(FileMode.REGULAR_FILE); + builder.add(dcEntry); + } + for (LinkFile linkfile : proj.getLinkFiles()) { + String link; + if (linkfile.dest.contains("/")) { //$NON-NLS-1$ + link = FileUtils.relativizeGitPath( linkfile.dest.substring(0, - linkfile.dest.lastIndexOf('/')), + linkfile.dest.lastIndexOf('/')), proj.getPath() + "/" + linkfile.src); //$NON-NLS-1$ - } else { - link = proj.getPath() + "/" + linkfile.src; //$NON-NLS-1$ - } + } else { + link = proj.getPath() + "/" + linkfile.src; //$NON-NLS-1$ + } - objectId = inserter.insert(Constants.OBJ_BLOB, + objectId = inserter.insert(Constants.OBJ_BLOB, link.getBytes( - Constants.CHARACTER_ENCODING)); - dcEntry = new DirCacheEntry(linkfile.dest); - dcEntry.setObjectId(objectId); - dcEntry.setFileMode(FileMode.SYMLINK); - builder.add(dcEntry); + Constants.CHARACTER_ENCODING)); + dcEntry = new DirCacheEntry(linkfile.dest); + dcEntry.setObjectId(objectId); + dcEntry.setFileMode(FileMode.SYMLINK); + builder.add(dcEntry); + } } } String content = cfg.toText();