はじめに
Atomのパネル間のdiffを取るパッケージであるsplit-diffにパッチ機能(vimでいうdiffget
、diffput
的なもの)が欲しいと思い、内部で利用しているjsdiffを調べていたら思いのほか高機能だったのでメモを行う。
文字列のdiffを取る
まずは普通に文字列同士を比較してみる。
jsdiff = require "diff"
orig = """
aaa
bbb
ccc
"""
modified = """
aaa
bbb
ddd
"""
diff = jsdiff.diffChars orig, modified
console.log diff
実行結果
[ { count: 8, value: 'aaa\nbbb\n' },
{ count: 3, added: undefined, removed: true, value: 'ccc' },
{ count: 3, added: true, removed: undefined, value: 'ddd' } ]
Unified形式のpatchを作る
jsdiffは単純に比較するだけでなく、Unified形式のpatchを出力できる。
jsdiff = require "diff"
orig = """
aaa
bbb
ccc
"""
modified = """
aaa
bbb
ddd
"""
patch = jsdiff.createPatch "test", orig, modified, "original text", "modified text"
console.log patch
実行結果
Index: test
===================================================================
--- test original text
+++ test modified text
@@ -1,3 +1,3 @@
aaa
bbb
-ccc
\ No newline at end of file
+ddd
patchを当てる
なんと、Unified形式のpatchを出力するだけでなく、patchを当てることもできた。
jsdiff = require "diff"
orig = """
aaa
bbb
ccc
"""
modified = """
aaa
bbb
ddd
"""
patch = jsdiff.createPatch "test", orig, modified, "original text", "modified text"
patched = jsdiff.applyPatch orig, patch
console.log patched
結果
aaa
bbb
ddd
Unified形式のパッチをパースする
patchを当てられるのだからある種当然ではあるが、Unified形式のpatchをパースして内容をObjectとして返す機能もある。
jsdiff = require "diff"
patch = """
Index: test
===================================================================
--- test original text
+++ test modified text
@@ -1,3 +1,3 @@
aaa
bbb
-ccc
\ No newline at end of file
+ddd
"""
content = jsdiff.parsePatch patch
console.log content
console.log content[0].hunks
実行結果
[ { index: 'test',
oldFileName: 'test',
oldHeader: 'original text',
newFileName: 'test',
newHeader: 'modified text',
hunks: [ [Object] ] } ]
[ { oldStart: 1,
oldLines: 3,
newStart: 1,
newLines: 3,
lines: [ ' aaa', ' bbb', '-ccc', ' No newline at end of file', '+ddd' ] } ]