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; }