Skip to content

Commit 1cc050a

Browse files
author
TheSnoozer
committed
git-commit-id/git-commit-id-maven-plugin#701: fix an issue with submodules
1 parent e020be1 commit 1cc050a

File tree

1 file changed

+50
-7
lines changed

1 file changed

+50
-7
lines changed

src/main/java/pl/project13/core/util/GitDirLocator.java

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,50 @@ public GitDirLocator(
6868
*/
6969
@Nullable
7070
public File lookupGitDirectory(@Nonnull File manuallyConfiguredDir) throws GitCommitIdExecutionException {
71-
File dotGitDirectory = runSearch(manuallyConfiguredDir);
71+
File dotGitDirectory = runSearch(manuallyConfiguredDir, true);
7272
if (shouldFailOnNoGitDirectory && !directoryExists(dotGitDirectory)) {
7373
throw new GitCommitIdExecutionException(
7474
".git directory is not found! Please specify a valid [dotGitDirectory] in your"
7575
+ " project");
7676
}
77+
// assert dotGitDirectory != null
7778
if (useNativeGit) {
78-
dotGitDirectory = dotGitDirectory.getParentFile();
79+
// Check if the resolved directory structure looks like it is a submodule
80+
// path like `your-project/.git/modules/remote-module`.
81+
if (dotGitDirectory != null) {
82+
File parent = dotGitDirectory.getParentFile();
83+
if (parent != null) {
84+
File parentParent = parent.getParentFile();
85+
if (parentParent != null && parentParent.getName().equals(".git") && parent.getName().equals("modules")) {
86+
// Yes, we have a submodule, so this becomes a bit more tricky!
87+
// First what we need to find is the unresolvedGitDir
88+
File unresolvedGitDir = runSearch(manuallyConfiguredDir, false);
89+
// Now to be extra sure, check if the unresolved
90+
// ".git" we have found is actually a file, which is the case for submodules
91+
if (unresolvedGitDir != null && unresolvedGitDir.isFile()) {
92+
// Yes, it's a submodule!
93+
// For the native git executable we can not use the resolved
94+
// dotGitDirectory which looks like `your-project/.git/modules/remote-module`.
95+
// The main reason seems that some git commands like `git config`
96+
// consume the relative worktree configuration like
97+
// `worktree = ../../../remote-module` from that location.
98+
// When running `git config` in `your-project/.git/modules/remote-module`
99+
// it would fail with an error since the relative worktree location is
100+
// only valid from the original location (`your-project/remote-module/.git`).
101+
//
102+
// Hence instead of using the resolved git dir location we need to use the
103+
// unresolvedGitDir, but we need to keep in mind that we initially have pointed to
104+
// a `git`-File like `your-project/remote-module/.git`
105+
dotGitDirectory = unresolvedGitDir;
106+
}
107+
}
108+
}
109+
}
110+
// The directory is likely an actual .dot-dir like `your-project/.git`.
111+
// In such a directory we can not run any git commands so we need to use the parent.
112+
if (dotGitDirectory != null) {
113+
dotGitDirectory = dotGitDirectory.getParentFile();
114+
}
79115
}
80116
return dotGitDirectory;
81117
}
@@ -84,15 +120,18 @@ private static boolean directoryExists(@Nullable File fileLocation) {
84120
return fileLocation != null && fileLocation.exists() && fileLocation.isDirectory();
85121
}
86122

87-
88-
private File runSearch(@Nonnull File manuallyConfiguredDir) {
123+
@Nullable
124+
private File runSearch(@Nonnull File manuallyConfiguredDir, boolean resolveGitReferenceFile) {
89125
if (manuallyConfiguredDir.exists()) {
90126

91127
// If manuallyConfiguredDir is a directory then we can use it as the git path.
92128
if (manuallyConfiguredDir.isDirectory()) {
93129
return manuallyConfiguredDir;
94130
}
95131

132+
if (manuallyConfiguredDir.isFile() && !resolveGitReferenceFile) {
133+
return manuallyConfiguredDir;
134+
}
96135
// If the path exists but is not a directory it might be a git submodule "gitdir" link.
97136
File gitDirLinkPath = processGitDirFile(manuallyConfiguredDir);
98137

@@ -108,7 +147,7 @@ private File runSearch(@Nonnull File manuallyConfiguredDir) {
108147
*/
109148
}
110149

111-
return findProjectGitDirectory();
150+
return findProjectGitDirectory(resolveGitReferenceFile);
112151
}
113152

114153
/**
@@ -117,15 +156,19 @@ private File runSearch(@Nonnull File manuallyConfiguredDir) {
117156
* @return File which represents the location of the .git directory or NULL if none found.
118157
*/
119158
@Nullable
120-
private File findProjectGitDirectory() {
159+
private File findProjectGitDirectory(boolean resolveGitReferenceFile) {
121160
File basedir = this.projectBasedir;
122161
while (basedir != null) {
123162
File gitdir = new File(basedir, Constants.DOT_GIT);
124163
if (gitdir.exists()) {
125164
if (gitdir.isDirectory()) {
126165
return gitdir;
127166
} else if (gitdir.isFile()) {
128-
return processGitDirFile(gitdir);
167+
if (resolveGitReferenceFile) {
168+
return processGitDirFile(gitdir);
169+
} else {
170+
return gitdir;
171+
}
129172
} else {
130173
return null;
131174
}

0 commit comments

Comments
 (0)