/// <summary>Write the given ref update to the ref's log</summary> /// <param name="update"></param> /// <param name="msg"></param> /// <param name="deref"></param> /// <returns>this writer</returns> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual NGit.Storage.File.ReflogWriter Log(RefUpdate update, string msg, bool deref) { ObjectId oldId = update.GetOldObjectId(); ObjectId newId = update.GetNewObjectId(); Ref @ref = update.GetRef(); PersonIdent ident = update.GetRefLogIdent(); if (ident == null) { ident = new PersonIdent(parent); } else { ident = new PersonIdent(ident); } byte[] rec = Encode(oldId, newId, ident, msg); if (deref && @ref.IsSymbolic()) { Log(@ref.GetName(), rec); Log(@ref.GetLeaf().GetName(), rec); } else { Log(@ref.GetName(), rec); } return(this); }
// TODO not implemented yet // TODO not implemented yet /// <summary> /// Executes the /// <code>Reset</code> /// command. Each instance of this class should /// only be used for one invocation of the command. Don't call this method /// twice on an instance. /// </summary> /// <returns>the Ref after reset</returns> /// <exception cref="System.IO.IOException"></exception> public override Ref Call() { CheckCallable(); Ref r; RevCommit commit; try { RepositoryState state = repo.GetRepositoryState(); bool merging = state.Equals(RepositoryState.MERGING) || state.Equals(RepositoryState .MERGING_RESOLVED); bool cherryPicking = state.Equals(RepositoryState.CHERRY_PICKING) || state.Equals (RepositoryState.CHERRY_PICKING_RESOLVED); // resolve the ref to a commit ObjectId commitId; try { commitId = repo.Resolve(@ref); } catch (IOException e) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().cannotRead, @ref ), e); } RevWalk rw = new RevWalk(repo); try { commit = rw.ParseCommit(commitId); } catch (IOException e) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().cannotReadCommit , commitId.ToString()), e); } finally { rw.Release(); } if (!filepaths.IsEmpty()) { // reset [commit] -- paths ResetIndexForPaths(commit); SetCallable(false); return(repo.GetRef(Constants.HEAD)); } // write the ref RefUpdate ru = repo.UpdateRef(Constants.HEAD); ru.SetNewObjectId(commitId); string refName = Repository.ShortenRefName(@ref); string message = refName + ": updating " + Constants.HEAD; //$NON-NLS-1$ ru.SetRefLogMessage(message, false); if (ru.ForceUpdate() == RefUpdate.Result.LOCK_FAILURE) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().cannotLock, ru .GetName())); } switch (mode) { case ResetCommand.ResetType.HARD: { CheckoutIndex(commit); break; } case ResetCommand.ResetType.MIXED: { ResetIndex(commit); break; } case ResetCommand.ResetType.SOFT: { // do nothing, only the ref was changed break; } case ResetCommand.ResetType.KEEP: case ResetCommand.ResetType.MERGE: { // TODO // TODO throw new NotSupportedException(); } } if (mode != ResetCommand.ResetType.SOFT) { if (merging) { ResetMerge(); } else { if (cherryPicking) { ResetCherryPick(); } } } SetCallable(false); r = ru.GetRef(); } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfResetCommand , e); } return(r); }
public static void HardReset(NGit.Repository repo, ObjectId newHead) { DirCache dc = null; try { // Reset head to upstream RefUpdate ru = repo.UpdateRef(Constants.HEAD); ru.SetNewObjectId(newHead); ru.SetForceUpdate(true); RefUpdate.Result rc = ru.Update(); switch (rc) { case RefUpdate.Result.NO_CHANGE: case RefUpdate.Result.NEW: case RefUpdate.Result.FAST_FORWARD: case RefUpdate.Result.FORCED: break; case RefUpdate.Result.REJECTED: case RefUpdate.Result.LOCK_FAILURE: throw new ConcurrentRefUpdateException(JGitText.Get().couldNotLockHEAD, ru.GetRef(), rc); default: throw new JGitInternalException("Reference update failed: " + rc); } dc = repo.LockDirCache(); RevWalk rw = new RevWalk(repo); RevCommit c = rw.ParseCommit(newHead); DirCacheCheckout checkout = new DirCacheCheckout(repo, null, dc, c.Tree); checkout.Checkout(); } catch { if (dc != null) { dc.Unlock(); } throw; } }
/// <exception cref="System.IO.IOException"></exception> /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException"></exception> private void UpdateHead(StringBuilder refLogMessage, ObjectId newHeadId, ObjectId oldHeadID) { RefUpdate refUpdate = repo.UpdateRef(Constants.HEAD); refUpdate.SetNewObjectId(newHeadId); refUpdate.SetRefLogMessage(refLogMessage.ToString(), false); refUpdate.SetExpectedOldObjectId(oldHeadID); RefUpdate.Result rc = refUpdate.Update(); switch (rc) { case RefUpdate.Result.NEW: case RefUpdate.Result.FAST_FORWARD: { return; } case RefUpdate.Result.REJECTED: case RefUpdate.Result.LOCK_FAILURE: { throw new ConcurrentRefUpdateException(JGitText.Get().couldNotLockHEAD, refUpdate .GetRef(), rc); } default: { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().updatingRefFailed , Constants.HEAD, newHeadId.ToString(), rc)); } } }
/// <summary> /// Executes the /// <code>commit</code> /// command with all the options and parameters /// collected by the setter methods of this class. Each instance of this /// class should only be used for one invocation of the command (means: one /// call to /// <see cref="Call()">Call()</see> /// ) /// </summary> /// <returns> /// a /// <see cref="NGit.Revwalk.RevCommit">NGit.Revwalk.RevCommit</see> /// object representing the successful commit. /// </returns> /// <exception cref="NGit.Api.Errors.NoHeadException">when called on a git repo without a HEAD reference /// </exception> /// <exception cref="NGit.Api.Errors.NoMessageException">when called without specifying a commit message /// </exception> /// <exception cref="NGit.Api.Errors.UnmergedPathsException">when the current index contained unmerged paths (conflicts) /// </exception> /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException"> /// when HEAD or branch ref is updated concurrently by someone /// else /// </exception> /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">when repository is not in the right state for committing /// </exception> /// <exception cref="NGit.Api.Errors.GitAPIException"></exception> public override RevCommit Call() { CheckCallable(); RepositoryState state = repo.GetRepositoryState(); if (!state.CanCommit()) { throw new WrongRepositoryStateException(MessageFormat.Format(JGitText.Get().cannotCommitOnARepoWithState , state.Name())); } ProcessOptions(state); try { if (all && !repo.IsBare && repo.WorkTree != null) { Git git = new Git(repo); try { git.Add().AddFilepattern(".").SetUpdate(true).Call(); } catch (NoFilepatternException e) { // should really not happen throw new JGitInternalException(e.Message, e); } } Ref head = repo.GetRef(Constants.HEAD); if (head == null) { throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported ); } // determine the current HEAD and the commit it is referring to ObjectId headId = repo.Resolve(Constants.HEAD + "^{commit}"); if (headId == null && amend) { throw new WrongRepositoryStateException(JGitText.Get().commitAmendOnInitialNotPossible ); } if (headId != null) { if (amend) { RevCommit previousCommit = new RevWalk(repo).ParseCommit(headId); RevCommit[] p = previousCommit.Parents; for (int i = 0; i < p.Length; i++) { parents.Add(0, p[i].Id); } if (author == null) { author = previousCommit.GetAuthorIdent(); } } else { parents.Add(0, headId); } } // lock the index DirCache index = repo.LockDirCache(); try { if (!only.IsEmpty()) { index = CreateTemporaryIndex(headId, index); } ObjectInserter odi = repo.NewObjectInserter(); try { // Write the index as tree to the object database. This may // fail for example when the index contains unmerged paths // (unresolved conflicts) ObjectId indexTreeId = index.WriteTree(odi); if (insertChangeId) { InsertChangeId(indexTreeId); } // Create a Commit object, populate it and write it NGit.CommitBuilder commit = new NGit.CommitBuilder(); commit.Committer = committer; commit.Author = author; commit.Message = message; commit.SetParentIds(parents); commit.TreeId = indexTreeId; ObjectId commitId = odi.Insert(commit); odi.Flush(); RevWalk revWalk = new RevWalk(repo); try { RevCommit revCommit = revWalk.ParseCommit(commitId); RefUpdate ru = repo.UpdateRef(Constants.HEAD); ru.SetNewObjectId(commitId); if (reflogComment != null) { ru.SetRefLogMessage(reflogComment, false); } else { string prefix = amend ? "commit (amend): " : "commit: "; ru.SetRefLogMessage(prefix + revCommit.GetShortMessage(), false); } if (headId != null) { ru.SetExpectedOldObjectId(headId); } else { ru.SetExpectedOldObjectId(ObjectId.ZeroId); } RefUpdate.Result rc = ru.ForceUpdate(); switch (rc) { case RefUpdate.Result.NEW: case RefUpdate.Result.FORCED: case RefUpdate.Result.FAST_FORWARD: { SetCallable(false); if (state == RepositoryState.MERGING_RESOLVED) { // Commit was successful. Now delete the files // used for merge commits repo.WriteMergeCommitMsg(null); repo.WriteMergeHeads(null); } else { if (state == RepositoryState.CHERRY_PICKING_RESOLVED) { repo.WriteMergeCommitMsg(null); repo.WriteCherryPickHead(null); } } return(revCommit); } case RefUpdate.Result.REJECTED: case RefUpdate.Result.LOCK_FAILURE: { throw new ConcurrentRefUpdateException(JGitText.Get().couldNotLockHEAD, ru.GetRef (), rc); } default: { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().updatingRefFailed , Constants.HEAD, commitId.ToString(), rc)); } } } finally { revWalk.Release(); } } finally { odi.Release(); } } finally { index.Unlock(); } } catch (UnmergedPathException e) { throw new UnmergedPathsException(e); } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfCommitCommand , e); } }
/// <summary> /// Executes the /// <code>tag</code> /// command with all the options and parameters /// collected by the setter methods of this class. Each instance of this /// class should only be used for one invocation of the command (means: one /// call to /// <see cref="Call()">Call()</see> /// ) /// </summary> /// <returns> /// a /// <see cref="NGit.Ref">NGit.Ref</see> /// a ref pointing to a tag /// </returns> /// <exception cref="NGit.Api.Errors.NoHeadException">when called on a git repo without a HEAD reference /// </exception> /// <since>2.0</since> /// <exception cref="NGit.Api.Errors.GitAPIException"></exception> /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException"></exception> /// <exception cref="NGit.Api.Errors.InvalidTagNameException"></exception> public override Ref Call() { CheckCallable(); RepositoryState state = repo.GetRepositoryState(); ProcessOptions(state); try { // create the tag object TagBuilder newTag = new TagBuilder(); newTag.SetTag(name); newTag.SetMessage(message); newTag.SetTagger(tagger); // if no id is set, we should attempt to use HEAD if (id == null) { ObjectId objectId = repo.Resolve(Constants.HEAD + "^{commit}"); if (objectId == null) { throw new NoHeadException(JGitText.Get().tagOnRepoWithoutHEADCurrentlyNotSupported ); } newTag.SetObjectId(objectId, Constants.OBJ_COMMIT); } else { newTag.SetObjectId(id); } // write the tag object ObjectInserter inserter = repo.NewObjectInserter(); try { ObjectId tagId = inserter.Insert(newTag); inserter.Flush(); RevWalk revWalk = new RevWalk(repo); try { string refName = Constants.R_TAGS + newTag.GetTag(); RefUpdate tagRef = repo.UpdateRef(refName); tagRef.SetNewObjectId(tagId); tagRef.SetForceUpdate(forceUpdate); tagRef.SetRefLogMessage("tagged " + name, false); RefUpdate.Result updateResult = tagRef.Update(revWalk); switch (updateResult) { case RefUpdate.Result.NEW: case RefUpdate.Result.FORCED: { return(repo.GetRef(refName)); } case RefUpdate.Result.LOCK_FAILURE: { throw new ConcurrentRefUpdateException(JGitText.Get().couldNotLockHEAD, tagRef.GetRef (), updateResult); } default: { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().updatingRefFailed , refName, newTag.ToString(), updateResult)); } } } finally { revWalk.Release(); } } finally { inserter.Release(); } } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfTagCommand , e); } }