예제 #1
0
 public HgDiffFile(HgRepository repo, HgManifestEntry manifest, string path)
 {
   this.Path = path;
   this.Revision = -1;
   _repo = repo;
   _manifest = manifest;
 }
예제 #2
0
        public static HgFlow GetHgFlow(HgRepository hgRepository)
        {
            if(hgRepository.Changelog.Tip == null) return new HgFlow(false);

            //
            // Check for .hgflow or .flow on open branches
            foreach(var hgBranch in hgRepository.GetBranches().Where(c => !c.Branch.Closed))
            {
                var hgManifest = hgRepository.Manifest[hgBranch.ManifestNodeID];
                if(hgManifest == null) continue;

                var hgFlowFileEntry = hgManifest[".hgflow"] ?? hgManifest[".flow"];
                if(hgFlowFileEntry == null) continue;

                var hgFlowFile = hgRepository.GetFile(hgFlowFileEntry);
                if(hgFlowFile == null) continue;

                var content = Encoding.UTF8.GetString(hgFlowFile.Data);

                var hgFlow = ParseHgFlow(content);
                if(hgFlow.Enabled)
                    return hgFlow;
            } // foreach

            return new HgFlow(false);
        }
        public HgBookmarkManager(HgRepository repository, HgFileSystem fileSystem)
        {
            this.repository = repository;
            this.fileSystem = fileSystem;

            bookmarksPath = Alphaleonis.Win32.Filesystem.Path.Combine(repository.BasePath, "bookmarks");
        }
예제 #4
0
 private IEnumerable<HgChunk> BuildManifestBundleGroup(HgRepository hgRepository, HgRevset hgRevset)
 {
     var manifestRevset =
         new HgRevset(hgRepository.Manifest.Revlog.Entries.Where(hre => hgRevset.Contains(hre.LinkRevision)));
     var manifest = BuildBundleGroup(hgRepository, hgRepository.Manifest.Revlog, manifestRevset);
     return manifest;
 }
예제 #5
0
    public HgDiffDirectory(HgRepository repo, HgChangeset changeset)
    {
      _repo = repo;
      var manifest = repo.Manifest[changeset.ManifestNodeID];
      _files = manifest.Files
        .Select(f => new HgDiffFile(repo, manifest, f.Path.FullPath.TrimStart('/')))
        .ToDictionary(f => f.Path);

      var changes = new Queue<HgChangeset>();
      changes.Enqueue(changeset);
      HgDiffFile file;
      HgChangeset curr;

      while (changes.Any() && _files.Values.Any(f => f.Revision < 0))
      {
        curr = changes.Dequeue();
        foreach (var path in curr.Files)
        {
          if (_files.TryGetValue(path, out file) && file.Revision < 0)
            file.Revision = (int)curr.Metadata.Revision;
        }

        foreach (var change in curr.Metadata.Parents.Select(r => _repo.Changelog[r.NodeID]))
        {
          changes.Enqueue(change);
        }
      }
    }
예제 #6
0
 private IEnumerable<HgBundleFile> BuildBundleFiles(HgRepository hgRepository, HgRevset hgRevset, HashSet<string> paths)
 {
     var orderedPaths = paths.OrderBy(p => p).ToList();
     foreach(var path in orderedPaths)
     {
         var bundleFile = BuildBundleFile(hgRepository, hgRevset, path);
         if(bundleFile != null)
             yield return bundleFile;
     } // foreach
 }
예제 #7
0
        public static bool IsEnabled(HgRepository hgRepository, HgFlow hgFlow)
        {
            if(!hgFlow.Enabled) return false;

            //
            // Ensure that the "develop" branch is not closed
            var hgDevelopBranch = 
                hgRepository.
                    GetBranches().
                        FirstOrDefault(c => !c.Branch.Closed && string.Equals(c.Branch.Name, hgFlow.Development, StringComparison.InvariantCulture));

            return hgDevelopBranch != null;
        }
예제 #8
0
        private HgBundleFile BuildBundleFile(HgRepository hgRepository, HgRevset hgRevset, string path)
        {
            // TODO: Do not bundle files without chunks
            log.Debug("bundling {0}", path);

            var hgPath = new HgPath(path);
            var hgFilelog = hgRepository.GetFilelog(hgPath);
            if(hgFilelog == null) return null;

            var filelogRevset = new HgRevset(hgFilelog.Revlog.Entries.Where(fre => hgRevset.Contains(fre.LinkRevision)));
            var hgBundleGroup = BuildBundleGroup(hgRepository, hgFilelog.Revlog, filelogRevset);

            var hgBundleFile = new HgBundleFile(hgPath, hgBundleGroup);
            return hgBundleFile;
        }
