Skip to content
This repository was archived by the owner on Mar 6, 2018. It is now read-only.

Commit 130c295

Browse files
committed
squash
1 parent bd8c0c3 commit 130c295

File tree

4 files changed

+588
-2
lines changed

4 files changed

+588
-2
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,7 @@ Because `buildPatchFromRevert + apply` offers more flexibility over `revert` it
127127
* use [pack/unpack](#patch-size) with the result of `buildPatchFromRevert` making it ideal for storage or transport
128128
* reverse a revert (and so on...) with `{reversible: true}`
129129
* [diff](#diff) between reverts
130-
* merge multiple reverts into one
131-
* rebase reverts
130+
* concat, squash, rebase multiple reverts
132131

133132
[](#json8-patch)
134133

index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ module.exports.unpack = require('./lib/unpack')
3131

3232
// Utilities
3333
module.exports.concat = require('./lib/concat')
34+
module.exports.squash = require('./lib/squash')

lib/squash.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use strict'
2+
3+
function wasModified(patch, path) {
4+
for (var i = 0; i < patch.length; i++) {
5+
var op = patch[i]
6+
if (op.path !== path) continue
7+
if (op.op === 'add' || op.op === 'replace' || op.op === 'remove' || op.op === 'move' || op.op === 'copy') return true
8+
}
9+
return false
10+
}
11+
12+
module.exports = function squash(patch) {
13+
var squashed = []
14+
15+
var push = true
16+
17+
patch.forEach(function(op) {
18+
// if current op overrides previous operations, remove them
19+
if (['add', 'replace', 'remove', 'move', 'copy'].indexOf(op.op) !== -1) {
20+
squashed.forEach(function(prev, idx) {
21+
if (prev.op === 'test') return
22+
if (prev.path === op.path) { // same path - FIXME children/parents ?
23+
if (wasModified(squashed, op.path)) {
24+
squashed[idx] = undefined
25+
}
26+
27+
// the path was created in the patch, the remove operation shouldn't be included
28+
// example
29+
// {"path": "/foo", "op": "add", "value": "foo"},
30+
// {"path": "/foo", "op": "remove"}
31+
if (op.op === 'remove') {
32+
push = false
33+
}
34+
// the path was created in the patch, replace op requires the target to exist
35+
// example
36+
// {"path": "/foo", "op": "add", "value": "foo"},
37+
// {"path": "/foo", "op": "replace", "value": "bar"}
38+
else if (op.op === 'replace') {
39+
// push = false
40+
op = {"path": op.path, "op": "add", "value": op.value}
41+
}
42+
}
43+
})
44+
}
45+
46+
if (push) {
47+
squashed.push(op)
48+
}
49+
})
50+
51+
var foo = []
52+
squashed.forEach(function(op) {
53+
if (op !== undefined) foo.push(op)
54+
})
55+
return foo
56+
}

0 commit comments

Comments
 (0)