private void WaitNextSec(FilePath f) { long initialLastModified = f.LastModified(); do { f.SetLastModified(Runtime.CurrentTimeMillis()); } while (f.LastModified() == initialLastModified); }
/// <summary> /// Waits until it is guaranteed that a subsequent file modification has a /// younger modification timestamp than the modification timestamp of the /// given file. /// </summary> /// <remarks> /// Waits until it is guaranteed that a subsequent file modification has a /// younger modification timestamp than the modification timestamp of the /// given file. This is done by touching a temporary file, reading the /// lastmodified attribute and, if needed, sleeping. After sleeping this loop /// starts again until the filesystem timer has advanced enough. /// </remarks> /// <param name="lastFile"> /// the file on which we want to wait until the filesystem timer /// has advanced more than the lastmodification timestamp of this /// file /// </param> /// <returns> /// return the last measured value of the filesystem timer which is /// greater than then the lastmodification time of lastfile. /// </returns> /// <exception cref="System.Exception">System.Exception</exception> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public static long FsTick(FilePath lastFile) { long sleepTime = 1; FilePath tmp = FilePath.CreateTempFile("FileTreeIteratorWithTimeControl", null); try { long startTime = (lastFile == null) ? tmp.LastModified() : lastFile.LastModified( ); long actTime = tmp.LastModified(); while (actTime <= startTime) { Sharpen.Thread.Sleep(sleepTime); sleepTime *= 5; tmp.SetLastModified(Runtime.CurrentTimeMillis()); actTime = tmp.LastModified(); } return actTime; } finally { FileUtils.Delete(tmp); } }
/// <summary>Kick the timestamp of a local file.</summary> /// <remarks> /// Kick the timestamp of a local file. /// <p> /// We shouldn't have to make these method calls. The cache is using file /// system timestamps, and on many systems unit tests run faster than the /// modification clock. Dumping the cache after we make an edit behind /// RefDirectory's back allows the tests to pass. /// </remarks> /// <param name="name">the file in the repository to force a time change on.</param> private void BUG_WorkAroundRacyGitIssues(string name) { FilePath path = new FilePath(db.Directory, name); long old = path.LastModified(); long set = 1250379778668L; // Sat Aug 15 20:12:58 GMT-03:30 2009 path.SetLastModified(set); NUnit.Framework.Assert.IsTrue(old != path.LastModified(), "time changed"); }
private static void Touch(long begin, FilePath dir) { while (begin >= dir.LastModified()) { try { Sharpen.Thread.Sleep(25); } catch (Exception) { } // dir.SetLastModified(Runtime.CurrentTimeMillis()); } }
/// <exception cref="System.IO.IOException"></exception> private DirCacheEntry AddEntryToBuilder(string path, FilePath file, ObjectInserter newObjectInserter, DirCacheBuilder builder, int stage) { FileInputStream inputStream = new FileInputStream(file); ObjectId id = newObjectInserter.Insert(Constants.OBJ_BLOB, file.Length(), inputStream ); inputStream.Close(); DirCacheEntry entry = new DirCacheEntry(path, stage); entry.SetObjectId(id); entry.FileMode = FileMode.REGULAR_FILE; entry.LastModified = file.LastModified(); entry.SetLength((int)file.Length()); builder.Add(entry); return entry; }
/// <summary>Check if the path may have been modified since the snapshot was saved.</summary> /// <remarks>Check if the path may have been modified since the snapshot was saved.</remarks> /// <param name="path">the path the snapshot describes.</param> /// <returns>true if the path needs to be read again.</returns> public virtual bool IsModified(FilePath path) { return IsModified(path.LastModified()); }
/// <summary>Record a snapshot for a specific file path.</summary> /// <remarks> /// Record a snapshot for a specific file path. /// <p> /// This method should be invoked before the file is accessed. /// </remarks> /// <param name="path"> /// the path to later remember. The path's current status /// information is saved. /// </param> /// <returns>the snapshot.</returns> public static NGit.Storage.File.FileSnapshot Save(FilePath path) { long read = Runtime.CurrentTimeMillis(); long modified = path.LastModified(); return new NGit.Storage.File.FileSnapshot(read, modified); }
/// <summary>Updates the index after a content merge has happened.</summary> /// <remarks> /// Updates the index after a content merge has happened. If no conflict has /// occurred this includes persisting the merged content to the object /// database. In case of conflicts this method takes care to write the /// correct stages to the index. /// </remarks> /// <param name="base"></param> /// <param name="ours"></param> /// <param name="theirs"></param> /// <param name="result"></param> /// <param name="of"></param> /// <exception cref="System.IO.FileNotFoundException">System.IO.FileNotFoundException /// </exception> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> private void UpdateIndex(CanonicalTreeParser @base, CanonicalTreeParser ours, CanonicalTreeParser theirs, MergeResult<RawText> result, FilePath of) { if (result.ContainsConflicts()) { // a conflict occurred, the file will contain conflict markers // the index will be populated with the three stages and only the // workdir (if used) contains the halfways merged content Add(tw.RawPath, @base, DirCacheEntry.STAGE_1); Add(tw.RawPath, ours, DirCacheEntry.STAGE_2); Add(tw.RawPath, theirs, DirCacheEntry.STAGE_3); mergeResults.Put(tw.PathString, result.Upcast ()); } else { // no conflict occurred, the file will contain fully merged content. // the index will be populated with the new merged version DirCacheEntry dce = new DirCacheEntry(tw.PathString); int newMode = MergeFileModes(tw.GetRawMode(0), tw.GetRawMode(1), tw.GetRawMode(2) ); // set the mode for the new content. Fall back to REGULAR_FILE if // you can't merge modes of OURS and THEIRS dce.FileMode = (newMode == FileMode.MISSING.GetBits()) ? FileMode.REGULAR_FILE : FileMode.FromBits(newMode); dce.LastModified = of.LastModified(); dce.SetLength((int)of.Length()); InputStream @is = new FileInputStream(of); try { dce.SetObjectId(oi.Insert(Constants.OBJ_BLOB, of.Length(), @is)); } finally { @is.Close(); if (inCore) { FileUtils.Delete(of); } } builder.Add(dce); } }
/// <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. /// <p> /// 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 /// </p> /// </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> /// <param name="or">object reader to use for checkout</param> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public static void CheckoutEntry(Repository repo, FilePath f, DirCacheEntry entry , ObjectReader or) { ObjectLoader ol = or.Open(entry.GetObjectId()); FilePath parentDir = f.GetParentFile(); FilePath tmpFile = FilePath.CreateTempFile("._" + f.GetName(), null, parentDir); WorkingTreeOptions opt = repo.GetConfig().Get(WorkingTreeOptions.KEY); FileOutputStream rawChannel = new FileOutputStream(tmpFile); OutputStream channel; if (opt.GetAutoCRLF() == CoreConfig.AutoCRLF.TRUE) { channel = new AutoCRLFOutputStream(rawChannel); } else { channel = rawChannel; } try { ol.CopyTo(channel); } finally { channel.Close(); } FS fs = repo.FileSystem; 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(); if (opt.GetAutoCRLF() != CoreConfig.AutoCRLF.FALSE) { entry.SetLength(f.Length()); } else { // AutoCRLF wants on-disk-size entry.SetLength((int)ol.GetSize()); } }
public virtual void TestUpdateSmudgedEntries() { git.BranchCreate().SetName("test2").Call(); RefUpdate rup = db.UpdateRef(Constants.HEAD); rup.Link("refs/heads/test2"); FilePath file = new FilePath(db.WorkTree, "Test.txt"); long size = file.Length(); long mTime = file.LastModified() - 5000L; NUnit.Framework.Assert.IsTrue(file.SetLastModified(mTime)); DirCache cache = DirCache.Lock(db.GetIndexFile(), db.FileSystem); DirCacheEntry entry = cache.GetEntry("Test.txt"); NUnit.Framework.Assert.IsNotNull(entry); entry.SetLength(0); entry.LastModified = 0; cache.Write(); NUnit.Framework.Assert.IsTrue(cache.Commit()); cache = DirCache.Read(db.GetIndexFile(), db.FileSystem); entry = cache.GetEntry("Test.txt"); NUnit.Framework.Assert.IsNotNull(entry); NUnit.Framework.Assert.AreEqual(0, entry.Length); NUnit.Framework.Assert.AreEqual(0, entry.LastModified); db.GetIndexFile().SetLastModified(db.GetIndexFile().LastModified() - 5000); NUnit.Framework.Assert.IsNotNull(git.Checkout().SetName("test").Call()); cache = DirCache.Read(db.GetIndexFile(), db.FileSystem); entry = cache.GetEntry("Test.txt"); NUnit.Framework.Assert.IsNotNull(entry); NUnit.Framework.Assert.AreEqual(size, entry.Length); NUnit.Framework.Assert.AreEqual(mTime, entry.LastModified); }