Browse Source

IndexDiff/SubmoduleWalk: handle submodule.<name>.ignore correctly

IndexDiff would apply ignore mode ALL from .gitmodules to all remaining
submodules, and would ignore other settings from .gitignore and always
apply the setting defined on the IndexDiff instead. Correct that.

In canonical git the ignore setting from .gitmodules can also be
overridden by .git/config.[1] Implement that override in SubmoduleWalk.

[1] https://git-scm.com/docs/gitmodules#Documentation/gitmodules.txt-submoduleltnamegtignore

Bug: 521613
Change-Id: I9199fd447e41c7838924856dce40678370b66395
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
tags/v5.6.0.201911271000-m3
Thomas Wolf 4 years ago
parent
commit
7a3b93cbed

+ 77
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java View File

@@ -60,9 +60,11 @@ 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;
@@ -295,4 +297,79 @@ public class IndexDiffSubmoduleTest extends RepositoryTestCase {
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));
}
}
}
}

+ 3
- 3
org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java View File

@@ -535,10 +535,10 @@ public class IndexDiff {
}

if (ignoreSubmoduleMode != IgnoreSubmoduleMode.ALL) {
IgnoreSubmoduleMode localIgnoreSubmoduleMode = ignoreSubmoduleMode;
try (SubmoduleWalk smw = new SubmoduleWalk(repository)) {
smw.setTree(new DirCacheIterator(dirCache));
while (smw.next()) {
IgnoreSubmoduleMode localIgnoreSubmoduleMode = ignoreSubmoduleMode;
try {
if (localIgnoreSubmoduleMode == null)
localIgnoreSubmoduleMode = smw.getModulesIgnore();
@@ -558,7 +558,7 @@ public class IndexDiff {
&& !subHead.equals(smw.getObjectId())) {
modified.add(subRepoPath);
recordFileMode(subRepoPath, FileMode.GITLINK);
} else if (ignoreSubmoduleMode != IgnoreSubmoduleMode.DIRTY) {
} else if (localIgnoreSubmoduleMode != IgnoreSubmoduleMode.DIRTY) {
IndexDiff smid = submoduleIndexDiffs
.get(smw.getPath());
if (smid == null) {
@@ -569,7 +569,7 @@ public class IndexDiff {
submoduleIndexDiffs.put(subRepoPath, smid);
}
if (smid.diff()) {
if (ignoreSubmoduleMode == IgnoreSubmoduleMode.UNTRACKED
if (localIgnoreSubmoduleMode == IgnoreSubmoduleMode.UNTRACKED
&& smid.getAdded().isEmpty()
&& smid.getChanged().isEmpty()
&& smid.getConflicting().isEmpty()

+ 7
- 0
org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java View File

@@ -735,6 +735,13 @@ public class SubmoduleWalk implements AutoCloseable {
*/
public IgnoreSubmoduleMode getModulesIgnore() throws IOException,
ConfigInvalidException {
IgnoreSubmoduleMode mode = repoConfig.getEnum(
IgnoreSubmoduleMode.values(),
ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(),
ConfigConstants.CONFIG_KEY_IGNORE, null);
if (mode != null) {
return mode;
}
lazyLoadModulesConfig();
return modulesConfig.getEnum(IgnoreSubmoduleMode.values(),
ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(),

Loading…
Cancel
Save