private HgManifestNode(HgManifestTreeNodeType type, string name, HgPath path, HgNodeID? nodeID) { Type = type; Name = name; Path = path; NodeID = nodeID; }
public HgChunk(HgNodeID nodeID, HgNodeID firstParentNodeID, HgNodeID secondParentNodeID, HgNodeID changesetNodeID, byte[] data) { NodeID = nodeID; FirstParentNodeID = firstParentNodeID; SecondParentNodeID = secondParentNodeID; ChangesetNodeID = changesetNodeID; Data = data; }
protected virtual HgRevlogEntryData GetRevlogEntryData(HgNodeID hgNodeID) { if(hgNodeID == HgNodeID.Null) return null; var key = string.Format("revlog:{0}@{1}", Revlog.IndexPath, hgNodeID.Long); var hgRevlogEntryData = revlogEntryCache.GetOrAdd(key, () => revlogReader.ReadRevlogEntry(hgNodeID)); return hgRevlogEntryData; }
public void UpdateBookmark(string name, HgNodeID changesetNodeID) { var bookmarks = ReadBookmarks(); bookmarks.Remove(bookmarks.SingleOrDefault(b => b.Name == name)); bookmarks.Add(new HgBookmark(name, repository.Changelog[changesetNodeID])); WriteBookmarks(bookmarks); }
public HgCommit(HgNodeID firstParentNodeID, HgNodeID secondParentNodeID, HgAuthor committedBy, DateTimeOffset committedAt, HgBranch branch, string comment, params HgCommitFileEntry[] files) : base(firstParentNodeID, secondParentNodeID) { CommittedBy = committedBy; CommittedAt = committedAt; Branch = branch; Comment = comment; Files = new ReadOnlyCollection<HgCommitFileEntry>(new List<HgCommitFileEntry>(files)); }
public HgRevlogEntryMetadata(HgNodeID nodeID, uint revision, uint linkRevision, HgNodeID firstParentRevisionNodeID, HgNodeID secondParentRevisionNodeID, uint firstParentRevision, uint secondParentRevision) { SecondParentRevision = secondParentRevision; FirstParentRevision = firstParentRevision; NodeID = nodeID; Revision = revision; LinkRevision = linkRevision; FirstParentRevisionNodeID = firstParentRevisionNodeID; SecondParentRevisionNodeID = secondParentRevisionNodeID; }
public override HgManifestEntry this[HgNodeID hgNodeID] { get { var largefilesEnabledManifestEntry = underlyingManifest[hgNodeID]; var manifestEntry = new HgManifestEntry( largefilesEnabledManifestEntry.Metadata, largefilesEnabledManifestEntry.Files.Select(f => new HgManifestFileEntry(new HgPath(f.Path.FullPath.SubstringAfter(".hglf/")), f.FilelogNodeID)).ToList()); return manifestEntry; } }
private static HgNodeID Max(HgNodeID l, HgNodeID r) { var ln = l.NodeID; var rn = r.NodeID; for(var i = 0; i < Math.Min(ln.Length, rn.Length); ++i) { if(ln[i] > rn[i]) return l; if(ln[i] < rn[i]) return r; } // for return l; }
public HgChangeset(HgRevlogEntryMetadata metadata, HgNodeID manifestNodeID, HgAuthor committedBy, DateTimeOffset committedAt, HgBranch branch, HgNodeID sourceNodeID, IEnumerable<string> files, string comment) { Metadata = metadata; ManifestNodeID = manifestNodeID; CommittedBy = committedBy; CommittedAt = committedAt; Branch = branch; SourceNodeID = sourceNodeID; Files = new ReadOnlyCollection<string>(new List<string>(files)); Comment = comment; }
public virtual HgRevlogEntry GetEntry(HgNodeID nodeID) { uint revision = 0; if(nodeCache.TryGetValue(nodeID, out revision)) return GetEntry(revision); if (nodeID.NodeID.Length == 20) return null; // // Nope, no match. Might be a shortened SHA, so we'll have to look through the whole revlog var node = entries.FirstOrDefault(e => e.NodeID.Equals(nodeID)); return node; }
public virtual HgManifestEntry this[HgNodeID hgNodeID] { get { var key = string.Format("manifest:{0}@{1}", Revlog.IndexPath, hgNodeID.Long); return ObjectCache.GetOrAdd(key, () => { var hgRevlogEntryData = GetRevlogEntryData(hgNodeID); return hgRevlogEntryData == null ? null : hgManifestReader.ReadManifestEntry(hgRevlogEntryData); }); } }
public HgRevlogEntry(UInt32 revision, HgNodeID nodeID, ulong offset, ushort flags, uint compressedLength, uint uncompressedLength, uint baseRevision, uint linkRevision, uint firstParentRevision, HgNodeID firstParentRevisionNodeID, uint secondParentRevision, HgNodeID secondParentRevisionNodeID) { Revision = revision; Offset = offset; Flags = flags; CompressedLength = compressedLength; UncompressedLength = uncompressedLength; BaseRevision = baseRevision; LinkRevision = linkRevision; FirstParentRevision = firstParentRevision; SecondParentRevision = secondParentRevision; NodeID = nodeID; FirstParentRevisionNodeID = firstParentRevisionNodeID; SecondParentRevisionNodeID = secondParentRevisionNodeID; }
public HgChangeset this[HgNodeID hgNodeID] { get { if(hgNodeID == HgNodeID.Null) return HgChangeset.Null; var key = string.Format("changelog:{0}@{1}", Revlog.IndexPath, hgNodeID.Long); return ObjectCache.GetOrAdd(key, () => { var hgRevlogEntryData = GetRevlogEntryData(hgNodeID); return hgRevlogEntryData == null ? null : hgChangelogReader.ReadChangeset(hgRevlogEntryData); }); } }
private HgChangeset ReadChangesetInternal(HgRevlogEntryData revlogEntryData) { var filesStart = revlogEntryData.Data.IndexOfNth((byte)'\n', 3); var filesEnd = revlogEntryData.Data.IndexOf((byte)'\n', (byte)'\n'); var headerString = hgEncoder.DecodeAsUtf8(revlogEntryData.Data, 0, filesStart); var filesString = filesStart == filesEnd ? "" : hgEncoder.DecodeAsLocal( revlogEntryData.Data, filesStart + 1, // The \n filesEnd - filesStart - 1); var commentString = hgEncoder.DecodeAsUtf8( revlogEntryData.Data, filesEnd + 2, // These \n\n bytes revlogEntryData.Data.Length - filesEnd - 2); var header = headerString.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); var manifestNodeID = new HgNodeID(header[0]); var committedBy = HgAuthor.Parse(header[1]); var timeParts = header[2].Split(' '); var time = int.Parse(timeParts[0]); var timeZone = int.Parse(timeParts[1]); var branchData = header[2].SubstringAfterNth(" ", 1).Or("branch:default"); var b = branchData.Split('\0').Select(s => new { key = s.Split(':')[0], value = s.Split(':')[1] }).ToDictionary(s => s.key, s => s.value).DefaultableWith(v => ""); var branchName = new HgBranch(b["branch"].Or("default"), b["close"] == "1"); var sourceNodeID = new HgNodeID(b["source"].Or(HgNodeID.Null.Long)); var dateTime = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(time).AddSeconds(-1 * timeZone), DateTimeKind.Local); var committedAt = new DateTimeOffset(dateTime); var files = filesString.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); var metadata = GetRevlogEntryMetadata(revlogEntryData.Entry); return new HgChangeset(metadata, manifestNodeID, committedBy, committedAt, branchName, sourceNodeID, files, commentString); }
private IList<HgBookmark> ReadBookmarks() { var bookmarks = new List<HgBookmark>(); if(!Alphaleonis.Win32.Filesystem.File.Exists(bookmarksPath)) return bookmarks; using(var booknmarksStream = fileSystem.OpenRead(bookmarksPath)) using(var streamReader = new StreamReader(booknmarksStream)) { var line = ""; while((line = streamReader.ReadLine()) != null) { var changesetNodeID = new HgNodeID(line.SubstringBefore(" ")); var name = line.SubstringAfter(" ").Trim(); bookmarks.Add(new HgBookmark(name, repository.Changelog[changesetNodeID])); } // while } // using return bookmarks; }
protected HgNodeID GetRevlogEntryDataNodeID(HgNodeID firstParentNodeID, HgNodeID secondParentNodeID, byte[] data) { var parents = new[] { Min(firstParentNodeID, secondParentNodeID), Max(firstParentNodeID, secondParentNodeID) }; using(var hash = new SHA1Managed()) { hash.Initialize(); var buffer = new byte[hash.HashSize / 8]; hash.TransformBlock(parents[0].NodeID, 0, 20, buffer, 0); hash.TransformBlock(parents[1].NodeID, 0, 20, buffer, 0); hash.TransformFinalBlock(data, 0, data.Length); buffer = hash.Hash; var node = new HgNodeID(buffer); return node; } // using }
public HgChangesetDetails GetChangesetDetails(HgNodeID hgNodeID, int context = 3) { var c = Changelog[hgNodeID]; if(c == null) return null; var m = Manifest[c.ManifestNodeID]; if(m == null) return new HgChangesetDetails(c, new List<HgChangesetFileDetails>()); IList<HgChangesetFileDetails> files; var diffGenerator = new HgDiffGenerator(); // // For a very first changeset we treat all files as Added if(c.Metadata.FirstParentRevisionNodeID == HgNodeID.Null) { files = m.Files. Select(f => new { f = f.Path, file = GetFile(m[f.Path.FullPath]), }). Select(f => new HgChangesetFileDetails(f.f, HgChangesetFileOperation.Added, f.file.IsBinary ? null : GetHgRollupFileDiffInfo(f.f, f.file.IsBinary, diffGenerator.UnifiedDiff("", Encoder.DecodeAsUtf8(f.file.Data), context, false, true, true)))). ToList(); } // if else { Func<HgManifestFileEntry, string> fileName = mfe => mfe.Path.FullPath.TrimStart('/'); HgManifestEntry mp1 = null; ISet<string> cf = null, f_ = null, fp1 = null; cf = new HashSet<string>(c.Files.Select(f => f.TrimStart('/')).ToList()); f_ = new HashSet<string>(m.Files.Select(fileName)); var p1 = Changelog[c.Metadata.FirstParentRevisionNodeID]; mp1 = Manifest[p1.ManifestNodeID]; fp1 = new HashSet<string>(mp1.Files.Select(fileName)); var addedFiles = f_.Except(fp1).Intersect(cf).ToList(); var removedFiles = fp1.Except(f_).Intersect(cf).ToList(); var modifiedFiles = f_.Intersect(fp1).Intersect(cf).Where(f => m[f].FilelogNodeID != mp1[f].FilelogNodeID || !GetFile(m[f]).Data.SequenceEqual(GetFile(mp1[f]).Data)).ToList(); Func<HgFile, HgFile, HgUnifiedDiff> diff = (f /* from */, t /* to */) => { if(f != null && f.IsBinary || t != null && t.IsBinary) return null; var a = f == null ? "" : Encoder.DecodeAsUtf8(f.Data); var b = t == null ? "" : Encoder.DecodeAsUtf8(t.Data); return diffGenerator.UnifiedDiff(a, b, context, false, true, true); }; var removed = removedFiles. Select(f => new { f, file = GetFile(mp1[f]), }). Where(f => f.file != null). Select(f => Removed(f.f, GetHgRollupFileDiffInfo( new HgPath(f.f), f.file.IsBinary, diff(f.file, null)))). Where(f => f.Diff != null && (f.Diff.Additions > 0 || f.Diff.Removals > 0)); var added = addedFiles. Select(f => new { f, file = GetFile(m[f]), }). Where(f => f.file != null). Select(f => Added(f.f, GetHgRollupFileDiffInfo( new HgPath(f.f), f.file.IsBinary, diff(null, f.file)))). Where(f => f.Diff != null && (f.Diff.Additions > 0 || f.Diff.Removals > 0)); var modified = modifiedFiles. Select(f => new { f, file = GetFile(m[f]), }). Where(f => f.file != null). Select(f => Modified(f.f, GetHgRollupFileDiffInfo( new HgPath(f.f), f.file.IsBinary, diff(GetFile(mp1[f.f]), f.file)))). Where(f => f.Diff == null || f.Diff.Additions > 0 || f.Diff.Removals > 0); // // Prepare enough room to avoid reallocations later on files = new List<HgChangesetFileDetails>(f_.Count * 2); files.AddRange(added); files.AddRange(modified); files.AddRange(removed); } // else var changesetDetails = new HgChangesetDetails(c, files); return changesetDetails; }
public HgRevlogEntryData ReadRevlogEntry(HgNodeID nodeID) { var revlogEntryData = standinRevlogReader.ReadRevlogEntry(nodeID); return GetRevlogEntryData(revlogEntryData); }
public HgSubrepository(HgPath path, string repositoryPath, HgNodeID nodeID) { Path = path; RepositoryPath = repositoryPath; NodeID = nodeID; }
public HgFileCopyInfo(HgPath path, HgNodeID nodeID) { Path = path; NodeID = nodeID; }
public HgCommitFileEntry(HgNodeID firstParentNodeID, HgNodeID secondParentNodeID, HgPath path, byte[] content) : base(firstParentNodeID, secondParentNodeID) { Path = path; Content = content; }
public HgCompareInfo PerformComparison(HgNodeID baseNodeID, HgNodeID headNodeID, bool includeFileDiffs = false) { var hgRevsetManager = new HgRevsetManager(); var @base = Changelog[baseNodeID]; var head = Changelog[headNodeID]; var baseAncestors = hgRevsetManager.GetAncestors(this, new HgRevset(@base.Metadata)); var headAncestors = hgRevsetManager.GetAncestors(this, new HgRevset(head.Metadata)); var changesets = GetChangesets(headAncestors - baseAncestors); if(changesets.Count == 0) return new HgCompareInfo(@base, head, new List<HgChangeset>(), new List<HgRollupFileDiffInfo>()); var files = changesets.SelectMany(c => c.Files).Distinct().OrderBy(f => f).ToList(); var startManifest = Manifest[@base.ManifestNodeID]; var endManifest = Manifest[head.ManifestNodeID]; // // Only pick files that were indeed changed between two bounding changesets var diffs = new List<HgRollupFileDiffInfo>(); if(includeFileDiffs) { var changedFiles = files.Where(f => startManifest[f] == null && endManifest[f] != null || startManifest[f] != null && endManifest[f] == null || (startManifest[f] != null && endManifest[f] != null && startManifest[f].FilelogNodeID != endManifest[f].FilelogNodeID)).ToList(); var diffGenerator = new HgDiffGenerator(); diffs = changedFiles. Select(f => new { file = f, start = startManifest[f], end = endManifest[f] }). Select(f => new { f.file, start = f.start == null ? null : GetFile(f.start), end = f.end == null ? null : GetFile(f.end) }). Select(f => new { f.file, isBinary = f.start != null && f.start.IsBinary || f.end != null && f.end.IsBinary, f.start, f.end }). Select(f => new { f.file, f.isBinary, start = f.start == null || f.isBinary ? "" : Encoder.DecodeAsUtf8(f.start.Data), end = f.end == null || f.isBinary ? "" : Encoder.DecodeAsUtf8(f.end.Data) }). Select(f => new { f.file, f.isBinary, diff = f.isBinary ? null : diffGenerator.UnifiedDiff(f.start, f.end, 3) }). // // Do not include files that were not in fact changed between revision Where(f => f.diff == null || f.diff.Hunks.Sum(h => h.Lines.Count(l => l.Added || l.Removed )) > 0). Select(f => GetHgRollupFileDiffInfo(new HgPath(f.file), f.isBinary, f.diff)). ToList(); } return new HgCompareInfo(@base, head, changesets, diffs); }
public void UpdateBookmark(string bookmarkName, HgNodeID changesetNodeID) { bookmarkManager.UpdateBookmark(bookmarkName, changesetNodeID); }
private IEnumerable<uint> GetFileHistory(HgFilelog filelog, HgNodeID startNodeID) { var entries = filelog.Revlog.Entries. OrderByDescending(e => e.Revision). SkipWhile(e => e.NodeID != startNodeID). ToList(); foreach(var entry in entries) { yield return entry.LinkRevision; var file = GetFile(new HgManifestFileEntry(filelog.Path, entry.NodeID)); if(file.CopyInfo != null) { var sourceFilelog = GetFilelog(file.CopyInfo.Path); if(sourceFilelog == null) yield break; foreach(var changeset in GetFileHistory(sourceFilelog, file.CopyInfo.NodeID)) yield return changeset; yield break; } if(entry.FirstParentRevisionNodeID == HgNodeID.Null) yield break; } // foreach }
public HgDivergenceInfo GetDivergence(HgNodeID baseNodeID, HgNodeID headNodeID) { var hgRevsetManager = new HgRevsetManager(); var @base = (baseNodeID == HgNodeID.Null ? null : Changelog[baseNodeID]); var head = (headNodeID == HgNodeID.Null ? null : Changelog[headNodeID]); var baseAncestors = @base == null ? new HgRevset() : hgRevsetManager.GetAncestors(this, new HgRevset(@base.Metadata)); var headAncestors = head == null ? new HgRevset() : hgRevsetManager.GetAncestors(this, new HgRevset(head.Metadata)); var ahead = headAncestors - baseAncestors; var behind = baseAncestors - headAncestors; // // If ahead has only one commit and that one is closing branch without affecting any files, ignore it altogether if(ahead.Count == 1) { var aheadChangeset = Changelog[ahead.Single().NodeID]; if(aheadChangeset.Branch.Closed && aheadChangeset.Files.Count == 0) ahead = new HgRevset(); } // if return new HgDivergenceInfo(ahead, head, behind, @base); }
public IList<HgChangeset> GetFileHistory(HgPath path, HgNodeID? startFilelogNodeID = null) { var filelog = GetFilelog(path); if(filelog == null) return null; var changesetNodeIDs = GetFileHistory(filelog, startFilelogNodeID ?? filelog.Revlog.Entries.Last().NodeID); var revsetManager = new HgRevsetManager(); var revset = revsetManager.GetRevset(this, changesetNodeIDs); return GetChangesets(revset).OrderByDescending(c => c.Metadata.Revision).ToList(); }
private HgNodeID Commit(HgNodeID firstParentNodeID, HgNodeID secondParentNodeID, byte[] content, HgRevlog hgRevlog) { var data = new byte[]{}; if(firstParentNodeID != HgNodeID.Null) { var hgRevlogReader = new HgRevlogReader(hgRevlog, fileSystem); data = hgRevlogReader.ReadRevlogEntry(firstParentNodeID).Data; } // if var linkRevision = Changelog == null ? 0 : Changelog.Revlog.Entries.Count; var hgNodeID = new HgRevlogWriter(hgRevlog, fileSystem).WriteRevlogEntryData((uint)linkRevision, firstParentNodeID, secondParentNodeID, content); return hgNodeID; }
private HgFile GetFileImpl(HgManifestFileEntry manifestFileEntry, HgNodeID filelogNodeID) { var filelog = GetFilelog(manifestFileEntry.Path); if(filelog == null) return null; var hgRevlogReader = Store.CreateRevlogReader(filelog.Revlog); var hgRevlogData = hgRevlogReader.ReadRevlogEntry(filelogNodeID); if(hgRevlogData == null) return null; // // Handle copyinfo and possibly other inband metadata. This part of Mercurial I don't like var data = hgRevlogData.Data; var copyInfo = HgFileCopyInfo.ExtractFileCopyInfo(ref data); log.Debug("retrieved file {0}@{1}", manifestFileEntry.Path.FullPath, filelogNodeID.Short); return new HgFile(manifestFileEntry.Path, hgRevlogData.Entry, data, copyInfo); }
internal HgRevlogEntry(HgNodeID nodeID) { NodeID = nodeID; }
public HgRevision(uint revision, HgNodeID nodeID) : this() { Revision = revision; NodeID = nodeID; }