/// <summary>Write (if necessary) this tree to the object store.</summary> /// <remarks>Write (if necessary) this tree to the object store.</remarks> /// <param name="cache">the complete cache from DirCache.</param> /// <param name="cIdx"> /// first position of <code>cache</code> that is a member of this /// tree. The path of <code>cache[cacheIdx].path</code> for the /// range <code>[0,pathOff-1)</code> matches the complete path of /// this tree, from the root of the repository. /// </param> /// <param name="pathOffset"> /// number of bytes of <code>cache[cacheIdx].path</code> that /// matches this tree's path. The value at array position /// <code>cache[cacheIdx].path[pathOff-1]</code> is always '/' if /// <code>pathOff</code> is > 0. /// </param> /// <param name="ow">the writer to use when serializing to the store.</param> /// <returns>identity of this tree.</returns> /// <exception cref="NGit.Errors.UnmergedPathException"> /// one or more paths contain higher-order stages (stage > 0), /// which cannot be stored in a tree object. /// </exception> /// <exception cref="System.IO.IOException">an unexpected error occurred writing to the object store. /// </exception> internal virtual ObjectId WriteTree(DirCacheEntry[] cache, int cIdx, int pathOffset , ObjectInserter ow) { if (id == null) { int endIdx = cIdx + entrySpan; TreeFormatter fmt = new TreeFormatter(ComputeSize(cache, cIdx, pathOffset, ow)); int childIdx = 0; int entryIdx = cIdx; while (entryIdx < endIdx) { DirCacheEntry e = cache[entryIdx]; byte[] ep = e.path; if (childIdx < childCnt) { NGit.Dircache.DirCacheTree st = children[childIdx]; if (st.Contains(ep, pathOffset, ep.Length)) { fmt.Append(st.encodedName, FileMode.TREE, st.id); entryIdx += st.entrySpan; childIdx++; continue; } } fmt.Append(ep, pathOffset, ep.Length - pathOffset, e.FileMode, e.IdBuffer, e.IdOffset ); entryIdx++; } id = ow.Insert(fmt); } return(id); }
/// <exception cref="NGit.Errors.UnmergedPathException"></exception> /// <exception cref="System.IO.IOException"></exception> private int ComputeSize(DirCacheEntry[] cache, int cIdx, int pathOffset, ObjectInserter ow) { int endIdx = cIdx + entrySpan; int childIdx = 0; int entryIdx = cIdx; int size = 0; while (entryIdx < endIdx) { DirCacheEntry e = cache[entryIdx]; if (e.Stage != 0) { throw new UnmergedPathException(e); } byte[] ep = e.path; if (childIdx < childCnt) { NGit.Dircache.DirCacheTree st = children[childIdx]; if (st.Contains(ep, pathOffset, ep.Length)) { int stOffset = pathOffset + st.NameLength() + 1; st.WriteTree(cache, entryIdx, stOffset, ow); size += TreeFormatter.EntrySize(FileMode.TREE, st.NameLength()); entryIdx += st.entrySpan; childIdx++; continue; } } size += TreeFormatter.EntrySize(e.FileMode, ep.Length - pathOffset); entryIdx++; } return(size); }
private void ParseEntry() { currentEntry = cache.GetEntry(ptr); byte[] cep = currentEntry.path; if (nextSubtreePos != tree.GetChildCount()) { DirCacheTree s = tree.GetChild(nextSubtreePos); if (s.Contains(cep, pathOffset, cep.Length)) { // The current position is the first file of this subtree. // Use the subtree instead as the current position. // currentSubtree = s; nextSubtreePos++; if (s.IsValid()) { s.GetObjectId().CopyRawTo(subtreeId, 0); } mode = FileMode.TREE.GetBits(); path = cep; pathLen = pathOffset + s.NameLength(); return; } } // The current position is a file/symlink/gitlink so we // do not have a subtree located here. // mode = currentEntry.RawMode; path = cep; pathLen = cep.Length; currentSubtree = null; }