• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

devonfw / IDEasy / 29771990807

20 Jul 2026 07:26PM UTC coverage: 72.476% (-0.04%) from 72.513%
29771990807

push

github

web-flow
#1594: Implement release commandlet (#2023)

Co-authored-by: Jörg Hohwiller <hohwille@users.noreply.github.com>

4946 of 7546 branches covered (65.54%)

Branch coverage included in aggregate %.

12775 of 16905 relevant lines covered (75.57%)

3.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.54
cli/src/main/java/com/devonfw/tools/ide/git/GitContext.java
1
package com.devonfw.tools.ide.git;
2

3
import java.nio.file.Files;
4
import java.nio.file.Path;
5
import java.util.List;
6

7
import com.devonfw.tools.ide.cli.CliException;
8
import com.devonfw.tools.ide.cli.CliOfflineException;
9

10
/**
11
 * Interface for git commands with input and output of information for the user.
12
 */
13
public interface GitContext {
14

15
  /** The default git remote name. */
16
  String DEFAULT_REMOTE = "origin";
17

18
  /** The default git url of the settings repository for IDEasy developers */
19
  String DEFAULT_SETTINGS_GIT_URL = "https://github.com/devonfw/ide-settings.git";
20

21
  /** The name of the internal metadata folder of a git repository. */
22
  String GIT_FOLDER = ".git";
23

24
  /** The name of the HEAD file inside {@link #GIT_FOLDER}. */
25
  String FILE_HEAD = "HEAD";
26

27
  /** The name of the FETCH_HEAD file inside {@link #GIT_FOLDER}. */
28
  String FILE_FETCH_HEAD = "FETCH_HEAD";
29

30
  /**
31
   * Checks if the Git repository in the specified target folder needs an update by inspecting the modification time of a magic file.
32
   *
33
   * @param gitUrl the {@link GitUrl} to clone from.
34
   * @param repository the {@link Path} to the target folder where the git repository should be cloned or pulled. It is not the parent directory where git
35
   *     will by default create a sub-folder by default on clone but the final folder that will contain the ".git" subfolder.
36
   * @throws CliOfflineException if offline and cloning is needed.
37
   */
38
  void pullOrCloneIfNeeded(GitUrl gitUrl, Path repository);
39

40
  /**
41
   * Checks if a git fetch is needed and performs it if required.
42
   * <p>
43
   * This method checks the last modified time of the `FETCH_HEAD` file in the `.git` directory to determine if a fetch is needed based on a predefined
44
   * threshold. If updates are available in the remote repository, it logs an information message prompting the user to pull the latest changes.
45
   *
46
   * @param repository the {@link Path} to the target folder where the git repository is located. It contains the `.git` subfolder.
47
   * @return {@code true} if updates were detected after fetching from the remote repository, indicating that the local repository is behind the remote. *
48
   *     {@code false} if no updates were detected or if no fetching was performed (e.g., the cache threshold was not met or the context is offline)
49
   */
50
  boolean fetchIfNeeded(Path repository);
51

52
  /**
53
   * Checks if a git fetch is needed and performs it if required.
54
   * <p>
55
   * This method checks the last modified time of the `FETCH_HEAD` file in the `.git` directory to determine if a fetch is needed based on a predefined
56
   * threshold. If updates are available in the remote repository, it logs an information message prompting the user to pull the latest changes.
57
   *
58
   * @param repository the {@link Path} to the target folder where the git repository is located. It contains the `.git` subfolder.
59
   * @param remoteName the name of the remote repository, e.g., "origin".
60
   * @param branch the name of the branch to check for updates.
61
   * @return {@code true} if updates were detected after fetching from the remote repository, indicating that the local repository is behind the remote.
62
   *     {@code false} if no updates were detected or if no fetching was performed (e.g., the cache threshold was not met or the context is offline)
63
   */
64
  boolean fetchIfNeeded(Path repository, String remoteName, String branch);
65

66
  /**
67
   * @param directory the {@link Path} to the directory to check for repo status
68
   * @return {@code true} if `directory` is a Git repo, {@code false} otherwise
69
   */
70
  default boolean isGitRepo(Path directory) {
71
    return directory != null && Files.exists(directory.resolve(GIT_FOLDER));
13!
72
  }
73

74
  /**
75
   * Checks if there are updates available for the Git repository in the specified target folder by comparing the local commit hash with the remote commit
76
   * hash.
77
   *
78
   * @param repository the {@link Path} to the target folder where the git repository is located.
79
   * @return {@code true} if the remote repository contains commits that are not present in the local repository, indicating that updates are available.
80
   *     {@code false} if the local and remote repositories are in sync, or if there was an issue retrieving the commit hashes.
81
   */
82
  boolean isRepositoryUpdateAvailable(Path repository);
83

84
  /**
85
   * Checks if there are updates available for the Git repository in the specified target folder by comparing the local commit hash with the remote commit
86
   * hash.
87
   *
88
   * @param repository the {@link Path} to the target folder where the git repository is located.
89
   * @param trackedCommitIdPath the {@link Path} to a file containing the last tracked commit ID of this repository.
90
   * @return {@code true} if the remote repository contains commits that are not present in the local repository, indicating that updates are available.
91
   *     {@code false} if the local and remote repositories are in sync, or if there was an issue retrieving the commit hashes.
92
   */
93
  boolean isRepositoryUpdateAvailable(Path repository, Path trackedCommitIdPath);
94

95
  /**
96
   * Attempts a git pull and reset if required.
97
   *
98
   * @param gitUrl the {@link GitUrl} to clone from.
99
   * @param repository the {@link Path} to the target folder where the git repository should be cloned or pulled. It is not the parent directory where git
100
   *     will by default create a sub-folder by default on clone but the final folder that will contain the ".git" subfolder.
101
   * @param remoteName the remote name e.g. origin.
102
   * @throws CliOfflineException if offline and cloning is needed.
103
   */
104
  void pullOrCloneAndResetIfNeeded(GitUrl gitUrl, Path repository, String remoteName);
105

106
  /**
107
   * Performs a {@code git pull} operation on the given repository while safely preserving and restoring any local untracked or modified files using a temporary
108
   * Git stash.
109
   *
110
   * @param repository the {@link Path} to the root directory of the Git repository. This must be the directory that directly contains the {@code .git}
111
   *     folder.
112
   */
113
  void pullSafelyWithStash(Path repository);
114

115
  /**
116
   * Checks whether the given Git repository contains any untracked files.
117
   * <p>
118
   * This method runs {@code git status --porcelain -uall} to retrieve a machine-readable status of the repository. The {@code -uall} option ensures that all
119
   * untracked files, including those in subdirectories, are listed. If the output of the command is non-empty, this method considers the repository to contain
120
   * untracked files.
121
   * </p>
122
   *
123
   * @param repository the {@link Path} to the target folder where the git repository should be checked for untracked files. It is not the parent directory
124
   *     where git will by default create a sub-folder by default on clone but the final folder that will contain the ".git" subfolder.
125
   * @return {@code true} if the local repository contains untracked changes. {@code false} if no untracked files are present or if the Git command fails.
126
   */
127
  boolean hasUntrackedFiles(Path repository);
128

129
  /**
130
   * Runs a git pull or a git clone.
131
   *
132
   * @param gitUrl the {@link GitUrl} to clone from.
133
   * @param repository the {@link Path} to the target folder where the git repository should be cloned or pulled. It is not the parent directory where git
134
   *     will by default create a sub-folder by default on clone but the final folder that will contain the ".git" subfolder.
135
   * @throws CliOfflineException if offline and cloning is needed.
136
   */
137
  void pullOrClone(GitUrl gitUrl, Path repository);
138

139
  /**
140
   * Runs a git clone.
141
   *
142
   * @param gitUrl the {@link GitUrl} to use for the repository URL.
143
   * @param repository the {@link Path} to the target folder where the git repository should be cloned or pulled. It is not the parent directory where git
144
   *     will by default create a sub-folder by default on clone but the * final folder that will contain the ".git" subfolder.
145
   * @throws CliOfflineException if offline and cloning is needed.
146
   */
147
  void clone(GitUrl gitUrl, Path repository);
148

149
  /**
150
   * Runs a git pull.
151
   *
152
   * @param repository the {@link Path} to the target folder where the git repository should be cloned or pulled. It is not the parent directory where git
153
   *     will by default create a sub-folder by default on clone but the * final folder that will contain the ".git" subfolder.
154
   */
155
  void pull(Path repository);
156

157
  /**
158
   * Runs a git diff-index to detect local changes and if so reverts them via git reset.
159
   *
160
   * @param repository the {@link Path} to the target folder where the git repository should be cloned or pulled. It is not the parent directory where git
161
   *     will by default create a sub-folder by default on clone but the final folder that will contain the ".git" subfolder.
162
   */
163
  default void reset(Path repository) {
164

165
    reset(repository, null);
4✔
166
  }
1✔
167

168
  /**
169
   * Runs a git diff-index to detect local changes and if so reverts them via git reset.
170
   *
171
   * @param repository the {@link Path} to the target folder where the git repository should be cloned or pulled. It is not the parent directory where git
172
   *     will by default create a sub-folder by default on clone but the final folder that will contain the ".git" subfolder.
173
   * @param branch the explicit name of the branch to checkout e.g. "main" or {@code null} to use the default branch.
174
   */
175
  default void reset(Path repository, String branch) {
176

177
    reset(repository, branch, null);
5✔
178
  }
1✔
179

180
  /**
181
   * Runs a git fetch.
182
   *
183
   * @param repository the {@link Path} to the target folder where the git repository should be cloned or pulled. It is not the parent directory where git
184
   *     will by default create a sub-folder by default on clone but the final folder that will contain the ".git" subfolder.
185
   * @param remote the name of the remote repository, e.g., "origin". If {@code null} or empty, the default remote name "origin" will be used.
186
   * @param branch the name of the branch to check for updates.
187
   */
188
  void fetch(Path repository, String remote, String branch);
189

190
  /**
191
   * Runs a git reset reverting all local changes to the git repository.
192
   *
193
   * @param repository the {@link Path} to the target folder where the git repository should be cloned or pulled. It is not the parent directory where git
194
   *     will by default create a sub-folder by default on clone but the * final folder that will contain the ".git" subfolder.
195
   * @param branch the explicit name of the branch to checkout e.g. "main" or {@code null} to use the default branch.
196
   * @param remoteName the name of the git remote e.g. "origin".
197
   */
198
  void reset(Path repository, String branch, String remoteName);
199

200
  /**
201
   * Runs a git cleanup if untracked files were found.
202
   *
203
   * @param repository the {@link Path} to the target folder where the git repository should be cloned or pulled. It is not the parent directory where git
204
   *     will by default create a sub-folder by default on clone but the * final folder that will contain the ".git" subfolder.
205
   */
206
  void cleanup(Path repository);
207

208
  /**
209
   * Returns the URL of a git repository
210
   *
211
   * @param repository the {@link Path} to the folder where the git repository is located.
212
   * @return the url of the repository as a {@link String}.
213
   */
214
  String retrieveGitUrl(Path repository);
215

216
  /**
217
   * @param repository the {@link Path} to the git repository.
218
   * @return the {@link List} of configured git remotes (output of {@code git remote -v}).
219
   */
220
  List<String> retrieveGitRemotes(Path repository);
221

222
  /**
223
   * Finds the {@link Path} to the git installation and throws an exception if there is none.
224
   *
225
   * @return the {@link Path} to the Git installation. Throws a {@link CliException} if no git was found.
226
   */
227
  Path findGitRequired();
228

229
  /**
230
   * Finds the path to the Git executable.
231
   *
232
   * @return the {@link Path} to the Git executable, or {@code null} if Git is not found.
233
   */
234
  Path findGit();
235

236
  /**
237
   * @param repository the {@link Path} to the folder where the git repository is located.
238
   * @return the name of the current branch.
239
   */
240
  String determineCurrentBranch(Path repository);
241

242
  /**
243
   * @param repository the {@link Path} to the folder where the git repository is located.
244
   * @return the name of the default origin.
245
   */
246
  String determineRemote(Path repository);
247

248
  /**
249
   * Saves the current git commit ID of a repository to a file given as an argument.
250
   *
251
   * @param repository the path to the git repository
252
   * @param trackedCommitIdPath the path to the file where the commit Id will be written.
253
   */
254
  void saveCurrentCommitId(Path repository, Path trackedCommitIdPath);
255

256
  /**
257
   * Commits the staged changes in the given repository.
258
   *
259
   * @param repository the {@link Path} to the git repository.
260
   * @param message the commit message.
261
   */
262
  default void commit(Path repository, String message) {
263

264
    commit(repository, message, false);
×
265
  }
×
266

267
  /**
268
   * Commits changes in the given repository.
269
   *
270
   * @param repository the {@link Path} to the git repository.
271
   * @param message the commit message.
272
   * @param addAll {@code true} to stage all modified tracked files before committing, {@code false} to only commit changes that are already staged.
273
   */
274
  void commit(Path repository, String message, boolean addAll);
275

276
  /**
277
   * Creates an annotated git tag in the given repository.
278
   *
279
   * @param repository the {@link Path} to the git repository.
280
   * @param tagName the name of the tag to create (e.g. "release/1.5.0").
281
   * @param message the annotation message of the tag.
282
   */
283
  void tag(Path repository, String tagName, String message);
284

285
  /**
286
   * Pushes the local commits of the given repository to the remote repository.
287
   *
288
   * @param repository the {@link Path} to the git repository.
289
   */
290
  default void push(Path repository) {
291

292
    push(repository, false);
×
293
  }
×
294

295
  /**
296
   * Pushes the local commits of the given repository to the remote repository.
297
   *
298
   * @param repository the {@link Path} to the git repository.
299
   * @param followTags {@code true} to also push annotated tags reachable from the pushed commits (git push --follow-tags), {@code false} to push commits only.
300
   */
301
  void push(Path repository, boolean followTags);
302
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc