Exemple #1
0
        private void createDummyPlaceHoldersForGitDiff(GitDiffArguments arguments, Comparison comparison,
                                                       out bool dummyOld, out bool dummyNew)
        {
            dummyOld = false;
            dummyNew = false;

            foreach (DiffStruct diff in comparison.Diffs)
            {
                if (diff.Old_Path == arguments.CommonArgs.Filename1 && diff.New_Path == arguments.CommonArgs.Filename2)
                {
                    Debug.Assert(!String.IsNullOrEmpty(diff.Old_Path) && !String.IsNullOrEmpty(diff.New_Path));
                    if (diff.New_File)
                    {
                        dummyOld = createDummyRevision(arguments.CommonArgs.Sha1, diff.Old_Path);
                        dummyNew = false;
                    }
                    else if (diff.Deleted_File)
                    {
                        dummyOld = false;
                        dummyNew = createDummyRevision(arguments.CommonArgs.Sha2, diff.New_Path);
                    }
                    return;
                }
            }
        }
 public Task FetchAsync(GitDiffArguments arguments)
 {
     try
     {
         return(runCommandAndCacheResultAsync(arguments, _cachedDiffs));
     }
     catch (GitCommandServiceInternalException ex)
     {
         ExceptionHandlers.Handle(ex.Message, ex);
         throw new FetchFailedException(ex);
     }
 }
 public IEnumerable <string> ShowDiff(GitDiffArguments arguments)
 {
     try
     {
         return(runCommandAndCacheResult(arguments, _cachedDiffs));
     }
     catch (GitCommandServiceInternalException ex)
     {
         ExceptionHandlers.Handle(ex.Message, ex);
         throw new GitNotAvailableDataException(ex);
     }
 }
 protected override object runCommand(GitDiffArguments arguments)
 {
     try
     {
         ConvertedArguments converted = _argumentConverter.Convert(arguments);
         return(startExternalProcess(converted.App, converted.Arguments, _path, true, new int[] { 0, 1 })
                .StdOut.Where(x => !String.IsNullOrEmpty(x)));
     }
     catch (ArgumentConversionException ex)
     {
         throw new GitCommandServiceInternalException(ex);
     }
 }
 async protected override Task <object> runCommandAsync(GitDiffArguments arguments)
 {
     try
     {
         ConvertedArguments   converted = _argumentConverter.Convert(arguments);
         IEnumerable <string> result    =
             (await startExternalProcessAsync(converted.App, converted.Arguments, _path, new int[] { 0, 1 })).StdOut;
         return(result.Where(x => !String.IsNullOrEmpty(x)));
     }
     catch (ArgumentConversionException ex)
     {
         throw new GitCommandServiceInternalException(ex);
     }
 }
