Rich diff for group changes (diffs)
When a library is modified externally, the group diff is very small.
To reproduce:
- Create a new library with a few groups and assign some entries to them
- Outside of JabRef, open the bib file in a text editor, scroll down to the end of JabRef and modify the group structure, e.g., change the group name or add new group by copy and paste
- Wait for the dialog "This library has been modified by another program"
- Click on Review Changes
- See the metadata like in the screenshot
The line "Modified groups tree" is generated from the object org.jabref.logic.bibtex.comparator.GroupDiff. This class should be refined to show a "real" diff (which is then somehow passed via org.jabref.gui.collab.DatabaseChange#setChangeName inside GroupDiff).
The second block with Optional is originating by simply outputting the list of differences and each old and new object with toString(). Since the group diff is handled explicitly (by org.jabref.logic.bibtex.comparator.MetaDataDiff#getGroupDifferences) and implicilty by the list org.jabref.logic.bibtex.comparator.MetaDataDiff#getDifferences it currently appears twice. (org.jabref.gui.collab.DatabaseChangeList#compareAndGetChanges)
The groupDiff should be removed from MetaDataDiff and handled in org.jabref.gui.collab.DatabaseChangesResolverDialog.
- [ ] The dialog should split up the changes in the meta data to separate lines to resolve
- [ ] The button "Merge" should be clickable and a UI appear
Ideas:
- Simple text highlight of the diff. See org.jabref.gui.mergeentries.DiffHighlighting for ideas
- Create a real diff for groups (enhanced
GroupDiff) and a UI to handle that - Convert group structure to JSON, offer RichTextEditor for JSON. Convert JSON back to group structure. Use web technologies to handle the JSON and the diff. Embed the html page inside a WebView used. (Use some JavaScript library to handle JSON diffs.)
- Related issue: https://github.com/JabRef/jabref/issues/11220 (which is a small part for the UI work)
- Converting the groups structure into JSON is preparation work for https://github.com/JabRef/jabref/issues/10371.
/assign-me
๐ Hey @aworjose, thank you for your interest in this issue! ๐
We're excited to have you on board. Start by exploring our Contributing guidelines, and don't forget to check out our workspace setup guidelines to get started smoothly.
In case you encounter failing tests during development, please check our developer FAQs!
Having any questions or issues? Feel free to ask here on GitHub. Need help setting up your local workspace? Join the conversation on JabRef's Gitter chat. And don't hesitate to open a (draft) pull request early on to show the direction it is heading towards. This way, you will receive valuable feedback.
Happy coding! ๐
โณ Please note, you will be automatically unassigned if the issue isn't closed within 45 days (by 21 April 2025). A maintainer can also add the "๐ Pinned"" label to prevent automatic unassignment.
๐ Assignment Update
Hi @aworjose, due to inactivity, you have been unassigned from this issue.
Next steps
If you still want to work on this:
- Ask a maintainer to assign you again
- If you're making progress, a maintainer can add the pin label to prevent future automatic unassignment
/assign-me
๐ Hey @aaspst, thank you for your interest in this issue! ๐
We're excited to have you on board. Start by exploring our Contributing guidelines, and don't forget to check out our workspace setup guidelines to get started smoothly.
In case you encounter failing tests during development, please check our developer FAQs!
Having any questions or issues? Feel free to ask here on GitHub. Need help setting up your local workspace? Join the conversation on JabRef's Gitter chat. And don't hesitate to open a (draft) pull request early on to show the direction it is heading towards. This way, you will receive valuable feedback.
Happy coding! ๐
๐ Assignment Update
Hi @aaspst, you are no longer assigned to this issue.
Next steps
If you still want to work on this:
- Comment with
/assign-meto request reassignment - Ask a maintainer to assign you again
- If you're making progress, a maintainer can add the ๐ Pinned label to prevent future automatic unassignment
Hi! I would like to work on this feature! If possible, could @almada39 be assigned as well? We are Computer Science students and would be working on it together for a University Project.
/assign-me
๐ Hey @MiguelCBar, looks like youโre eager to work on this issueโgreat! ๐ It also looks like you skipped reading our CONTRIBUTING.md, which explains exactly how to participate. No worries, it happens to the best of us. Give it a read, and youโll discover the ancient wisdom of assigning issues to yourself. Trust me, itโs worth it. ๐
/assign @MiguelCBar
๐ Hey @MiguelCBar, thank you for your interest in this issue! ๐
We're excited to have you on board. Start by exploring our Contributing guidelines, and don't forget to check out our workspace setup guidelines to get started smoothly.
In case you encounter failing tests during development, please check our developer FAQs!
Having any questions or issues? Feel free to ask here on GitHub. Need help setting up your local workspace? Join the conversation on JabRef's Gitter chat. And don't hesitate to open a (draft) pull request early on to show the direction it is heading towards. This way, you will receive valuable feedback.
Happy coding! ๐
@MiguelCBar Your team mate needs to comment so that GitHub allows for assignment...
Hi! Could you assign me as well please? Thank you!
โ ๏ธ Issue Already Assigned
Hi @almada39, this issue is currently assigned to @MiguelCBar.
[!NOTE] If no progress is made within 14 days, the issue will be automatically unassigned.
Options for contributors
- Wait for availability: The issue may become available if auto-unassigned
- Collaborate: You can ask the assignee if they want help
- Maintainer assistance: A maintainer can add you as co-assignee if appropriate
โฐ Assignment Reminder
Hi @MiguelCBar, this is a friendly reminder about your assignment to this issue.
[!WARNING] This issue will be automatically unassigned in 11 days if there's no activity.
How to keep your assignment
If you are working on it, you can prevent automatic unassignment by:
- Submitting a draft PR with your progress
- Asking for the ๐ Pinned label if you need more time
We appreciate your contribution and are here to help if needed!
Hi again! Me and @almada39 are currently working on the development of this feature! Will be updating you within the next few days!
Hi again! Me and @almada39 are currently working on the development of this feature! Will be updating you within the next few days!
TBH, I wonder why we did not see any draft PR yet. Any concept work existing? You know, writing text into Markdown files?
Note that you can use https://gurubase.io/g/jabref for Q&A
We apologize, the reason was that we were caught up with other urgent projects of other subjects with difficult deadlines, but now we are only focused on this issue and will give updates in the next few days. Also, thanks for the Q&A tip.
Hi @koppor . We have some questions about the way groups are handled in JabRef that we couldn't totally understand after some digging and checking the Q&A help.
What we understand:
If we change a property of a .bib file entry outside of JabRef, like its title, the "Review Changes" dialog is a little different, since it wasn't the group structure that was changed.
With the same change, we also verified in the org/jabref/gui/collab/entrychange/PreviewWithSourceTab.java file that the BibTeX Source view, instead of reading from the .bib file, reads from a BibEntry.
We also understand that the groups from a .bib file are stored in the metadata of the library (though weโre not sure how).
What we want to clarify:
Is it possible to access the .bib file to get the groups associated with the library in question? If not, is there a way to access them and compare their structure with the metadata information?
In terms of the feature proposal, what are we supposed to show in the "Review Changes" dialog? For example, if this is the end of the .bib file which was changed outside of JabRef:
@Comment{jabref-meta: grouping:
0 AllEntriesGroup:;
1 StaticGroup:test\;0\;1\;\;\;\;;
2 StaticGroup:subgroup_test\;0\;1\;\;\;\;;
}
Are we supposed to show this in the dialog, plus an additional panel to see the original grouping structure? Or is it something else? And is it supposed to appear after "The following metadata changed:"?
Also, in the "external changes resolver" dialog that appears in the screenshot of the feature proposal, there are two different things: "metadata change" and "modified groups tree". how sould we handle this issue, is one of them the repercussion of the other?
Furthermore, about the merge button functionality, what should be the behavior of the UI? Should it open another dialog, like when a change is made that doesnโt involve a group tree change, such as just changing the title of an article? Weโre asking this mainly because, in that case, the diff presented is already clear, and the accept and deny changes buttons work. The merge button, which opens another dialog to pick what changes to merge, doesnโt seem to workโat least not in the several times we tried it. So we are a bit confused about what functionality the merge is supposed to provide and what repercussions it should have for a successful merge.
Thank you!
how sould we handle this issue, is one of them the repercussion of the other
May I ask if you followed the steps in the issue description? Did you try to set some breakpoints to learn how JabRef behaves? Did you ask https://gurubase.io/g/jabref?
I don't know about your goal. Currently your questions appear to be of software programmers, not developers or engineers. Developers and engineers should come up with proposals.
I can refine this, but it takes time. Not sure until when you need the input.
No problem, we completely understand the question and we're sorry for the long message with doubts.
This said, we have indeed followed the steps and reproduced the behaviour several times as well as spent some hours understanding how it works and using https://gurubase.io/g/jabref.
Our proposal for the External Changes Resolver View was to show, for the "Metadata Change" entry, under the "The following metadata changed:" title, the changes for the group structure. This would be done by showing to the user the old and new structure, as it is written in the .bib file, like we have shown in the previous comment.
This said, the method compare in GroupDiff only reports if there is a change, and not even what kind of change. And has a comment saying that it would be difficult to do properly. That got us thinking that adding information to MetadataChangeDetailsView.java and GroupChangeDetailsView.java in this case might not be that easy and we're looking if there's some other way we might be missing.
To solve this, we thought of searching in the database for the actual .bib file and extract the @comment{jabref-meta: grouping:(...)}structure and show two panels, one with the old structure and the other with the newer one.
Then, if we accepted the changes, we would save the file normally again in the database.
@MiguelCBar At the point in GroupDiff you already have the parsed groups Tree. You can either iterate through all the groups and compare each node. That is expensive.
For importing BIbDesk Group I needed something similar and I came up with searching the group metadata: https://github.com/JabRef/jabref/blob/4d2fd15fe244fed17bb6eb31c8dc958f2e4a265c/jablib/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java#L269-L276
That should give you some hints above the groups metadata.
We changed how the metadata group differences are displayed. Now, instead of just showing text, we present the old and the updated metadata side by side in a tree structure. This makes it easier for users to visually understand the changes. To achieve this, we adjusted the code to display both versions using a SplitPane, with each side showing the group tree in a scrollable and properly indented format. We also made sure that the change type and section headers appear outside the scroll area for better readability.
Is this enough for the diff? What kind of visual changes would you recommend?
Regarding the future behaviour of the Merge Button, we saw that the Accept Button overrides the original metadata with the new one. We have some doubts on what the Merge should do. We thought of creating a Selective Merge, where the User chooses which change to accept. However, is it even possible with the way Metadata is saving the groups? Or is there a better option to choose from?
Thank you!
Is this enough for the diff? What kind of visual changes would you recommend?
Please try to color the diff.
See the merge entriesd dialog: https://docs.jabref.org/finding-sorting-and-cleaning-entries/mergeentries
Meaning:
- Added group: green
- Removed group: red;
- Renamed group: character diff
- In case a group property changed: yellow (this is new and not existing in the merge entries dialog)
Regarding the future behaviour of the Merge Button, we saw that the Accept Button overrides the original metadata with the new one. We have some doubts on what the Merge should do. We thought of creating a Selective Merge, where the User chooses which change to accept. However, is it even possible with the way Metadata is saving the groups? Or is there a better option to choose from?
Please do an "intelligent" merge. You need to think, here some hints:
Let's call the input left and right - and the output result.
- In general: Result should contain changes from left and right
- Group added on the left: Add it to the result
- Group added on the right: Add it to the result
- Group removed on the left: Remove it from result
- Group removed on the right: Remove it from result
- Group changed on left: Apply changes in result
-
- Group changed on right: Apply changes in result
- Group changed in both left and right: conflictMaybe following works:
Take left as base and try to patch-in right.
You really, really need to do test-driven development: Write tests for all group cases.
In case there is a conflict, ask the user what to do.
Initial implementation idea: Show two group properties dialogs. One for result and one for right. Then, the user needs to update the result with data they want to take from right.
Please be aware that we have users with thousands of groups and very deep nested
Maybe the existing groups tree can be re-used somehow?
We think that this issue was fixed. Please head to https://builds.jabref.org/main to download a development build and try it out.
For any feedback, add a comment to the pull request at https://github.com/JabRef/jabref/pull/13325.