internal virtual void Stored(RefDirectoryUpdate update, FileSnapshot snapshot) { ObjectId target = update.GetNewObjectId().Copy(); Ref leaf = update.GetRef().GetLeaf(); PutLooseRef(new RefDirectory.LooseUnpeeled(snapshot, leaf.GetName(), target)); }
/// <exception cref="System.IO.IOException"></exception> public override RefRename NewRename(string fromName, string toName) { RefDirectoryUpdate from = ((RefDirectoryUpdate)NewUpdate(fromName, false)); RefDirectoryUpdate to = ((RefDirectoryUpdate)NewUpdate(toName, false)); return(new RefDirectoryRename(from, to)); }
/// <exception cref="System.IO.IOException"></exception> public override RefUpdate NewUpdate(string name, bool detach) { bool detachingSymbolicRef = false; RefList <Ref> packed = GetPackedRefs(); Ref @ref = ReadRef(name, packed); if (@ref != null) { @ref = Resolve(@ref, 0, null, null, packed); } if (@ref == null) { @ref = new ObjectIdRef.Unpeeled(RefStorage.NEW, name, null); } else { detachingSymbolicRef = detach && @ref.IsSymbolic(); if (detachingSymbolicRef) { @ref = new ObjectIdRef.Unpeeled(RefStorage.LOOSE, name, @ref.GetObjectId()); } } RefDirectoryUpdate refDirUpdate = new RefDirectoryUpdate(this, @ref); if (detachingSymbolicRef) { refDirUpdate.SetDetachingSymbolicRef(); } return(refDirUpdate); }
/// <exception cref="System.IO.IOException"></exception> private void WriteReflog(Repository db, ObjectId newId, string msg, string refName ) { RefDirectory refs = (RefDirectory)db.RefDatabase; RefDirectoryUpdate update = ((RefDirectoryUpdate)refs.NewUpdate(refName, true)); update.SetNewObjectId(newId); refs.Log(update, msg, true); }
/// <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(); }
internal RefDirectoryRename(RefDirectoryUpdate src, RefDirectoryUpdate dst) : base (src, dst) { refdb = ((RefDirectory)src.GetRefDatabase()); }
/// <exception cref="System.IO.IOException"></exception> protected internal override RefUpdate.Result DoRename() { if (source.GetRef().IsSymbolic()) { return(RefUpdate.Result.IO_FAILURE); } // not supported objId = source.GetOldObjectId(); updateHEAD = NeedToUpdateHEAD(); tmp = refdb.NewTemporaryUpdate(); RevWalk rw = new RevWalk(refdb.GetRepository()); try { // First backup the source so its never unreachable. tmp.SetNewObjectId(objId); tmp.SetForceUpdate(true); tmp.DisableRefLog(); switch (tmp.Update(rw)) { case RefUpdate.Result.NEW: case RefUpdate.Result.FORCED: case RefUpdate.Result.NO_CHANGE: { break; } default: { return(tmp.GetResult()); break; } } // Save the source's log under the temporary name, we must do // this before we delete the source, otherwise we lose the log. if (!RenameLog(source, tmp)) { return(RefUpdate.Result.IO_FAILURE); } // If HEAD has to be updated, link it now to destination. // We have to link before we delete, otherwise the delete // fails because its the current branch. RefUpdate dst = destination; if (updateHEAD) { if (!LinkHEAD(destination)) { RenameLog(tmp, source); return(RefUpdate.Result.LOCK_FAILURE); } // Replace the update operation so HEAD will log the rename. dst = ((RefDirectoryUpdate)refdb.NewUpdate(Constants.HEAD, false)); dst.SetRefLogIdent(destination.GetRefLogIdent()); dst.SetRefLogMessage(destination.GetRefLogMessage(), false); } // Delete the source name so its path is free for replacement. source.SetExpectedOldObjectId(objId); source.SetForceUpdate(true); source.DisableRefLog(); if (source.Delete(rw) != RefUpdate.Result.FORCED) { RenameLog(tmp, source); if (updateHEAD) { LinkHEAD(source); } return(source.GetResult()); } // Move the log to the destination. if (!RenameLog(tmp, destination)) { RenameLog(tmp, source); source.SetExpectedOldObjectId(ObjectId.ZeroId); source.SetNewObjectId(objId); source.Update(rw); if (updateHEAD) { LinkHEAD(source); } return(RefUpdate.Result.IO_FAILURE); } // Create the destination, logging the rename during the creation. dst.SetExpectedOldObjectId(ObjectId.ZeroId); dst.SetNewObjectId(objId); if (dst.Update(rw) != RefUpdate.Result.NEW) { // If we didn't create the destination we have to undo // our work. Put the log back and restore source. if (RenameLog(destination, tmp)) { RenameLog(tmp, source); } source.SetExpectedOldObjectId(ObjectId.ZeroId); source.SetNewObjectId(objId); source.Update(rw); if (updateHEAD) { LinkHEAD(source); } return(dst.GetResult()); } return(RefUpdate.Result.RENAMED); } finally { // Always try to free the temporary name. try { refdb.Delete(tmp); } catch (IOException) { FileUtils.Delete(refdb.FileFor(tmp.GetName())); } rw.Release(); } }
/// <exception cref="System.IO.IOException"></exception> protected internal override RefUpdate.Result DoRename() { if (source.GetRef().IsSymbolic()) { return RefUpdate.Result.IO_FAILURE; } // not supported objId = source.GetOldObjectId(); updateHEAD = NeedToUpdateHEAD(); tmp = refdb.NewTemporaryUpdate(); RevWalk rw = new RevWalk(refdb.GetRepository()); try { // First backup the source so its never unreachable. tmp.SetNewObjectId(objId); tmp.SetForceUpdate(true); tmp.DisableRefLog(); switch (tmp.Update(rw)) { case RefUpdate.Result.NEW: case RefUpdate.Result.FORCED: case RefUpdate.Result.NO_CHANGE: { break; } default: { return tmp.GetResult(); break; } } // Save the source's log under the temporary name, we must do // this before we delete the source, otherwise we lose the log. if (!RenameLog(source, tmp)) { return RefUpdate.Result.IO_FAILURE; } // If HEAD has to be updated, link it now to destination. // We have to link before we delete, otherwise the delete // fails because its the current branch. RefUpdate dst = destination; if (updateHEAD) { if (!LinkHEAD(destination)) { RenameLog(tmp, source); return RefUpdate.Result.LOCK_FAILURE; } // Replace the update operation so HEAD will log the rename. dst = ((RefDirectoryUpdate)refdb.NewUpdate(Constants.HEAD, false)); dst.SetRefLogIdent(destination.GetRefLogIdent()); dst.SetRefLogMessage(destination.GetRefLogMessage(), false); } // Delete the source name so its path is free for replacement. source.SetExpectedOldObjectId(objId); source.SetForceUpdate(true); source.DisableRefLog(); if (source.Delete(rw) != RefUpdate.Result.FORCED) { RenameLog(tmp, source); if (updateHEAD) { LinkHEAD(source); } return source.GetResult(); } // Move the log to the destination. if (!RenameLog(tmp, destination)) { RenameLog(tmp, source); source.SetExpectedOldObjectId(ObjectId.ZeroId); source.SetNewObjectId(objId); source.Update(rw); if (updateHEAD) { LinkHEAD(source); } return RefUpdate.Result.IO_FAILURE; } // Create the destination, logging the rename during the creation. dst.SetExpectedOldObjectId(ObjectId.ZeroId); dst.SetNewObjectId(objId); if (dst.Update(rw) != RefUpdate.Result.NEW) { // If we didn't create the destination we have to undo // our work. Put the log back and restore source. if (RenameLog(destination, tmp)) { RenameLog(tmp, source); } source.SetExpectedOldObjectId(ObjectId.ZeroId); source.SetNewObjectId(objId); source.Update(rw); if (updateHEAD) { LinkHEAD(source); } return dst.GetResult(); } return RefUpdate.Result.RENAMED; } finally { // Always try to free the temporary name. try { refdb.Delete(tmp); } catch (IOException) { FileUtils.Delete(refdb.FileFor(tmp.GetName())); } rw.Release(); } }
internal RefDirectoryRename(RefDirectoryUpdate src, RefDirectoryUpdate dst) : base(src, dst) { refdb = ((RefDirectory)src.GetRefDatabase()); }
internal virtual void StoredSymbolicRef(RefDirectoryUpdate u, FileSnapshot snapshot , string target) { PutLooseRef(NewSymbolicRef(snapshot, u.GetRef().GetName(), target)); FireRefsChanged(); }