/// <summary> /// Construct and write tree out of index. /// </summary> /// <returns> SHA-1 of the constructed tree</returns> /// <exception cref="IOException"></exception> public ObjectId writeTree() { CheckWriteOk(); var writer = new ObjectWriter(Repository); var current = new Tree(Repository); var trees = new Stack <Tree>(); trees.Push(current); var prevName = new string[0]; foreach (Entry e in _entries.Values) { if (e.Stage != STAGE_0) { continue; } string[] newName = SplitDirPath(e.Name); int c = LongestCommonPath(prevName, newName); while (c < trees.Count - 1) { current.Id = writer.WriteTree(current); trees.Pop(); current = trees.Count == 0 ? null : trees.Peek(); } while (trees.Count < newName.Length) { if (!current.ExistsTree(newName[trees.Count - 1])) { current = new Tree(current, Constants.encode(newName[trees.Count - 1])); current.Parent.AddEntry(current); trees.Push(current); } else { current = (Tree)current.findTreeMember(newName[trees.Count - 1]); trees.Push(current); } } var ne = new FileTreeEntry(current, e.ObjectId, Constants.encode(newName[newName.Length - 1]), (e.Mode & FileMode.ExecutableFile.Bits) == FileMode.ExecutableFile.Bits); current.AddEntry(ne); } while (trees.Count != 0) { current.Id = writer.WriteTree(current); trees.Pop(); if (trees.Count != 0) { current = trees.Peek(); } } return(current.TreeId); }
/// <summary> /// Adds a new or existing file with the specified name to this tree. /// Trees are added if necessary as the name may contain '/':s. /// </summary> /// <param name="s"> an array containing the name </param> /// <param name="offset"> when the name starts in the tree. /// </param> /// <returns>A <seealso cref="FileTreeEntry"/> for the added file.</returns> /// <exception cref="IOException"></exception> public FileTreeEntry AddFile(byte[] s, int offset) { int slash; for (slash = offset; slash < s.Length && s[slash] != '/'; slash++) { // search for path component terminator // [henon] body is empty by intention! } EnsureLoaded(); byte xlast = slash < s.Length ? (byte)'/' : (byte)0; int p = BinarySearch(_contents, s, xlast, offset, slash); if (p >= 0 && slash < s.Length && _contents[p] is Tree) { return(((Tree)_contents[p]).AddFile(s, slash + 1)); } byte[] newName = SubString(s, offset, slash); if (p >= 0) { throw new EntryExistsException(RawParseUtils.decode(newName)); } if (slash < s.Length) { Tree t = new Tree(this, newName); InsertEntry(p, t); return(t.AddFile(s, slash + 1)); } FileTreeEntry f = new FileTreeEntry(this, null, newName, false); InsertEntry(p, f); return(f); }
private void ReadTree(byte[] raw) { int rawSize = raw.Length; int rawPtr = 0; int nextIndex = 0; while (rawPtr < rawSize) { while (rawPtr < rawSize && raw[rawPtr] != 0) { rawPtr++; } rawPtr++; rawPtr += Constants.OBJECT_ID_LENGTH; nextIndex++; } var temp = new TreeEntry[nextIndex]; rawPtr = 0; nextIndex = 0; while (rawPtr < rawSize) { int c = raw[rawPtr++]; if (c < '0' || c > '7') { throw new CorruptObjectException(Id, "invalid entry mode"); } int mode = c - '0'; while (true) { c = raw[rawPtr++]; if (' ' == c) { break; } if (c < '0' || c > '7') { throw new CorruptObjectException(Id, "invalid mode"); } mode <<= 3; mode += c - '0'; } int nameLen = 0; while (raw[rawPtr + nameLen] != 0) { nameLen++; } var name = new byte[nameLen]; Array.Copy(raw, rawPtr, name, 0, nameLen); rawPtr += nameLen + 1; ObjectId id = ObjectId.FromRaw(raw, rawPtr); rawPtr += Constants.OBJECT_ID_LENGTH; TreeEntry ent; if (FileMode.RegularFile.Equals(mode)) { ent = new FileTreeEntry(this, id, name, false); } else if (FileMode.ExecutableFile.Equals(mode)) { ent = new FileTreeEntry(this, id, name, true); } else if (FileMode.Tree.Equals(mode)) { ent = new Tree(this, id, name); } else if (FileMode.Symlink.Equals(mode)) { ent = new SymlinkTreeEntry(this, id, name); } else if (FileMode.GitLink.Equals(mode)) { ent = new GitLinkTreeEntry(this, id, name); } else { throw new CorruptObjectException(Id, "Invalid mode: " + Convert.ToString(mode, 8)); } temp[nextIndex++] = ent; } _contents = temp; }
private void ReadTree(byte[] raw) { int rawSize = raw.Length; int rawPtr = 0; int nextIndex = 0; while (rawPtr < rawSize) { while (rawPtr < rawSize && raw[rawPtr] != 0) { rawPtr++; } rawPtr++; rawPtr += Constants.OBJECT_ID_LENGTH; nextIndex++; } var temp = new TreeEntry[nextIndex]; rawPtr = 0; nextIndex = 0; while (rawPtr < rawSize) { int c = raw[rawPtr++]; if (c < '0' || c > '7') { throw new CorruptObjectException(Id, "invalid entry mode"); } int mode = c - '0'; while (true) { c = raw[rawPtr++]; if (' ' == c) break; if (c < '0' || c > '7') { throw new CorruptObjectException(Id, "invalid mode"); } mode <<= 3; mode += c - '0'; } int nameLen = 0; while (raw[rawPtr + nameLen] != 0) { nameLen++; } var name = new byte[nameLen]; Array.Copy(raw, rawPtr, name, 0, nameLen); rawPtr += nameLen + 1; ObjectId id = ObjectId.FromRaw(raw, rawPtr); rawPtr += Constants.OBJECT_ID_LENGTH; TreeEntry ent; if (FileMode.RegularFile.Equals(mode)) { ent = new FileTreeEntry(this, id, name, false); } else if (FileMode.ExecutableFile.Equals(mode)) { ent = new FileTreeEntry(this, id, name, true); } else if (FileMode.Tree.Equals(mode)) { ent = new Tree(this, id, name); } else if (FileMode.Symlink.Equals(mode)) { ent = new SymlinkTreeEntry(this, id, name); } else if (FileMode.GitLink.Equals(mode)) { ent = new GitLinkTreeEntry(this, id, name); } else { throw new CorruptObjectException(Id, "Invalid mode: " + Convert.ToString(mode, 8)); } temp[nextIndex++] = ent; } _contents = temp; }
/// <summary> /// Adds a new or existing file with the specified name to this tree. /// Trees are added if necessary as the name may contain '/':s. /// </summary> /// <param name="s"> an array containing the name </param> /// <param name="offset"> when the name starts in the tree. /// </param> /// <returns>A <seealso cref="FileTreeEntry"/> for the added file.</returns> /// <exception cref="IOException"></exception> public FileTreeEntry AddFile(byte[] s, int offset) { int slash; for (slash = offset; slash < s.Length && s[slash] != '/'; slash++) { // search for path component terminator // [henon] body is empty by intention! } EnsureLoaded(); byte xlast = slash < s.Length ? (byte)'/' : (byte)0; int p = BinarySearch(_contents, s, xlast, offset, slash); if (p >= 0 && slash < s.Length && _contents[p] is Tree) { return ((Tree)_contents[p]).AddFile(s, slash + 1); } byte[] newName = SubString(s, offset, slash); if (p >= 0) { throw new EntryExistsException(RawParseUtils.decode(newName)); } if (slash < s.Length) { Tree t = new Tree(this, newName); InsertEntry(p, t); return t.AddFile(s, slash + 1); } FileTreeEntry f = new FileTreeEntry(this, null, newName, false); InsertEntry(p, f); return f; }
public abstract void VisitFile(FileTreeEntry f);
public override void VisitFile(FileTreeEntry f) { f.Id = ow.WriteBlob(PathUtil.CombineFilePath(GetCurrentDirectory(), f.Name)); }
public GitTreeEntry(FileTreeEntry entry) { _entry = entry; }