/// <summary> /// Executes the /// <code>push</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> /// an iteration over /// <see cref="NGit.Transport.PushResult">NGit.Transport.PushResult</see> /// objects /// </returns> /// <exception cref="NGit.Api.Errors.InvalidRemoteException">when called with an invalid remote uri /// </exception> /// <exception cref="NGit.Api.Errors.JGitInternalException"> /// a low-level exception of JGit has occurred. The original /// exception can be retrieved by calling /// <see cref="System.Exception.InnerException()">System.Exception.InnerException()</see> /// . /// </exception> public override Iterable <PushResult> Call() { CheckCallable(); AList <PushResult> pushResults = new AList <PushResult>(3); try { if (force) { IList <RefSpec> orig = new AList <RefSpec>(refSpecs); refSpecs.Clear(); foreach (RefSpec spec in orig) { refSpecs.AddItem(spec.SetForceUpdate(true)); } } IList <NGit.Transport.Transport> transports; transports = NGit.Transport.Transport.OpenAll(repo, remote, NGit.Transport.Transport.Operation.PUSH ); foreach (NGit.Transport.Transport transport in transports) { if (0 <= timeout) { transport.SetTimeout(timeout); } transport.SetPushThin(thin); if (receivePack != null) { transport.SetOptionReceivePack(receivePack); } transport.SetDryRun(dryRun); if (credentialsProvider != null) { transport.SetCredentialsProvider(credentialsProvider); } ICollection <RemoteRefUpdate> toPush = transport.FindRemoteRefUpdatesFor(refSpecs); try { PushResult result = transport.Push(monitor, toPush); pushResults.AddItem(result); } catch (TransportException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPushCommand , e); } finally { transport.Close(); } } } catch (URISyntaxException) { throw new InvalidRemoteException(MessageFormat.Format(JGitText.Get().invalidRemote , remote)); } catch (NotSupportedException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPushCommand , e); } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPushCommand , e); } return(pushResults.AsIterable()); }
/// <exception cref="NGit.Api.Errors.RefNotFoundException"></exception> /// <exception cref="System.IO.IOException"></exception> /// <exception cref="NGit.Api.Errors.NoHeadException"></exception> /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception> private RebaseResult InitFilesAndRewind() { // we need to store everything into files so that we can implement // --skip, --continue, and --abort // first of all, we determine the commits to be applied IList <RevCommit> cherryPickList = new AList <RevCommit>(); Ref head = repo.GetRef(Constants.HEAD); if (head == null || head.GetObjectId() == null) { throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved , Constants.HEAD)); } string headName; if (head.IsSymbolic()) { headName = head.GetTarget().GetName(); } else { headName = "detached HEAD"; } ObjectId headId = head.GetObjectId(); if (headId == null) { throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved , Constants.HEAD)); } RevCommit headCommit = walk.LookupCommit(headId); monitor.BeginTask(JGitText.Get().obtainingCommitsForCherryPick, ProgressMonitor.UNKNOWN ); LogCommand cmd = new Git(repo).Log().AddRange(upstreamCommit, headCommit); Iterable <RevCommit> commitsToUse = cmd.Call(); foreach (RevCommit commit in commitsToUse) { cherryPickList.AddItem(commit); } // if the upstream commit is in a direct line to the current head, // the log command will not report any commits; in this case, // we create the cherry-pick list ourselves if (cherryPickList.IsEmpty()) { Iterable <RevCommit> parents = new Git(repo).Log().Add(upstreamCommit).Call(); foreach (RevCommit parent in parents) { if (parent.Equals(headCommit)) { break; } if (parent.ParentCount != 1) { throw new JGitInternalException(JGitText.Get().canOnlyCherryPickCommitsWithOneParent ); } cherryPickList.AddItem(parent); } } // nothing to do: return with UP_TO_DATE_RESULT if (cherryPickList.IsEmpty()) { return(RebaseResult.UP_TO_DATE_RESULT); } Sharpen.Collections.Reverse(cherryPickList); // create the folder for the meta information FileUtils.Mkdir(rebaseDir); CreateFile(repo.Directory, Constants.ORIG_HEAD, headId.Name); CreateFile(rebaseDir, REBASE_HEAD, headId.Name); CreateFile(rebaseDir, HEAD_NAME, headName); CreateFile(rebaseDir, ONTO, upstreamCommit.Name); CreateFile(rebaseDir, INTERACTIVE, string.Empty); BufferedWriter fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream (new FilePath(rebaseDir, GIT_REBASE_TODO)), Constants.CHARACTER_ENCODING)); fw.Write("# Created by EGit: rebasing " + upstreamCommit.Name + " onto " + headId .Name); fw.NewLine(); try { StringBuilder sb = new StringBuilder(); ObjectReader reader = walk.GetObjectReader(); foreach (RevCommit commit_1 in cherryPickList) { sb.Length = 0; sb.Append(RebaseCommand.Action.PICK.ToToken()); sb.Append(" "); sb.Append(reader.Abbreviate(commit_1).Name); sb.Append(" "); sb.Append(commit_1.GetShortMessage()); fw.Write(sb.ToString()); fw.NewLine(); } } finally { fw.Close(); } monitor.EndTask(); // we rewind to the upstream commit monitor.BeginTask(MessageFormat.Format(JGitText.Get().rewinding, upstreamCommit.GetShortMessage ()), ProgressMonitor.UNKNOWN); CheckoutCommit(upstreamCommit); monitor.EndTask(); return(null); }
/// <summary> /// Construct a NotesMergeConflictException for the specified base, ours and /// theirs note versions. /// </summary> /// <remarks> /// Construct a NotesMergeConflictException for the specified base, ours and /// theirs note versions. /// </remarks> /// <param name="base">note version</param> /// <param name="ours">note version</param> /// <param name="theirs">note version</param> public NotesMergeConflictException(Note @base, Note ours, Note theirs) : base(MessageFormat .Format(JGitText.Get().mergeConflictOnNotes, NoteOn(@base, ours, theirs), NoteData (@base), NoteData(ours), NoteData(theirs))) { }
/// <exception cref="NGit.Api.Errors.RefAlreadyExistsException"> /// when trying to create (without force) a branch with a name /// that already exists /// </exception> /// <exception cref="NGit.Api.Errors.RefNotFoundException">if the start point or branch can not be found /// </exception> /// <exception cref="NGit.Api.Errors.InvalidRefNameException"> /// if the provided name is <code>null</code> or otherwise /// invalid /// </exception> /// <returns>the newly created branch</returns> /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception> public override Ref Call() { CheckCallable(); ProcessOptions(); try { if (createBranch) { Git git = new Git(repo); CreateBranchCommand command = git.BranchCreate(); command.SetName(name); command.SetStartPoint(GetStartPoint().Name); if (upstreamMode != null) { command.SetUpstreamMode(upstreamMode); } command.Call(); } Ref headRef = repo.GetRef(Constants.HEAD); string refLogMessage = "checkout: moving from " + headRef.GetTarget().GetName(); ObjectId branch = repo.Resolve(name); if (branch == null) { throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved , name)); } RevWalk revWalk = new RevWalk(repo); AnyObjectId headId = headRef.GetObjectId(); RevCommit headCommit = headId == null ? null : revWalk.ParseCommit(headId); RevCommit newCommit = revWalk.ParseCommit(branch); RevTree headTree = headCommit == null ? null : headCommit.Tree; DirCacheCheckout dco = new DirCacheCheckout(repo, headTree, repo.LockDirCache(), newCommit.Tree); dco.SetFailOnConflict(true); try { dco.Checkout(); } catch (NGit.Errors.CheckoutConflictException e) { status = new CheckoutResult(CheckoutResult.Status.CONFLICTS, dco.GetConflicts()); throw; } Ref @ref = repo.GetRef(name); if (@ref != null && [email protected]().StartsWith(Constants.R_HEADS)) { @ref = null; } RefUpdate refUpdate = repo.UpdateRef(Constants.HEAD, @ref == null); refUpdate.SetForceUpdate(force); refUpdate.SetRefLogMessage(refLogMessage + " to " + newCommit.GetName(), false); RefUpdate.Result updateResult; if (@ref != null) { updateResult = refUpdate.Link(@ref.GetName()); } else { refUpdate.SetNewObjectId(newCommit); updateResult = refUpdate.ForceUpdate(); } SetCallable(false); bool ok = false; switch (updateResult) { case RefUpdate.Result.NEW: { ok = true; break; } case RefUpdate.Result.NO_CHANGE: case RefUpdate.Result.FAST_FORWARD: case RefUpdate.Result.FORCED: { ok = true; break; } default: { break; break; } } if (!ok) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().checkoutUnexpectedResult , updateResult.ToString())); } if (!dco.GetToBeDeleted().IsEmpty()) { status = new CheckoutResult(CheckoutResult.Status.NONDELETED, dco.GetToBeDeleted( )); } else { status = CheckoutResult.OK_RESULT; } return(@ref); } catch (IOException ioe) { throw new JGitInternalException(ioe.Message, ioe); } finally { if (status == null) { status = CheckoutResult.ERROR_RESULT; } } }
/// <summary> /// Executes the /// <code>revert</code> /// command with all the options and parameters /// collected by the setter methods (e.g. /// <see cref="Include(NGit.Ref)">Include(NGit.Ref)</see> /// of this /// class. 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> /// on success the /// <see cref="NGit.Revwalk.RevCommit">NGit.Revwalk.RevCommit</see> /// pointed to by the new HEAD is /// returned. If a failure occurred during revert <code>null</code> /// is returned. The list of successfully reverted /// <see cref="NGit.Ref">NGit.Ref</see> /// 's can /// be obtained by calling /// <see cref="GetRevertedRefs()">GetRevertedRefs()</see> /// </returns> /// <exception cref="NGit.Api.Errors.GitAPIException"></exception> public override RevCommit Call() { RevCommit newHead = null; CheckCallable(); RevWalk revWalk = new RevWalk(repo); try { // get the head commit Ref headRef = repo.GetRef(Constants.HEAD); if (headRef == null) { throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported ); } RevCommit headCommit = revWalk.ParseCommit(headRef.GetObjectId()); newHead = headCommit; // loop through all refs to be reverted foreach (Ref src in commits) { // get the commit to be reverted // handle annotated tags ObjectId srcObjectId = src.GetPeeledObjectId(); if (srcObjectId == null) { srcObjectId = src.GetObjectId(); } RevCommit srcCommit = revWalk.ParseCommit(srcObjectId); // get the parent of the commit to revert if (srcCommit.ParentCount != 1) { throw new MultipleParentsNotAllowedException(JGitText.Get().canOnlyRevertCommitsWithOneParent ); } RevCommit srcParent = srcCommit.GetParent(0); revWalk.ParseHeaders(srcParent); ResolveMerger merger = (ResolveMerger)((ThreeWayMerger)MergeStrategy.RESOLVE.NewMerger (repo)); merger.SetWorkingTreeIterator(new FileTreeIterator(repo)); merger.SetBase(srcCommit.Tree); if (merger.Merge(headCommit, srcParent)) { if (AnyObjectId.Equals(headCommit.Tree.Id, merger.GetResultTreeId())) { continue; } DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache (), merger.GetResultTreeId()); dco.SetFailOnConflict(true); dco.Checkout(); string newMessage = "Revert \"" + srcCommit.GetShortMessage() + "\"" + "\n\n" + "This reverts commit " + srcCommit.Id.GetName() + "\n"; newHead = new Git(GetRepository()).Commit().SetMessage(newMessage).Call(); revertedRefs.AddItem(src); } else { return(null); } } } catch (IOException e) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionCaughtDuringExecutionOfRevertCommand , e), e); } finally { revWalk.Release(); } return(newHead); }
/// <summary> /// Construct an EntryExistsException when the specified name already /// exists in a tree. /// </summary> /// <remarks> /// Construct an EntryExistsException when the specified name already /// exists in a tree. /// </remarks> /// <param name="name">workdir relative file name</param> public EntryExistsException(string name) : base(MessageFormat.Format(JGitText.Get ().treeEntryAlreadyExists, name)) { }
/// <exception cref="System.IO.IOException"></exception> private ObjectId ProcessHaveLines(IList <ObjectId> peerHas, ObjectId last) { if (peerHas.IsEmpty()) { return(last); } IList <ObjectId> toParse = peerHas; HashSet <ObjectId> peerHasSet = null; bool needMissing = false; if (wantAll.IsEmpty() && !wantIds.IsEmpty()) { // We have not yet parsed the want list. Parse it now. peerHasSet = new HashSet <ObjectId>(peerHas); int cnt = wantIds.Count + peerHasSet.Count; toParse = new AList <ObjectId>(cnt); Sharpen.Collections.AddAll(toParse, wantIds); Sharpen.Collections.AddAll(toParse, peerHasSet); needMissing = true; } AsyncRevObjectQueue q = walk.ParseAny(toParse.AsIterable(), needMissing); try { for (; ;) { RevObject obj; try { obj = q.Next(); } catch (MissingObjectException notFound) { ObjectId id = notFound.GetObjectId(); if (wantIds.Contains(id)) { string msg = MessageFormat.Format(JGitText.Get().wantNotValid, id.Name); pckOut.WriteString("ERR " + msg); throw new PackProtocolException(msg, notFound); } continue; } if (obj == null) { break; } // If the object is still found in wantIds, the want // list wasn't parsed earlier, and was done in this batch. // if (wantIds.Remove(obj)) { if (!advertised.Contains(obj)) { string msg = MessageFormat.Format(JGitText.Get().wantNotValid, obj.Name); pckOut.WriteString("ERR " + msg); throw new PackProtocolException(msg); } if (!obj.Has(WANT)) { obj.Add(WANT); wantAll.AddItem(obj); } if (!(obj is RevCommit)) { obj.Add(SATISFIED); } if (obj is RevTag) { RevObject target = walk.Peel(obj); if (target is RevCommit) { if (!target.Has(WANT)) { target.Add(WANT); wantAll.AddItem(target); } } } if (!peerHasSet.Contains(obj)) { continue; } } last = obj; if (obj is RevCommit) { RevCommit c = (RevCommit)obj; if (oldestTime == 0 || c.CommitTime < oldestTime) { oldestTime = c.CommitTime; } } if (obj.Has(PEER_HAS)) { continue; } obj.Add(PEER_HAS); if (obj is RevCommit) { ((RevCommit)obj).Carry(PEER_HAS); } AddCommonBase(obj); switch (multiAck) { case BasePackFetchConnection.MultiAck.OFF: { // If both sides have the same object; let the client know. // if (commonBase.Count == 1) { pckOut.WriteString("ACK " + obj.Name + "\n"); } break; } case BasePackFetchConnection.MultiAck.CONTINUE: { pckOut.WriteString("ACK " + obj.Name + " continue\n"); break; } case BasePackFetchConnection.MultiAck.DETAILED: { pckOut.WriteString("ACK " + obj.Name + " common\n"); break; } } } } finally { q.Release(); } // If we don't have one of the objects but we're also willing to // create a pack at this point, let the client know so it stops // telling us about its history. // bool didOkToGiveUp = false; for (int i = peerHas.Count - 1; i >= 0; i--) { ObjectId id = peerHas[i]; if (walk.LookupOrNull(id) == null) { didOkToGiveUp = true; if (OkToGiveUp()) { switch (multiAck) { case BasePackFetchConnection.MultiAck.OFF: { break; } case BasePackFetchConnection.MultiAck.CONTINUE: { pckOut.WriteString("ACK " + id.Name + " continue\n"); break; } case BasePackFetchConnection.MultiAck.DETAILED: { pckOut.WriteString("ACK " + id.Name + " ready\n"); break; } } } break; } } if (multiAck == BasePackFetchConnection.MultiAck.DETAILED && !didOkToGiveUp && OkToGiveUp ()) { ObjectId id = peerHas[peerHas.Count - 1]; pckOut.WriteString("ACK " + id.Name + " ready\n"); } peerHas.Clear(); return(last); }
private PackProtocolException DuplicateAdvertisement(string name) { return(new PackProtocolException(transport.uri, MessageFormat.Format(JGitText.Get ().duplicateAdvertisementsOf, name))); }
/// <exception cref="NGit.Errors.TransportException"></exception> private void VerifyPrerequisites() { if (prereqs.IsEmpty()) { return; } RevWalk rw = new RevWalk(transport.local); try { RevFlag PREREQ = rw.NewFlag("PREREQ"); RevFlag SEEN = rw.NewFlag("SEEN"); IDictionary <ObjectId, string> missing = new Dictionary <ObjectId, string>(); IList <RevObject> commits = new AList <RevObject>(); foreach (KeyValuePair <ObjectId, string> e in prereqs.EntrySet()) { ObjectId p = e.Key; try { RevCommit c = rw.ParseCommit(p); if (!c.Has(PREREQ)) { c.Add(PREREQ); commits.AddItem(c); } } catch (MissingObjectException) { missing.Put(p, e.Value); } catch (IOException err) { throw new TransportException(transport.uri, MessageFormat.Format(JGitText.Get().cannotReadCommit , p.Name), err); } } if (!missing.IsEmpty()) { throw new MissingBundlePrerequisiteException(transport.uri, missing); } foreach (Ref r in transport.local.GetAllRefs().Values) { try { rw.MarkStart(rw.ParseCommit(r.GetObjectId())); } catch (IOException) { } } // If we cannot read the value of the ref skip it. int remaining = commits.Count; try { RevCommit c; while ((c = rw.Next()) != null) { if (c.Has(PREREQ)) { c.Add(SEEN); if (--remaining == 0) { break; } } } } catch (IOException err) { throw new TransportException(transport.uri, JGitText.Get().cannotReadObject, err); } if (remaining > 0) { foreach (RevObject o in commits) { if (!o.Has(SEEN)) { missing.Put(o, prereqs.Get(o)); } } throw new MissingBundlePrerequisiteException(transport.uri, missing); } } finally { rw.Release(); } }
/// <exception cref="System.IO.IOException"></exception> private void ReadStatusReport(IDictionary <string, RemoteRefUpdate> refUpdates) { string unpackLine = ReadStringLongTimeout(); if (!unpackLine.StartsWith("unpack ")) { throw new PackProtocolException(uri, MessageFormat.Format(JGitText.Get().unexpectedReportLine , unpackLine)); } string unpackStatus = Sharpen.Runtime.Substring(unpackLine, "unpack ".Length); if (!unpackStatus.Equals("ok")) { throw new TransportException(uri, MessageFormat.Format(JGitText.Get().errorOccurredDuringUnpackingOnTheRemoteEnd , unpackStatus)); } string refLine; while ((refLine = pckIn.ReadString()) != PacketLineIn.END) { bool ok = false; int refNameEnd = -1; if (refLine.StartsWith("ok ")) { ok = true; refNameEnd = refLine.Length; } else { if (refLine.StartsWith("ng ")) { ok = false; refNameEnd = refLine.IndexOf(" ", 3); } } if (refNameEnd == -1) { throw new PackProtocolException(MessageFormat.Format(JGitText.Get().unexpectedReportLine2 , uri, refLine)); } string refName = Sharpen.Runtime.Substring(refLine, 3, refNameEnd); string message = (ok ? null : Sharpen.Runtime.Substring(refLine, refNameEnd + 1)); RemoteRefUpdate rru = refUpdates.Get(refName); if (rru == null) { throw new PackProtocolException(MessageFormat.Format(JGitText.Get().unexpectedRefReport , uri, refName)); } if (ok) { rru.SetStatus(RemoteRefUpdate.Status.OK); } else { rru.SetStatus(RemoteRefUpdate.Status.REJECTED_OTHER_REASON); rru.SetMessage(message); } } foreach (RemoteRefUpdate rru_1 in refUpdates.Values) { if (rru_1.GetStatus() == RemoteRefUpdate.Status.AWAITING_REPORT) { throw new PackProtocolException(MessageFormat.Format(JGitText.Get().expectedReportForRefNotReceived , uri, rru_1.GetRemoteName())); } } }
internal virtual int ParseBody(NGit.Patch.Patch script, int end) { byte[] buf = file.buf; int c = RawParseUtils.NextLF(buf, startOffset); int last = c; old.nDeleted = 0; old.nAdded = 0; for (; c < end; last = c, c = RawParseUtils.NextLF(buf, c)) { switch (buf[c]) { case (byte)(' '): case (byte)('\n'): { nContext++; continue; goto case (byte)('-'); } case (byte)('-'): { old.nDeleted++; continue; goto case (byte)('+'); } case (byte)('+'): { old.nAdded++; continue; goto case (byte)('\\'); } case (byte)('\\'): { // Matches "\ No newline at end of file" continue; goto default; } default: { goto SCAN_break; break; } } SCAN_continue :; } SCAN_break :; if (last < end && nContext + old.nDeleted - 1 == old.lineCount && nContext + old. nAdded == newLineCount && RawParseUtils.Match(buf, last, NGit.Patch.Patch.SIG_FOOTER ) >= 0) { // This is an extremely common occurrence of "corruption". // Users add footers with their signatures after this mark, // and git diff adds the git executable version number. // Let it slide; the hunk otherwise looked sound. // old.nDeleted--; return(last); } if (nContext + old.nDeleted < old.lineCount) { int missingCount = old.lineCount - (nContext + old.nDeleted); script.Error(buf, startOffset, MessageFormat.Format(JGitText.Get().truncatedHunkOldLinesMissing , missingCount)); } else { if (nContext + old.nAdded < newLineCount) { int missingCount = newLineCount - (nContext + old.nAdded); script.Error(buf, startOffset, MessageFormat.Format(JGitText.Get().truncatedHunkNewLinesMissing , missingCount)); } else { if (nContext + old.nDeleted > old.lineCount || nContext + old.nAdded > newLineCount) { string oldcnt = old.lineCount + ":" + newLineCount; string newcnt = (nContext + old.nDeleted) + ":" + (nContext + old.nAdded); script.Warn(buf, startOffset, MessageFormat.Format(JGitText.Get().hunkHeaderDoesNotMatchBodyLineCountOf , oldcnt, newcnt)); } } } return(c); }
/// <param name="path"></param> public InvalidPathException(string path) : base(MessageFormat.Format(JGitText.Get ().invalidPath, path)) { }
/// <summary>Create a new unmerged path exception.</summary> /// <remarks>Create a new unmerged path exception.</remarks> /// <param name="dce">the first non-zero stage of the unmerged path.</param> public UnmergedPathException(DirCacheEntry dce) : base(MessageFormat.Format(JGitText .Get().unmergedPath, dce.PathString)) { entry = dce; }
/// <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); } }
/// <summary>Construct a MissingObjectException for the specified object id.</summary> /// <remarks> /// Construct a MissingObjectException for the specified object id. Expected /// type is reported to simplify tracking down the problem. /// </remarks> /// <param name="id">SHA-1</param> /// <param name="type">object type</param> public MissingObjectException(AbbreviatedObjectId id, int type) : base(MessageFormat .Format(JGitText.Get().missingObject, Constants.TypeString(type), id.Name)) { missing = null; }
/// <summary> /// Executes the /// <code>push</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> /// an iteration over /// <see cref="NGit.Transport.PushResult">NGit.Transport.PushResult</see> /// objects /// </returns> /// <exception cref="NGit.Api.Errors.InvalidRemoteException">when called with an invalid remote uri /// </exception> /// <exception cref="NGit.Api.Errors.TransportException">when an error occurs with the transport /// </exception> /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException /// </exception> public override Iterable <PushResult> Call() { CheckCallable(); AList <PushResult> pushResults = new AList <PushResult>(3); try { if (refSpecs.IsEmpty()) { RemoteConfig config = new RemoteConfig(repo.GetConfig(), GetRemote()); Sharpen.Collections.AddAll(refSpecs, config.PushRefSpecs); } if (refSpecs.IsEmpty()) { Ref head = repo.GetRef(Constants.HEAD); if (head != null && head.IsSymbolic()) { refSpecs.AddItem(new RefSpec(head.GetLeaf().GetName())); } } if (force) { for (int i = 0; i < refSpecs.Count; i++) { refSpecs.Set(i, refSpecs[i].SetForceUpdate(true)); } } IList <NGit.Transport.Transport> transports; transports = NGit.Transport.Transport.OpenAll(repo, remote, NGit.Transport.Transport.Operation.PUSH ); foreach (NGit.Transport.Transport transport in transports) { transport.SetPushThin(thin); if (receivePack != null) { transport.SetOptionReceivePack(receivePack); } transport.SetDryRun(dryRun); Configure(transport); ICollection <RemoteRefUpdate> toPush = transport.FindRemoteRefUpdatesFor(refSpecs); try { PushResult result = transport.Push(monitor, toPush); pushResults.AddItem(result); } catch (NGit.Errors.TransportException e) { throw new NGit.Errors.TransportException(e.Message, e); } finally { transport.Close(); } } } catch (URISyntaxException) { throw new InvalidRemoteException(MessageFormat.Format(JGitText.Get().invalidRemote , remote)); } catch (NGit.Errors.NotSupportedException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPushCommand , e); } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPushCommand , e); } return(pushResults.AsIterable()); }
// 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="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException /// </exception> /// <exception cref="NGit.Api.Errors.CheckoutConflictException"></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 + "^{commit}"); if (commitId == null) { // @TODO throw an InvalidRefNameException. We can't do that // now because this would break the API throw new JGitInternalException("Invalid ref " + @ref + " specified"); } } 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())); } ObjectId origHead = ru.GetOldObjectId(); if (origHead != null) { repo.WriteOrigHead(origHead); } 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(); } else { if (repo.ReadSquashCommitMsg() != null) { repo.WriteSquashCommitMsg(null); } } } } SetCallable(false); r = ru.GetRef(); } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfResetCommand , e); } return(r); }
private static string CreateRandomImageUrl() => MessageFormat.Format("https://lorempixel.com/{0}/{1}/", new Random().Next(400) + 200, new Random().Next(200) + 400);
/// <exception cref="System.IO.IOException"></exception> private bool Negotiate() { okToGiveUp = false; ObjectId last = ObjectId.ZeroId; IList <ObjectId> peerHas = new AList <ObjectId>(64); for (; ;) { string line; try { line = pckIn.ReadString(); } catch (EOFException eof) { throw; } if (line == PacketLineIn.END) { last = ProcessHaveLines(peerHas, last); if (commonBase.IsEmpty() || multiAck != BasePackFetchConnection.MultiAck.OFF) { pckOut.WriteString("NAK\n"); } if (!biDirectionalPipe) { return(false); } pckOut.Flush(); } else { if (line.StartsWith("have ") && line.Length == 45) { peerHas.AddItem(ObjectId.FromString(Sharpen.Runtime.Substring(line, 5))); } else { if (line.Equals("done")) { last = ProcessHaveLines(peerHas, last); if (commonBase.IsEmpty()) { pckOut.WriteString("NAK\n"); } else { if (multiAck != BasePackFetchConnection.MultiAck.OFF) { pckOut.WriteString("ACK " + last.Name + "\n"); } } return(true); } else { throw new PackProtocolException(MessageFormat.Format(JGitText.Get().expectedGot, "have", line)); } } } } }
/// <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>Merge</code> /// command with all the options and parameters /// collected by the setter methods (e.g. /// <see cref="Include(NGit.Ref)">Include(NGit.Ref)</see> /// ) of this /// class. 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 result of the merge</returns> /// <exception cref="NGit.Api.Errors.NoHeadException"></exception> /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException"></exception> /// <exception cref="NGit.Api.Errors.CheckoutConflictException"></exception> /// <exception cref="NGit.Api.Errors.InvalidMergeHeadsException"></exception> /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException"></exception> /// <exception cref="NGit.Api.Errors.NoMessageException"></exception> public override MergeCommandResult Call() { CheckCallable(); if (commits.Count != 1) { throw new InvalidMergeHeadsException(commits.IsEmpty() ? JGitText.Get().noMergeHeadSpecified : MessageFormat.Format(JGitText.Get().mergeStrategyDoesNotSupportHeads, mergeStrategy .GetName(), Sharpen.Extensions.ValueOf(commits.Count))); } RevWalk revWalk = null; try { Ref head = repo.GetRef(Constants.HEAD); if (head == null) { throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported ); } StringBuilder refLogMessage = new StringBuilder("merge "); // Check for FAST_FORWARD, ALREADY_UP_TO_DATE revWalk = new RevWalk(repo); // we know for now there is only one commit Ref @ref = commits[0]; refLogMessage.Append(@ref.GetName()); // handle annotated tags ObjectId objectId = @ref.GetPeeledObjectId(); if (objectId == null) { objectId = @ref.GetObjectId(); } RevCommit srcCommit = revWalk.LookupCommit(objectId); ObjectId headId = head.GetObjectId(); if (headId == null) { revWalk.ParseHeaders(srcCommit); DirCacheCheckout dco = new DirCacheCheckout(repo, repo.LockDirCache(), srcCommit. Tree); dco.SetFailOnConflict(true); dco.Checkout(); RefUpdate refUpdate = repo.UpdateRef(head.GetTarget().GetName()); refUpdate.SetNewObjectId(objectId); refUpdate.SetExpectedOldObjectId(null); refUpdate.SetRefLogMessage("initial pull", false); if (refUpdate.Update() != RefUpdate.Result.NEW) { throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported ); } SetCallable(false); return(new MergeCommandResult(srcCommit, srcCommit, new ObjectId[] { null, srcCommit }, MergeStatus.FAST_FORWARD, mergeStrategy, null, null)); } RevCommit headCommit = revWalk.LookupCommit(headId); if (revWalk.IsMergedInto(srcCommit, headCommit)) { SetCallable(false); return(new MergeCommandResult(headCommit, srcCommit, new ObjectId[] { headCommit, srcCommit }, MergeStatus.ALREADY_UP_TO_DATE, mergeStrategy, null, null)); } else { if (revWalk.IsMergedInto(headCommit, srcCommit)) { // FAST_FORWARD detected: skip doing a real merge but only // update HEAD refLogMessage.Append(": " + MergeStatus.FAST_FORWARD); DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache (), srcCommit.Tree); dco.SetFailOnConflict(true); dco.Checkout(); UpdateHead(refLogMessage, srcCommit, headId); SetCallable(false); return(new MergeCommandResult(srcCommit, srcCommit, new ObjectId[] { headCommit, srcCommit }, MergeStatus.FAST_FORWARD, mergeStrategy, null, null)); } else { repo.WriteMergeCommitMsg(new MergeMessageFormatter().Format(commits, head)); repo.WriteMergeHeads(Arrays.AsList(@ref.GetObjectId())); ThreeWayMerger merger = (ThreeWayMerger)mergeStrategy.NewMerger(repo); bool noProblems; IDictionary <string, MergeResult <NGit.Diff.Sequence> > lowLevelResults = null; IDictionary <string, ResolveMerger.MergeFailureReason> failingPaths = null; if (merger is ResolveMerger) { ResolveMerger resolveMerger = (ResolveMerger)merger; resolveMerger.SetCommitNames(new string[] { "BASE", "HEAD", @ref.GetName() }); resolveMerger.SetWorkingTreeIterator(new FileTreeIterator(repo)); noProblems = merger.Merge(headCommit, srcCommit); lowLevelResults = resolveMerger.GetMergeResults(); failingPaths = resolveMerger.GetFailingPaths(); } else { noProblems = merger.Merge(headCommit, srcCommit); } if (noProblems) { DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache (), merger.GetResultTreeId()); dco.SetFailOnConflict(true); dco.Checkout(); RevCommit newHead = new Git(GetRepository()).Commit().Call(); return(new MergeCommandResult(newHead.Id, null, new ObjectId[] { headCommit.Id, srcCommit .Id }, MergeStatus.MERGED, mergeStrategy, null, null)); } else { if (failingPaths != null) { repo.WriteMergeCommitMsg(null); repo.WriteMergeHeads(null); return(new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] { headCommit.Id, srcCommit.Id }, MergeStatus.FAILED, mergeStrategy, lowLevelResults , null)); } else { return(new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] { headCommit.Id, srcCommit.Id }, MergeStatus.CONFLICTING, mergeStrategy, lowLevelResults , null)); } } } } } catch (IOException e) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionCaughtDuringExecutionOfMergeCommand , e), e); } finally { if (revWalk != null) { revWalk.Release(); } } }
/// <exception cref="System.IO.IOException"></exception> private DirCache CreateTemporaryIndex(ObjectId headId, DirCache index) { ObjectInserter inserter = null; // get DirCacheEditor to modify the index if required DirCacheEditor dcEditor = index.Editor(); // get DirCacheBuilder for newly created in-core index to build a // temporary index for this commit DirCache inCoreIndex = DirCache.NewInCore(); DirCacheBuilder dcBuilder = inCoreIndex.Builder(); onlyProcessed = new bool[only.Count]; bool emptyCommit = true; TreeWalk treeWalk = new TreeWalk(repo); int dcIdx = treeWalk.AddTree(new DirCacheIterator(index)); int fIdx = treeWalk.AddTree(new FileTreeIterator(repo)); int hIdx = -1; if (headId != null) { hIdx = treeWalk.AddTree(new RevWalk(repo).ParseTree(headId)); } treeWalk.Recursive = true; while (treeWalk.Next()) { string path = treeWalk.PathString; // check if current entry's path matches a specified path int pos = LookupOnly(path); CanonicalTreeParser hTree = null; if (hIdx != -1) { hTree = treeWalk.GetTree <CanonicalTreeParser>(hIdx); } if (pos >= 0) { // include entry in commit DirCacheIterator dcTree = treeWalk.GetTree <DirCacheIterator>(dcIdx); FileTreeIterator fTree = treeWalk.GetTree <FileTreeIterator>(fIdx); // check if entry refers to a tracked file bool tracked = dcTree != null || hTree != null; if (!tracked) { break; } if (fTree != null) { // create a new DirCacheEntry with data retrieved from disk DirCacheEntry dcEntry = new DirCacheEntry(path); long entryLength = fTree.GetEntryLength(); dcEntry.SetLength(entryLength); dcEntry.LastModified = fTree.GetEntryLastModified(); dcEntry.FileMode = fTree.GetIndexFileMode(dcTree); bool objectExists = (dcTree != null && fTree.IdEqual(dcTree)) || (hTree != null && fTree.IdEqual(hTree)); if (objectExists) { dcEntry.SetObjectId(fTree.EntryObjectId); } else { if (FileMode.GITLINK.Equals(dcEntry.FileMode)) { dcEntry.SetObjectId(fTree.EntryObjectId); } else { // insert object if (inserter == null) { inserter = repo.NewObjectInserter(); } long contentLength = fTree.GetEntryContentLength(); InputStream inputStream = fTree.OpenEntryStream(); try { dcEntry.SetObjectId(inserter.Insert(Constants.OBJ_BLOB, contentLength, inputStream )); } finally { inputStream.Close(); } } } // update index dcEditor.Add(new _PathEdit_375(dcEntry, path)); // add to temporary in-core index dcBuilder.Add(dcEntry); if (emptyCommit && (hTree == null || !hTree.IdEqual(fTree) || hTree.EntryRawMode != fTree.EntryRawMode)) { // this is a change emptyCommit = false; } } else { // if no file exists on disk, remove entry from index and // don't add it to temporary in-core index dcEditor.Add(new DirCacheEditor.DeletePath(path)); if (emptyCommit && hTree != null) { // this is a change emptyCommit = false; } } // keep track of processed path onlyProcessed[pos] = true; } else { // add entries from HEAD for all other paths if (hTree != null) { // create a new DirCacheEntry with data retrieved from HEAD DirCacheEntry dcEntry = new DirCacheEntry(path); dcEntry.SetObjectId(hTree.EntryObjectId); dcEntry.FileMode = hTree.EntryFileMode; // add to temporary in-core index dcBuilder.Add(dcEntry); } } } // there must be no unprocessed paths left at this point; otherwise an // untracked or unknown path has been specified for (int i = 0; i < onlyProcessed.Length; i++) { if (!onlyProcessed[i]) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().entryNotFoundByPath , only[i])); } } // there must be at least one change if (emptyCommit) { throw new JGitInternalException(JGitText.Get().emptyCommit); } // update index dcEditor.Commit(); // finish temporary in-core index used for this commit dcBuilder.Finish(); return(inCoreIndex); }
/// <summary>Construct and IncorrectObjectTypeException for the specified object id.</summary> /// <remarks> /// Construct and IncorrectObjectTypeException for the specified object id. /// Provide the type to make it easier to track down the problem. /// </remarks> /// <param name="id">SHA-1</param> /// <param name="type">object type</param> public IncorrectObjectTypeException(ObjectId id, string type) : base(MessageFormat .Format(JGitText.Get().objectIsNotA, id.Name, type)) { }
/// <summary>Sets default values for not explicitly specified options.</summary> /// <remarks> /// Sets default values for not explicitly specified options. Then validates /// that all required data has been provided. /// </remarks> /// <param name="state">the state of the repository we are working on</param> /// <exception cref="NGit.Api.Errors.NoMessageException">if the commit message has not been specified /// </exception> private void ProcessOptions(RepositoryState state) { if (committer == null) { committer = new PersonIdent(repo); } if (author == null && !amend) { author = committer; } // when doing a merge commit parse MERGE_HEAD and MERGE_MSG files if (state == RepositoryState.MERGING_RESOLVED) { try { parents = repo.ReadMergeHeads(); } catch (IOException e) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionOccurredDuringReadingOfGIT_DIR , Constants.MERGE_HEAD, e), e); } if (message == null) { try { message = repo.ReadMergeCommitMsg(); } catch (IOException e) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionOccurredDuringReadingOfGIT_DIR , Constants.MERGE_MSG, e), e); } } } else { if (state == RepositoryState.SAFE && message == null) { try { message = repo.ReadSquashCommitMsg(); if (message != null) { repo.WriteSquashCommitMsg(null); } } catch (IOException e) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionOccurredDuringReadingOfGIT_DIR , Constants.MERGE_MSG, e), e); } } } if (message == null) { // as long as we don't support -C option we have to have // an explicit message throw new NoMessageException(JGitText.Get().commitMessageNotSpecified); } }
/// <summary> /// Executes the /// <code>Rebase</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. Don't call /// this method twice on an instance. /// </summary> /// <returns>an object describing the result of this command</returns> /// <exception cref="NGit.Api.Errors.NoHeadException"></exception> /// <exception cref="NGit.Api.Errors.RefNotFoundException"></exception> /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception> /// <exception cref="NGit.Api.Errors.GitAPIException"></exception> public override RebaseResult Call() { RevCommit newHead = null; bool lastStepWasForward = false; CheckCallable(); CheckParameters(); try { switch (operation) { case RebaseCommand.Operation.ABORT: { try { return(Abort()); } catch (IOException ioe) { throw new JGitInternalException(ioe.Message, ioe); } goto case RebaseCommand.Operation.SKIP; } case RebaseCommand.Operation.SKIP: case RebaseCommand.Operation.CONTINUE: { // fall through string upstreamCommitName = ReadFile(rebaseDir, ONTO); this.upstreamCommit = walk.ParseCommit(repo.Resolve(upstreamCommitName)); break; } case RebaseCommand.Operation.BEGIN: { RebaseResult res = InitFilesAndRewind(); if (res != null) { return(res); } break; } } if (monitor.IsCancelled()) { return(Abort()); } if (this.operation == RebaseCommand.Operation.CONTINUE) { newHead = ContinueRebase(); } if (this.operation == RebaseCommand.Operation.SKIP) { newHead = CheckoutCurrentHead(); } ObjectReader or = repo.NewObjectReader(); IList <RebaseCommand.Step> steps = LoadSteps(); foreach (RebaseCommand.Step step in steps) { PopSteps(1); ICollection <ObjectId> ids = or.Resolve(step.commit); if (ids.Count != 1) { throw new JGitInternalException("Could not resolve uniquely the abbreviated object ID" ); } RevCommit commitToPick = walk.ParseCommit(ids.Iterator().Next()); if (monitor.IsCancelled()) { return(new RebaseResult(commitToPick)); } monitor.BeginTask(MessageFormat.Format(JGitText.Get().applyingCommit, commitToPick .GetShortMessage()), ProgressMonitor.UNKNOWN); // if the first parent of commitToPick is the current HEAD, // we do a fast-forward instead of cherry-pick to avoid // unnecessary object rewriting newHead = TryFastForward(commitToPick); lastStepWasForward = newHead != null; if (!lastStepWasForward) { // TODO if the content of this commit is already merged here // we should skip this step in order to avoid confusing // pseudo-changed newHead = new Git(repo).CherryPick().Include(commitToPick).Call(); } monitor.EndTask(); if (newHead == null) { return(Stop(commitToPick)); } } if (newHead != null) { // point the previous head (if any) to the new commit string headName = ReadFile(rebaseDir, HEAD_NAME); if (headName.StartsWith(Constants.R_REFS)) { RefUpdate rup = repo.UpdateRef(headName); rup.SetNewObjectId(newHead); RefUpdate.Result res_1 = rup.ForceUpdate(); switch (res_1) { case RefUpdate.Result.FAST_FORWARD: case RefUpdate.Result.FORCED: case RefUpdate.Result.NO_CHANGE: { break; } default: { throw new JGitInternalException("Updating HEAD failed"); } } rup = repo.UpdateRef(Constants.HEAD); res_1 = rup.Link(headName); switch (res_1) { case RefUpdate.Result.FAST_FORWARD: case RefUpdate.Result.FORCED: case RefUpdate.Result.NO_CHANGE: { break; } default: { throw new JGitInternalException("Updating HEAD failed"); } } } FileUtils.Delete(rebaseDir, FileUtils.RECURSIVE); if (lastStepWasForward) { return(new RebaseResult(RebaseResult.Status.FAST_FORWARD)); } return(new RebaseResult(RebaseResult.Status.OK)); } return(new RebaseResult(RebaseResult.Status.UP_TO_DATE)); } catch (IOException ioe) { throw new JGitInternalException(ioe.Message, ioe); } }
internal override int ParseBody(NGit.Patch.Patch script, int end) { byte[] buf = file.buf; int c = RawParseUtils.NextLF(buf, startOffset); foreach (CombinedHunkHeader.CombinedOldImage o in old) { o.nDeleted = 0; o.nAdded = 0; o.nContext = 0; } nContext = 0; int nAdded = 0; for (int eol; c < end; c = eol) { eol = RawParseUtils.NextLF(buf, c); if (eol - c < old.Length + 1) { // Line isn't long enough to mention the state of each // ancestor. It must be the end of the hunk. goto SCAN_break; } switch (buf[c]) { case (byte)(' '): case (byte)('-'): case (byte)('+'): { break; } default: { // Line can't possibly be part of this hunk; the first // ancestor information isn't recognizable. // goto SCAN_break; break; } } int localcontext = 0; for (int ancestor = 0; ancestor < old.Length; ancestor++) { switch (buf[c + ancestor]) { case (byte)(' '): { localcontext++; old[ancestor].nContext++; continue; goto case (byte)('-'); } case (byte)('-'): { old[ancestor].nDeleted++; continue; goto case (byte)('+'); } case (byte)('+'): { old[ancestor].nAdded++; nAdded++; continue; goto default; } default: { goto SCAN_break; break; } } } if (localcontext == old.Length) { nContext++; } SCAN_continue :; } SCAN_break :; for (int ancestor_1 = 0; ancestor_1 < old.Length; ancestor_1++) { CombinedHunkHeader.CombinedOldImage o_1 = old[ancestor_1]; int cmp = o_1.nContext + o_1.nDeleted; if (cmp < o_1.lineCount) { int missingCnt = o_1.lineCount - cmp; script.Error(buf, startOffset, MessageFormat.Format(JGitText.Get().truncatedHunkLinesMissingForAncestor , Sharpen.Extensions.ValueOf(missingCnt), Sharpen.Extensions.ValueOf(ancestor_1 + 1))); } } if (nContext + nAdded < newLineCount) { int missingCount = newLineCount - (nContext + nAdded); script.Error(buf, startOffset, MessageFormat.Format(JGitText.Get().truncatedHunkNewLinesMissing , Sharpen.Extensions.ValueOf(missingCount))); } return(c); }
/// <exception cref="NGit.Api.Errors.RefNotFoundException"> /// if the old branch can not be found (branch with provided old /// name does not exist or old name resolves to a tag) /// </exception> /// <exception cref="NGit.Api.Errors.InvalidRefNameException"> /// if the provided new name is <code>null</code> or otherwise /// invalid /// </exception> /// <exception cref="NGit.Api.Errors.RefAlreadyExistsException">if a branch with the new name already exists /// </exception> /// <exception cref="NGit.Api.Errors.DetachedHeadException"> /// if rename is tried without specifying the old name and HEAD /// is detached /// </exception> /// <exception cref="NGit.Api.Errors.GitAPIException"></exception> public override Ref Call() { CheckCallable(); if (newName == null) { throw new InvalidRefNameException(MessageFormat.Format(JGitText.Get().branchNameInvalid , "<null>")); } try { string fullOldName; string fullNewName; if (repo.GetRef(newName) != null) { throw new RefAlreadyExistsException(MessageFormat.Format(JGitText.Get().refAlreadyExists1 , newName)); } if (oldName != null) { Ref @ref = repo.GetRef(oldName); if (@ref == null) { throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved , oldName)); } if (@ref.GetName().StartsWith(Constants.R_TAGS)) { throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().renameBranchFailedBecauseTag , oldName)); } fullOldName = @ref.GetName(); } else { fullOldName = repo.GetFullBranch(); if (ObjectId.IsId(fullOldName)) { throw new DetachedHeadException(); } } if (fullOldName.StartsWith(Constants.R_REMOTES)) { fullNewName = Constants.R_REMOTES + newName; } else { fullNewName = Constants.R_HEADS + newName; } if (!Repository.IsValidRefName(fullNewName)) { throw new InvalidRefNameException(MessageFormat.Format(JGitText.Get().branchNameInvalid , fullNewName)); } RefRename rename = repo.RenameRef(fullOldName, fullNewName); RefUpdate.Result renameResult = rename.Rename(); SetCallable(false); if (RefUpdate.Result.RENAMED != renameResult) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().renameBranchUnexpectedResult , renameResult.ToString())); } if (fullNewName.StartsWith(Constants.R_HEADS)) { string shortOldName = Sharpen.Runtime.Substring(fullOldName, Constants.R_HEADS.Length ); StoredConfig repoConfig = repo.GetConfig(); // Copy all configuration values over to the new branch foreach (string name in repoConfig.GetNames(ConfigConstants.CONFIG_BRANCH_SECTION , shortOldName)) { string[] values = repoConfig.GetStringList(ConfigConstants.CONFIG_BRANCH_SECTION, shortOldName, name); if (values.Length == 0) { continue; } // Keep any existing values already configured for the // new branch name string[] existing = repoConfig.GetStringList(ConfigConstants.CONFIG_BRANCH_SECTION , newName, name); if (existing.Length > 0) { string[] newValues = new string[values.Length + existing.Length]; System.Array.Copy(existing, 0, newValues, 0, existing.Length); System.Array.Copy(values, 0, newValues, existing.Length, values.Length); values = newValues; } repoConfig.SetStringList(ConfigConstants.CONFIG_BRANCH_SECTION, newName, name, Arrays .AsList(values)); } repoConfig.UnsetSection(ConfigConstants.CONFIG_BRANCH_SECTION, shortOldName); repoConfig.Save(); } Ref resultRef = repo.GetRef(newName); if (resultRef == null) { throw new JGitInternalException(JGitText.Get().renameBranchFailedUnknownReason); } return(resultRef); } catch (IOException ioe) { throw new JGitInternalException(ioe.Message, ioe); } }
/// <summary>Construct a MissingObjectException for the specified object id.</summary> /// <remarks> /// Construct a MissingObjectException for the specified object id. /// Expected type is reported to simplify tracking down the problem. /// </remarks> /// <param name="id">SHA-1</param> /// <param name="type">object type</param> public MissingObjectException(ObjectId id, string type) : base(MessageFormat.Format (JGitText.Get().missingObject, type, id.Name)) { missing = id.Copy(); }
/// <summary> /// Constructs a NotesMergeConflictException for the specified base, ours and /// theirs versions of the root note tree. /// </summary> /// <remarks> /// Constructs a NotesMergeConflictException for the specified base, ours and /// theirs versions of the root note tree. /// </remarks> /// <param name="base">version of the root note tree</param> /// <param name="ours">version of the root note tree</param> /// <param name="theirs">version of the root note tree</param> internal NotesMergeConflictException(NonNoteEntry @base, NonNoteEntry ours, NonNoteEntry theirs) : base(MessageFormat.Format(JGitText.Get().mergeConflictOnNonNoteEntries , Name(@base), Name(ours), Name(theirs))) { }
internal virtual void Reject(IOException err) { SetResult(ReceiveCommand.Result.REJECTED_OTHER_REASON, MessageFormat.Format(JGitText .Get().lockError, err.Message)); }