/// <summary>Look up an entry with the specified path.</summary> /// <remarks>Look up an entry with the specified path.</remarks> /// <param name="path"></param> /// <returns>index entry for the path or null if not in index.</returns> /// <exception cref="Sharpen.UnsupportedEncodingException">Sharpen.UnsupportedEncodingException /// </exception> public virtual GitIndex.Entry GetEntry(string path) { return(entries.Get(Repository.GitInternalSlash(Constants.Encode(path)))); }
/// <summary>Write content of index to disk.</summary> /// <remarks>Write content of index to disk.</remarks> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual void Write() { CheckWriteOk(); FilePath tmpIndex = new FilePath(cacheFile.GetAbsoluteFile() + ".tmp"); FilePath Lock = new FilePath(cacheFile.GetAbsoluteFile() + ".lock"); if (!Lock.CreateNewFile()) { throw new IOException(JGitText.Get().indexFileIsInUse); } try { FileOutputStream fileOutputStream = new FileOutputStream(tmpIndex); FileChannel fc = fileOutputStream.GetChannel(); ByteBuffer buf = ByteBuffer.Allocate(4096); MessageDigest newMessageDigest = Constants.NewMessageDigest(); header = new GitIndex.Header(entries); header.Write(buf); buf.Flip(); newMessageDigest.Update(((byte[])buf.Array()), buf.ArrayOffset(), buf.Limit()); fc.Write(buf); buf.Flip(); buf.Clear(); for (Iterator i = entries.Values.Iterator(); i.HasNext();) { GitIndex.Entry e = (GitIndex.Entry)i.Next(); e.Write(buf); buf.Flip(); newMessageDigest.Update(((byte[])buf.Array()), buf.ArrayOffset(), buf.Limit()); fc.Write(buf); buf.Flip(); buf.Clear(); } buf.Put(newMessageDigest.Digest()); buf.Flip(); fc.Write(buf); fc.Close(); fileOutputStream.Close(); if (cacheFile.Exists()) { if (db.FileSystem.RetryFailedLockFileCommit()) { // file deletion fails on windows if another // thread is reading the file concurrently // So let's try 10 times... bool deleted = false; for (int i_1 = 0; i_1 < 10; i_1++) { if (cacheFile.Delete()) { deleted = true; break; } try { Sharpen.Thread.Sleep(100); } catch (Exception) { } } // ignore if (!deleted) { throw new IOException(JGitText.Get().couldNotRenameDeleteOldIndex); } } else { if (!cacheFile.Delete()) { throw new IOException(JGitText.Get().couldNotRenameDeleteOldIndex); } } } if (!tmpIndex.RenameTo(cacheFile)) { throw new IOException(JGitText.Get().couldNotRenameTemporaryIndexFileToIndex); } changed = false; statDirty = false; lastCacheTime = cacheFile.LastModified(); db.FireEvent(new IndexChangedEvent()); } finally { if (!Lock.Delete()) { throw new IOException(JGitText.Get().couldNotDeleteLockFileShouldNotHappen); } if (tmpIndex.Exists() && !tmpIndex.Delete()) { throw new IOException(JGitText.Get().couldNotDeleteTemporaryIndexFileShouldNotHappen ); } } }
/// <summary>Construct and write tree out of index.</summary> /// <remarks>Construct and write tree out of index.</remarks> /// <returns>SHA-1 of the constructed tree</returns> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual ObjectId WriteTree() { CheckWriteOk(); ObjectInserter inserter = db.NewObjectInserter(); try { Tree current = new Tree(db); Stack <Tree> trees = new Stack <Tree>(); trees.Push(current); string[] prevName = new string[0]; foreach (GitIndex.Entry e in entries.Values) { if (e.GetStage() != 0) { continue; } string[] newName = SplitDirPath(e.GetName()); int c = LongestCommonPath(prevName, newName); while (c < trees.Count - 1) { current.SetId(inserter.Insert(Constants.OBJ_TREE, current.Format())); trees.Pop(); current = trees.IsEmpty() ? null : (Tree)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.GetParent().AddEntry(current); trees.Push(current); } else { current = (Tree)current.FindTreeMember(newName[trees.Count - 1]); trees.Push(current); } } FileTreeEntry ne = new FileTreeEntry(current, e.sha1, Constants.Encode(newName[newName .Length - 1]), (e.mode & FileMode.EXECUTABLE_FILE.GetBits()) == FileMode.EXECUTABLE_FILE .GetBits()); current.AddEntry(ne); } while (!trees.IsEmpty()) { current.SetId(inserter.Insert(Constants.OBJ_TREE, current.Format())); trees.Pop(); if (!trees.IsEmpty()) { current = trees.Peek(); } } inserter.Flush(); return(current.GetId()); } finally { inserter.Release(); } }