feat: Initial clean release of CHM
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
这个提交包含在:
@@ -0,0 +1,57 @@
|
||||
import { autoMerge, MergedSection } from './diffNotes';
|
||||
|
||||
export interface NoteVersion {
|
||||
title: string;
|
||||
body: string;
|
||||
}
|
||||
|
||||
// A title is a conflict only when the both sides changed it differently
|
||||
export const mergeTitle = (base: string, local: string, remote: string) => {
|
||||
if (local === remote) return { merged: local, conflict: false };
|
||||
if (base === local) return { merged: remote, conflict: false };
|
||||
if (base === remote) return { merged: local, conflict: false };
|
||||
return { merged: '', conflict: true };
|
||||
};
|
||||
|
||||
// Only conflict sections differ between the two sides; everything else is shared between them
|
||||
const buildBody = (sections: MergedSection[], conflictSide: 'localText' | 'remoteText'): string => {
|
||||
const lineCount = conflictSide === 'localText' ? 'localLineCount' : 'remoteLineCount';
|
||||
return sections
|
||||
.filter(section => section.type !== 'conflict' || section[lineCount] !== 0)
|
||||
.map(section => section.type === 'conflict' ? (section[conflictSide] ?? '') : section.text)
|
||||
.join('\n');
|
||||
};
|
||||
|
||||
export interface PartialMergeResult {
|
||||
fullyMerged: boolean;
|
||||
// Non-conflicting changes are merged, and any remaining conflicts keep the user's version
|
||||
resolvedLocal: NoteVersion;
|
||||
// Same, but remaining conflicts kept as the incoming side
|
||||
resolvedCurrent: NoteVersion;
|
||||
}
|
||||
|
||||
export default (base: NoteVersion, local: NoteVersion, remote: NoteVersion): PartialMergeResult => {
|
||||
const title = mergeTitle(base.title ?? '', local.title ?? '', remote.title ?? '');
|
||||
|
||||
const localBody = local.body ?? '';
|
||||
const remoteBody = remote.body ?? '';
|
||||
|
||||
if (localBody === remoteBody && !title.conflict) {
|
||||
return { fullyMerged: true, resolvedLocal: { title: title.merged, body: localBody }, resolvedCurrent: { title: title.merged, body: localBody } };
|
||||
}
|
||||
|
||||
const merged = autoMerge(base.body ?? '', localBody, remoteBody);
|
||||
const bodyFullyMerged = !merged.sections.some(s => s.type === 'conflict');
|
||||
|
||||
return {
|
||||
fullyMerged: bodyFullyMerged && !title.conflict,
|
||||
resolvedLocal: {
|
||||
title: title.conflict ? (local.title ?? '') : title.merged,
|
||||
body: bodyFullyMerged ? merged.mergedText : buildBody(merged.sections, 'localText'),
|
||||
},
|
||||
resolvedCurrent: {
|
||||
title: title.conflict ? (remote.title ?? '') : title.merged,
|
||||
body: bodyFullyMerged ? merged.mergedText : buildBody(merged.sections, 'remoteText'),
|
||||
},
|
||||
};
|
||||
};
|
||||
在新工单中引用
屏蔽一个用户