/// <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);
         }
     }
 }
Beispiel #3
0
 /// <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
                                          );
                }
            }
        }