/// <summary>Save the configuration as a Git text style configuration file.</summary> /// <remarks> /// Save the configuration as a Git text style configuration file. /// <p> /// <b>Warning:</b> Although this method uses the traditional Git file /// locking approach to protect against concurrent writes of the /// configuration file, it does not ensure that the file has not been /// modified since the last read, which means updates performed by other /// objects accessing the same backing file may be lost. /// </remarks> /// <exception cref="System.IO.IOException">the file could not be written.</exception> public override void Save() { byte[] @out = Constants.Encode(ToText()); LockFile lf = new LockFile(GetFile(), fs); if (!lf.Lock()) { throw new LockFailedException(GetFile()); } try { lf.SetNeedSnapshot(true); lf.Write(@out); if (!lf.Commit()) { throw new IOException(MessageFormat.Format(JGitText.Get().cannotCommitWriteTo, GetFile ())); } } finally { lf.Unlock(); } snapshot = lf.GetCommitSnapshot(); hash = Hash(@out); // notify the listeners FireConfigChangedEvent(); }
public virtual void TestUpdateRefLockFailureLocked() { ObjectId opid = db.Resolve("refs/heads/master"); ObjectId pid = db.Resolve("refs/heads/master^"); RefUpdate updateRef = db.UpdateRef("refs/heads/master"); updateRef.SetNewObjectId(pid); LockFile lockFile1 = new LockFile(new FilePath(db.Directory, "refs/heads/master") , db.FileSystem); try { NUnit.Framework.Assert.IsTrue(lockFile1.Lock()); // precondition to test RefUpdate.Result update = updateRef.Update(); NUnit.Framework.Assert.AreEqual(RefUpdate.Result.LOCK_FAILURE, update); NUnit.Framework.Assert.AreEqual(opid, db.Resolve("refs/heads/master")); LockFile lockFile2 = new LockFile(new FilePath(db.Directory, "refs/heads/master") , db.FileSystem); NUnit.Framework.Assert.IsFalse(lockFile2.Lock()); } finally { // was locked, still is lockFile1.Unlock(); } }
public virtual void LockFailedExceptionRecovery() { Git git = new Git(db); WriteTrashFile("file.txt", "content"); git.Add().AddFilepattern("file.txt").Call(); RevCommit commit1 = git.Commit().SetMessage("create file").Call(); NUnit.Framework.Assert.IsNotNull(commit1); WriteTrashFile("file.txt", "content2"); git.Add().AddFilepattern("file.txt").Call(); NUnit.Framework.Assert.IsNotNull(git.Commit().SetMessage("edit file").Call()); LockFile lf = new LockFile(db.GetIndexFile(), db.FileSystem); NUnit.Framework.Assert.IsTrue(lf.Lock()); try { git.Checkout().SetName(commit1.Name).Call(); NUnit.Framework.Assert.Fail("JGitInternalException not thrown"); } catch (JGitInternalException e) { NUnit.Framework.Assert.IsTrue(e.InnerException is LockFailedException); lf.Unlock(); git.Checkout().SetName(commit1.Name).Call(); } }
/// <exception cref="System.IO.IOException"></exception> public virtual void TryRenameWhenLocked(string toLock, string fromName, string toName , string headPointsTo) { // setup WriteSymref(Constants.HEAD, headPointsTo); ObjectId oldfromId = db.Resolve(fromName); ObjectId oldHeadId = db.Resolve(Constants.HEAD); WriteReflog(db, oldfromId, oldfromId, "Just a message", fromName); IList <ReflogReader.Entry> oldFromLog = db.GetReflogReader(fromName).GetReverseEntries (); IList <ReflogReader.Entry> oldHeadLog = oldHeadId != null?db.GetReflogReader(Constants .HEAD).GetReverseEntries() : null; NUnit.Framework.Assert.IsTrue(new FilePath(db.Directory, "logs/" + fromName).Exists (), "internal check, we have a log"); // "someone" has branch X locked LockFile lockFile = new LockFile(new FilePath(db.Directory, toLock), db.FileSystem ); try { NUnit.Framework.Assert.IsTrue(lockFile.Lock()); // Now this is our test RefRename renameRef = db.RenameRef(fromName, toName); RefUpdate.Result result = renameRef.Rename(); NUnit.Framework.Assert.AreEqual(RefUpdate.Result.LOCK_FAILURE, result); // Check that the involved refs are the same despite the failure AssertExists(false, toName); if (!toLock.Equals(toName)) { AssertExists(false, toName + ".lock"); } AssertExists(true, toLock + ".lock"); if (!toLock.Equals(fromName)) { AssertExists(false, "logs/" + fromName + ".lock"); } AssertExists(false, "logs/" + toName + ".lock"); NUnit.Framework.Assert.AreEqual(oldHeadId, db.Resolve(Constants.HEAD)); NUnit.Framework.Assert.AreEqual(oldfromId, db.Resolve(fromName)); NUnit.Framework.Assert.IsNull(db.Resolve(toName)); NUnit.Framework.Assert.AreEqual(oldFromLog.ToString(), db.GetReflogReader(fromName ).GetReverseEntries().ToString()); if (oldHeadId != null) { NUnit.Framework.Assert.AreEqual(oldHeadLog.ToString(), db.GetReflogReader(Constants .HEAD).GetReverseEntries().ToString()); } } finally { lockFile.Unlock(); } }
/// <exception cref="System.IO.IOException"></exception> internal virtual void Delete(RefDirectoryUpdate update) { Ref dst = update.GetRef().GetLeaf(); string name = dst.GetName(); // Write the packed-refs file using an atomic update. We might // wind up reading it twice, before and after the lock, to ensure // we don't miss an edit made externally. RefDirectory.PackedRefList packed = GetPackedRefs(); if (packed.Contains(name)) { LockFile lck = new LockFile(packedRefsFile, update.GetRepository().FileSystem); if (!lck.Lock()) { throw new LockFailedException(packedRefsFile); } try { RefDirectory.PackedRefList cur = ReadPackedRefs(); int idx = cur.Find(name); if (0 <= idx) { CommitPackedRefs(lck, cur.Remove(idx), packed); } } finally { lck.Unlock(); } } RefList <RefDirectory.LooseRef> curLoose; RefList <RefDirectory.LooseRef> newLoose; do { curLoose = looseRefs.Get(); int idx = curLoose.Find(name); if (idx < 0) { break; } newLoose = curLoose.Remove(idx); }while (!looseRefs.CompareAndSet(curLoose, newLoose)); int levels = LevelsIn(name) - 2; Delete(logWriter.LogFor(name), levels); if (dst.GetStorage().IsLoose()) { update.Unlock(); Delete(FileFor(name), levels); } modCnt.IncrementAndGet(); FireRefsChanged(); }
protected internal override void WriteFile(string file, byte[] content) { FilePath p = new FilePath(_db.Directory, file); LockFile lck = new LockFile(p, FS.DETECTED); if (!lck.Lock()) throw new ObjectWritingException("Can't write " + p); try { lck.Write(content); } catch (IOException) { throw new ObjectWritingException("Can't write " + p); } if (!lck.Commit()) throw new ObjectWritingException("Can't write " + p); }
/// <summary>Save the configuration as a Git text style configuration file.</summary> /// <remarks> /// Save the configuration as a Git text style configuration file. /// <p> /// <b>Warning:</b> Although this method uses the traditional Git file /// locking approach to protect against concurrent writes of the /// configuration file, it does not ensure that the file has not been /// modified since the last read, which means updates performed by other /// objects accessing the same backing file may be lost. /// </remarks> /// <exception cref="System.IO.IOException">the file could not be written.</exception> public override void Save() { byte[] @out; string text = ToText(); if (utf8Bom) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); bos.Write(unchecked ((int)(0xEF))); bos.Write(unchecked ((int)(0xBB))); bos.Write(unchecked ((int)(0xBF))); bos.Write(Sharpen.Runtime.GetBytesForString(text, RawParseUtils.UTF8_CHARSET.Name ())); @out = bos.ToByteArray(); } else { @out = Constants.Encode(text); } LockFile lf = new LockFile(GetFile(), fs); if (!lf.Lock()) { throw new LockFailedException(GetFile()); } try { lf.SetNeedSnapshot(true); lf.Write(@out); if (!lf.Commit()) { throw new IOException(MessageFormat.Format(JGitText.Get().cannotCommitWriteTo, GetFile ())); } } finally { lf.Unlock(); } snapshot = lf.GetCommitSnapshot(); hash = Hash(@out); // notify the listeners FireConfigChangedEvent(); }
/// <summary>Create the <code>pack-*.keep</code> file, with the given message.</summary> /// <remarks>Create the <code>pack-*.keep</code> file, with the given message.</remarks> /// <param name="msg">message to store in the file.</param> /// <returns>true if the keep file was successfully written; false otherwise.</returns> /// <exception cref="System.IO.IOException">the keep file could not be written.</exception> public virtual bool Lock(string msg) { if (msg == null) { return(false); } if (!msg.EndsWith("\n")) { msg += "\n"; } LockFile lf = new LockFile(keepFile, fs); if (!lf.Lock()) { return(false); } lf.Write(Constants.Encode(msg)); return(lf.Commit()); }
/// <exception cref="System.IO.IOException"></exception> protected internal override bool TryLock(bool deref) { Ref dst = GetRef(); if (deref) { dst = dst.GetLeaf(); } string name = dst.GetName(); Lock = new LockFile(database.FileFor(name), GetRepository().FileSystem); if (Lock.Lock()) { dst = database.GetRef(name); SetOldObjectId(dst != null ? dst.GetObjectId() : null); return true; } else { return false; } }
/// <exception cref="System.IO.IOException"></exception> protected internal override bool TryLock(bool deref) { Ref dst = GetRef(); if (deref) { dst = dst.GetLeaf(); } string name = dst.GetName(); Lock = new LockFile(database.FileFor(name), GetRepository().FileSystem); if (Lock.Lock()) { dst = database.GetRef(name); SetOldObjectId(dst != null ? dst.GetObjectId() : null); return(true); } else { return(false); } }
public virtual void PackRefsWhileRefLocked_refNotPackedNoError() { RevBlob a = tr.Blob("a"); tr.LightweightTag("t1", a); tr.LightweightTag("t2", a); LockFile refLock = new LockFile(new FilePath(repo.Directory, "refs/tags/t1"), repo .FileSystem); try { refLock.Lock(); gc.PackRefs(); } finally { refLock.Unlock(); } NUnit.Framework.Assert.AreEqual(repo.GetRef("refs/tags/t1").GetStorage(), RefStorage .LOOSE); NUnit.Framework.Assert.AreEqual(repo.GetRef("refs/tags/t2").GetStorage(), RefStorage .PACKED); }
/// <exception cref="System.IO.IOException"></exception> public virtual void TryRenameWhenLocked(string toLock, string fromName, string toName , string headPointsTo) { // setup WriteSymref(Constants.HEAD, headPointsTo); ObjectId oldfromId = db.Resolve(fromName); ObjectId oldHeadId = db.Resolve(Constants.HEAD); WriteReflog(db, oldfromId, "Just a message", fromName); IList<ReflogEntry> oldFromLog = db.GetReflogReader(fromName).GetReverseEntries(); IList<ReflogEntry> oldHeadLog = oldHeadId != null ? db.GetReflogReader(Constants. HEAD).GetReverseEntries() : null; NUnit.Framework.Assert.IsTrue(new FilePath(db.Directory, "logs/" + fromName).Exists (), "internal check, we have a log"); // "someone" has branch X locked LockFile lockFile = new LockFile(new FilePath(db.Directory, toLock), db.FileSystem ); try { NUnit.Framework.Assert.IsTrue(lockFile.Lock()); // Now this is our test RefRename renameRef = db.RenameRef(fromName, toName); RefUpdate.Result result = renameRef.Rename(); NUnit.Framework.Assert.AreEqual(RefUpdate.Result.LOCK_FAILURE, result); // Check that the involved refs are the same despite the failure AssertExists(false, toName); if (!toLock.Equals(toName)) { AssertExists(false, toName + ".lock"); } AssertExists(true, toLock + ".lock"); if (!toLock.Equals(fromName)) { AssertExists(false, "logs/" + fromName + ".lock"); } AssertExists(false, "logs/" + toName + ".lock"); NUnit.Framework.Assert.AreEqual(oldHeadId, db.Resolve(Constants.HEAD)); NUnit.Framework.Assert.AreEqual(oldfromId, db.Resolve(fromName)); NUnit.Framework.Assert.IsNull(db.Resolve(toName)); NUnit.Framework.Assert.AreEqual(oldFromLog.ToString(), db.GetReflogReader(fromName ).GetReverseEntries().ToString()); if (oldHeadId != null) { NUnit.Framework.Assert.AreEqual(oldHeadLog.ToString(), db.GetReflogReader(Constants .HEAD).GetReverseEntries().ToString()); } } finally { lockFile.Unlock(); } }
/// <summary>Save the configuration as a Git text style configuration file.</summary> /// <remarks> /// Save the configuration as a Git text style configuration file. /// <p> /// <b>Warning:</b> Although this method uses the traditional Git file /// locking approach to protect against concurrent writes of the /// configuration file, it does not ensure that the file has not been /// modified since the last read, which means updates performed by other /// objects accessing the same backing file may be lost. /// </remarks> /// <exception cref="System.IO.IOException">the file could not be written.</exception> public override void Save() { byte[] @out; string text = ToText(); if (utf8Bom) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); bos.Write(unchecked((int)(0xEF))); bos.Write(unchecked((int)(0xBB))); bos.Write(unchecked((int)(0xBF))); bos.Write(Sharpen.Runtime.GetBytesForString(text, RawParseUtils.UTF8_CHARSET.Name ())); @out = bos.ToByteArray(); } else { @out = Constants.Encode(text); } LockFile lf = new LockFile(GetFile(), fs); if (!lf.Lock()) { throw new LockFailedException(GetFile()); } try { lf.SetNeedSnapshot(true); lf.Write(@out); if (!lf.Commit()) { throw new IOException(MessageFormat.Format(JGitText.Get().cannotCommitWriteTo, GetFile ())); } } finally { lf.Unlock(); } snapshot = lf.GetCommitSnapshot(); hash = Hash(@out); // notify the listeners FireConfigChangedEvent(); }
/// <summary>Create the <code>pack-*.keep</code> file, with the given message.</summary> /// <remarks>Create the <code>pack-*.keep</code> file, with the given message.</remarks> /// <param name="msg">message to store in the file.</param> /// <returns>true if the keep file was successfully written; false otherwise.</returns> /// <exception cref="System.IO.IOException">the keep file could not be written.</exception> public virtual bool Lock(string msg) { if (msg == null) { return false; } if (!msg.EndsWith("\n")) { msg += "\n"; } LockFile lf = new LockFile(keepFile, fs); if (!lf.Lock()) { return false; } lf.Write(Constants.Encode(msg)); return lf.Commit(); }
/// <exception cref="System.IO.IOException"></exception> private void UpdateFETCH_HEAD(FetchResult result) { FilePath meta = transport.local.Directory; if (meta == null) { return; } LockFile Lock = new LockFile(new FilePath(meta, "FETCH_HEAD"), transport.local.FileSystem ); try { if (Lock.Lock()) { TextWriter w = new OutputStreamWriter(Lock.GetOutputStream()); try { foreach (FetchHeadRecord h in fetchHeadUpdates) { h.Write(w); result.Add(h); } } finally { w.Close(); } Lock.Commit(); } } finally { Lock.Unlock(); } }