예제 #9
0
        public HgBundle BuildBundle(HgRepository hgRepository, HgRevset hgRevset)
        {
            log.Debug("bundling changelog");
            var paths = new HashSet<string>();
            var changelog = BuildChangesetBundleGroup(hgRepository, hgRevset, hc => paths.AddRange(hc.Files));

            log.Debug("bundling manifests");
            var manifest = BuildManifestBundleGroup(hgRepository, hgRevset);

            //
            // List of all files that ever were tracked
            log.Debug("bundling filelogs");
            var files = BuildBundleFiles(hgRepository, hgRevset, paths);

            var hgBundle = new HgBundle(changelog, manifest, files);
            return hgBundle;
        }
예제 #10
0
    public HgMergeOperation(string repoPath, int local = -1, int remote = -1)
    {
      _repo = new HgRepository(repoPath);

      var heads = _repo.GetHeads().Select(h => _repo.Changelog[h.NodeID]).ToArray();
      _local = local < 0
        ? heads.FirstOrDefault(h => h.Branch.Name == "default") ?? heads.First()
        : _repo.Changelog[(uint)local];
      _remote = remote < 0
        ? heads.First(h => h.Metadata.NodeID != _local.Metadata.NodeID)
        : _repo.Changelog[(uint)remote];
      _baseRev = _repo.CommonParent(_local, _remote);

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

      foreach (var file in ChangesetManifestPaths(_repo, _baseRev))
      {
        dict[file] = new FileCompare() { Path = file, InBase = FileStatus.Unchanged };
      }

      FileCompare buffer;
      var modifiedFiles = new HashSet<string>(_local.Files);
      foreach (var file in ChangesetManifestPaths(_repo, _local))
      {
        if (!dict.TryGetValue(file, out buffer))
        {
          buffer = new FileCompare() { Path = file };
          dict.Add(file, buffer);
        }
        buffer.InLocal = modifiedFiles.Contains(file) ? FileStatus.Modified : FileStatus.Unchanged;
      }

      modifiedFiles = new HashSet<string>(_remote.Files);
      foreach (var file in ChangesetManifestPaths(_repo, _remote))
      {
        if (!dict.TryGetValue(file, out buffer))
        {
          buffer = new FileCompare() { Path = file };
          dict.Add(file, buffer);
        }
        buffer.InRemote = modifiedFiles.Contains(file) ? FileStatus.Modified : FileStatus.Unchanged;
      }

      _compares = dict.Values.ToArray();
    }
        public HgManifestTree GetManifestTreeNode(HgRepository hgRepository, HgManifestEntry hgManifestEntry, HgPath hgPath)
        {
            var separators = hgPath.FullPath.Count(c => c == '/');
            
            var paths =
                hgManifestEntry.Files.
                    Select(f => new {
                        file = f,
                        separators = f.Path.FullPath.Count(c => c == '/')
                    }).
                    Where(f => f.file.Path.FullPath.StartsWith(hgPath.FullPath)).
                    ToList();

            var directories =
                paths.
                    Where(d => d.separators > separators).
                    Select(d => d.file.Path.FullPath.SubstringBeforeNth("/", separators)).
                    Distinct().
                    Select(d => HgManifestNode.Directory(new HgPath(d))).
                    ToList();
            
            var files = 
                paths.
                    Where(f => f.separators == separators).
                    Select(f => HgManifestNode.File(f.file.Path, f.file.FilelogNodeID)).
                    ToList();

            var subrepositories =
                hgRepository.GetSubrepositories(hgManifestEntry).
                    Select(s => new {
                        subrepository = s,
                        separators = s.Path.FullPath.Count(c => c == '/')
                    }).
                    Where(s => s.subrepository.Path.FullPath.StartsWith(hgPath.FullPath) && s.separators == separators).
                    Select(s => HgManifestNode.Subrepository(s.subrepository.Path, s.subrepository.NodeID)).
                    ToList();

            return new HgManifestTree(hgPath, directories.Append(files).Append(subrepositories));
        }
