23
23
import org .eclipse .jgit .lib .Repository ;
24
24
import org .eclipse .jgit .revwalk .RevCommit ;
25
25
import org .eclipse .jgit .storage .file .FileRepositoryBuilder ;
26
+ import org .jetbrains .annotations .NotNull ;
26
27
import org .springframework .sbm .engine .context .ProjectContext ;
27
28
import org .springframework .sbm .project .resource .SbmApplicationProperties ;
28
29
import org .springframework .stereotype .Component ;
32
33
import java .nio .file .Path ;
33
34
import java .util .List ;
34
35
import java .util .Optional ;
36
+ import java .util .function .Consumer ;
35
37
import java .util .stream .Collectors ;
38
+ import java .util .stream .Stream ;
36
39
37
40
/**
38
41
* Provides basic Git support.
@@ -46,38 +49,72 @@ public class GitSupport {
46
49
47
50
private final SbmApplicationProperties sbmApplicationProperties ;
48
51
52
+ /**
53
+ * Find and return a git repository at given location.
54
+ * It searches up the hierarchy if {@code .git} does not exist in the given directory.
55
+ *
56
+ * @param repo the location of the repo to search for. {@code .git} is added to file location if not contained
57
+ */
58
+ public static Optional <Repository > findRepository (File repo ) {
59
+ Optional <Repository > repository = Optional .empty ();
60
+ try {
61
+ repository = Optional .of (new FileRepositoryBuilder ().findGitDir (repo ).setMustExist (true ).build ());
62
+
63
+ } catch (IllegalArgumentException | IOException e ) {
64
+ log .error ("Could not find .git in the given directory '{}' or any of it's parents" , repo , e );
65
+ }
66
+ return repository ;
67
+ }
68
+
69
+ /**
70
+ * Get the git repository or throw exception
71
+ */
72
+ public static Git getGit (File repo ) {
73
+ Repository repository = findRepository (repo ).orElseThrow (() -> new RuntimeException ());
74
+ return Git .wrap (repository );
75
+ }
76
+
49
77
/**
50
78
* Adds files to git index.
51
79
*
52
- * @param repo the location of the repo
53
- * @param filePatterns the filePatterns to add
80
+ * @param dirUnderGit a directory which itself or some parent dir contains .git
81
+ * @param filePatterns the filePatterns for files to add
54
82
*/
55
- public void add (File repo , String ... filePatterns ) {
83
+ public void add (File dirUnderGit , String ... filePatterns ) {
56
84
try {
57
- Git git = getRepository ( repo );
85
+ Git git = getGit ( dirUnderGit );
58
86
AddCommand add = git .add ();
59
- for (String filePattern : filePatterns ) {
60
- add .addFilepattern (filePattern );
61
- }
87
+ processFilePatterns (dirUnderGit , git , s -> add .addFilepattern (s ), filePatterns );
62
88
DirCache call = add .call ();
63
89
} catch (GitAPIException e ) {
64
90
throw new RuntimeException (e );
65
91
}
66
92
}
67
93
94
+ private void processFilePatterns (File dirUnderGit , Git git , Consumer <String > add , String [] filePatterns ) {
95
+ Path repoDir = git .getRepository ().getDirectory ().toPath ().getParent ();
96
+ Path pathFromGit = repoDir .relativize (dirUnderGit .toPath ());
97
+ for (String filePattern : filePatterns ) {
98
+ if (filePattern .equals ("." )) {
99
+ add .accept ("." );
100
+ } else {
101
+ filePattern = pathFromGit .resolve (filePattern ).toString ();
102
+ add .accept (filePattern );
103
+ }
104
+ }
105
+ }
106
+
68
107
/**
69
108
* Adds removed files to index.
70
109
*
71
- * @param repo the location of the repo
72
- * @param deleted the filePatterns to remove
110
+ * @param dirUnderGit a directory which itself or some parent dir contains .git
111
+ * @param filePatterns the filePatterns to remove
73
112
*/
74
- public void delete (File repo , String ... deleted ) {
113
+ public void delete (File dirUnderGit , String ... filePatterns ) {
75
114
try {
76
- Git git = getRepository ( repo );
115
+ Git git = getGit ( dirUnderGit );
77
116
RmCommand rm = git .rm ();
78
- for (String filePattern : deleted ) {
79
- rm .addFilepattern (filePattern );
80
- }
117
+ processFilePatterns (dirUnderGit , git , s -> rm .addFilepattern (s ), filePatterns );
81
118
rm .call ();
82
119
} catch (GitAPIException e ) {
83
120
throw new RuntimeException (e );
@@ -92,7 +129,7 @@ public void delete(File repo, String... deleted) {
92
129
*/
93
130
public Commit commit (File repo , String message ) {
94
131
try {
95
- Git git = getRepository (repo );
132
+ Git git = getGit (repo );
96
133
CommitCommand commit = git .commit ();
97
134
commit .setMessage (message );
98
135
RevCommit call = commit .call ();
@@ -109,10 +146,8 @@ public Commit commit(File repo, String message) {
109
146
*/
110
147
public Optional <Commit > getLatestCommit (File repo ) {
111
148
try {
112
- Git git = getRepository (repo );
113
- Iterable <RevCommit > revCommits = git .log ()
114
- .setMaxCount (1 )
115
- .call ();
149
+ Git git = getGit (repo );
150
+ Iterable <RevCommit > revCommits = git .log ().setMaxCount (1 ).call ();
116
151
RevCommit lastCommit = revCommits .iterator ().next ();
117
152
return Optional .of (new Commit (lastCommit .getName (), lastCommit .getFullMessage ()));
118
153
} catch (GitAPIException e ) {
@@ -122,37 +157,6 @@ public Optional<Commit> getLatestCommit(File repo) {
122
157
}
123
158
124
159
125
- /**
126
- * Find and return a git repository at given location.
127
- *
128
- * @param repo the location of the repo to search for. {@code .git} is added to file location if not contained
129
- */
130
- public static Optional <Repository > findRepository (File repo ) {
131
- Optional <Repository > repository = Optional .empty ();
132
- try {
133
- repository = Optional .of (new FileRepositoryBuilder ()
134
- .findGitDir (repo )
135
- .setMustExist (true )
136
- .build ());
137
-
138
- } catch (IllegalArgumentException | IOException e ) {
139
- }
140
- return repository ;
141
- }
142
-
143
- /**
144
- * Get the git repository or throw exception
145
- */
146
- public static Git getRepository (File repo ) {
147
- try {
148
- Repository repository = findRepository (repo )
149
- .orElseThrow (() -> new RuntimeException ());
150
- return Git .open (repository .getDirectory ());
151
- } catch (IOException e ) {
152
- throw new RuntimeException (e );
153
- }
154
- }
155
-
156
160
/**
157
161
* Init a new git repo or return existing
158
162
*
@@ -186,10 +190,7 @@ private static boolean dirContainsGitRepo(File repo) {
186
190
public void softReset (File repo , String ref ) {
187
191
try {
188
192
Git git = initGit (repo );
189
- git .reset ()
190
- .setMode (ResetCommand .ResetType .SOFT )
191
- .setRef (ref )
192
- .call ();
193
+ git .reset ().setMode (ResetCommand .ResetType .SOFT ).setRef (ref ).call ();
193
194
} catch (GitAPIException e ) {
194
195
throw new RuntimeException (e );
195
196
}
@@ -201,10 +202,9 @@ public void softReset(File repo, String ref) {
201
202
* @param repo the location of the repo
202
203
* @param expectedRevision the revision to check
203
204
*/
204
- // TODO: test this method
205
205
public boolean hasUncommittedChangesOrDifferentRevision (File repo , String expectedRevision ) {
206
206
try {
207
- Git git = getRepository (repo );
207
+ Git git = getGit (repo );
208
208
Status status = git .status ().call ();
209
209
Optional <Commit > latestCommit = getLatestCommit (repo );
210
210
if (latestCommit .isEmpty ()) {
@@ -225,7 +225,6 @@ public boolean hasUncommittedChangesOrDifferentRevision(File repo, String expect
225
225
* @param modifedResources to add as modified
226
226
* @param deletedResources to add as deleted
227
227
*/
228
- // TODO: test this method
229
228
public Commit addAllAndCommit (File repo , String commitMessage , List <String > modifedResources , List <String > deletedResources ) {
230
229
if (!modifedResources .isEmpty ()) {
231
230
String [] modified = modifedResources .toArray (new String []{});
@@ -246,12 +245,16 @@ public boolean repoExists(File repoDir) {
246
245
return repository .isPresent ();
247
246
}
248
247
249
- // TODO: test this method
250
248
public void commitWhenGitAvailable (ProjectContext context , String appliedRecipeName , List <String > modifiedResources , List <String > deletedResources ) {
249
+ modifiedResources = modifiedResources .stream ()
250
+ .map (r -> context .getProjectRootDirectory ().relativize (Path .of (r )).toString ())
251
+ .collect (Collectors .toList ());
252
+ deletedResources = deletedResources .stream ()
253
+ .map (r -> context .getProjectRootDirectory ().relativize (Path .of (r )).toString ())
254
+ .collect (Collectors .toList ());
255
+
251
256
if (sbmApplicationProperties .isGitSupportEnabled ()) {
252
257
File repoDir = context .getProjectRootDirectory ().toFile ();
253
- modifiedResources = makeRelativeToRepositoryLocation (modifiedResources , repoDir );
254
- deletedResources = makeRelativeToRepositoryLocation (deletedResources , repoDir );
255
258
if (repoExists (repoDir )) {
256
259
String commitMessage = "SBM: applied recipe '" + appliedRecipeName + "'" ;
257
260
Commit latestCommit = addAllAndCommit (repoDir , commitMessage , modifiedResources , deletedResources );
@@ -261,24 +264,38 @@ public void commitWhenGitAvailable(ProjectContext context, String appliedRecipeN
261
264
}
262
265
263
266
public static Optional <String > getBranchName (File repo ) {
264
- Git git = getRepository (repo );
267
+ Git git = getGit (repo );
265
268
try {
266
269
return Optional .ofNullable (git .getRepository ().getBranch ());
267
270
} catch (IOException e ) {
268
271
return Optional .empty ();
269
272
}
270
273
}
271
274
272
- private List <String > makeRelativeToRepositoryLocation (List <String > paths , File projectRootDir ) {
273
- return paths .stream ()
274
- .map (p -> projectRootDir .toPath ().relativize (Path .of (p ).toAbsolutePath ().normalize ()))
275
+ private List <String > makeRelativeToRepositoryPath (List <String > paths , File projectRootDir ) {
276
+ Path gitPath = projectRootDir .toPath ();
277
+ while (!gitPath .resolve (".git" ).toFile ().isDirectory ()) {
278
+ gitPath = gitPath .getParent ();
279
+ if (gitPath == null ) {
280
+ throw new IllegalArgumentException (
281
+ "Could not find a .git dir in given project root dir '%s' or any parent directory." );
282
+ }
283
+ }
284
+ return getRelativePaths (paths , gitPath );
285
+ }
286
+
287
+ @ NotNull
288
+ private List <String > getRelativePaths (List <String > paths , Path curPath ) {
289
+ return paths
290
+ .stream ()
291
+ .map (p -> curPath .relativize (Path .of (p ).toAbsolutePath ().normalize ()))
275
292
.map (Path ::toString )
276
293
.collect (Collectors .toList ());
277
294
}
278
295
279
296
public GitStatus getStatus (File repo ) {
280
297
try {
281
- Git git = getRepository (repo );
298
+ Git git = getGit (repo );
282
299
Status status = null ;
283
300
status = git .status ().call ();
284
301
GitStatus gitStatus = new GitStatus (status );
@@ -290,7 +307,7 @@ public GitStatus getStatus(File repo) {
290
307
291
308
public void switchToBranch (File repo , String branchName ) {
292
309
try {
293
- Git git = getRepository (repo );
310
+ Git git = getGit (repo );
294
311
git .checkout ().setName (branchName ).setCreateBranch (true ).call ();
295
312
} catch (GitAPIException e ) {
296
313
e .printStackTrace ();
0 commit comments