Exemple #6
0
        public ConvertedArguments Convert(GitDiffArguments arguments)
        {
            string baseSha = arguments.CommonArgs.Sha1;
            string headSha = arguments.CommonArgs.Sha2;

            throwOnEmptySha(new[] { baseSha, headSha });
            throwOnBadFilenamePair(arguments.CommonArgs.Filename1, arguments.CommonArgs.Filename2);

            Comparison comparison = getComparison(baseSha, headSha);

            createDummyPlaceHoldersForGitDiff(arguments, comparison, out bool dummyOld, out bool dummyNew);

            string filename1;
            string filename2;

            switch (arguments.Mode)
            {
            case GitDiffArguments.DiffMode.Context:
                filename1 = getFilePath(baseSha, arguments.CommonArgs.Filename1, dummyOld);
                filename2 = getFilePath(headSha, arguments.CommonArgs.Filename2, dummyNew);
                break;

            case GitDiffArguments.DiffMode.ShortStat:
                filename1 = getPath(baseSha);
                filename2 = getPath(headSha);
                break;

            case GitDiffArguments.DiffMode.NumStat:
            // Not tested.
            // NumStat Mode is used to detect renames in GitRepositoryRenameDetector.
            // FileStorageRenameDetector does not use it.

            default:
                throw new NotImplementedException();
            }

            GitDiffArguments modifiedArguments = new GitDiffArguments(arguments.Mode,
                                                                      new GitDiffArguments.CommonArguments(string.Empty, string.Empty, filename1, filename2,
                                                                                                           arguments.CommonArgs.Filter), arguments.SpecialArgs);

            return(new ConvertedArguments("git", modifiedArguments.ToString()));
        }
 abstract protected Task <object> runCommandAsync(GitDiffArguments arguments);
 abstract protected object runCommand(GitDiffArguments arguments);
 async protected override Task <object> runCommandAsync(GitDiffArguments arguments)
 {
     return((await startExternalProcessAsync("git", arguments.ToString(), _path, null)).StdOut);
 }
 protected override object runCommand(GitDiffArguments arguments)
 {
     return(startExternalProcess("git", arguments.ToString(), _path, true, null).StdOut);
 }
        /// <summary>
        /// Returns a name of file at the opposite side.
        /// Throws MatchingException.
        /// </summary>
        public string IsRenamed(string leftcommit, string rightcommit, string filename, bool leftsidename, out bool moved)
        {
            GitDiffArguments arguments = new GitDiffArguments(
                GitDiffArguments.DiffMode.NumStat,
                new GitDiffArguments.CommonArguments(leftcommit, rightcommit, null, null, "R"),
                null);

            IEnumerable <string> renames;

            try
            {
                renames = _git?.ShowDiff(arguments);
            }
            catch (GitNotAvailableDataException ex)
            {
                throw new FileRenameDetectorException("Cannot obtain list of renamed files", ex);
            }

            if (renames == null)
            {
                throw new FileRenameDetectorException("Cannot obtain list of renamed files", null);
            }

            moved = false;

            foreach (string line in renames)
            {
                Match m = diffRenameRe.Match(line);
                if (!m.Success || m.Groups.Count < 4)
                {
                    continue;
                }

                if (!m.Groups["left_name"].Success || !m.Groups["right_name"].Success)
                {
                    continue;
                }

                Debug.Assert(m.Groups["added"].Success);
                Debug.Assert(m.Groups["deleted"].Success);

                int added   = int.Parse(m.Groups["added"].Value);
                int deleted = int.Parse(m.Groups["deleted"].Value);

                string leftName  = m.Groups["left_name"].Value;
                string rightName = m.Groups["right_name"].Value;

                if (leftName.Contains('{'))
                {
                    Debug.Assert(rightName.Contains('}'));

                    int    leftPathIdx  = leftName.IndexOf('{');
                    string commonPrefix = leftName.Substring(0, leftPathIdx);
                    string leftPart     = leftName.Substring(leftPathIdx + 1, leftName.Length - leftPathIdx - 1);

                    int    rightPathIdx = rightName.IndexOf('}');
                    string commonSuffix = rightName.Substring(rightPathIdx + 1, rightName.Length - rightPathIdx - 1);
                    string rightPart    = rightName.Substring(0, rightPathIdx);

                    leftName  = commonPrefix + leftPart + commonSuffix;
                    rightName = commonPrefix + rightPart + commonSuffix;
                }

                if (leftsidename && leftName == filename)
                {
                    moved = (added + deleted == 0);
                    return(rightName);
                }
                else if (!leftsidename && rightName == filename)
                {
                    moved = (added + deleted == 0);
                    return(leftName);
                }
            }

            return(filename);
        }