예제 #12
0
        public static HgRepository Clone(string sourceRepositoryPath, string destinationRepositoryPath)
        {
            //
            // Create dummy repo and then clone over existing files
            var sourceHgRepository = new HgRepository(sourceRepositoryPath);
            var destinationHgRepository = HgRepository.Create(destinationRepositoryPath);

            using(sourceHgRepository.AcquireLock())
            {
                foreach(var hgDataFile in sourceHgRepository.Store.GetDataFiles())
                {
                    var destinationPath = System.IO.Path.Combine(destinationRepositoryPath, ".hg\\store", hgDataFile.Path.FullPath.Trim('/'));
                
                    var directoryName = System.IO.Path.GetDirectoryName(destinationPath);
                    if(!Directory.Exists(directoryName))
                        Directory.CreateDirectory(directoryName);

                    File.CreateHardlink(hgDataFile.StoreRelativePath, destinationPath);
                } // foreach
            } // using

            return destinationHgRepository;
        }
예제 #13
0
 public HgAclModule(HgRepository hgRepository, Func<HgPrincipal> hgPrincipalProvider)
 {
     this.hgRepository = hgRepository;
     this.hgPrincipalProvider = hgPrincipalProvider;
     this.hgRepository.BundleCommitting += BundleCommitting;
 }
 public HgSubrepositoryReader(HgRepository hgRepository)
 {
     this.hgRepository = hgRepository;
 }
예제 #15
0
        public static HgRevsetEntry GetPrimaryMergeStreamBranchHead(HgRepository hgRepository, HgFlow hgFlow, HgFlowStream stream)
        {
            var primaryMergeStream = GetPrimaryMergeStream(stream);

            var primaryMergeStreamBranchHead = 
                primaryMergeStream.HasValue ?
                    hgRepository.GetBranchmap().
                        Where(bm => bm.Branch == hgFlow[primaryMergeStream.Value].TrimEnd('/')).
                        SelectMany(bm => bm.Heads).
                        OrderByDescending(h => h.Revision).
                        FirstOrDefault() :
                null;
            
            return primaryMergeStreamBranchHead;
        }
예제 #16
0
 private IEnumerable<HgChunk> BuildChangesetBundleGroup(HgRepository hgRepository, HgRevset hgRevset, Action<HgChangeset> callback)
 {
     var hgChangelogReader = new HgChangelogReader(hgEncoder);
     return BuildBundleGroup(hgRepository, hgRepository.Changelog.Revlog, hgRevset, hred => callback(hgChangelogReader.ReadChangeset(hred)));
 }
예제 #17
0
        private IEnumerable<HgChunk> BuildBundleGroup(HgRepository hgRepository, HgRevlog hgRevlog, HgRevset hgRevset, Action<HgRevlogEntryData> callback = null)
        {
            var hgRevlogReader = new HgRevlogReader(hgRevlog, fileSystem);
            
            //
            // See http://stackoverflow.com/a/10359273/60188. Pure magic
            var revisionChunks =
                hgRevset.
                    Select(hre => hre.Revision).
                    OrderBy(r => r).
                    Select((r, i) => new { r, i }).
                    GroupBy(x => x.r - x.i). 
                    Select(x => x.Select(xx => xx.r)).
                    Select(c => c.ToArray()).
                    ToArray();

            if(revisionChunks.Length == 0) yield break;

            byte[] prev = null;
            uint prevRev = uint.MaxValue;
            var prediff = false;
            var hgRevlogEntry = hgRevlog[revisionChunks[0][0]];
            if(hgRevlogEntry.FirstParentRevisionNodeID != HgNodeID.Null)
            {
                prev = hgRevlogReader.ReadRevlogEntry(hgRevlogEntry.FirstParentRevision).Data;
                prediff = true;
            }
            
            foreach(var revisionChunk in revisionChunks)
            {
                foreach(var revision in revisionChunk)
                {
                    hgRevlogEntry = hgRevlog[revision];
                    var hgChangeset = hgRepository.Changelog.Revlog[hgRevlogEntry.LinkRevision];
                
                    byte[] data = null;

                    if(prev == null || hgRevlogEntry.BaseRevision == hgRevlogEntry.Revision || prediff || (prevRev != UInt32.MaxValue && prevRev + 1 != revision))
                    {
                        var hgRevlogEntryData = hgRevlogReader.ReadRevlogEntry(revision);

                        if(prev == null)
                        {   
                            //
                            // Trivial case
                            var buffer = new byte[hgRevlogEntryData.Data.Length + 12];
                            using(var stream = new MemoryStream(buffer))
                            using(var binaryWriter = new BigEndianBinaryWriter(stream))
                            {
                                binaryWriter.Write((uint)0);
                                binaryWriter.Write((uint)0);
                                binaryWriter.Write((uint)hgRevlogEntryData.Data.Length);
                                binaryWriter.Write(hgRevlogEntryData.Data);
                            } // using

                            data = buffer;
                        } // if
                        else
                        {
                            data = BDiff.Diff(prev, hgRevlogEntryData.Data);
                            if(prediff)
                                prediff = false;
                        } // else

                        prev = hgRevlogEntryData.Data;
                    } // if
                    else
                    {
                        data = hgRevlogReader.ReadRevlogEntryDataRaw(revision);
                        prev = MPatch.Patch(prev, new List<byte[]> { data });
                    } // else

                    if(callback != null) callback(new HgRevlogEntryData(hgRevlogEntry, prev));

                    if(performIntegrityChecks)
                    {
                        var expectedNodeID = GetRevlogEntryDataNodeID(hgRevlogEntry.FirstParentRevisionNodeID, hgRevlogEntry.SecondParentRevisionNodeID, prev);
                        if(expectedNodeID != hgRevlogEntry.NodeID)
                        {
                            // TODO: Exception class
                            throw new ApplicationException("integrity violation for " + hgRevlogEntry.NodeID.Short);
                        } // if
                    } // if

                    var hgChunk = new HgChunk(hgRevlogEntry.NodeID, hgRevlogEntry.FirstParentRevisionNodeID, hgRevlogEntry.SecondParentRevisionNodeID,
                        hgChangeset.NodeID, data);

                    yield return hgChunk;

                    prevRev = revision;
                } // foreach
            } // foreach
        }
