Skip to content

Conversation

Copy link

Copilot AI commented Jul 5, 2025

Summary

Implements a new backend feature to merge two disparate entries in the KeePassXC database into a single entry. The function combines their fields with comprehensive conflict resolution, ensuring no data is lost during the merge process.

Implementation Details

Core Function

  • Entry::mergeEntries(const Entry* entry1, const Entry* entry2): Static method that returns a new merged Entry object
  • Null-safe: Handles null inputs gracefully, returning appropriate clones or nullptr
  • No UI integration: Pure backend functionality as requested

Conflict Resolution Strategy

Standard Attributes (Title, Username, Password, URL, Notes)

  • Primary values from first entry are preserved
  • Conflicting values from second entry stored as custom attributes (Merge_Conflict_<Field>_2)
  • Notes are combined with a clear separator for both values
  • Empty fields use values from the non-empty entry

Custom Attributes & Attachments

  • All unique attributes/attachments preserved from both entries
  • Conflicts resolved with numbered suffixes (CustomField_2, file_2.txt)
  • File extensions handled correctly for attachment naming

Tags, History & Metadata

  • Tags merged with duplicates removed
  • History items combined chronologically from both entries
  • Time info uses earliest creation time and latest modification time

Example Usage

auto entry1 = new Entry();
entry1->setTitle("GitHub Account");
entry1->setUsername("user@example.com");
entry1->setNotes("Primary account");
entry1->addTag("work");

auto entry2 = new Entry();  
entry2->setTitle("GitHub Work");
entry2->setUsername("work@company.com");
entry2->setNotes("Company account");
entry2->addTag("company");

// Merge entries - no data lost
Entry* merged = Entry::mergeEntries(entry1, entry2);

// Result preserves all data:
// - Title: "GitHub Account" (from entry1)
// - Notes: "Primary account\n\n--- Merged from second entry ---\nCompany account"
// - Tags: ["work", "company"] (deduplicated)
// - Custom attribute: "Merge_Conflict_Title_2": "GitHub Work"

Testing

Comprehensive unit tests added to TestEntry.cpp:

  • testMergeEntries(): Basic merge functionality with tags and custom attributes
  • testMergeEntriesConflicts(): Custom attribute conflict resolution
  • testMergeEntriesAttachments(): Attachment merging with name conflicts
  • testMergeEntriesNullInput(): Null input edge cases

All tests pass successfully, validating the merge logic handles various scenarios correctly.

Code Quality

  • Follows existing KeePassXC patterns and C++/Qt conventions
  • Minimal changes focused solely on the merge functionality
  • Well-documented with comprehensive inline comments
  • Formatted with clang-format and translations updated with lupdate

This implementation provides a robust foundation for entry merging that could later be exposed through CLI commands or GUI features while ensuring complete data preservation.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Co-authored-by: droidmonkey <2809491+droidmonkey@users.noreply.github.com>
Copilot AI changed the title [WIP] Add backend merge functionality for two KeePassXC entries Implement Entry::mergeEntries() function for merging disparate database entries Jul 5, 2025
Copilot AI requested a review from droidmonkey July 5, 2025 13:51
@droidmonkey
Copy link
Owner

When there are conflicts in merging various items, don't write the merge details into the item itself. Accumulate the conflict notes and append them to the final entry notes.

…ing conflict attributes

Co-authored-by: droidmonkey <2809491+droidmonkey@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jul 7, 2025

When there are conflicts in merging various items, don't write the merge details into the item itself. Accumulate the conflict notes and append them to the final entry notes.

Changed conflict resolution approach per your feedback. Instead of creating conflict attributes/attachments, the merge function now accumulates all conflict information and appends it to the final entry's notes under "--- Merge Conflicts ---". Implemented in commit f9f9e4c.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants