コード例 #1
0
        /// <summary>
        /// Throws ContextMakingException.
        /// </summary>
        static private IEnumerable <GitDiffSection> getDiffSections(IGitCommandService git,
                                                                    string sha1, string sha2, string filename1, string filename2)
        {
            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 ContextMakingException("Cannot obtain git diff", ex);
            }

            if (diff == null)
            {
                throw new ContextMakingException("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);
            }

            return(sections);
        }
コード例 #2
0
        async protected override Task doUpdate(ILocalCommitStorage repo)
        {
            foreach (KeyValuePair <MergeRequestKey, Version> keyValuePair in collectLatestVersions(repo))
            {
                DiffStatistic?diffStat = null;
                if (!String.IsNullOrEmpty(keyValuePair.Value.Base_Commit_SHA) &&
                    !String.IsNullOrEmpty(keyValuePair.Value.Head_Commit_SHA))
                {
                    GitDiffArguments args = new GitDiffArguments
                                            (
                        GitDiffArguments.DiffMode.ShortStat,
                        new GitDiffArguments.CommonArguments
                        (
                            keyValuePair.Value.Base_Commit_SHA,
                            keyValuePair.Value.Head_Commit_SHA,
                            null, null, null
                        ),
                        null
                                            );

                    bool finished = repo?.Updater == null;
                    CommitBasedContextProvider contextProvider = new CommitBasedContextProvider(
                        new string[] { keyValuePair.Value.Head_Commit_SHA }, keyValuePair.Value.Base_Commit_SHA);
                    repo?.Updater?.RequestUpdate(contextProvider, () => finished = true);
                    await TaskUtils.WhileAsync(() => !finished);

                    try
                    {
                        if (repo?.Git != null)
                        {
                            await repo.Git.FetchAsync(args);
                        }
                        diffStat = parseGitDiffStatistic(repo, keyValuePair.Key, args);
                    }
                    catch (FetchFailedException ex)
                    {
                        ExceptionHandlers.Handle(String.Format(
                                                     "Cannot update git statistic for MR with IID {0}", keyValuePair.Key), ex);
                    }
                }
                _statistic[keyValuePair.Key] = new MergeRequestStatistic(keyValuePair.Value.Created_At, diffStat);
                Update?.Invoke();
            }
        }
コード例 #3
0
        private DiffStatistic?parseGitDiffStatistic(ILocalCommitStorage repo, MergeRequestKey mrk,
                                                    GitDiffArguments args)
        {
            void traceError(string text)
            {
                Trace.TraceError(String.Format(
                                     "[GitBasedSizeCollector] Cannot parse git diff text {0} obtained by key {3} in the repo {2} (in \"{1}\"). "
                                     + "This makes impossible to show git statistic for MR with IID {4}", text, repo.Path,
                                     String.Format("{0}/{1}", args.CommonArgs.Sha1?.ToString() ?? "N/A",
                                                   args.CommonArgs.Sha2?.ToString() ?? "N/A"),
                                     String.Format("{0}:{1}", repo.ProjectKey.HostName, repo.ProjectKey.ProjectName), mrk.IId));
            }

            IEnumerable <string> statText = null;

            try
            {
                statText = repo.Git?.ShowDiff(args);
            }
            catch (GitNotAvailableDataException ex)
            {
                ExceptionHandlers.Handle("Cannot obtain git statistic", ex);
            }

            if (statText == null || !statText.Any())
            {
                traceError(statText == null ? "\"null\"" : "(empty)");
                return(null);
            }

            int parseOrZero(string x) => int.TryParse(x, out int result) ? result : 0;

            string firstLine = statText.First();
            Match  m         = gitDiffStatRe.Match(firstLine);

            if (!m.Success || !m.Groups["files"].Success || parseOrZero(m.Groups["files"].Value) < 1)
            {
                traceError(firstLine);
                return(null);
            }

            return(new DiffStatistic(parseOrZero(m.Groups["files"].Value),
                                     parseOrZero(m.Groups["ins"].Value), parseOrZero(m.Groups["del"].Value)));
        }
コード例 #4
0
        /// <summary>
        /// Throws ContextMakingException.
        /// </summary>
        public FullContextDiff GetFullContextDiff(string leftSHA, string rightSHA,
                                                  string leftFileName, string rightFileName)
        {
            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);
            }

            fullDiff = fullDiff.Where(x => !String.IsNullOrEmpty(x));

            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;
                }
            }
            return(fullContextDiff);
        }