Beispiel #1
0
        private Task Diff(string filePath)
        {
            // TODO: throw? warn?
            if (string.IsNullOrEmpty(diffTool.Cmd))
            {
                return(Task.CompletedTask);
            }

            var changes = repository.Diff.Compare <TreeChanges>().Modified.First(x => x.Path == filePath);
            var old     = repository.Lookup <Blob>(changes.OldOid);

            // We can't show diff in this case
            if (changes.Mode != Mode.NonExecutableFile || !changes.Exists || old == null || old.IsBinary)
            {
                return(Task.CompletedTask);
            }

            // Write the old content to a temp file for comparison.
            var baseFile = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(Path.GetFileName(filePath), ".BASE" + Path.GetExtension(filePath)));

            File.WriteAllText(baseFile, old.GetContentText());

#pragma warning disable CS8602 // Dereference of a possibly null reference.
            var indexOfDolar = diffTool.Cmd.IndexOf("$");
            if (indexOfDolar == -1)
            {
                // TODO: There were no replacements, so we can't diff anything. Report warning/error?
                return(Task.CompletedTask);
            }

            var indexOfArgs  = diffTool.Cmd.Substring(0, indexOfDolar).LastIndexOf(' ');
            var toolFilePath = diffTool.Cmd.Substring(0, indexOfArgs).Trim();
            var fullFilePath = repository.GetFullPath(filePath);

            // Replace arguments as documented in https://git-scm.com/docs/git-difftool#_options
            var arguments = diffTool.Cmd.Substring(indexOfArgs)
                            // "$LOCAL is set to the name of the temporary file containing the contents of the diff pre-image"
                            .Replace("$LOCAL", baseFile)
                            // "$REMOTE is set to the name of the temporary file containing the contents of the diff post-image"
                            // We want the current file to be the one including the "changes post-image".
                            .Replace("$REMOTE", fullFilePath)
                            // Yes, it's confusing even in the docs that $BASE == $MERGED.
                            // "$MERGED is the name of the file which is being compared.
                            .Replace("$MERGED", fullFilePath)
                            // "$BASE is provided for compatibility with custom merge tool commands and has the same value as $MERGED."
                            .Replace("$BASE", fullFilePath);

#pragma warning restore CS8602 // Dereference of a possibly null reference.

            RunTool(toolFilePath, arguments);

            return(Task.CompletedTask);
        }