public void WriteBundle(HgBundle hgBundle, Stream stream, HgBundleFormat format, HgBundleCompression compression) { // // First things first -- we need to write out bundle header var header = format == HgBundleFormat.BundlePre10 ? null : GetCompressionHeader(compression); if(header != null) { var headerBuffer = Encoding.ASCII.GetBytes(header); stream.Write(headerBuffer, 0, headerBuffer.Length); } // if using(var compressedStream = GetCompressedStream(stream, compression)) using(var binaryWriter = new BigEndianBinaryWriter(new BufferedStream(compressedStream, 1024 * 128))) { log.Debug("writing changesets"); WriteBundleGroup(hgBundle.Changelog, binaryWriter); binaryWriter.Flush(); log.Debug("writing manifests"); WriteBundleGroup(hgBundle.Manifest, binaryWriter); binaryWriter.Flush(); // // Sometimes HgBundleFile.File has no chunks and Mercurial chokes on that. log.Debug("writing files"); foreach(var file in hgBundle.Files) { string filePath = null; foreach(var chunk in file.File) { if(filePath == null) { filePath = file.Path.FullPath.TrimStart('/'); binaryWriter.Write((uint)filePath.Length + 4); binaryWriter.Write(hgEncoder.EncodeAsLocal(filePath)); log.Debug("writing file '{0}'", filePath); } // if WriteChunk(binaryWriter, chunk); } // foreach if(filePath != null) WriteZeroChunk(binaryWriter); binaryWriter.Flush(); } // foreach binaryWriter.Write((uint)0); binaryWriter.Flush(); compressedStream.Flush(); stream.Flush(); } // using }
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; }
public HgCommitStats Commit(HgBundle hgBundle) { log.Info("committing bundle"); using(AcquireLock()) { var hgJournal = new HgJournal(Store); var hgTransaction = new HgTransaction(Store, hgJournal); var tip = Changelog.Tip; try { // // Adding changesets log.Info("committing changesets"); hgTransaction.Enlist(Changelog); int changesets; var revisions = CommitChangelog(tip, hgBundle.Changelog, Changelog.Revlog, out changesets); // // Adding manifests log.Info("committing manifests"); hgTransaction.Enlist(Manifest); var manifests = 0; Commit(revisions, hgBundle.Manifest, Manifest.Revlog, ref manifests); // // Adding file changes log.Info("committing files"); var changedFiles = 0; var changes = 0; foreach(var file in hgBundle.Files) { changedFiles++; log.Debug("committing '{0}'", file.Path.FullPath); var filelog = Store.GetFilelog(file.Path) ?? Store.CreateFilelog(file.Path); hgTransaction.Enlist(filelog); var hgBundleGroup = file.File; Commit(revisions, hgBundleGroup, filelog.Revlog, ref changes); } // foreach if(BundleCommitting != null) { var args = new HgBundleCommittedEventArgs(revisions.Keys.Select(k => Changelog[k])); BundleCommitting(args); } // if hgTransaction.Commit(); // // We need to force changelog re-read since after CommitChangelog() the changelog is // being read off a temp file. changelog = null; branchManager.RefreshBranchmap(tip == null ? 0 : tip.Metadata.Revision, Changelog.Tip.Metadata); if(BundleCommitted != null) { var args = new HgBundleCommittedEventArgs(revisions.Keys.Select(k => Changelog[k])); BundleCommitted(args); } // if return new HgCommitStats(changesets, manifests, changes, changedFiles); } // try catch(Exception e) { log.ErrorException("could not commit bundle", e); hgTransaction.Rollback(); // // Reset changelog and manifest so that they'll be reread changelog = null; manifest = null; throw; } // catch } // using }