// Modification of difflib's unified differ
185430
func GetAdditions(a, b []string) []string {
	matcher := difflib.NewMatcher(a, b)
	differences := matcher.GetGroupedOpCodes(0)

	adds := []string{}
	for _, group := range differences {
		for _, opCode := range group {
			j1, j2 := opCode.J1, opCode.J2
			if opCode.Tag == 'r' || opCode.Tag == 'i' {
				for _, line := range b[j1:j2] {
					adds = append(adds, line)
				}
			}
		}
	}
	return adds
}
308097
func (t *Task) Diff(other *Task, contextual bool) (*TaskDiff, error) {
	diff := &TaskDiff{Type: DiffTypeNone}
	var oldPrimitiveFlat, newPrimitiveFlat map[string]string
	filter := []string{"Name", "Config"}

	if t == nil && other == nil {
		return diff, nil
	} else if t == nil {
		t = &Task{}
		diff.Type = DiffTypeAdded
		diff.Name = other.Name
		newPrimitiveFlat = flatmap.Flatten(other, filter, true)
	} else if other == nil {
		other = &Task{}
		diff.Type = DiffTypeDeleted
		diff.Name = t.Name
		oldPrimitiveFlat = flatmap.Flatten(t, filter, true)
	} else {
		if !reflect.DeepEqual(t, other) {
			diff.Type = DiffTypeEdited
		}
		if t.Name != other.Name {
			return nil, fmt.Errorf("can not diff tasks with different names: %q and %q", t.Name, other.Name)
		}
		diff.Name = other.Name
		oldPrimitiveFlat = flatmap.Flatten(t, filter, true)
		newPrimitiveFlat = flatmap.Flatten(other, filter, true)
	}

	// Diff the primitive fields.
	diff.Fields = fieldDiffs(oldPrimitiveFlat, newPrimitiveFlat, false)

	// Constraints diff
	conDiff := primitiveObjectSetDiff(
		interfaceSlice(t.Constraints),
		interfaceSlice(other.Constraints),
		[]string{"str"},
		"Constraint",
		contextual)
	if conDiff != nil {
		diff.Objects = append(diff.Objects, conDiff...)
	}

	// Affinities diff
	affinitiesDiff := primitiveObjectSetDiff(
		interfaceSlice(t.Affinities),
		interfaceSlice(other.Affinities),
		[]string{"str"},
		"Affinity",
		contextual)
	if affinitiesDiff != nil {
		diff.Objects = append(diff.Objects, affinitiesDiff...)
	}

	// Config diff
	if cDiff := configDiff(t.Config, other.Config, contextual); cDiff != nil {
		diff.Objects = append(diff.Objects, cDiff)
	}

	// Resources diff
	if rDiff := t.Resources.Diff(other.Resources, contextual); rDiff != nil {
		diff.Objects = append(diff.Objects, rDiff)
	}

	// LogConfig diff
	lDiff := primitiveObjectDiff(t.LogConfig, other.LogConfig, nil, "LogConfig", contextual)
	if lDiff != nil {
		diff.Objects = append(diff.Objects, lDiff)
	}

	// Dispatch payload diff
	dDiff := primitiveObjectDiff(t.DispatchPayload, other.DispatchPayload, nil, "DispatchPayload", contextual)
	if dDiff != nil {
		diff.Objects = append(diff.Objects, dDiff)
	}

	// Artifacts diff
	diffs := primitiveObjectSetDiff(
		interfaceSlice(t.Artifacts),
		interfaceSlice(other.Artifacts),
		nil,
		"Artifact",
		contextual)
	if diffs != nil {
		diff.Objects = append(diff.Objects, diffs...)
	}

	// Services diff
	if sDiffs := serviceDiffs(t.Services, other.Services, contextual); sDiffs != nil {
		diff.Objects = append(diff.Objects, sDiffs...)
	}

	// Vault diff
	vDiff := vaultDiff(t.Vault, other.Vault, contextual)
	if vDiff != nil {
		diff.Objects = append(diff.Objects, vDiff)
	}

	// Template diff
	tmplDiffs := primitiveObjectSetDiff(
		interfaceSlice(t.Templates),
		interfaceSlice(other.Templates),
		nil,
		"Template",
		contextual)
	if tmplDiffs != nil {
		diff.Objects = append(diff.Objects, tmplDiffs...)
	}

	return diff, nil
}
1295974
func (r *RequestedDevice) Diff(other *RequestedDevice, contextual bool) *ObjectDiff {
	diff := &ObjectDiff{Type: DiffTypeNone, Name: "Device"}
	var oldPrimitiveFlat, newPrimitiveFlat map[string]string

	if reflect.DeepEqual(r, other) {
		return nil
	} else if r == nil {
		diff.Type = DiffTypeAdded
		newPrimitiveFlat = flatmap.Flatten(other, nil, true)
	} else if other == nil {
		diff.Type = DiffTypeDeleted
		oldPrimitiveFlat = flatmap.Flatten(r, nil, true)
	} else {
		diff.Type = DiffTypeEdited
		oldPrimitiveFlat = flatmap.Flatten(r, nil, true)
		newPrimitiveFlat = flatmap.Flatten(other, nil, true)
	}

	// Diff the primitive fields.
	diff.Fields = fieldDiffs(oldPrimitiveFlat, newPrimitiveFlat, contextual)

	return diff
}
971284
func (set IdentifierSet) SymmetricDifference(other IdentifierSet) IdentifierSet {
	aDiff := set.Difference(other)
	bDiff := other.Difference(set)
	return aDiff.Union(bDiff)
}
1163009
func (args Arguments) Diff(objects []interface{}) (string, int) {
	//TODO: could return string as error and nil for No difference

	var output = "\n"
	var differences int

	var maxArgCount = len(args)
	if len(objects) > maxArgCount {
		maxArgCount = len(objects)
	}

	for i := 0; i < maxArgCount; i++ {
		var actual, expected interface{}
		var actualFmt, expectedFmt string

		if len(objects) <= i {
			actual = "(Missing)"
			actualFmt = "(Missing)"
		} else {
			actual = objects[i]
			actualFmt = fmt.Sprintf("(%[1]T=%[1]v)", actual)
		}

		if len(args) <= i {
			expected = "(Missing)"
			expectedFmt = "(Missing)"
		} else {
			expected = args[i]
			expectedFmt = fmt.Sprintf("(%[1]T=%[1]v)", expected)
		}

		if matcher, ok := expected.(argumentMatcher); ok {
			if matcher.Matches(actual) {
				output = fmt.Sprintf("%s\t%d: PASS:  %s matched by %s\n", output, i, actualFmt, matcher)
			} else {
				differences++
				output = fmt.Sprintf("%s\t%d: FAIL:  %s not matched by %s\n", output, i, actualFmt, matcher)
			}
		} else if reflect.TypeOf(expected) == reflect.TypeOf((*AnythingOfTypeArgument)(nil)).Elem() {

			// type checking
			if reflect.TypeOf(actual).Name() != string(expected.(AnythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(AnythingOfTypeArgument)) {
				// not match
				differences++
				output = fmt.Sprintf("%s\t%d: FAIL:  type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actualFmt)
			}

		} else {

			// normal checking

			if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) {
				// match
				output = fmt.Sprintf("%s\t%d: PASS:  %s == %s\n", output, i, actualFmt, expectedFmt)
			} else {
				// not match
				differences++
				output = fmt.Sprintf("%s\t%d: FAIL:  %s != %s\n", output, i, actualFmt, expectedFmt)
			}
		}

	}

	if differences == 0 {
		return "No differences.", differences
	}

	return output, differences

}
619213
func diffListsOfMaps(original, modified []interface{}, t reflect.Type, mergeKey string, ignoreChangesAndAdditions, ignoreDeletions bool) ([]interface{}, error) {
	patch := make([]interface{}, 0)

	originalSorted, err := sortMergeListsByNameArray(original, t, mergeKey, false)
	if err != nil {
		return nil, err
	}

	modifiedSorted, err := sortMergeListsByNameArray(modified, t, mergeKey, false)
	if err != nil {
		return nil, err
	}

	originalIndex, modifiedIndex := 0, 0

loopB:
	for ; modifiedIndex < len(modifiedSorted); modifiedIndex++ {
		modifiedMap, ok := modifiedSorted[modifiedIndex].(map[string]interface{})
		if !ok {
			return nil, fmt.Errorf(errBadArgTypeFmt, "map[string]interface{}", modifiedSorted[modifiedIndex])
		}

		modifiedValue, ok := modifiedMap[mergeKey]
		if !ok {
			return nil, fmt.Errorf(errNoMergeKeyFmt, modifiedMap, mergeKey)
		}

		for ; originalIndex < len(originalSorted); originalIndex++ {
			originalMap, ok := originalSorted[originalIndex].(map[string]interface{})
			if !ok {
				return nil, fmt.Errorf(errBadArgTypeFmt, "map[string]interface{}", originalSorted[originalIndex])
			}

			originalValue, ok := originalMap[mergeKey]
			if !ok {
				return nil, fmt.Errorf(errNoMergeKeyFmt, originalMap, mergeKey)
			}

			// Assume that the merge key values are comparable strings
			originalString := fmt.Sprintf("%v", originalValue)
			modifiedString := fmt.Sprintf("%v", modifiedValue)
			if originalString >= modifiedString {
				if originalString == modifiedString {
					// Merge key values are equal, so recurse
					patchValue, err := diffMaps(originalMap, modifiedMap, t, ignoreChangesAndAdditions, ignoreDeletions)
					if err != nil {
						return nil, err
					}

					originalIndex++
					if len(patchValue) > 0 {
						patchValue[mergeKey] = modifiedValue
						patch = append(patch, patchValue)
					}
				} else if !ignoreChangesAndAdditions {
					// Item was added, so add to patch
					patch = append(patch, modifiedMap)
				}

				continue loopB
			}

			if !ignoreDeletions {
				// Item was deleted, so add delete directive
				patch = append(patch, map[string]interface{}{mergeKey: originalValue, directiveMarker: deleteDirective})
			}
		}

		break
	}

	if !ignoreDeletions {
		// Delete any remaining items found only in original
		for ; originalIndex < len(originalSorted); originalIndex++ {
			originalMap, ok := originalSorted[originalIndex].(map[string]interface{})
			if !ok {
				return nil, fmt.Errorf(errBadArgTypeFmt, "map[string]interface{}", originalSorted[originalIndex])
			}

			originalValue, ok := originalMap[mergeKey]
			if !ok {
				return nil, fmt.Errorf(errNoMergeKeyFmt, originalMap, mergeKey)
			}

			patch = append(patch, map[string]interface{}{mergeKey: originalValue, directiveMarker: deleteDirective})
		}
	}

	if !ignoreChangesAndAdditions {
		// Add any remaining items found only in modified
		for ; modifiedIndex < len(modifiedSorted); modifiedIndex++ {
			patch = append(patch, modified[modifiedIndex])
		}
	}

	return patch, nil
}
275470
func (d *Driver) Diff(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) (io.ReadCloser, error) {
	if d.useNaiveDiff() || !d.isParent(id, parent) {
		return d.naiveDiff.Diff(id, idMappings, parent, parentMappings, mountLabel)
	}

	if idMappings == nil {
		idMappings = &idtools.IDMappings{}
	}

	lowerDirs, err := d.getLowerDirs(id)
	if err != nil {
		return nil, err
	}

	diffPath := d.getDiffPath(id)
	logrus.Debugf("Tar with options on %s", diffPath)
	return archive.TarWithOptions(diffPath, &archive.TarOptions{
		Compression:    archive.Uncompressed,
		UIDMaps:        idMappings.UIDs(),
		GIDMaps:        idMappings.GIDs(),
		WhiteoutFormat: d.getWhiteoutFormat(),
		WhiteoutData:   lowerDirs,
	})
}
866227
func (gdw *NaiveDiffDriver) Diff(id, parent string) (arch io.ReadCloser, err error) {
	startTime := time.Now()
	driver := gdw.ProtoDriver

	layerRootFs, err := driver.Get(id, "")
	if err != nil {
		return nil, err
	}
	layerFs := layerRootFs.Path()

	defer func() {
		if err != nil {
			driver.Put(id)
		}
	}()

	if parent == "" {
		archive, err := archive.Tar(layerFs, archive.Uncompressed)
		if err != nil {
			return nil, err
		}
		return ioutils.NewReadCloserWrapper(archive, func() error {
			err := archive.Close()
			driver.Put(id)
			return err
		}), nil
	}

	parentRootFs, err := driver.Get(parent, "")
	if err != nil {
		return nil, err
	}
	defer driver.Put(parent)

	parentFs := parentRootFs.Path()

	changes, err := archive.ChangesDirs(layerFs, parentFs)
	if err != nil {
		return nil, err
	}

	archive, err := archive.ExportChanges(layerFs, changes, gdw.uidMaps, gdw.gidMaps)
	if err != nil {
		return nil, err
	}

	return ioutils.NewReadCloserWrapper(archive, func() error {
		err := archive.Close()
		driver.Put(id)

		// NaiveDiffDriver compares file metadata with parent layers. Parent layers
		// are extracted from tar's with full second precision on modified time.
		// We need this hack here to make sure calls within same second receive
		// correct result.
		time.Sleep(time.Until(startTime.Truncate(time.Second).Add(time.Second)))
		return err
	}), nil
}
876578
func (c Case) Diff(actual string) {
	exp := c.Out.Bytes()
	act := []byte(actual)
	if !bytes.Equal(exp, act) {
		must(c.T, errors.New(diff(c.T, exp, act)))
	}
}
544833
func Diff(left, right []byte) error {
	lf, err := ioutil.TempFile("/tmp", "actual-file-")
	if err != nil {
		return err
	}
	defer lf.Close()
	defer os.Remove(lf.Name())

	rf, err := ioutil.TempFile("/tmp", "expected-file-")
	if err != nil {
		return err
	}
	defer rf.Close()
	defer os.Remove(rf.Name())

	_, err = lf.Write(left)
	if err != nil {
		return err
	}
	lf.Close()

	_, err = rf.Write(right)
	if err != nil {
		return err
	}
	rf.Close()

	cmd := exec.Command("/usr/bin/diff", "-u", lf.Name(), rf.Name())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Run()

	return nil
}
274524
func NewDiffVersion(name string) (*DiffVersion, error) {
	dir, err := CreateDirectory(name)
	if err != nil {
		return nil, err
	}
	return &DiffVersion{
		Dir:  dir,
		Name: name,
	}, nil
}
318132
func mainDiff(ctx *cli.Context) error {
	// Parse encryption keys per command.
	encKeyDB, err := getEncKeys(ctx)
	fatalIf(err, "Unable to parse encryption keys.")

	// check 'diff' cli arguments.
	checkDiffSyntax(ctx, encKeyDB)

	// Additional command specific theme customization.
	console.SetColor("DiffMessage", color.New(color.FgGreen, color.Bold))
	console.SetColor("DiffOnlyInFirst", color.New(color.FgRed))
	console.SetColor("DiffOnlyInSecond", color.New(color.FgGreen))
	console.SetColor("DiffType", color.New(color.FgMagenta))
	console.SetColor("DiffSize", color.New(color.FgYellow, color.Bold))
	console.SetColor("DiffTime", color.New(color.FgYellow, color.Bold))

	URLs := ctx.Args()
	firstURL := URLs.Get(0)
	secondURL := URLs.Get(1)

	return doDiffMain(firstURL, secondURL)
}
1208316
func (g *Geometry) Difference(other *Geometry) (*Geometry, error) {
	return g.binaryTopo("Difference", cGEOSDifference, other)
}
1104091
func (set LiteralFieldSet) Difference(other LiteralFieldSet) LiteralFieldSet {
	differencedSet := NewLiteralFieldSet()
	for elem := range set {
		if !other.Contains(elem) {
			differencedSet.Add(elem)
		}
	}
	return differencedSet
}
40726
func (set StringSet) SymmetricDifference(other StringSet) StringSet {
	aDiff := set.Difference(other)
	bDiff := other.Difference(set)
	return aDiff.Union(bDiff)
}
1368695
func difference(sourceClnt, targetClnt Client, sourceURL, targetURL string, isRecursive, returnSimilar bool, dirOpt DirOpt) (diffCh chan diffMessage) {
	var (
		srcEOF, tgtEOF       bool
		srcOk, tgtOk         bool
		srcCtnt, tgtCtnt     *clientContent
		srcSuffix, tgtSuffix string
	)

	// Set default values for listing.
	isIncomplete := false // we will not compare any incomplete objects.
	srcCh := sourceClnt.List(isRecursive, isIncomplete, dirOpt)
	tgtCh := targetClnt.List(isRecursive, isIncomplete, dirOpt)

	diffCh = make(chan diffMessage, 1000)

	go func() {

		srcCtnt, srcOk = <-srcCh
		tgtCtnt, tgtOk = <-tgtCh

		defer close(diffCh)

		for {
			srcEOF = !srcOk
			tgtEOF = !tgtOk

			// No objects from source AND target: Finish
			if srcEOF && tgtEOF {
				break
			}

			if !srcEOF && srcCtnt.Err != nil {
				diffCh <- diffMessage{Error: srcCtnt.Err.Trace(sourceURL, targetURL)}
				return
			}

			if !tgtEOF && tgtCtnt.Err != nil {
				diffCh <- diffMessage{Error: tgtCtnt.Err.Trace(sourceURL, targetURL)}
				return
			}

			// If source doesn't have objects anymore, comparison becomes obvious
			if srcEOF {
				diffCh <- diffMessage{
					SecondURL:     tgtCtnt.URL.String(),
					Diff:          differInSecond,
					secondContent: tgtCtnt,
				}
				tgtCtnt, tgtOk = <-tgtCh
				continue
			}

			// The same for target
			if tgtEOF {
				diffCh <- diffMessage{
					FirstURL:     srcCtnt.URL.String(),
					Diff:         differInFirst,
					firstContent: srcCtnt,
				}
				srcCtnt, srcOk = <-srcCh
				continue
			}

			srcSuffix = strings.TrimPrefix(srcCtnt.URL.String(), sourceURL)
			tgtSuffix = strings.TrimPrefix(tgtCtnt.URL.String(), targetURL)

			current := urlJoinPath(targetURL, srcSuffix)
			expected := urlJoinPath(targetURL, tgtSuffix)

			if !utf8.ValidString(srcSuffix) {
				// Error. Keys must be valid UTF-8.
				diffCh <- diffMessage{Error: errInvalidSource(current).Trace()}
				srcCtnt, srcOk = <-srcCh
				continue
			}
			if !utf8.ValidString(tgtSuffix) {
				// Error. Keys must be valid UTF-8.
				diffCh <- diffMessage{Error: errInvalidTarget(expected).Trace()}
				tgtCtnt, tgtOk = <-tgtCh
				continue
			}

			// Normalize to avoid situations where multiple byte representations are possible.
			// e.g. 'ä' can be represented as precomposed U+00E4 (UTF-8 0xc3a4) or decomposed
			// U+0061 U+0308 (UTF-8 0x61cc88).
			normalizedCurrent := norm.NFC.String(current)
			normalizedExpected := norm.NFC.String(expected)

			if normalizedExpected > normalizedCurrent {
				diffCh <- diffMessage{
					FirstURL:     srcCtnt.URL.String(),
					Diff:         differInFirst,
					firstContent: srcCtnt,
				}
				srcCtnt, srcOk = <-srcCh
				continue
			}
			if normalizedExpected == normalizedCurrent {
				srcType, tgtType := srcCtnt.Type, tgtCtnt.Type
				srcSize, tgtSize := srcCtnt.Size, tgtCtnt.Size
				srcTime, tgtTime := srcCtnt.Time, tgtCtnt.Time
				if srcType.IsRegular() && !tgtType.IsRegular() ||
					!srcType.IsRegular() && tgtType.IsRegular() {
					// Type differs. Source is never a directory.
					diffCh <- diffMessage{
						FirstURL:      srcCtnt.URL.String(),
						SecondURL:     tgtCtnt.URL.String(),
						Diff:          differInType,
						firstContent:  srcCtnt,
						secondContent: tgtCtnt,
					}
					continue
				}
				if (srcType.IsRegular() && tgtType.IsRegular()) && srcSize != tgtSize {
					// Regular files differing in size.
					diffCh <- diffMessage{
						FirstURL:      srcCtnt.URL.String(),
						SecondURL:     tgtCtnt.URL.String(),
						Diff:          differInSize,
						firstContent:  srcCtnt,
						secondContent: tgtCtnt,
					}
				} else if srcTime.After(tgtTime) {
					// Regular files differing in timestamp.
					diffCh <- diffMessage{
						FirstURL:      srcCtnt.URL.String(),
						SecondURL:     tgtCtnt.URL.String(),
						Diff:          differInTime,
						firstContent:  srcCtnt,
						secondContent: tgtCtnt,
					}
				}
				// No differ
				if returnSimilar {
					diffCh <- diffMessage{
						FirstURL:      srcCtnt.URL.String(),
						SecondURL:     tgtCtnt.URL.String(),
						Diff:          differInNone,
						firstContent:  srcCtnt,
						secondContent: tgtCtnt,
					}
				}
				srcCtnt, srcOk = <-srcCh
				tgtCtnt, tgtOk = <-tgtCh
				continue
			}
			// Differ in second
			diffCh <- diffMessage{
				SecondURL:     tgtCtnt.URL.String(),
				Diff:          differInSecond,
				secondContent: tgtCtnt,
			}
			tgtCtnt, tgtOk = <-tgtCh
			continue
		}
	}()

	return diffCh
}
1139040
func (s *ChangesService) GetDiff(changeID, revisionID, fileID string, opt *DiffOptions) (*DiffInfo, *Response, error) {
	u := fmt.Sprintf("changes/%s/revisions/%s/files/%s/diff", changeID, revisionID, url.PathEscape(fileID))

	u, err := addOptions(u, opt)
	if err != nil {
		return nil, nil, err
	}

	req, err := s.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	v := new(DiffInfo)
	resp, err := s.client.Do(req, v)
	if err != nil {
		return nil, resp, err
	}

	return v, resp, err
}