Git style file locking and replacement. To modify a ref file Git tries to use an atomic update approach: we write the new data into a brand new file, then rename it in place over the old name. This way we can just delete the temporary file if anything goes wrong, and nothing has been damaged. To coordinate access from multiple processes at once Git tries to atomically create the new temporary file under a well-known name.
Inheritance: IDisposable
		protected override void writeFile(string file, byte[] content) {
			FileInfo p = PathUtil.CombineFilePath(_db.Directory, file);
			LockFile lck = new LockFile(p);
			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);
		}
Exemple #2
0
        /// <summary>
        /// Create the <code>pack-*.keep</code> file, with the given message.
        /// </summary>
        /// <param name="msg">message to store in the file.</param>
        /// <returns>
        /// true if the keep file was successfully written; false otherwise.
        /// </returns>
        /// <exception cref="IOException">
		/// The keep file could not be written.
        /// </exception>
        public bool Lock(string msg)
        {
            if (msg == null) 
				return false;
			
            if (!msg.EndsWith("\n")) msg += "\n";
            using(LockFile lf = new LockFile(_keepFile))
			{
	            if (!lf.Lock()) 
					return false;
	            lf.Write(Constants.encode(msg));
	            return lf.Commit();
			}
        }
 protected override bool tryLock(bool deref)
 {
     Ref dst = Ref;
     if (deref)
         dst = dst.getLeaf();
     string name = dst.getName();
     _lock = new LockFile(_database.fileFor(name));
     if (_lock.Lock())
     {
         dst = _database.getRef(name);
         OldObjectId = (dst != null ? dst.getObjectId() : null);
         return true;
     }
     else
     {
         return false;
     }
 }
 public override void unlock()
 {
     if (_lock != null)
     {
         _lock.Unlock();
         _lock = null;
     }
 }
Exemple #5
0
 public LockFileOutputStream(LockFile lockfile)
 {
     _lockFile = lockfile;
 }