Exemple #12
0
        /// <summary>
        /// Throws GitDiffAnalyzerException.
        /// </summary>
        private IEnumerable <GitDiffSection> getDiffSections(string sha1, string sha2, string filename1, string filename2)
        {
            CacheKey key = new CacheKey(sha1, sha2, filename1, filename2);

            if (_cachedSections.TryGetValue(key, out IEnumerable <GitDiffSection> cachedSections))
            {
                return(cachedSections);
            }

            List <GitDiffSection> sections = new List <GitDiffSection>();

            GitDiffArguments arguments = new GitDiffArguments(
                GitDiffArguments.DiffMode.Context,
                new GitDiffArguments.CommonArguments(sha1, sha2, filename1, filename2, null),
                new GitDiffArguments.DiffContextArguments(0));

            IEnumerable <string> diff;

            try
            {
                diff = _git?.ShowDiff(arguments);
            }
            catch (GitNotAvailableDataException ex)
            {
                throw new GitDiffAnalyzerException("Cannot obtain git diff", ex);
            }

            if (diff == null)
            {
                throw new GitDiffAnalyzerException("Cannot obtain git diff", null);
            }

            foreach (string line in diff)
            {
                Match m = diffSectionRe.Match(line);
                if (!m.Success || m.Groups.Count < 3)
                {
                    continue;
                }

                if (!m.Groups["left_start"].Success || !m.Groups["right_start"].Success)
                {
                    continue;
                }

                // @@ -1 +1 @@ is essentially the same as @@ -1,1 +1,1 @@
                int leftSectionStart  = int.Parse(m.Groups["left_start"].Value);
                int leftSectionLength = m.Groups["left_len"].Success ? int.Parse(m.Groups["left_len"].Value) : 1;

                int rightSectionStart  = int.Parse(m.Groups["right_start"].Value);
                int rightSectionLength = m.Groups["right_len"].Success ? int.Parse(m.Groups["right_len"].Value) : 1;

                GitDiffSection section = new GitDiffSection(
                    leftSectionStart, leftSectionStart + leftSectionLength,
                    rightSectionStart, rightSectionStart + rightSectionLength);
                sections.Add(section);
            }

            _cachedSections.Add(key, sections);
            return(sections);
        }
Exemple #13
0
        /// <summary>
        /// Throws FullContextDiffProviderException.
        /// </summary>
        public FullContextDiff GetFullContextDiff(string leftSHA, string rightSHA,
                                                  string leftFileName, string rightFileName)
        {
            CacheKey key = new CacheKey(leftSHA, rightSHA, leftFileName, rightFileName);

            if (_cachedContexts.TryGetValue(key, out FullContextDiff context))
            {
                return(context);
            }

            FullContextDiff fullContextDiff = new FullContextDiff(new SparsedList <string>(), new SparsedList <string>());

            GitDiffArguments arguments = new GitDiffArguments(
                GitDiffArguments.DiffMode.Context,
                new GitDiffArguments.CommonArguments(leftSHA, rightSHA, leftFileName, rightFileName, null),
                new GitDiffArguments.DiffContextArguments(Constants.FullContextSize));

            IEnumerable <string> fullDiff;

            try
            {
                fullDiff = _git?.ShowDiff(arguments);
            }
            catch (GitNotAvailableDataException ex)
            {
                throw new FullContextDiffProviderException("Cannot obtain git diff", ex);
            }

            if (fullDiff == null)
            {
                throw new FullContextDiffProviderException("Cannot obtain git diff", null);
            }

            if (fullDiff.Count() == 0)
            {
                Trace.TraceWarning(String.Format(
                                       "[FullContextDiffProvider] Context size is zero. LeftSHA: {0}, Right SHA: {1}, Left file: {2}, Right file: {3}",
                                       leftSHA, rightSHA, leftFileName, rightFileName));
            }

            bool skip = true;

            foreach (string line in fullDiff)
            {
                char sign = line[0];
                if (skip)
                {
                    // skip meta information about diff
                    if (sign == '@')
                    {
                        // next lines should not be skipped because they contain a diff itself
                        skip = false;
                    }
                    continue;
                }
                string lineOrig = line.Substring(1, line.Length - 1);
                switch (sign)
                {
                case '-':
                    fullContextDiff.Left.Add(lineOrig);
                    fullContextDiff.Right.Add(null);
                    break;

                case '+':
                    fullContextDiff.Left.Add(null);
                    fullContextDiff.Right.Add(lineOrig);
                    break;

                case ' ':
                    fullContextDiff.Left.Add(lineOrig);
                    fullContextDiff.Right.Add(lineOrig);
                    break;
                }
            }

            _cachedContexts.Add(key, fullContextDiff);
            return(fullContextDiff);
        }