123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- /*
- * Copyright (C) 2014, Christian Halstrick <christian.halstrick@sap.com> 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.lib;
-
- import static org.junit.Assert.assertArrayEquals;
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertFalse;
- import static org.junit.Assert.assertTrue;
-
- import java.io.File;
- import java.io.IOException;
- import java.util.Arrays;
- import java.util.Set;
-
- import org.eclipse.jgit.api.CloneCommand;
- import org.eclipse.jgit.api.Git;
- import org.eclipse.jgit.api.errors.GitAPIException;
- import org.eclipse.jgit.errors.NoWorkTreeException;
- import org.eclipse.jgit.internal.storage.file.FileRepository;
- import org.eclipse.jgit.junit.JGitTestUtil;
- import org.eclipse.jgit.junit.RepositoryTestCase;
- import org.eclipse.jgit.storage.file.FileBasedConfig;
- import org.eclipse.jgit.submodule.SubmoduleWalk.IgnoreSubmoduleMode;
- import org.eclipse.jgit.treewalk.FileTreeIterator;
- import org.junit.Before;
- import org.junit.Test;
- import org.junit.experimental.theories.DataPoints;
- import org.junit.experimental.theories.Theories;
- import org.junit.experimental.theories.Theory;
- import org.junit.runner.RunWith;
-
- @RunWith(Theories.class)
- public class IndexDiffSubmoduleTest extends RepositoryTestCase {
- /** a submodule repository inside a root repository */
- protected FileRepository submodule_db;
-
- /** Working directory of the submodule repository */
- protected File submodule_trash;
-
- @DataPoints
- public static IgnoreSubmoduleMode allModes[] = IgnoreSubmoduleMode.values();
-
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
- FileRepository submoduleStandalone = createWorkRepository();
- JGitTestUtil.writeTrashFile(submoduleStandalone, "fileInSubmodule",
- "submodule");
- Git submoduleStandaloneGit = Git.wrap(submoduleStandalone);
- submoduleStandaloneGit.add().addFilepattern("fileInSubmodule").call();
- submoduleStandaloneGit.commit().setMessage("add file to submodule")
- .call();
-
- submodule_db = (FileRepository) Git.wrap(db).submoduleAdd()
- .setPath("modules/submodule")
- .setURI(submoduleStandalone.getDirectory().toURI().toString())
- .call();
- submodule_trash = submodule_db.getWorkTree();
- addRepoToClose(submodule_db);
- writeTrashFile("fileInRoot", "root");
- Git rootGit = Git.wrap(db);
- rootGit.add().addFilepattern("fileInRoot").call();
- rootGit.commit().setMessage("add submodule and root file").call();
- }
-
- @Theory
- public void testInitiallyClean(IgnoreSubmoduleMode mode)
- throws IOException {
- IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- indexDiff.setIgnoreSubmoduleMode(mode);
- assertFalse(indexDiff.diff());
- }
-
- private Repository cloneWithoutCloningSubmodule() throws Exception {
- File directory = createTempDirectory(
- "testCloneWithoutCloningSubmodules");
- CloneCommand clone = Git.cloneRepository();
- clone.setDirectory(directory);
- clone.setCloneSubmodules(false);
- clone.setURI(db.getDirectory().toURI().toString());
- Git git2 = clone.call();
- addRepoToClose(git2.getRepository());
- return git2.getRepository();
- }
-
- @Theory
- public void testCleanAfterClone(IgnoreSubmoduleMode mode) throws Exception {
- Repository db2 = cloneWithoutCloningSubmodule();
- IndexDiff indexDiff = new IndexDiff(db2, Constants.HEAD,
- new FileTreeIterator(db2));
- indexDiff.setIgnoreSubmoduleMode(mode);
- boolean changed = indexDiff.diff();
- assertFalse(changed);
- }
-
- @Theory
- public void testMissingIfDirectoryGone(IgnoreSubmoduleMode mode)
- throws Exception {
- recursiveDelete(submodule_trash);
- IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- indexDiff.setIgnoreSubmoduleMode(mode);
- boolean hasChanges = indexDiff.diff();
- if (mode != IgnoreSubmoduleMode.ALL) {
- assertTrue(hasChanges);
- assertEquals("[modules/submodule]",
- indexDiff.getMissing().toString());
- } else {
- assertFalse(hasChanges);
- }
- }
-
- @Theory
- public void testSubmoduleReplacedByFile(IgnoreSubmoduleMode mode)
- throws Exception {
- recursiveDelete(submodule_trash);
- writeTrashFile("modules/submodule", "nonsense");
- IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- indexDiff.setIgnoreSubmoduleMode(mode);
- assertTrue(indexDiff.diff());
- assertEquals("[]", indexDiff.getMissing().toString());
- assertEquals("[]", indexDiff.getUntracked().toString());
- assertEquals("[modules/submodule]", indexDiff.getModified().toString());
- }
-
- @Theory
- public void testDirtyRootWorktree(IgnoreSubmoduleMode mode)
- throws IOException {
- writeTrashFile("fileInRoot", "2");
-
- IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- indexDiff.setIgnoreSubmoduleMode(mode);
- assertTrue(indexDiff.diff());
- }
-
- private void assertDiff(IndexDiff indexDiff, IgnoreSubmoduleMode mode,
- IgnoreSubmoduleMode... expectedEmptyModes) throws IOException {
- boolean diffResult = indexDiff.diff();
- Set<String> submodulePaths = indexDiff
- .getPathsWithIndexMode(FileMode.GITLINK);
- boolean emptyExpected = false;
- for (IgnoreSubmoduleMode empty : expectedEmptyModes) {
- if (mode.equals(empty)) {
- emptyExpected = true;
- break;
- }
- }
- if (emptyExpected) {
- assertFalse("diff should be false with mode=" + mode,
- diffResult);
- assertEquals("should have no paths with FileMode.GITLINK", 0,
- submodulePaths.size());
- } else {
- assertTrue("diff should be true with mode=" + mode,
- diffResult);
- assertTrue("submodule path should have FileMode.GITLINK",
- submodulePaths.contains("modules/submodule"));
- }
- }
-
- @Theory
- public void testDirtySubmoduleWorktree(IgnoreSubmoduleMode mode)
- throws IOException {
- JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule", "2");
- IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- indexDiff.setIgnoreSubmoduleMode(mode);
- assertDiff(indexDiff, mode, IgnoreSubmoduleMode.ALL,
- IgnoreSubmoduleMode.DIRTY);
- }
-
- @Theory
- public void testDirtySubmoduleHEAD(IgnoreSubmoduleMode mode)
- throws IOException, GitAPIException {
- JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule", "2");
- Git submoduleGit = Git.wrap(submodule_db);
- submoduleGit.add().addFilepattern("fileInSubmodule").call();
- submoduleGit.commit().setMessage("Modified fileInSubmodule").call();
-
- IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- indexDiff.setIgnoreSubmoduleMode(mode);
- assertDiff(indexDiff, mode, IgnoreSubmoduleMode.ALL);
- }
-
- @Theory
- public void testDirtySubmoduleIndex(IgnoreSubmoduleMode mode)
- throws IOException, GitAPIException {
- JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule", "2");
- Git submoduleGit = Git.wrap(submodule_db);
- submoduleGit.add().addFilepattern("fileInSubmodule").call();
-
- IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- indexDiff.setIgnoreSubmoduleMode(mode);
- assertDiff(indexDiff, mode, IgnoreSubmoduleMode.ALL,
- IgnoreSubmoduleMode.DIRTY);
- }
-
- @Theory
- public void testDirtySubmoduleIndexAndWorktree(IgnoreSubmoduleMode mode)
- throws IOException, GitAPIException, NoWorkTreeException {
- JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule", "2");
- Git submoduleGit = Git.wrap(submodule_db);
- submoduleGit.add().addFilepattern("fileInSubmodule").call();
- JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule", "3");
-
- IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- indexDiff.setIgnoreSubmoduleMode(mode);
- assertDiff(indexDiff, mode, IgnoreSubmoduleMode.ALL,
- IgnoreSubmoduleMode.DIRTY);
- }
-
- @Theory
- public void testDirtySubmoduleWorktreeUntracked(IgnoreSubmoduleMode mode)
- throws IOException {
- JGitTestUtil.writeTrashFile(submodule_db, "additionalFileInSubmodule",
- "2");
- IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- indexDiff.setIgnoreSubmoduleMode(mode);
- assertDiff(indexDiff, mode, IgnoreSubmoduleMode.ALL,
- IgnoreSubmoduleMode.DIRTY, IgnoreSubmoduleMode.UNTRACKED);
- }
-
- @Theory
- public void testSubmoduleReplacedByMovedFile(IgnoreSubmoduleMode mode)
- throws Exception {
- Git git = Git.wrap(db);
- git.rm().setCached(true).addFilepattern("modules/submodule").call();
- recursiveDelete(submodule_trash);
- JGitTestUtil.deleteTrashFile(db, "fileInRoot");
- // Move the fileInRoot file
- writeTrashFile("modules/submodule/fileInRoot", "root");
- git.rm().addFilepattern("fileInRoot").addFilepattern("modules/").call();
- git.add().addFilepattern("modules/").call();
- IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- indexDiff.setIgnoreSubmoduleMode(mode);
- assertTrue(indexDiff.diff());
- String[] removed = indexDiff.getRemoved().toArray(new String[0]);
- Arrays.sort(removed);
- if (IgnoreSubmoduleMode.ALL.equals(mode)) {
- assertArrayEquals(new String[] { "fileInRoot" }, removed);
- } else {
- assertArrayEquals(
- new String[] { "fileInRoot", "modules/submodule" },
- removed);
- }
- assertEquals("[modules/submodule/fileInRoot]",
- indexDiff.getAdded().toString());
- }
-
- @Test
- public void testIndexDiffTwoSubmodules() throws Exception {
- // Create a second submodule
- try (Repository submodule2 = createWorkRepository()) {
- JGitTestUtil.writeTrashFile(submodule2, "fileInSubmodule2",
- "submodule2");
- Git subGit = Git.wrap(submodule2);
- subGit.add().addFilepattern("fileInSubmodule2").call();
- subGit.commit().setMessage("add file to submodule2").call();
-
- try (Repository sub2 = Git.wrap(db)
- .submoduleAdd().setPath("modules/submodule2")
- .setURI(submodule2.getDirectory().toURI().toString())
- .call()) {
- writeTrashFile("fileInRoot", "root+");
- Git rootGit = Git.wrap(db);
- rootGit.add().addFilepattern("fileInRoot").call();
- rootGit.commit().setMessage("add submodule2 and root file")
- .call();
- // Now change files in both submodules
- JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule",
- "submodule changed");
- JGitTestUtil.writeTrashFile(sub2, "fileInSubmodule2",
- "submodule2 changed");
- // Set up .gitmodules
- FileBasedConfig gitmodules = new FileBasedConfig(
- new File(db.getWorkTree(), Constants.DOT_GIT_MODULES),
- db.getFS());
- gitmodules.load();
- gitmodules.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
- "modules/submodule", ConfigConstants.CONFIG_KEY_IGNORE,
- "all");
- gitmodules.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
- "modules/submodule2", ConfigConstants.CONFIG_KEY_IGNORE,
- "none");
- gitmodules.save();
- IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- assertTrue(indexDiff.diff());
- String[] modified = indexDiff.getModified()
- .toArray(new String[0]);
- Arrays.sort(modified);
- assertEquals("[.gitmodules, modules/submodule2]",
- Arrays.toString(modified));
- // Try again with "dirty"
- gitmodules.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
- "modules/submodule", ConfigConstants.CONFIG_KEY_IGNORE,
- "dirty");
- gitmodules.save();
- indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- assertTrue(indexDiff.diff());
- modified = indexDiff.getModified().toArray(new String[0]);
- Arrays.sort(modified);
- assertEquals("[.gitmodules, modules/submodule2]",
- Arrays.toString(modified));
- // Test the config override
- StoredConfig cfg = db.getConfig();
- cfg.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
- "modules/submodule", ConfigConstants.CONFIG_KEY_IGNORE,
- "none");
- cfg.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
- "modules/submodule2", ConfigConstants.CONFIG_KEY_IGNORE,
- "all");
- cfg.save();
- indexDiff = new IndexDiff(db, Constants.HEAD,
- new FileTreeIterator(db));
- assertTrue(indexDiff.diff());
- modified = indexDiff.getModified().toArray(new String[0]);
- Arrays.sort(modified);
- assertEquals("[.gitmodules, modules/submodule]",
- Arrays.toString(modified));
- }
- }
- }
- }
|