3
3
import java .net .URL ;
4
4
import java .nio .file .Files ;
5
5
import java .nio .file .Path ;
6
- import java .util .AbstractMap ;
7
- import java .util .HashMap ;
8
6
import java .util .List ;
9
- import java .util .Map ;
10
7
import java .util .Objects ;
11
- import java .util .Optional ;
12
8
13
9
import com .devonfw .tools .ide .cli .CliOfflineException ;
14
10
import com .devonfw .tools .ide .process .ProcessContext ;
@@ -34,7 +30,7 @@ public class GitContextImpl implements GitContext {
34
30
public GitContextImpl (IdeContext context ) {
35
31
36
32
this .context = context ;
37
- this .processContext = this .context .newProcess ().executable ("git" ).withEnvVar ("GIT_TERMINAL_PROMPT" , "0" );
33
+ this .processContext = this .context .newProcess ().executable ("git" ).withEnvVar ("GIT_TERMINAL_PROMPT" , "0" ). errorHandling ( ProcessErrorHandling . WARNING ) ;
38
34
}
39
35
40
36
@ Override
@@ -56,74 +52,60 @@ public boolean fetchIfNeeded(Path targetRepository, String remote, String branch
56
52
}
57
53
58
54
@ Override
59
- public boolean isRepositoryUpdateAvailable (Path targetRepository ) {
55
+ public boolean isRepositoryUpdateAvailable (Path repository ) {
60
56
61
- this .processContext .directory (targetRepository );
62
- ProcessResult result ;
63
-
64
- // get local commit code
65
- result = this .processContext .addArg ("rev-parse" ).addArg ("HEAD" ).run (PROCESS_MODE_FOR_FETCH );
57
+ ProcessResult result = this .processContext .directory (repository ).addArg ("rev-parse" ).addArg ("HEAD" ).run (PROCESS_MODE_FOR_FETCH );
66
58
if (!result .isSuccessful ()) {
67
59
this .context .warning ("Failed to get the local commit hash." );
68
60
return false ;
69
61
}
70
-
71
- String local_commit_code = result .getOut ().stream ().findFirst ().orElse ("" ).trim ();
72
-
62
+ String localCommitHash = result .getOut ().stream ().findFirst ().orElse ("" ).trim ();
73
63
// get remote commit code
74
64
result = this .processContext .addArg ("rev-parse" ).addArg ("@{u}" ).run (PROCESS_MODE_FOR_FETCH );
75
65
if (!result .isSuccessful ()) {
76
66
this .context .warning ("Failed to get the remote commit hash." );
77
67
return false ;
78
68
}
79
69
String remote_commit_code = result .getOut ().stream ().findFirst ().orElse ("" ).trim ();
80
- return !local_commit_code .equals (remote_commit_code );
70
+ return !localCommitHash .equals (remote_commit_code );
81
71
}
82
72
83
73
@ Override
84
- public void pullOrCloneAndResetIfNeeded (String repoUrl , Path targetRepository , String branch , String remoteName ) {
74
+ public void pullOrCloneAndResetIfNeeded (String repoUrl , Path repository , String branch , String remoteName ) {
85
75
86
- pullOrCloneIfNeeded (repoUrl , branch , targetRepository );
76
+ pullOrCloneIfNeeded (repoUrl , branch , repository );
87
77
88
- reset (targetRepository , "master" , remoteName );
78
+ reset (repository , "master" , remoteName );
89
79
90
- cleanup (targetRepository );
80
+ cleanup (repository );
91
81
}
92
82
93
83
@ Override
94
- public void pullOrClone (String gitRepoUrl , Path targetRepository ) {
84
+ public void pullOrClone (String gitRepoUrl , Path repository ) {
95
85
96
- pullOrClone (gitRepoUrl , targetRepository , null );
86
+ pullOrClone (gitRepoUrl , repository , null );
97
87
}
98
88
99
89
@ Override
100
- public void pullOrClone (String gitRepoUrl , Path targetRepository , String branch ) {
90
+ public void pullOrClone (String gitRepoUrl , Path repository , String branch ) {
101
91
102
- Objects .requireNonNull (targetRepository );
92
+ Objects .requireNonNull (repository );
103
93
Objects .requireNonNull (gitRepoUrl );
104
-
105
94
if (!gitRepoUrl .startsWith ("http" )) {
106
95
throw new IllegalArgumentException ("Invalid git URL '" + gitRepoUrl + "'!" );
107
96
}
108
-
109
- if (Files .isDirectory (targetRepository .resolve (GIT_FOLDER ))) {
97
+ if (Files .isDirectory (repository .resolve (GIT_FOLDER ))) {
110
98
// checks for remotes
111
- this .processContext .directory (targetRepository );
112
- ProcessResult result = this .processContext .addArg ("remote" ).run (ProcessMode .DEFAULT_CAPTURE );
113
- List <String > remotes = result .getOut ();
114
- if (remotes .isEmpty ()) {
115
- String message = targetRepository + " is a local git repository with no remote - if you did this for testing, you may continue...\n "
99
+ String remote = determineRemote (repository );
100
+ if (remote == null ) {
101
+ String message = repository + " is a local git repository with no remote - if you did this for testing, you may continue...\n "
116
102
+ "Do you want to ignore the problem and continue anyhow?" ;
117
103
this .context .askToContinue (message );
118
104
} else {
119
- this .processContext .errorHandling (ProcessErrorHandling .WARNING );
120
-
121
- if (!this .context .isOffline ()) {
122
- pull (targetRepository );
123
- }
105
+ pull (repository );
124
106
}
125
107
} else {
126
- clone (new GitUrl (gitRepoUrl , branch ), targetRepository );
108
+ clone (new GitUrl (gitRepoUrl , branch ), repository );
127
109
}
128
110
}
129
111
@@ -185,89 +167,66 @@ public void clone(GitUrl gitRepoUrl, Path targetRepository) {
185
167
}
186
168
187
169
@ Override
188
- public void pull (Path targetRepository ) {
189
-
190
- this .processContext .directory (targetRepository );
191
- ProcessResult result ;
192
- // pull from remote
193
- result = this .processContext .addArg ("--no-pager" ).addArg ("pull" ).addArg ("--quiet" ).run (PROCESS_MODE );
170
+ public void pull (Path repository ) {
194
171
172
+ if (this .context .isOffline ()) {
173
+ this .context .info ("Skipping git pull on {} because offline" , repository );
174
+ return ;
175
+ }
176
+ ProcessResult result = this .processContext .directory (repository ).addArg ("--no-pager" ).addArg ("pull" ).addArg ("--quiet" ).run (PROCESS_MODE );
195
177
if (!result .isSuccessful ()) {
196
- Map <String , String > remoteAndBranchName = retrieveRemoteAndBranchName ();
197
- this .context .warning ("Git pull for {}/{} failed for repository {}." , remoteAndBranchName .get ("remote" ), remoteAndBranchName .get ("branch" ),
198
- targetRepository );
199
- handleErrors (targetRepository , result );
178
+ String branchName = determineCurrentBranch (repository );
179
+ this .context .warning ("Git pull on branch {} failed for repository {}." , branchName , repository );
180
+ handleErrors (repository , result );
200
181
}
201
182
}
202
183
203
184
@ Override
204
185
public void fetch (Path targetRepository , String remote , String branch ) {
205
186
206
- if ((remote == null ) || (branch == null )) {
207
- Optional <String []> remoteAndBranchOpt = getLocalRemoteAndBranch (targetRepository );
208
- if (remoteAndBranchOpt .isEmpty ()) {
209
- context .warning ("Could not determine the remote or branch for the git repository at {}" , targetRepository );
210
- return ; // false;
211
- }
212
- String [] remoteAndBranch = remoteAndBranchOpt .get ();
213
- if (remote == null ) {
214
- remote = remoteAndBranch [0 ];
215
- }
216
- if (branch == null ) {
217
- branch = remoteAndBranch [1 ];
218
- }
187
+ if (branch == null ) {
188
+ branch = determineCurrentBranch (targetRepository );
219
189
}
220
-
221
- this .processContext .directory (targetRepository );
222
- ProcessResult result ;
223
-
224
- result = this .processContext .addArg ("fetch" ).addArg (remote ).addArg (branch ).run (PROCESS_MODE_FOR_FETCH );
190
+ if (remote == null ) {
191
+ remote = determineRemote (targetRepository );
192
+ }
193
+ ProcessResult result = this .processContext .directory (targetRepository ).addArg ("fetch" ).addArg (remote ).addArg (branch ).run (PROCESS_MODE_FOR_FETCH );
225
194
226
195
if (!result .isSuccessful ()) {
227
196
this .context .warning ("Git fetch for '{}/{} failed.'." , remote , branch );
228
197
}
229
198
}
230
199
231
- private Map <String , String > retrieveRemoteAndBranchName () {
232
-
233
- Map <String , String > remoteAndBranchName = new HashMap <>();
234
- ProcessResult remoteResult = this .processContext .addArg ("branch" ).addArg ("-vv" ).run (PROCESS_MODE );
235
- List <String > remotes = remoteResult .getOut ();
236
- if (!remotes .isEmpty ()) {
237
- for (String remote : remotes ) {
238
- if (remote .startsWith ("*" )) {
239
- String checkedOutBranch = remote .substring (remote .indexOf ("[" ) + 1 , remote .indexOf ("]" ));
240
- remoteAndBranchName .put ("remote" , checkedOutBranch .substring (0 , checkedOutBranch .indexOf ("/" )));
241
- // check if current repo is behind remote and omit message
242
- if (checkedOutBranch .contains (":" )) {
243
- remoteAndBranchName .put ("branch" , checkedOutBranch .substring (checkedOutBranch .indexOf ("/" ) + 1 , checkedOutBranch .indexOf (":" )));
244
- } else {
245
- remoteAndBranchName .put ("branch" , checkedOutBranch .substring (checkedOutBranch .indexOf ("/" ) + 1 ));
246
- }
247
-
248
- }
200
+ @ Override
201
+ public String determineCurrentBranch (Path repository ) {
202
+
203
+ ProcessResult remoteResult = this .processContext .directory (repository ).addArg ("branch" ).addArg ("--show-current" ).run (ProcessMode .DEFAULT_CAPTURE );
204
+ if (remoteResult .isSuccessful ()) {
205
+ List <String > remotes = remoteResult .getOut ();
206
+ if (!remotes .isEmpty ()) {
207
+ assert (remotes .size () == 1 );
208
+ return remotes .get (0 );
249
209
}
250
210
} else {
251
- return Map . ofEntries ( new AbstractMap . SimpleEntry <>( "remote" , "unknown" ), new AbstractMap . SimpleEntry <>( " branch" , "unknown" ) );
211
+ this . context . warning ( "Failed to determine current branch of git repository {} " , repository );
252
212
}
253
-
254
- return remoteAndBranchName ;
213
+ return null ;
255
214
}
256
215
257
- private Optional < String []> getLocalRemoteAndBranch ( Path repositoryPath ) {
258
-
259
- this . processContext . directory ( repositoryPath );
260
- ProcessResult result = this .processContext .addArg ( "rev-parse" ).addArg ("--abbrev-ref " ).addArg ( "--symbolic-full-name" ). addArg ( "@{u}" )
261
- . run ( PROCESS_MODE_FOR_FETCH );
262
- if ( result . isSuccessful ()) {
263
- String upstream = result . getOut (). stream (). findFirst (). orElse ( "" );
264
- if ( upstream . contains ( "/" )) {
265
- return Optional . of ( upstream . split ( "/" , 2 )); // Split into remote and branch
216
+ @ Override
217
+ public String determineRemote ( Path repository ) {
218
+
219
+ ProcessResult remoteResult = this .processContext .directory ( repository ).addArg ("remote " ).run ( ProcessMode . DEFAULT_CAPTURE );
220
+ if ( remoteResult . isSuccessful ()) {
221
+ List < String > remotes = remoteResult . getOut ();
222
+ if (! remotes . isEmpty ()) {
223
+ assert ( remotes . size () == 1 );
224
+ return remotes . get ( 0 );
266
225
}
267
226
} else {
268
- this .context .warning ("Failed to determine the remote tracking branch." );
227
+ this .context .warning ("Failed to determine current origin of git repository {}" , repository );
269
228
}
270
- return Optional . empty () ;
229
+ return null ;
271
230
}
272
231
273
232
@ Override
0 commit comments