|
2 | 2 |
|
3 | 3 | import java.io.IOException;
|
4 | 4 | import java.nio.file.Path;
|
5 |
| -import java.util.ArrayList; |
6 |
| -import java.util.List; |
7 |
| -import java.util.Optional; |
8 | 5 |
|
9 | 6 | import org.jabref.gui.AbstractViewModel;
|
10 |
| -import org.jabref.gui.DialogService; |
11 | 7 | import org.jabref.logic.JabRefException;
|
12 |
| -import org.jabref.logic.git.GitConflictResolver; |
13 |
| -import org.jabref.logic.git.GitHandler; |
14 |
| -import org.jabref.logic.git.conflicts.GitConflictResolver; |
15 |
| -import org.jabref.logic.git.conflicts.SemanticConflictDetector; |
16 |
| -import org.jabref.logic.git.conflicts.ThreeWayEntryConflict; |
17 |
| -import org.jabref.logic.git.io.GitBibParser; |
18 |
| -import org.jabref.logic.git.io.GitFileReader; |
19 |
| -import org.jabref.logic.git.io.GitFileWriter; |
20 |
| -import org.jabref.logic.git.io.GitRevisionLocator; |
21 |
| -import org.jabref.logic.git.io.RevisionTriple; |
22 |
| -import org.jabref.logic.git.merge.GitMergeUtil; |
23 |
| -import org.jabref.logic.git.merge.MergePlan; |
24 |
| -import org.jabref.logic.git.merge.SemanticMerger; |
| 8 | +import org.jabref.logic.git.GitSyncService; |
25 | 9 | import org.jabref.logic.git.model.MergeResult;
|
26 |
| -import org.jabref.logic.importer.ImportFormatPreferences; |
27 |
| -import org.jabref.model.database.BibDatabaseContext; |
28 |
| -import org.jabref.model.entry.BibEntry; |
29 | 10 |
|
30 |
| -import org.eclipse.jgit.api.Git; |
31 | 11 | import org.eclipse.jgit.api.errors.GitAPIException;
|
32 |
| -import org.eclipse.jgit.revwalk.RevCommit; |
33 | 12 |
|
34 | 13 | public class GitPullViewModel extends AbstractViewModel {
|
35 |
| - private final ImportFormatPreferences importFormatPreferences; |
36 |
| - private final GitConflictResolver conflictResolver; |
37 |
| - private final DialogService dialogService; |
38 |
| - private final GitHandler gitHandler; |
| 14 | + private final GitSyncService syncService; |
39 | 15 | private final GitStatusViewModel gitStatusViewModel;
|
40 | 16 | private final Path bibFilePath;
|
41 | 17 |
|
42 |
| - public GitPullViewModel(ImportFormatPreferences importFormatPreferences, |
43 |
| - GitConflictResolver conflictResolver, |
44 |
| - DialogService dialogService, |
45 |
| - GitHandler gitHandler, |
46 |
| - GitStatusViewModel gitStatusViewModel) { |
47 |
| - this.importFormatPreferences = importFormatPreferences; |
48 |
| - this.conflictResolver = conflictResolver; |
49 |
| - this.dialogService = dialogService; |
50 |
| - this.gitHandler = gitHandler; |
| 18 | + public GitPullViewModel(GitSyncService syncService, GitStatusViewModel gitStatusViewModel) { |
| 19 | + this.syncService = syncService; |
51 | 20 | this.gitStatusViewModel = gitStatusViewModel;
|
52 | 21 | this.bibFilePath = gitStatusViewModel.getCurrentBibFile();
|
53 | 22 | }
|
54 | 23 |
|
55 | 24 | public MergeResult pull() throws IOException, GitAPIException, JabRefException {
|
56 |
| - // Open the Git repository from the parent folder of the .bib file |
57 |
| - Git git = Git.open(gitHandler.getRepositoryPathAsFile()); |
| 25 | + MergeResult result = syncService.fetchAndMerge(bibFilePath); |
58 | 26 |
|
59 |
| - gitHandler.fetchOnCurrentBranch(); |
60 |
| - |
61 |
| - // Determine the three-way merge base, local, and remote commits |
62 |
| - GitRevisionLocator locator = new GitRevisionLocator(); |
63 |
| - RevisionTriple triple = locator.locateMergeCommits(git); |
64 |
| - |
65 |
| - RevCommit baseCommit = triple.base(); |
66 |
| - RevCommit localCommit = triple.local(); |
67 |
| - RevCommit remoteCommit = triple.remote(); |
68 |
| - |
69 |
| - // Ensure file is inside the Git working tree |
70 |
| - Path repoRoot = gitHandler.getRepositoryPathAsFile().toPath().toRealPath(); |
71 |
| - Path resolvedBibPath = bibFilePath.toRealPath(); |
72 |
| - if (!resolvedBibPath.startsWith(repoRoot)) { |
73 |
| - throw new JabRefException("The provided .bib file is not inside the Git repository."); |
| 27 | + if (result.isSuccessful()) { |
| 28 | + gitStatusViewModel.updateStatusFromPath(bibFilePath); |
74 | 29 | }
|
75 |
| - Path relativePath = repoRoot.relativize(resolvedBibPath); |
76 |
| - |
77 |
| - // 1. Load three versions |
78 |
| - String baseContent = GitFileReader.readFileFromCommit(git, baseCommit, relativePath); |
79 |
| - String localContent = GitFileReader.readFileFromCommit(git, localCommit, relativePath); |
80 |
| - String remoteContent = GitFileReader.readFileFromCommit(git, remoteCommit, relativePath); |
81 |
| - |
82 |
| - BibDatabaseContext base = GitBibParser.parseBibFromGit(baseContent, importFormatPreferences); |
83 |
| - BibDatabaseContext local = GitBibParser.parseBibFromGit(localContent, importFormatPreferences); |
84 |
| - BibDatabaseContext remote = GitBibParser.parseBibFromGit(remoteContent, importFormatPreferences); |
85 |
| - |
86 |
| - // 2. Conflict detection |
87 |
| - List<ThreeWayEntryConflict> conflicts = SemanticConflictDetector.detectConflicts(base, local, remote); |
88 |
| - |
89 |
| - // 3. If there are conflicts, prompt user to resolve them via GUI |
90 |
| - BibDatabaseContext effectiveRemote = remote; |
91 |
| - if (!conflicts.isEmpty()) { |
92 |
| - List<BibEntry> resolvedRemoteEntries = new ArrayList<>(); |
93 |
| - for (ThreeWayEntryConflict conflict : conflicts) { |
94 |
| - // Ask user to resolve this conflict via GUI dialog |
95 |
| - Optional<BibEntry> maybeResolved = conflictResolver.resolveConflict(conflict); |
96 |
| - if (maybeResolved.isPresent()) { |
97 |
| - resolvedRemoteEntries.add(maybeResolved.get()); |
98 |
| - } else { |
99 |
| - // User canceled the merge dialog → abort the whole merge |
100 |
| - throw new JabRefException("Merge aborted: Not all conflicts were resolved by user."); |
101 |
| - } |
102 |
| - } |
103 |
| - // Replace original conflicting entries in remote with resolved versions |
104 |
| - effectiveRemote = GitMergeUtil.replaceEntries(remote, resolvedRemoteEntries); |
105 |
| - } |
106 |
| - |
107 |
| - // Extract merge plan and apply it to the local database |
108 |
| - MergePlan plan = SemanticConflictDetector.extractMergePlan(base, effectiveRemote); |
109 |
| - SemanticMerger.applyMergePlan(local, plan); |
110 |
| - |
111 |
| - // Save merged result to .bib file |
112 |
| - GitFileWriter.write(bibFilePath, local, importFormatPreferences); |
113 |
| - |
114 |
| - // Create Git commit for the merged result |
115 |
| - gitHandler.createCommitOnCurrentBranch("Auto-merged by JabRef", true); |
116 | 30 |
|
117 |
| - gitStatusViewModel.updateStatusFromPath(bibFilePath); |
118 |
| - return MergeResult.success(); |
| 31 | + return result; |
119 | 32 | }
|
120 | 33 | }
|
0 commit comments