33import java .net .URL ;
44import java .nio .file .Files ;
55import java .nio .file .Path ;
6- import java .util .AbstractMap ;
7- import java .util .HashMap ;
86import java .util .List ;
9- import java .util .Map ;
107import java .util .Objects ;
11- import java .util .Optional ;
128
139import com .devonfw .tools .ide .cli .CliOfflineException ;
1410import com .devonfw .tools .ide .process .ProcessContext ;
@@ -34,7 +30,7 @@ public class GitContextImpl implements GitContext {
3430 public GitContextImpl (IdeContext context ) {
3531
3632 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 ) ;
3834 }
3935
4036 @ Override
@@ -56,74 +52,60 @@ public boolean fetchIfNeeded(Path targetRepository, String remote, String branch
5652 }
5753
5854 @ Override
59- public boolean isRepositoryUpdateAvailable (Path targetRepository ) {
55+ public boolean isRepositoryUpdateAvailable (Path repository ) {
6056
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 );
6658 if (!result .isSuccessful ()) {
6759 this .context .warning ("Failed to get the local commit hash." );
6860 return false ;
6961 }
70-
71- String local_commit_code = result .getOut ().stream ().findFirst ().orElse ("" ).trim ();
72-
62+ String localCommitHash = result .getOut ().stream ().findFirst ().orElse ("" ).trim ();
7363 // get remote commit code
7464 result = this .processContext .addArg ("rev-parse" ).addArg ("@{u}" ).run (PROCESS_MODE_FOR_FETCH );
7565 if (!result .isSuccessful ()) {
7666 this .context .warning ("Failed to get the remote commit hash." );
7767 return false ;
7868 }
7969 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 );
8171 }
8272
8373 @ 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 ) {
8575
86- pullOrCloneIfNeeded (repoUrl , branch , targetRepository );
76+ pullOrCloneIfNeeded (repoUrl , branch , repository );
8777
88- reset (targetRepository , "master" , remoteName );
78+ reset (repository , "master" , remoteName );
8979
90- cleanup (targetRepository );
80+ cleanup (repository );
9181 }
9282
9383 @ Override
94- public void pullOrClone (String gitRepoUrl , Path targetRepository ) {
84+ public void pullOrClone (String gitRepoUrl , Path repository ) {
9585
96- pullOrClone (gitRepoUrl , targetRepository , null );
86+ pullOrClone (gitRepoUrl , repository , null );
9787 }
9888
9989 @ Override
100- public void pullOrClone (String gitRepoUrl , Path targetRepository , String branch ) {
90+ public void pullOrClone (String gitRepoUrl , Path repository , String branch ) {
10191
102- Objects .requireNonNull (targetRepository );
92+ Objects .requireNonNull (repository );
10393 Objects .requireNonNull (gitRepoUrl );
104-
10594 if (!gitRepoUrl .startsWith ("http" )) {
10695 throw new IllegalArgumentException ("Invalid git URL '" + gitRepoUrl + "'!" );
10796 }
108-
109- if (Files .isDirectory (targetRepository .resolve (GIT_FOLDER ))) {
97+ if (Files .isDirectory (repository .resolve (GIT_FOLDER ))) {
11098 // 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 "
116102 + "Do you want to ignore the problem and continue anyhow?" ;
117103 this .context .askToContinue (message );
118104 } else {
119- this .processContext .errorHandling (ProcessErrorHandling .WARNING );
120-
121- if (!this .context .isOffline ()) {
122- pull (targetRepository );
123- }
105+ pull (repository );
124106 }
125107 } else {
126- clone (new GitUrl (gitRepoUrl , branch ), targetRepository );
108+ clone (new GitUrl (gitRepoUrl , branch ), repository );
127109 }
128110 }
129111
@@ -185,89 +167,66 @@ public void clone(GitUrl gitRepoUrl, Path targetRepository) {
185167 }
186168
187169 @ 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 ) {
194171
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 );
195177 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 );
200181 }
201182 }
202183
203184 @ Override
204185 public void fetch (Path targetRepository , String remote , String branch ) {
205186
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 );
219189 }
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 );
225194
226195 if (!result .isSuccessful ()) {
227196 this .context .warning ("Git fetch for '{}/{} failed.'." , remote , branch );
228197 }
229198 }
230199
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 );
249209 }
250210 } 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 );
252212 }
253-
254- return remoteAndBranchName ;
213+ return null ;
255214 }
256215
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 );
266225 }
267226 } 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 );
269228 }
270- return Optional . empty () ;
229+ return null ;
271230 }
272231
273232 @ Override
0 commit comments