Пример #1
0
        public RevRangeSet Subtract(RevRangeSet what)
        {
            if (!_normalized)
                return Normalize().Subtract(what);

            if (!what._normalized)
                return Subtract(what.Normalize());

            // make copies
            var subtracted = _ranges.ToList();

            foreach (var subRange in what._ranges)
            {
                for (var i = 0; i < subtracted.Count; i++)
                {
                    // complete cut
                    if (subRange.RangeStart <= subtracted[i].RangeStart && subRange.RangeEnd >= subtracted[i].RangeEnd)
                    {
                        subtracted.RemoveAt(i);
                        // can eat other ranges
                        i--;
                        continue;
                    }

                    // split
                    if (subRange.RangeStart > subtracted[i].RangeStart && subRange.RangeEnd < subtracted[i].RangeEnd)
                    {
                        // completly inside of range
                        var left = new RevRange { RangeStart = subtracted[i].RangeStart, RangeEnd = subRange.RangeStart - 1 };
                        var right = new RevRange { RangeStart = subRange.RangeEnd + 1, RangeEnd = subtracted[i].RangeEnd };

                        subtracted[i] = left;
                        subtracted.Insert(i + 1, right);

                        // can't cut other ranges
                        break;
                    }

                    // left cut
                    if (subRange.RangeEnd >= subtracted[i].RangeStart && subRange.RangeEnd < subtracted[i].RangeEnd)
                    {
                        subtracted[i] = new RevRange { RangeStart = subRange.RangeEnd + 1, RangeEnd = subtracted[i].RangeEnd };
                        // can't cut other ranges
                        break;
                    }

                    // right cut
                    if (subRange.RangeStart > subtracted[i].RangeStart && subRange.RangeStart <= subtracted[i].RangeEnd)
                    {
                        subtracted[i] = new RevRange { RangeStart = subtracted[i].RangeStart, RangeEnd = subRange.RangeStart - 1 };
                        // can cut next range
                    }
                }
            }

            return new RevRangeSet(subtracted).Normalize();
        }
        void LoadLogEntries(Uri branchUri, RevRangeSet revRangesSet)
        {
            var min = revRangesSet.Ranges.First().RangeStart;
            var max = revRangesSet.Ranges.Last().RangeEnd;

            var args = new SvnLogArgs(new SvnRevisionRange(min, max)) {
                RetrieveChangedPaths = true,
                OperationalRevision = min
            };

            Collection<SvnLogEventArgs> logEntries;
            _client.GetLog(branchUri, args, out logEntries);
            _cancellationToken.ThrowIfCancellationRequested();

            foreach (var logEntry in logEntries)
            {
                if (!revRangesSet.ContainsRevision(logEntry.Revision))
                    continue;

                if (_revLogEntries.ContainsKey(logEntry.Revision))
                    continue;

                // mark as in progress
                _revLogEntries[logEntry.Revision] = null;

                var changedDirs = logEntry.ChangedPaths.Where(IsPossibleMergeRevision).ToArray();

                var mergeRevision = false;
                foreach (var cd in changedDirs)
                {
                    var changedUri = new Uri(_repoRoot.ToString().TrimEnd('/') + cd.Path);
                    var merged = GetMergedRevisions(changedUri.ToString(), logEntry.Revision);
                    if (merged.Count > 0)
                    {
                        mergeRevision = true;

                        // exclude merged revisions from branch which was requested. to avoid merged messages from
                        // trunk < reintegrate feature < sync trunc
                        // sync trunk messages shall be droped
                        while (true)
                        {
                            var removed = false;
                            foreach (var kvp in merged)
                            {
                                if ((kvp.Key.TrimEnd('/') + "/").StartsWith(_requestedMergeMessageForBranch))
                                {
                                    merged.Remove(kvp.Key);
                                    removed = true;
                                    break;
                                }
                            }

                            if (!removed)
                                break;
                        }

                        if (merged.Count > 0)
                            LoadLogEntries(merged);
                    }
                }

                // not store merge revisions message
                if (mergeRevision)
                    continue;

                // check if it is agan merge revision
                _revLogEntries[logEntry.Revision] = new RevLogEntry {
                    Author = logEntry.Author,
                    Message = logEntry.LogMessage,
                    Revision = logEntry.Revision
                };
            }
        }
        static Dictionary<string, RevRangeSet> ParseMegeinfoLines(string text)
        {
            var lines = text.Replace('\r', '\n').Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            var dict = new Dictionary<string, RevRangeSet>();

            foreach (var line in lines)
            {
                var parts = line.Split(':');
                if(parts.Length != 2)
                    throw new ApplicationException("Invalid (?) merge info line: " + line);

                var branch = parts[0];

                var rangesList = new List<RevRange>();

                foreach (var range in parts[1].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Select(r => r.TrimEnd('*')))
                {
                    var rangePair = range.Split('-');
                    if (rangePair.Length == 1)
                        rangesList.Add(new RevRange { RangeStart = Int32.Parse(rangePair[0]), RangeEnd = Int32.Parse(rangePair[0]) });
                    else if(rangePair.Length == 2)
                        rangesList.Add(new RevRange { RangeStart = Int32.Parse(rangePair[0]), RangeEnd = Int32.Parse(rangePair[1]) });
                    else
                        throw new ApplicationException(string.Format("Invalid (?) range '{0}' in merge info line: '{1}'", range, line));
                }

                dict[branch] = new RevRangeSet(rangesList).Normalize();
            }

            return dict;
        }