Пример #1
0
        /// <summary>
        /// Updates the file in the working tree with content and mode from an entry
        /// in the index.
        /// </summary>
        /// <remarks>
        /// Updates the file in the working tree with content and mode from an entry
        /// in the index. The new content is first written to a new temporary file in
        /// the same directory as the real file. Then that new file is renamed to the
        /// final filename.
        /// TODO: this method works directly on File IO, we may need another
        /// abstraction (like WorkingTreeIterator). This way we could tell e.g.
        /// Eclipse that Files in the workspace got changed
        /// </remarks>
        /// <param name="repo"></param>
        /// <param name="f">
        /// the file to be modified. The parent directory for this file
        /// has to exist already
        /// </param>
        /// <param name="entry">the entry containing new mode and content</param>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        public static void CheckoutEntry(Repository repo, FilePath f, DirCacheEntry entry
                                         )
        {
            ObjectLoader     ol        = repo.Open(entry.GetObjectId());
            FilePath         parentDir = f.GetParentFile();
            FilePath         tmpFile   = FilePath.CreateTempFile("._" + f.GetName(), null, parentDir);
            FileOutputStream channel   = new FileOutputStream(tmpFile);

            try
            {
                ol.CopyTo(channel);
            }
            finally
            {
                channel.Close();
            }
            FS fs = repo.FileSystem;
            WorkingTreeOptions opt = repo.GetConfig().Get(WorkingTreeOptions.KEY);

            if (opt.IsFileMode() && fs.SupportsExecute())
            {
                if (FileMode.EXECUTABLE_FILE.Equals(entry.RawMode))
                {
                    if (!fs.CanExecute(tmpFile))
                    {
                        fs.SetExecute(tmpFile, true);
                    }
                }
                else
                {
                    if (fs.CanExecute(tmpFile))
                    {
                        fs.SetExecute(tmpFile, false);
                    }
                }
            }
            if (!tmpFile.RenameTo(f))
            {
                // tried to rename which failed. Let' delete the target file and try
                // again
                FileUtils.Delete(f);
                if (!tmpFile.RenameTo(f))
                {
                    throw new IOException(MessageFormat.Format(JGitText.Get().couldNotWriteFile, tmpFile
                                                               .GetPath(), f.GetPath()));
                }
            }
            entry.LastModified = f.LastModified();
            entry.SetLength((int)ol.GetSize());
        }