Exemple #6
0
        public void tryRenameWhenLocked(string toLock, string fromName,
            string toName, string headPointsTo)
        {
            // setup
            db.WriteSymref(Constants.HEAD, headPointsTo);
            ObjectId oldfromId = db.Resolve(fromName);
            ObjectId oldHeadId = db.Resolve(Constants.HEAD);
            RefLogWriter.WriteReflog(db, oldfromId, oldfromId, "Just a message",
                    fromName);
            IList<ReflogReader.Entry> oldFromLog = db
                    .ReflogReader(fromName).getReverseEntries();
            IList<ReflogReader.Entry> oldHeadLog = oldHeadId != null ? db
                    .ReflogReader(Constants.HEAD).getReverseEntries() : null;

            Assert.IsTrue(new FileInfo(Path.Combine(db.Directory.FullName, "logs/" + fromName)).Exists, "internal check, we have a log");

            // "someone" has branch X locked
            var lockFile = new LockFile(new FileInfo(Path.Combine(db.Directory.FullName, toLock)));
            try
            {
                Assert.IsTrue(lockFile.Lock());

                // Now this is our test
                RefRename renameRef = db.RenameRef(fromName, toName);
                RefUpdate.RefUpdateResult result = renameRef.Rename();
                Assert.AreEqual(RefUpdate.RefUpdateResult.LockFailure, 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");
                Assert.AreEqual(oldHeadId, db.Resolve(Constants.HEAD));
                Assert.AreEqual(oldfromId, db.Resolve(fromName));
                Assert.IsNull(db.Resolve(toName));
                Assert.AreEqual(oldFromLog.ToString(), db.ReflogReader(fromName)
                        .getReverseEntries().ToString());
                if (oldHeadId != null)
                    Assert.AreEqual(oldHeadLog, db.ReflogReader(Constants.HEAD)
                            .getReverseEntries());
            }
            finally
            {
                lockFile.Unlock();
            }
        }
Exemple #7
0
 public void testUpdateRefLockFailureLocked()
 {
     ObjectId opid = db.Resolve("refs/heads/master");
     ObjectId pid = db.Resolve("refs/heads/master^");
     RefUpdate updateRef = db.UpdateRef("refs/heads/master");
     updateRef.NewObjectId = pid;
     var lockFile1 = new LockFile(new FileInfo(Path.Combine(db.Directory.FullName, "refs/heads/master")));
     try
     {
         Assert.IsTrue(lockFile1.Lock()); // precondition to test
         RefUpdate.RefUpdateResult update = updateRef.Update();
         Assert.AreEqual(RefUpdate.RefUpdateResult.LockFailure, update);
         Assert.AreEqual(opid, db.Resolve("refs/heads/master"));
         var lockFile2 = new LockFile(new FileInfo(Path.Combine(db.Directory.FullName, "refs/heads/master")));
         Assert.IsFalse(lockFile2.Lock()); // was locked, still is
     }
     finally
     {
         lockFile1.Unlock();
     }
 }
Exemple #8
0
 public void save()
 {
     byte[] o = Constants.encode(toText());
     LockFile lf = new LockFile(getFile());
     if (!lf.Lock())
         throw new IOException("Cannot lock " + getFile());
     try
     {
         lf.Write(o);
         if (!lf.Commit())
             throw new IOException("Cannot commit write to " + getFile());
     }
     finally
     {
         lf.Unlock();
     }
 }
Exemple #9
0
 public override RefUpdateResult Store(LockFile lockFile, RefUpdateResult status)
 {
     return RefUpdate.UpdateRepositoryStore(lockFile, status);
 }
Exemple #10
0
 public abstract RefUpdateResult Store(LockFile lockFile, RefUpdateResult status);
Exemple #11
0
            public override RefUpdateResult Store(LockFile @lockFile, RefUpdateResult status)
            {
                var storage = RefUpdate._ref.StorageFormat;
                if (storage == Ref.Storage.New)
                {
                    return status;
                }

                if (storage.IsPacked)
                {
                    RefUpdate._db.RemovePackedRef(RefUpdate._ref.Name);
                }

                int levels = Count(RefUpdate._ref.Name, '/') - 2;

                // Delete logs _before_ unlocking
                DirectoryInfo gitDir = RefUpdate._db.Repository.Directory;
                var logDir = new DirectoryInfo(gitDir + "/" + Constants.LOGS);
                DeleteFileAndEmptyDir(new FileInfo(logDir + "/" + RefUpdate._ref.Name), levels);

                // We have to unlock before (maybe) deleting the parent directories
                lockFile.Unlock();
                if (storage.IsLoose)
                {
                    DeleteFileAndEmptyDir(RefUpdate._looseFile, levels);
                }
                return status;
            }
Exemple #12
0
        private RefUpdateResult UpdateRepositoryStore(LockFile @lock, RefUpdateResult status)
        {
            if (status == RefUpdateResult.NoChange) return status;

            @lock.NeedStatInformation = true;
            @lock.Write(_newValue);

            string msg = GetRefLogMessage();

            if (msg != null)
            {
                if (_refLogIncludeResult)
                {
                    string strResult = ToResultString(status);
                    if (strResult != null)
                    {
                        msg = !string.IsNullOrEmpty(msg) ? msg + ": " + strResult : strResult;
                    }
                }

                RefLogWriter.append(this, msg);
            }

            if ([email protected]())
            {
                return RefUpdateResult.LockFailure;
            }

            _db.Stored(_ref.OriginalName, _ref.Name, _newValue, @lock.CommitLastModified);
            return status;
        }
Exemple #13
0
        private RefUpdateResult UpdateImpl(RevWalk.RevWalk walk, StoreBase store)
        {
            if (isNameConflicting())
            {
                return RefUpdateResult.LockFailure;
            }

            using (LockFile @lock = new LockFile(_looseFile))
            {
                if ([email protected]())
                {
                    return RefUpdateResult.LockFailure;
                }

                OldObjectId = _db.IdOf(Name);
                if (_expValue != null)
                {
                    ObjectId o = OldObjectId ?? ObjectId.ZeroId;
                    if (!AnyObjectId.equals(_expValue, o))
                    {
                        return RefUpdateResult.LockFailure;
                    }
                }

                if (OldObjectId == null)
                {
                    return store.Store(@lock, RefUpdateResult.New);
                }

                RevObject newObj = SafeParse(walk, _newValue);
                RevObject oldObj = SafeParse(walk, OldObjectId);
                if (newObj == oldObj)
                {
                    return store.Store(@lock, RefUpdateResult.NoChange);
                }

                RevCommit newCom = (newObj as RevCommit);
                RevCommit oldCom = (oldObj as RevCommit);
                if (newCom != null && oldCom != null)
                {
                    if (walk.isMergedInto(oldCom, newCom))
                    {
                        return store.Store(@lock, RefUpdateResult.FastForward);
                    }
                }

                if (IsForceUpdate)
                {
                    return store.Store(@lock, RefUpdateResult.Forced);
                }

                return RefUpdateResult.Rejected;
            }
        }
Exemple #14
0
 public LockFileOutputStream(LockFile lockfile)
 {
     _lockFile = lockfile;
 }
 private void commitPackedRefs(LockFile lck, RefList <Ref> refs, PackedRefList oldPackedList)
 {
     new PackedRefsWriter(lck, refs, oldPackedList, packedRefs).writePackedRefs();
 }
Exemple #16
0
        }

        private static void LockAndWriteFile(FileInfo file, byte[] content)
        {
            string name = file.Name;
            using (LockFile lck = new LockFile(file))
            {
                if (!lck.Lock())
                {
                    throw new ObjectWritingException("Unable to lock " + name);
                }

                try
                {
                    lck.Write(content);
                }
                catch (IOException ioe)
                {
                    throw new ObjectWritingException("Unable to write " + name, ioe);
                }
                if (!lck.Commit())
                {
                    throw new ObjectWritingException("Unable to write " + name);
                }