internal static IBlob Write(Repository aRepository, byte[] aContents) { string id = aRepository.WriteObject(aContents, EObjectType.Blob); return (new Blob(aRepository, id, aContents)); }
internal static ITree Write(Repository aRepository, IEnumerable<TreeItem> aItems) { int count = 0; List<byte[]> list = new List<byte[]>(); foreach (TreeItem item in aItems) { byte[] bytes = item.Bytes(); list.Add(bytes); count += bytes.Length; } byte[] obj = new byte[count]; int offset = 0; foreach (byte[] item in list) { Array.Copy(item, 0, obj, offset, item.Length); offset += item.Length; } string id = aRepository.WriteObject(obj, EObjectType.Tree); // TODO return (new Tree(new TreeRef(aRepository, id, obj))); }
private static bool Fetch(Repository aRepository, Uri aUri, BinaryWriter aWriter, BinaryReader aReader) { // Request WriteFetchRequest(aUri, aWriter); // Collect HEAD and capabilities string sha1; byte[] bytes = ReadFetchHeader(aReader, out sha1); if (bytes.Length < 5 || bytes[4] != 0) { return (false); } string head = ASCIIEncoding.ASCII.GetString(bytes, 0, 4); if (head != "HEAD") { return (false); } string capabilities = ASCIIEncoding.ASCII.GetString(bytes, 5, bytes.Length - 5); if (capabilities.EndsWith("\n")) { capabilities = capabilities.Substring(0, capabilities.Length - 1); } List<string> caps = new List<string>(capabilities.Split(new char[] { ' ' })); if (!caps.Contains("ofs-delta")) { return (false); } // Collect remote branches Dictionary<string, string> branches = new Dictionary<string, string>(); while (true) { bytes = ReadFetchHeader(aReader, out sha1); if (bytes == null) { break; } string branch = ASCIIEncoding.ASCII.GetString(bytes); if (branch.StartsWith("refs/heads/")) { branch = branch.Substring(11); if (branch.EndsWith("\n")) { branch = branch.Substring(0, branch.Length - 1); } if (branch.Length > 0) { branches.Add(branch, sha1); } } } // Find branches that are different Dictionary<string, string> update = new Dictionary<string, string>(); Dictionary<string, string> create = new Dictionary<string, string>(); foreach (KeyValuePair<string, string> entry in branches) { var branch = aRepository.Branch(entry.Key); if (branch != null) { if (branch.IsEmpty || branch.Commit.Id != entry.Value) { update.Add(entry.Key, entry.Value); } } else { create.Add(entry.Key, entry.Value); } } if (update.Count + create.Count == 0) { return (false); } // Write request capabilities = "\0ofs-delta"; if (caps.Contains("thin-pack")) { capabilities += " thin-pack"; } foreach (string entry in update.Values) { string want = "want " + entry + capabilities + "\n"; WriteFetchHeader(aWriter, want); capabilities = String.Empty; } foreach (string entry in create.Values) { string want = "want " + entry + capabilities + "\n"; WriteFetchHeader(aWriter, want); capabilities = String.Empty; } WriteZeroHeader(aWriter); foreach (IBranch branch in aRepository.Branches) { if (!branch.IsEmpty) { string have = "have " + branch.Commit.Id + "\n"; WriteFetchHeader(aWriter, have); } } WriteFetchHeader(aWriter, "done\n"); // Read acks foreach (string entry in create.Values) { string ack = ReadFetchRecord(aReader); //Console.WriteLine("CREATE: {0}", ack); } foreach (string entry in update.Values) { string ack = ReadFetchRecord(aReader); //Console.WriteLine("UPDATE: {0}", ack); } /* foreach (IBranch branch in aRepository.Branches) { string ack = ReadFetchRecord(reader); if (!branch.IsEmpty) { if (!ack.StartsWith("ACK ")) { return (false); } } else { if (ack !="NAK\n") { return (false); } } } */ // Collect pack parts int count = 0; List<byte[]> parts = new List<byte[]>(); while (true) { byte[] part = aReader.ReadBytes(10000); if (part.Length == 0) { break; } count += part.Length; parts.Add(part); } // Combine pack parts byte[] pack = new byte[count]; int index = 0; foreach (byte[] part in parts) { Array.Copy(part, 0, pack, index, part.Length); index += part.Length; } // Read pack header var pstream = new MemoryStream(pack); using (var preader = new BinaryReader(pstream)) { Pack.ReadSignature(preader); Pack.ReadVersion(preader); uint objectcount = Pack.ReadItemCount(preader); // Inflate items Dictionary<long, Object> objects = new Dictionary<long, Object>(); while (objectcount-- > 0) { Object obj; long length; long start = pstream.Position; int type = Pack.ReadItemTypeAndLength(preader, out length); switch (type) { case 0: case 5: return (false); case 6: long offset = start - Pack.ReadDeltaOffset(preader); obj = Pack.ApplyDelta(preader, objects[offset], length); break; case 7: byte[] id = new byte[20]; preader.Read(id, 0, 20); obj = Pack.ApplyDelta(preader, aRepository.GetObject(Hash.String(id)), length); break; default: obj = Pack.ReadObject(preader, type, length); break; } objects.Add(start, obj); aRepository.WriteObject(obj.Contents, obj.Type); } } // Update existing branches foreach (var entry in update) { aRepository.UpdateBranch(entry.Key, entry.Value); } // Create new branches foreach (var entry in create) { aRepository.CreateBranch(entry.Key, entry.Value); } return (true); }
internal static ICommit Write(Repository aRepository, ITree aTree, IEnumerable<ICommit> aParents, IPerson aAuthor, IPerson aCommitter, string aDescription) { StringBuilder builder = new StringBuilder(); builder.Append("tree " + aTree.Id + "\n"); foreach (ICommit parent in aParents) { builder.Append("parent " + parent.Id + "\n"); } builder.Append("author " + PersonTime.String(aAuthor) + "\n"); builder.Append("committer " + PersonTime.String(aCommitter) + "\n"); builder.Append("\n"); builder.Append(aDescription); byte[] bytes = ASCIIEncoding.ASCII.GetBytes(builder.ToString()); string id = aRepository.WriteObject(bytes, EObjectType.Commit); // TODO return (new Commit(new CommitRef(aRepository, id, bytes))); }