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))); }
internal TreeModifiable(Repository aRepository, ITree aTree) { iRepository = aRepository; iTree = aTree; iModified = false; iTreeAddList = new Dictionary<string, TreeModifiableNew>(); iTreeModifyList = new Dictionary<string, TreeModifiable>(); iBlobAddList = new Dictionary<string, BlobModifiableNew>(); iBlobModifyList = new Dictionary<string, BlobModifiable>(); iModeChangeList = new Dictionary<string, string>(); iDeleteList = new List<string>(); iWritten = false; }
internal Tag(Repository aRepository, string aId, byte[] aBytes) { iRepository = aRepository; iId = aId; string id = null; string type = null; string tag = ASCIIEncoding.ASCII.GetString(aBytes); string[] lines = tag.Split(new char[] { '\n' }); int offset = 1; foreach (string line in lines) { if (line.Length == 0) { break; } offset += line.Length + 1; int keyEnd = line.IndexOf(' '); CorruptIf(keyEnd < 0); string key = line.Substring(0, keyEnd); string value = line.Substring(keyEnd + 1); switch (key) { case "object": id = value; break; case "type": type = value; break; case "tag": iName = value; break; case "tagger": iTagger = PersonTime.Create(value); break; default: CorruptIf(true); break; } } iDescription = tag.Substring(offset); CorruptIf(iName == null); CorruptIf(iTagger == null); CorruptIf(id == null); CorruptIf(type == null); switch (type) { case "commit": iType = EObjectType.Commit; break; case "blob": iType = EObjectType.Blob; break; case "tree": iType = EObjectType.Tree; break; case "tag": iType = EObjectType.Tag; break; default: CorruptIf(true); break; } }
internal RefPacked(Repository aRepository, string aName, string aId) { iRepository = aRepository; iName = aName; iId = aId; }
internal CommitRef(Repository aRepository, string aId, byte[] aContents) { iRepository = aRepository; iId = aId; }
internal static IBlob Write(Repository aRepository, string aContents) { byte[] contents = UTF8Encoding.UTF8.GetBytes(aContents); return (Write(aRepository, contents)); }
internal Change(Repository aRepository, Branch aBranch) { iRepository = aRepository; iBranch = aBranch; iParents = new List<IBranch>(); iParents.Add(iBranch); iWritten = false; if (iBranch.IsEmpty) { iRoot = new TreeModifiable(iRepository, iBranch.Commit.Tree); } else { iRoot = new TreeModifiable(iRepository, null); } }
internal BlobModifiable(Repository aRepository, byte[] aContents) { iRepository = aRepository; iContents = aContents; }
internal TreeRef(Repository aRepository, string aId) : this(aRepository, aId, null) { }
internal TreeItem(Repository aRepository, string aId, byte[] aBytes) { iRepository = aRepository; iId = aId; string value = ASCIIEncoding.ASCII.GetString(aBytes); string[] parts = value.Split(new char[] { ' ' }, 2); if (parts.Length != 2) { throw (new GitException("Tree item corrupt")); } iMode = parts[0]; iName = parts[1]; }
internal TreeRef(Repository aRepository, string aId, byte[] aContents) { iRepository = aRepository; iId = aId; iContents = aContents; }
internal TreeItem(Repository aRepository, string aId, string aMode, string aName) { iRepository = aRepository; iId = aId; iMode = aMode; iName = aName; }
internal static ITree WriteRoot(Repository aRepository) { return (Write(aRepository, new List<TreeItem>())); }
internal CommitRef(Repository aRepository, string aId) : this(aRepository, aId, null) { }
private static bool Fetch(Repository aRepository, Uri aUri, NetworkStream aStream) { var writer = new BinaryWriter(aStream); using (var reader = new BinaryReader(aStream)) { return (Fetch(aRepository, aUri, writer, reader)); } }
protected ObjectRefFile(Repository aRepository, FileInfo aFileInfo) { iRepository = aRepository; iFileInfo = aFileInfo; }
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 IObject Create(Repository aRepository, string aId) { switch (iType) { case EObjectType.Blob: return (new Blob(aRepository, aId, iContents)); case EObjectType.Commit: return (new Commit(new CommitRef(aRepository, aId, iContents))); case EObjectType.Tag: return (new Tag(aRepository, aId, iContents)); case EObjectType.Tree: return (new Tree(new TreeRef(aRepository, aId, iContents))); default: throw (new GitException("Object " + aId + " corrupt")); } }
internal BlobModifiableNew(Repository aRepository, byte[] aContents, string aName, string aMode) : base(aRepository, aContents) { iName = aName; iMode = aMode; }
internal BranchEmpty(Repository aRepository, string aName) : base(aRepository, aName, null) { }
internal TreeModifiableNew(Repository aRepository, string aName, string aMode) : base(aRepository, null) { iName = aName; iMode = aMode; }
internal BranchFile(Repository aRepository, FileInfo aFileInfo) : base(aRepository, aFileInfo) { }
public Blob(Repository aRepository, string aId, byte[] aContents) { iRepository = aRepository; iId = aId; iContents = aContents; }
internal RefFile(Repository aRepository, FileInfo aFileInfo) : base(aRepository, aFileInfo) { }
internal static IBlob Write(Repository aRepository, byte[] aContents) { string id = aRepository.WriteObject(aContents, EObjectType.Blob); return (new Blob(aRepository, id, aContents)); }
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))); }