/// <summary>Add tree entry to index</summary> /// <param name="te">tree entry</param> /// <returns>new or modified index entry</returns> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual GitIndex.Entry AddEntry(TreeEntry te) { byte[] key = Constants.Encode(te.GetFullName()); GitIndex.Entry e = new GitIndex.Entry(this, te, 0); entries.Put(key, e); return(e); }
/// <exception cref="System.IO.IOException"></exception> internal virtual void ReadTree(string prefix, Tree t) { TreeEntry[] members = t.Members(); for (int i = 0; i < members.Length; ++i) { TreeEntry te = members[i]; string name; if (prefix.Length > 0) { name = prefix + "/" + te.GetName(); } else { name = te.GetName(); } if (te is Tree) { ReadTree(name, (Tree)te); } else { GitIndex.Entry e = new GitIndex.Entry(this, te, 0); entries.Put(Constants.Encode(name), e); } } }
/// <summary>Helper for accessing tree/blob/index methods.</summary> /// <remarks>Helper for accessing tree/blob/index methods.</remarks> /// <param name="i"></param> /// <returns>'/' for Tree entries and NUL for non-treeish objects</returns> public static int LastChar(GitIndex.Entry i) { // FIXME, gitlink etc. Currently Trees cannot appear in the // index so '\0' is always returned, except maybe for submodules // which we do not support yet. return(FileMode.TREE.Equals(i.GetModeBits()) ? '/' : '\0'); }
/// <exception cref="System.IO.IOException"></exception> private void CheckWriteOk() { for (Iterator i = entries.Values.Iterator(); i.HasNext();) { GitIndex.Entry e = (GitIndex.Entry)i.Next(); if (e.GetStage() != 0) { throw new NGit.Errors.NotSupportedException(JGitText.Get().cannotWorkWithOtherStagesThanZeroRightNow ); } } }
/// <summary>Add the content of a file to the index.</summary> /// <remarks>Add the content of a file to the index.</remarks> /// <param name="wd">workdir</param> /// <param name="f">the file</param> /// <param name="content">content of the file</param> /// <returns>a new or updated index entry for the path represented by f</returns> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual GitIndex.Entry Add(FilePath wd, FilePath f, byte[] content) { byte[] key = MakeKey(wd, f); GitIndex.Entry e = entries.Get(key); if (e == null) { e = new GitIndex.Entry(this, key, f, 0, content); entries.Put(key, e); } else { e.Update(f, content); } return(e); }
/// <summary>Read the cache file into memory.</summary> /// <remarks>Read the cache file into memory.</remarks> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual void Read() { changed = false; statDirty = false; if (!cacheFile.Exists()) { header = null; entries.Clear(); lastCacheTime = 0; return; } cache = new RandomAccessFile(cacheFile, "r"); try { FileChannel channel = cache.GetChannel(); ByteBuffer buffer = ByteBuffer.AllocateDirect((int)cacheFile.Length()); buffer.Order(ByteOrder.BIG_ENDIAN); int j = channel.Read(buffer); if (j != buffer.Capacity()) { throw new IOException(MessageFormat.Format(JGitText.Get().couldNotReadIndexInOneGo , j, buffer.Capacity())); } buffer.Flip(); header = new GitIndex.Header(buffer); entries.Clear(); for (int i = 0; i < header.entries; ++i) { GitIndex.Entry entry = new GitIndex.Entry(this, buffer); GitIndex.Entry existing = entries.Get(entry.name); entries.Put(entry.name, entry); if (existing != null) { entry.stages |= existing.stages; } } lastCacheTime = cacheFile.LastModified(); } finally { cache.Close(); } }
/// <summary>Check out content of the specified index entry</summary> /// <param name="wd">workdir</param> /// <param name="e">index entry</param> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual void CheckoutEntry(FilePath wd, GitIndex.Entry e) { ObjectLoader ol = db.Open(e.sha1, Constants.OBJ_BLOB); FilePath file = new FilePath(wd, e.GetName()); file.Delete(); FileUtils.Mkdirs(file.GetParentFile(), true); FileOutputStream dst = new FileOutputStream(file); try { ol.CopyTo(dst); } finally { dst.Close(); } if (Config_filemode() && File_hasExecute()) { if (FileMode.EXECUTABLE_FILE.Equals(e.mode)) { if (!File_canExecute(file)) { File_setExecute(file, true); } } else { if (File_canExecute(file)) { File_setExecute(file, false); } } } e.mtime = file.LastModified() * 1000000L; e.ctime = e.mtime; }
/// <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 ); } } }