diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java index 19281f6c993..a8023562ea4 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, Christian Halstrick and others + * Copyright (C) 2011, 2026 Christian Halstrick 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 @@ -30,6 +30,26 @@ public class StatusCommandTest extends RepositoryTestCase { + @Test + public void testRelativeCoreExcludesFile() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("sub/myexclusions", "ignoring\n"); + FileBasedConfig config = db.getConfig(); + config.setString("core", null, "excludesFile", "sub/myexclusions"); + config.save(); + writeTrashFile("foo", "foo"); + writeTrashFile("ignoring", "foo"); + writeTrashFile("sub/foo", "foo"); + writeTrashFile("sub/ignoring", "foo"); + + Status stat = git.status().call(); + assertEquals(Sets.of("foo", "sub/foo", "sub/myexclusions"), + stat.getUntracked()); + assertEquals(Sets.of("ignoring", "sub/ignoring"), + stat.getIgnoredNotInIndex()); + } + } + @Test public void testEmptyStatus() throws NoWorkTreeException, GitAPIException { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java index ab08c997969..d5b3a524b38 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, Red Hat Inc. and others + * Copyright (C) 2010, 2026 Red Hat 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 @@ -58,6 +58,32 @@ public void closeWalk() { } } + @Test + public void testRelativeCoreExcludesFileResolvedAgainstWorkTree() + throws Exception { + // C Git resolves a relative core.excludesFile against the work tree + // root, not the process current directory. See + // https://github.com/eclipse-jgit/jgit/issues/280 + writeIgnoreFile("sub/myexclusions", "ignoring"); + db.getConfig().setString("core", null, "excludesFile", + "sub/myexclusions"); + db.getConfig().save(); + + writeTrashFile("foo", "foo"); + writeTrashFile("ignoring", "foo"); + writeTrashFile("sub/foo", "foo"); + writeTrashFile("sub/ignoring", "foo"); + + beginWalk(); + assertEntry(F, tracked, "foo"); + assertEntry(F, ignored, "ignoring"); + assertEntry(D, tracked, "sub"); + assertEntry(F, tracked, "sub/foo"); + assertEntry(F, ignored, "sub/ignoring"); + assertEntry(F, tracked, "sub/myexclusions"); + endWalk(); + } + @Test public void testSimpleRootGitIgnoreGlobalIgnore() throws IOException { writeIgnoreFile(".gitignore", "x"); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java index f16d800f630..bd1689d40c6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -2,7 +2,7 @@ * Copyright (C) 2008, Shawn O. Pearce * Copyright (C) 2010, Christian Halstrick * Copyright (C) 2010, Matthias Sohn - * Copyright (C) 2012, 2022, Robin Rosenberg and others + * Copyright (C) 2012, 2026, Robin Rosenberg 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 @@ -1291,9 +1291,12 @@ private static class RootIgnoreNode extends PerDirectoryIgnoreNode { IgnoreNode load(IgnoreNode parent) throws IOException { IgnoreNode coreExclude = new IgnoreNodeWithParent(parent); FS fs = repository.getFS(); + // C Git resolves a relative core.excludesFile against the work + // tree root (it chdirs there). Do not use the process CWD. Path path = repository.getConfig().getPath( ConfigConstants.CONFIG_CORE_SECTION, null, - ConfigConstants.CONFIG_KEY_EXCLUDESFILE, fs, null, null); + ConfigConstants.CONFIG_KEY_EXCLUDESFILE, fs, + repository.getWorkTree(), null); if (path != null) { if (Files.exists(path)) { loadRulesFromFile(coreExclude, path.toFile());