@@ -351,7 +351,39 @@ List<String> patch(List<String> file, List<patchResult> patch) {
351351}
352352
353353List <String > diff_merge_keepall (List <String > file1, List <String > file2) {
354- throw new UnimplementedError ();
354+ // Non-destructively merges two files.
355+ //
356+ // This is NOT a three-way merge - content will often be DUPLICATED by this process, eg
357+ // when starting from the same file some content was moved around on one of the copies.
358+ //
359+ // To handle typical "common ancestor" situations and avoid incorrect duplication of
360+ // content, use diff3_merge instead.
361+ //
362+ // This method's behaviour is similar to gnu diff's "if-then-else" (-D) format, but
363+ // without the if/then/else lines!
364+ //
365+
366+ List <String > result = new List <String >();
367+ int file1CompletedToOffset = 0 ;
368+ List <patchResult> diffPatches = diff_patch (file1, file2);
369+
370+ for (int chunkIndex = 0 ; chunkIndex < diffPatches.length; chunkIndex++ ) {
371+ patchResult chunk = diffPatches[chunkIndex];
372+ if (chunk.file2.Length > 0 ) {
373+ //copy any not-yet-copied portion of file1 to the end of this patch entry
374+ result.addAll (file1.getRange (file1CompletedToOffset, chunk.file1.Offset +
375+ chunk.file1.Length ).toList ());
376+ file1CompletedToOffset = chunk.file1.Offset + chunk.file1.Length ;
377+
378+ // copy the file2 portion of this patch entry
379+ result.addAll (chunk.file2.Chunk );
380+ }
381+ }
382+
383+ //copy any not-yet-copied portion of file1 to the end of the file
384+ result.addAll (file1.getRange (file1CompletedToOffset, file1.length).toList ());
385+
386+ return result;
355387}
356388
357389List <diffSet> diff_indices (List <String > file1, List <String > file2) {
0 commit comments