mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-23 13:44:27 +08:00
fix(diff): modify diff logic and comment
License: MIT Signed-off-by: Overbool <overbool.xu@gmail.com>
This commit is contained in:
@ -95,29 +95,23 @@ func ApplyChange(ctx context.Context, ds ipld.DAGService, nd *dag.ProtoNode, cs
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Diff returns a set of changes that transform node 'a' into node 'b'.
|
// Diff returns a set of changes that transform node 'a' into node 'b'.
|
||||||
// It supports two nodes forms: ProtoNode and RawNode. Because we treat
|
// It only traverses links in the following cases:
|
||||||
// the nodes as IPLD nodes as long as possible and only convert them
|
// 1. two node's links number are greater than 0.
|
||||||
// to ProtoNode when necessary: when we need to remove links, and at that point
|
// 2. both of two nodes are ProtoNode.
|
||||||
// (if they have links to remove) we know they are not raw nodes.
|
// Otherwise, it compares the cid and emits a Mod change object.
|
||||||
func Diff(ctx context.Context, ds ipld.DAGService, a, b ipld.Node) ([]*Change, error) {
|
func Diff(ctx context.Context, ds ipld.DAGService, a, b ipld.Node) ([]*Change, error) {
|
||||||
// Base case where both nodes are leaves, just compare
|
// Base case where both nodes are leaves, just compare
|
||||||
// their CIDs.
|
// their CIDs.
|
||||||
if len(a.Links()) == 0 && len(b.Links()) == 0 {
|
if len(a.Links()) == 0 && len(b.Links()) == 0 {
|
||||||
if a.Cid().Equals(b.Cid()) {
|
return getChange(a, b)
|
||||||
return []*Change{}, nil
|
|
||||||
}
|
|
||||||
return []*Change{
|
|
||||||
{
|
|
||||||
Type: Mod,
|
|
||||||
Before: a.Cid(),
|
|
||||||
After: b.Cid(),
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var out []*Change
|
var out []*Change
|
||||||
cleanA := a.Copy()
|
cleanA, okA := a.Copy().(*dag.ProtoNode)
|
||||||
cleanB := b.Copy()
|
cleanB, okB := b.Copy().(*dag.ProtoNode)
|
||||||
|
if !okA || !okB {
|
||||||
|
return getChange(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
// strip out unchanged stuff
|
// strip out unchanged stuff
|
||||||
for _, lnk := range a.Links() {
|
for _, lnk := range a.Links() {
|
||||||
@ -146,12 +140,8 @@ func Diff(ctx context.Context, ds ipld.DAGService, a, b ipld.Node) ([]*Change, e
|
|||||||
out = append(out, subc)
|
out = append(out, subc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if cleanA, ok := cleanA.(*dag.ProtoNode); ok {
|
cleanA.RemoveNodeLink(l.Name)
|
||||||
cleanA.RemoveNodeLink(l.Name)
|
cleanB.RemoveNodeLink(l.Name)
|
||||||
}
|
|
||||||
if cleanB, ok := cleanB.(*dag.ProtoNode); ok {
|
|
||||||
cleanB.RemoveNodeLink(l.Name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,3 +197,16 @@ func MergeDiffs(a, b []*Change) ([]*Change, []Conflict) {
|
|||||||
}
|
}
|
||||||
return out, conflicts
|
return out, conflicts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getChange(a, b ipld.Node) ([]*Change, error) {
|
||||||
|
if a.Cid().Equals(b.Cid()) {
|
||||||
|
return []*Change{}, nil
|
||||||
|
}
|
||||||
|
return []*Change{
|
||||||
|
{
|
||||||
|
Type: Mod,
|
||||||
|
Before: a.Cid(),
|
||||||
|
After: b.Cid(),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
@ -58,19 +58,19 @@ test_expect_success "diff against self (single file) is empty" '
|
|||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success "diff (raw-leaves) against self (single file) is empty" '
|
test_expect_success "diff (raw-leaves) against self (single file) is empty" '
|
||||||
ipfs object diff $SINGLE_FILE_RAW $SINGLE_FILE_RAW > diff_raw_out
|
ipfs object diff $SINGLE_FILE_RAW $SINGLE_FILE_RAW > diff_raw_out &&
|
||||||
printf "" > diff_raw_exp &&
|
printf "" > diff_raw_exp &&
|
||||||
test_cmp diff_raw_exp diff_raw_out
|
test_cmp diff_raw_exp diff_raw_out
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success "diff against self (empty dir) is empty" '
|
test_expect_success "diff against self (empty dir) is empty" '
|
||||||
ipfs object diff $EMPTY_DIR $EMPTY_DIR > diff_out
|
ipfs object diff $EMPTY_DIR $EMPTY_DIR > diff_out &&
|
||||||
printf "" > diff_exp &&
|
printf "" > diff_exp &&
|
||||||
test_cmp diff_exp diff_out
|
test_cmp diff_exp diff_out
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success "diff (raw-leaves) against self (empty dir) is empty" '
|
test_expect_success "diff (raw-leaves) against self (empty dir) is empty" '
|
||||||
ipfs object diff $EMPTY_DIR_RAW $EMPTY_DIR_RAW > diff_raw_out
|
ipfs object diff $EMPTY_DIR_RAW $EMPTY_DIR_RAW > diff_raw_out &&
|
||||||
printf "" > diff_raw_exp &&
|
printf "" > diff_raw_exp &&
|
||||||
test_cmp diff_raw_exp diff_raw_out
|
test_cmp diff_raw_exp diff_raw_out
|
||||||
'
|
'
|
||||||
|
Reference in New Issue
Block a user