Skip to content

Commit 7233c6e

Browse files
committed
fix(git): add missing imports
1 parent 6ab17d0 commit 7233c6e

File tree

5 files changed

+174
-75
lines changed

5 files changed

+174
-75
lines changed

jabgui/src/main/java/org/jabref/gui/git/GitShareToGitHubDialogView.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ public GitShareToGitHubDialogView(StateManager stateManager, DialogService dialo
5656
@FXML
5757
private void initialize() {
5858
patHelpTooltip.setText(
59-
Localization.lang("Need help?") + "\n" +
60-
Localization.lang("Click to open GitHub Personal Access Token documentation")
59+
Localization.lang("Click to open GitHub Personal Access Token documentation")
6160
);
6261

6362
username.setPromptText(Localization.lang("Your GitHub username"));

jabgui/src/main/java/org/jabref/gui/git/GitShareToGitHubDialogViewModel.java

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -86,53 +86,62 @@ public boolean shareToGitHub() {
8686

8787
try {
8888
GitInitService.initRepoAndSetRemote(bibPath, url);
89+
} catch (JabRefException e) {
90+
dialogService.showErrorDialogAndWait(Localization.lang("Git error"), e.getMessage(), e);
91+
return false;
92+
}
8993

90-
GitHandlerRegistry registry = new GitHandlerRegistry();
91-
GitHandler handler = registry.get(bibPath.getParent());
94+
GitHandlerRegistry registry = new GitHandlerRegistry();
95+
GitHandler handler = registry.get(bibPath.getParent());
9296

93-
boolean hasStoredPat = gitPreferences.getPersonalAccessToken().isPresent();
94-
if (!rememberSettingsProperty().get() || !hasStoredPat) {
95-
handler.setCredentials(user, pat);
96-
}
97-
GitStatusSnapshot status = GitStatusChecker.checkStatusAndFetch(handler);
98-
99-
if (status.syncStatus() == SyncStatus.BEHIND) {
100-
dialogService.showWarningDialogAndWait(
101-
Localization.lang("Remote repository is not empty"),
102-
Localization.lang("Please pull changes before pushing.")
103-
);
104-
return false;
105-
}
106-
107-
handler.createCommitOnCurrentBranch(Localization.lang("Share library to GitHub"), false);
108-
try {
109-
if (status.syncStatus() == SyncStatus.REMOTE_EMPTY) {
110-
handler.pushCurrentBranchCreatingUpstream();
111-
} else {
112-
handler.pushCommitsToRemoteRepository();
113-
}
114-
} catch (IOException | GitAPIException e) {
115-
LOGGER.error("Push failed", e);
116-
dialogService.showErrorDialogAndWait(Localization.lang("Git error"), e);
117-
return false;
118-
}
97+
boolean hasStoredPat = gitPreferences.getPersonalAccessToken().isPresent();
98+
if (!rememberSettingsProperty().get() || !hasStoredPat) {
99+
handler.setCredentials(user, pat);
100+
}
119101

120-
setGitPreferences(url, user, pat);
102+
GitStatusSnapshot status = null;
103+
try {
104+
status = GitStatusChecker.checkStatusAndFetch(handler);
105+
} catch (IOException | JabRefException e) {
106+
dialogService.showErrorDialogAndWait(Localization.lang("Cannot reach remote"), e);
107+
return false;
108+
}
121109

122-
dialogService.showInformationDialogAndWait(
123-
Localization.lang("GitHub Share"),
124-
Localization.lang("Successfully pushed to %0", url)
110+
if (status.syncStatus() == SyncStatus.BEHIND) {
111+
dialogService.showWarningDialogAndWait(
112+
Localization.lang("Remote repository is not empty"),
113+
Localization.lang("Please pull changes before pushing.")
125114
);
126-
return true;
127-
} catch (GitAPIException |
128-
IOException e) {
129-
LOGGER.error("Error sharing to GitHub", e);
130-
dialogService.showErrorDialogAndWait(Localization.lang("Git error"), e);
131115
return false;
132-
} catch (JabRefException e) {
116+
}
117+
118+
try {
119+
handler.createCommitOnCurrentBranch(Localization.lang("Share library to GitHub"), false);
120+
} catch (IOException | GitAPIException e) {
121+
dialogService.showErrorDialogAndWait(Localization.lang("Create commit failed", e));
122+
}
123+
124+
try {
125+
if (status.syncStatus() == SyncStatus.REMOTE_EMPTY) {
126+
handler.pushCurrentBranchCreatingUpstream();
127+
} else {
128+
handler.pushCommitsToRemoteRepository();
129+
}
130+
} catch (IOException | GitAPIException e) {
131+
LOGGER.error("Push failed", e);
133132
dialogService.showErrorDialogAndWait(Localization.lang("Git error"), e);
134133
return false;
134+
} catch (JabRefException e) {
135+
dialogService.showErrorDialogAndWait(Localization.lang("Missing Git credentials"), e);
135136
}
137+
138+
setGitPreferences(url, user, pat);
139+
140+
dialogService.showInformationDialogAndWait(
141+
Localization.lang("GitHub Share"),
142+
Localization.lang("Successfully pushed to %0", url)
143+
);
144+
return true;
136145
}
137146

138147
private void applyGitPreferences() {
@@ -158,7 +167,7 @@ private void setGitPreferences(String url, String user, String pat) {
158167
}
159168

160169
private static String trimOrEmpty(String s) {
161-
return (s == null) ? "" : s.trim();
170+
return s == null ? "" : s.trim();
162171
}
163172

164173
public StringProperty githubUsernameProperty() {

jablib/src/main/java/org/jabref/logic/git/GitHandler.java

Lines changed: 121 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,30 @@
33
import java.io.File;
44
import java.io.IOException;
55
import java.io.InputStream;
6+
import java.net.URISyntaxException;
67
import java.nio.file.Files;
78
import java.nio.file.Path;
89
import java.util.Optional;
10+
import java.util.Set;
911

1012
import org.jabref.logic.JabRefException;
1113
import org.jabref.logic.git.prefs.GitPreferences;
1214

15+
import org.eclipse.jgit.api.FetchCommand;
1316
import org.eclipse.jgit.api.Git;
17+
import org.eclipse.jgit.api.PullCommand;
18+
import org.eclipse.jgit.api.PushCommand;
1419
import org.eclipse.jgit.api.RmCommand;
1520
import org.eclipse.jgit.api.Status;
1621
import org.eclipse.jgit.api.errors.GitAPIException;
1722
import org.eclipse.jgit.lib.Ref;
1823
import org.eclipse.jgit.lib.Repository;
1924
import org.eclipse.jgit.lib.RepositoryState;
25+
import org.eclipse.jgit.lib.StoredConfig;
2026
import org.eclipse.jgit.merge.MergeStrategy;
21-
import org.eclipse.jgit.revwalk.RevCommit;
2227
import org.eclipse.jgit.transport.CredentialsProvider;
2328
import org.eclipse.jgit.transport.RefSpec;
29+
import org.eclipse.jgit.transport.URIish;
2430
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
2531
import org.slf4j.Logger;
2632
import org.slf4j.LoggerFactory;
@@ -73,7 +79,7 @@ public void initIfNeeded() {
7379
}
7480
}
7581

76-
private Optional<CredentialsProvider> resolveCredentialsOrLoad() throws JabRefException {
82+
private Optional<CredentialsProvider> resolveCredentials() {
7783
if (credentialsProvider != null) {
7884
return Optional.of(credentialsProvider);
7985
}
@@ -107,6 +113,46 @@ public void setCredentials(String username, String pat) {
107113
this.credentialsProvider = new UsernamePasswordCredentialsProvider(username, pat);
108114
}
109115

116+
private static Optional<String> currentRemoteUrl(Repository repo) {
117+
try {
118+
StoredConfig config = repo.getConfig();
119+
String branch = repo.getBranch();
120+
121+
String remote = config.getString("branch", branch, "remote");
122+
if (remote == null) {
123+
Set<String> remotes = config.getSubsections("remote");
124+
if (remotes.contains("origin")) {
125+
remote = "origin";
126+
} else if (!remotes.isEmpty()) {
127+
remote = remotes.iterator().next();
128+
}
129+
}
130+
if (remote == null) {
131+
return Optional.empty();
132+
}
133+
String url = config.getString("remote", remote, "url");
134+
if (url == null || url.isBlank()) {
135+
return Optional.empty();
136+
}
137+
return Optional.of(url);
138+
} catch (IOException e) {
139+
return Optional.empty();
140+
}
141+
}
142+
143+
private static boolean requiresCredentialsForUrl(String url) {
144+
try {
145+
URIish uri = new URIish(url);
146+
String scheme = uri.getScheme();
147+
if (scheme == null) {
148+
return false;
149+
}
150+
return "http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme);
151+
} catch (URISyntaxException e) {
152+
return false;
153+
}
154+
}
155+
110156
void setupGitIgnore() {
111157
Path gitignore = Path.of(repositoryPath.toString(), ".gitignore");
112158
if (!Files.exists(gitignore)) {
@@ -231,37 +277,65 @@ public void mergeBranches(String targetBranch, String sourceBranch, MergeStrateg
231277
* If pushing to remote fails, it fails silently.
232278
*/
233279
public void pushCommitsToRemoteRepository() throws IOException, GitAPIException, JabRefException {
234-
CredentialsProvider provider = resolveCredentialsOrLoad().orElseThrow(() -> new IOException("Missing Git credentials (username and Personal Access Token)."));
235-
236280
try (Git git = Git.open(this.repositoryPathAsFile)) {
237-
git.push()
238-
.setCredentialsProvider(provider)
239-
.call();
281+
Optional<String> urlOpt = currentRemoteUrl(git.getRepository());
282+
Optional<CredentialsProvider> credsOpt = resolveCredentials();
283+
284+
boolean needCreds = urlOpt.map(GitHandler::requiresCredentialsForUrl).orElse(false);
285+
if (needCreds && credsOpt.isEmpty()) {
286+
throw new IOException("Missing Git credentials (username and Personal Access Token).");
287+
}
288+
289+
PushCommand pushCommand = git.push();
290+
if (credsOpt.isPresent()) {
291+
pushCommand.setCredentialsProvider(credsOpt.get());
292+
}
293+
pushCommand.call();
240294
}
241295
}
242296

243297
public void pushCurrentBranchCreatingUpstream() throws IOException, GitAPIException, JabRefException {
244298
try (Git git = open()) {
245-
CredentialsProvider provider = resolveCredentialsOrLoad().orElseThrow(() -> new IOException("Missing Git credentials (username and Personal Access Token)."));
246-
String branch = git.getRepository().getBranch();
247-
git.push()
248-
.setRemote("origin")
249-
.setCredentialsProvider(provider)
250-
.setRefSpecs(new RefSpec("refs/heads/" + branch + ":refs/heads/" + branch))
251-
.call();
299+
Repository repo = git.getRepository();
300+
StoredConfig config = repo.getConfig();
301+
String remoteUrl = config.getString("remote", "origin", "url");
302+
303+
Optional<CredentialsProvider> credsOpt = resolveCredentials();
304+
boolean needCreds = (remoteUrl != null) && requiresCredentialsForUrl(remoteUrl);
305+
if (needCreds && credsOpt.isEmpty()) {
306+
throw new IOException("Missing Git credentials (username and Personal Access Token).");
307+
}
308+
309+
String branch = repo.getBranch();
310+
311+
PushCommand pushCommand = git.push()
312+
.setRemote("origin")
313+
.setRefSpecs(new RefSpec("refs/heads/" + branch + ":refs/heads/" + branch));
314+
315+
if (credsOpt.isPresent()) {
316+
pushCommand.setCredentialsProvider(credsOpt.get());
317+
}
318+
pushCommand.call();
252319
}
253320
}
254321

255-
public void pullOnCurrentBranch() throws IOException, JabRefException {
256-
CredentialsProvider provider = resolveCredentialsOrLoad().orElseThrow(() -> new IOException("Missing Git credentials (username and Personal Access Token)."));
322+
public void pullOnCurrentBranch() throws IOException {
257323
try (Git git = Git.open(this.repositoryPathAsFile)) {
258-
try {
259-
git.pull()
260-
.setCredentialsProvider(provider)
261-
.call();
262-
} catch (GitAPIException e) {
263-
LOGGER.info("Failed to push");
324+
Optional<String> urlOpt = currentRemoteUrl(git.getRepository());
325+
Optional<CredentialsProvider> credsOpt = resolveCredentials();
326+
327+
boolean needCreds = urlOpt.map(GitHandler::requiresCredentialsForUrl).orElse(false);
328+
if (needCreds && credsOpt.isEmpty()) {
329+
throw new IOException("Missing Git credentials (username and Personal Access Token).");
330+
}
331+
332+
PullCommand pullCommand = git.pull();
333+
if (credsOpt.isPresent()) {
334+
pullCommand.setCredentialsProvider(credsOpt.get());
264335
}
336+
pullCommand.call();
337+
} catch (GitAPIException e) {
338+
throw new IOException("Failed to pull from remote: " + e.getMessage(), e);
265339
}
266340
}
267341

@@ -271,14 +345,22 @@ public String getCurrentlyCheckedOutBranch() throws IOException {
271345
}
272346
}
273347

274-
public void fetchOnCurrentBranch() throws IOException, JabRefException {
275-
CredentialsProvider provider = resolveCredentialsOrLoad().orElseThrow(() -> new IOException("Missing Git credentials (username and Personal Access Token)."));
348+
public void fetchOnCurrentBranch() throws IOException {
276349
try (Git git = Git.open(this.repositoryPathAsFile)) {
277-
git.fetch()
278-
.setCredentialsProvider(provider)
279-
.call();
350+
Optional<String> urlOpt = currentRemoteUrl(git.getRepository());
351+
Optional<CredentialsProvider> credsOpt = resolveCredentials();
352+
353+
boolean needCreds = urlOpt.map(GitHandler::requiresCredentialsForUrl).orElse(false);
354+
if (needCreds && credsOpt.isEmpty()) {
355+
throw new IOException("Missing Git credentials (username and Personal Access Token).");
356+
}
357+
FetchCommand fetchCommand = git.fetch();
358+
if (credsOpt.isPresent()) {
359+
fetchCommand.setCredentialsProvider(credsOpt.get());
360+
}
361+
fetchCommand.call();
280362
} catch (GitAPIException e) {
281-
LOGGER.error("Failed to fetch from remote", e);
363+
throw new IOException("Failed to fetch from remote: " + e.getMessage(), e);
282364
}
283365
}
284366

@@ -312,4 +394,15 @@ public File getRepositoryPathAsFile() {
312394
public Git open() throws IOException {
313395
return Git.open(this.repositoryPathAsFile);
314396
}
397+
398+
public boolean hasRemote(String remoteName) {
399+
try (Git git = Git.open(this.repositoryPathAsFile)) {
400+
return git.getRepository().getConfig()
401+
.getSubsections("remote")
402+
.contains(remoteName);
403+
} catch (IOException e) {
404+
LOGGER.error("Failed to check remote configuration", e);
405+
return false;
406+
}
407+
}
315408
}

jablib/src/test/java/org/jabref/logic/crawler/StudyCatalogToFetcherConverterTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.jabref.logic.crawler;
22

3-
import java.io.IOException;
43
import java.net.URISyntaxException;
54
import java.net.URL;
65
import java.nio.file.Path;
@@ -9,7 +8,6 @@
98

109
import javafx.collections.FXCollections;
1110

12-
import org.jabref.logic.JabRefException;
1311
import org.jabref.logic.exporter.SaveConfiguration;
1412
import org.jabref.logic.git.SlrGitHandler;
1513
import org.jabref.logic.importer.ImportFormatPreferences;
@@ -51,7 +49,7 @@ void setUpMocks() {
5149
}
5250

5351
@Test
54-
void getActiveFetcherInstances() throws IOException, URISyntaxException, JabRefException {
52+
void getActiveFetcherInstances() throws Exception {
5553
Path studyDefinition = tempRepositoryDirectory.resolve(StudyRepository.STUDY_DEFINITION_FILE_NAME);
5654
copyTestStudyDefinitionFileIntoDirectory(studyDefinition);
5755

jablib/src/test/java/org/jabref/logic/git/GitSyncServiceTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import org.jabref.logic.git.io.GitFileReader;
1313
import org.jabref.logic.git.merge.GitSemanticMergeExecutor;
1414
import org.jabref.logic.git.merge.GitSemanticMergeExecutorImpl;
15-
import org.jabref.logic.git.model.MergeResult;
15+
import org.jabref.logic.git.model.PullResult;
1616
import org.jabref.logic.git.util.GitHandlerRegistry;
1717
import org.jabref.logic.importer.ImportFormatPreferences;
1818
import org.jabref.logic.importer.ParserResult;
@@ -209,7 +209,7 @@ void cleanup() {
209209
@Test
210210
void pullTriggersSemanticMergeWhenNoConflicts() throws Exception {
211211
GitSyncService syncService = new GitSyncService(importFormatPreferences, gitHandlerRegistry, gitConflictResolverStrategy, mergeExecutor);
212-
MergeResult result = syncService.fetchAndMerge(context, library);
212+
PullResult result = syncService.fetchAndMerge(context, library);
213213

214214
assertTrue(result.isSuccessful());
215215
String merged = Files.readString(library);
@@ -310,7 +310,7 @@ void mergeConflictOnSameFieldTriggersDialogAndUsesUserResolution() throws Except
310310
});
311311

312312
GitSyncService service = new GitSyncService(importFormatPreferences, gitHandlerRegistry, resolver, mergeExecutor);
313-
MergeResult result = service.fetchAndMerge(context, library);
313+
PullResult result = service.fetchAndMerge(context, library);
314314

315315
assertTrue(result.isSuccessful());
316316
String content = Files.readString(library);

0 commit comments

Comments
 (0)