blob: d54117005d767a9b8bc8994c7704ae4003ef9ea1 [file]
/*
* Copyright (C) 2011, GitHub Inc. and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.submodule;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.InitCommand;
import org.eclipse.jgit.api.SubmoduleAddCommand;
import org.eclipse.jgit.api.SubmoduleUpdateCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEditor;
import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.junit.Test;
/**
* Unit tests of {@link SubmoduleUpdateCommand}
*/
public class SubmoduleUpdateTest extends RepositoryTestCase {
private Repository submoduleRepo;
private Git git;
private AnyObjectId subRepoCommit2;
private void createSubmoduleRepo() throws IOException, GitAPIException {
File directory = createTempDirectory("submodule_repo");
InitCommand init = Git.init();
init.setDirectory(directory);
init.call();
submoduleRepo = Git.open(directory).getRepository();
try (Git sub = Git.wrap(submoduleRepo)) {
// commit something
JGitTestUtil.writeTrashFile(submoduleRepo, "commit1.txt",
"commit 1");
sub.add().addFilepattern("commit1.txt").call();
sub.commit().setMessage("commit 1").call().getId();
JGitTestUtil.writeTrashFile(submoduleRepo, "commit2.txt",
"commit 2");
sub.add().addFilepattern("commit2.txt").call();
subRepoCommit2 = sub.commit().setMessage("commit 2").call().getId();
}
}
private void addSubmodule(String path) throws GitAPIException {
SubmoduleAddCommand command = new SubmoduleAddCommand(db);
command.setPath(path);
String uri = submoduleRepo.getDirectory().toURI().toString();
command.setURI(uri);
try (Repository repo = command.call()) {
assertNotNull(repo);
}
git.add().addFilepattern(path).addFilepattern(Constants.DOT_GIT_MODULES)
.call();
git.commit().setMessage("adding submodule").call();
recursiveDelete(new File(git.getRepository().getWorkTree(), path));
recursiveDelete(
new File(new File(git.getRepository().getCommonDirectory(),
Constants.MODULES), path));
}
@Override
public void setUp() throws Exception {
super.setUp();
createSubmoduleRepo();
git = Git.wrap(db);
// commit something
writeTrashFile("initial.txt", "initial");
git.add().addFilepattern("initial.txt").call();
git.commit().setMessage("initial commit").call();
}
public void updateModeClonedRestoredSubmoduleTemplate(String mode)
throws Exception {
String path = "sub";
addSubmodule(path);
StoredConfig cfg = git.getRepository().getConfig();
if (mode != null) {
cfg.load();
cfg.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
ConfigConstants.CONFIG_KEY_UPDATE, mode);
cfg.save();
}
SubmoduleUpdateCommand update = new SubmoduleUpdateCommand(db);
update.call();
try (Git subGit = Git.open(new File(db.getWorkTree(), path))) {
update.call();
assertEquals(subRepoCommit2.getName(),
subGit.getRepository().getBranch());
}
recursiveDelete(new File(db.getWorkTree(), path));
update.call();
try (Git subGit = Git.open(new File(db.getWorkTree(), path))) {
update.call();
assertEquals(subRepoCommit2.getName(),
subGit.getRepository().getBranch());
}
}
@Test
public void repositoryWithNoSubmodules() throws GitAPIException {
SubmoduleUpdateCommand command = new SubmoduleUpdateCommand(db);
Collection<String> modules = command.call();
assertNotNull(modules);
assertTrue(modules.isEmpty());
}
@Test
public void repositoryWithSubmodule() throws Exception {
final String path = "sub";
addSubmodule(path);
SubmoduleUpdateCommand command = new SubmoduleUpdateCommand(db);
Collection<String> updated = command.call();
assertNotNull(updated);
assertEquals(1, updated.size());
assertEquals(path, updated.iterator().next());
try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
assertTrue(generator.next());
try (Repository subRepo = generator.getRepository()) {
assertNotNull(subRepo);
assertEquals(subRepoCommit2, subRepo.resolve(Constants.HEAD));
String worktreeDir = subRepo.getConfig().getString(
ConfigConstants.CONFIG_CORE_SECTION, null,
ConfigConstants.CONFIG_KEY_WORKTREE);
assertEquals("../../../sub", worktreeDir);
String gitdir = read(
new File(subRepo.getWorkTree(), Constants.DOT_GIT));
assertEquals("gitdir: ../.git/modules/sub", gitdir);
}
}
}
@Test
public void repositoryWithUnconfiguredSubmodule()
throws IOException, GitAPIException {
final ObjectId id = ObjectId
.fromString("abcd1234abcd1234abcd1234abcd1234abcd1234");
final String path = "sub";
DirCache cache = db.lockDirCache();
DirCacheEditor editor = cache.editor();
editor.add(new PathEdit(path) {
@Override
public void apply(DirCacheEntry ent) {
ent.setFileMode(FileMode.GITLINK);
ent.setObjectId(id);
}
});
editor.commit();
FileBasedConfig modulesConfig = new FileBasedConfig(
new File(db.getWorkTree(), Constants.DOT_GIT_MODULES),
db.getFS());
modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
ConfigConstants.CONFIG_KEY_PATH, path);
String url = "git://server/repo.git";
modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
ConfigConstants.CONFIG_KEY_URL, url);
modulesConfig.save();
SubmoduleUpdateCommand command = new SubmoduleUpdateCommand(db);
Collection<String> updated = command.call();
assertNotNull(updated);
assertTrue(updated.isEmpty());
}
@Test
public void repositoryWithInitializedSubmodule()
throws IOException, GitAPIException {
final ObjectId id = ObjectId
.fromString("abcd1234abcd1234abcd1234abcd1234abcd1234");
final String path = "sub";
DirCache cache = db.lockDirCache();
DirCacheEditor editor = cache.editor();
editor.add(new PathEdit(path) {
@Override
public void apply(DirCacheEntry ent) {
ent.setFileMode(FileMode.GITLINK);
ent.setObjectId(id);
}
});
editor.commit();
try (Repository subRepo = Git.init().setBare(false)
.setDirectory(new File(db.getWorkTree(), path)).call()
.getRepository()) {
assertNotNull(subRepo);
}
SubmoduleUpdateCommand command = new SubmoduleUpdateCommand(db);
Collection<String> updated = command.call();
assertNotNull(updated);
assertTrue(updated.isEmpty());
}
@Test
public void updateModeMergeClonedRestoredSubmodule() throws Exception {
updateModeClonedRestoredSubmoduleTemplate(
ConfigConstants.CONFIG_KEY_MERGE);
}
@Test
public void updateModeRebaseClonedRestoredSubmodule() throws Exception {
updateModeClonedRestoredSubmoduleTemplate(
ConfigConstants.CONFIG_KEY_REBASE);
}
@Test
public void updateModeCheckoutClonedRestoredSubmodule() throws Exception {
updateModeClonedRestoredSubmoduleTemplate(
ConfigConstants.CONFIG_KEY_CHECKOUT);
}
@Test
public void updateModeMissingClonedRestoredSubmodule() throws Exception {
updateModeClonedRestoredSubmoduleTemplate(null);
}
@Test
public void updateMode() throws Exception {
String path = "sub";
addSubmodule(path);
StoredConfig cfg = git.getRepository().getConfig();
cfg.load();
cfg.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
ConfigConstants.CONFIG_KEY_UPDATE,
ConfigConstants.CONFIG_KEY_REBASE);
cfg.save();
SubmoduleUpdateCommand update = new SubmoduleUpdateCommand(db);
update.call();
try (Git subGit = Git.open(new File(db.getWorkTree(), path))) {
CheckoutCommand checkout = subGit.checkout();
checkout.setName("master");
checkout.call();
update.call();
assertEquals("master", subGit.getRepository().getBranch());
}
cfg.load();
cfg.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
ConfigConstants.CONFIG_KEY_UPDATE,
ConfigConstants.CONFIG_KEY_CHECKOUT);
cfg.save();
update.call();
try (Git subGit = Git.open(new File(db.getWorkTree(), path))) {
assertEquals(subRepoCommit2.getName(),
subGit.getRepository().getBranch());
}
cfg.load();
cfg.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
ConfigConstants.CONFIG_KEY_UPDATE,
ConfigConstants.CONFIG_KEY_MERGE);
cfg.save();
update.call();
try (Git subGit = Git.open(new File(db.getWorkTree(), path))) {
CheckoutCommand checkout = subGit.checkout();
checkout.setName("master");
checkout.call();
update.call();
assertEquals("master", subGit.getRepository().getBranch());
}
}
}