예제 #18
0
 public static bool IsEnabled(HgRepository hgRepository)
 {
     var hgFlow = GetHgFlow(hgRepository);
     return IsEnabled(hgRepository, hgFlow);
 }
예제 #19
0
 public HgClient(HgRepository repository)
 {
     
 }
예제 #20
0
        private static Tuple<DateTimeOffset, int, string> GetLatestTag(HgRepository hgRepository, HgNodeID hgNodeID)
        {
            var revisions = new Stack<uint>();
            var revision = hgRepository.Changelog[hgNodeID].Metadata.Revision;

            var cache = new Dictionary<uint, Tuple<DateTimeOffset, int, string>>();

            revisions.Push(revision);

            while(revisions.Count > 0)
            {
                revision = revisions.Pop();
                if(cache.ContainsKey(revision)) continue;

                var hgChangeset = hgRepository.Changelog[revision];
                var tags = hgRepository.GetTags().Where(t => t.Name != "tip" && t.NodeID == hgChangeset.Metadata.NodeID).ToList();

                if(tags.Count > 0)
                {
                    cache[revision] = Tuple.Create(hgChangeset.CommittedAt, 0, tags[0].Name);
                    continue;
                } // if

                int distance = 0;
                string name = "";
                DateTimeOffset committedAt = DateTimeOffset.MinValue;

                if(hgChangeset.Metadata.Parents.All(p => cache.ContainsKey(p.Revision)))
                {
                    var enumerable = hgChangeset.Metadata.Parents.Select(p => cache[p.Revision]).ToList();
                    if(enumerable.Any())
                    {
                        var max = enumerable.MaxBy(p => p.Item1);

                        committedAt = max.Item1;
                        distance = max.Item2;
                        name = max.Item3;
                    } // if
                }
                else
                {
                    revisions.Push(revision);
                    
                    foreach(var p in hgChangeset.Metadata.Parents)
                        revisions.Push(p.Revision);

                    continue;
                } // catch

                cache[revision] = Tuple.Create(committedAt, distance + 1, name);
            } // while

            revision = hgRepository.Changelog[hgNodeID].Metadata.Revision;
            
            return cache[revision];
        } 
예제 #21
0
 public HgArchiveWriter(HgRepository hgRepository)
 {
     this.hgRepository = hgRepository;
 }
예제 #22
0
 private static IEnumerable<string> ChangesetManifestPaths(HgRepository repo, HgChangeset ch)
 {
   return repo.Manifest[ch.ManifestNodeID].Files.Select(f => f.Path.FullPath.TrimStart('/'));
 }
 public HgRepositoryVerifier(HgRepository repository)
 {
     this.repository = repository;
 }
 public HgAnnotationManager(HgRepository repository)
 {
     this.repository = repository;
 }
예제 #25
0
 public HgTagManager(HgRepository repository, HgFileSystem fileSystem)
 {
     this.repository = repository;
     this.fileSystem = fileSystem;
 }