/// <exception cref="NGit.Errors.MissingObjectException"></exception> /// <exception cref="System.IO.IOException"></exception> private ObjectIdRef DoPeel(Ref leaf) { RevWalk rw = new RevWalk(GetRepository()); try { RevObject obj = rw.ParseAny(leaf.GetObjectId()); if (obj is RevTag) { return(new ObjectIdRef.PeeledTag(leaf.GetStorage(), leaf.GetName(), leaf.GetObjectId (), rw.Peel(obj).Copy())); } else { return(new ObjectIdRef.PeeledNonTag(leaf.GetStorage(), leaf.GetName(), leaf.GetObjectId ())); } } finally { rw.Release(); } }
/// <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 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.GitAPIException"></exception> public override Ref Call() { CheckCallable(); ProcessOptions(); RevWalk revWalk = new RevWalk(repo); try { Ref refToCheck = repo.GetRef(name); bool exists = refToCheck != null && refToCheck.GetName().StartsWith(Constants.R_HEADS ); if (!force && exists) { throw new RefAlreadyExistsException(MessageFormat.Format(JGitText.Get().refAlreadyExists1 , name)); } ObjectId startAt = GetStartPoint(); string startPointFullName = null; if (startPoint != null) { Ref baseRef = repo.GetRef(startPoint); if (baseRef != null) { startPointFullName = baseRef.GetName(); } } // determine whether we are based on a commit, // a branch, or a tag and compose the reflog message string refLogMessage; string baseBranch = string.Empty; if (startPointFullName == null) { string baseCommit; if (startCommit != null) { baseCommit = startCommit.GetShortMessage(); } else { RevCommit commit = revWalk.ParseCommit(repo.Resolve(startPoint)); baseCommit = commit.GetShortMessage(); } if (exists) { refLogMessage = "branch: Reset start-point to commit " + baseCommit; } else { refLogMessage = "branch: Created from commit " + baseCommit; } } else { if (startPointFullName.StartsWith(Constants.R_HEADS) || startPointFullName.StartsWith (Constants.R_REMOTES)) { baseBranch = startPointFullName; if (exists) { refLogMessage = "branch: Reset start-point to branch " + startPointFullName; } else { // TODO refLogMessage = "branch: Created from branch " + baseBranch; } } else { startAt = revWalk.Peel(revWalk.ParseAny(startAt)); if (exists) { refLogMessage = "branch: Reset start-point to tag " + startPointFullName; } else { refLogMessage = "branch: Created from tag " + startPointFullName; } } } RefUpdate updateRef = repo.UpdateRef(Constants.R_HEADS + name); updateRef.SetNewObjectId(startAt); updateRef.SetRefLogMessage(refLogMessage, false); RefUpdate.Result updateResult; if (exists && force) { updateResult = updateRef.ForceUpdate(); } else { updateResult = updateRef.Update(); } SetCallable(false); bool ok = false; switch (updateResult) { case RefUpdate.Result.NEW: { ok = !exists; break; } case RefUpdate.Result.NO_CHANGE: case RefUpdate.Result.FAST_FORWARD: case RefUpdate.Result.FORCED: { ok = exists; break; } default: { break; break; } } if (!ok) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().createBranchUnexpectedResult , updateResult.ToString())); } Ref result = repo.GetRef(name); if (result == null) { throw new JGitInternalException(JGitText.Get().createBranchFailedUnknownReason); } if (baseBranch.Length == 0) { return(result); } // if we are based on another branch, see // if we need to configure upstream configuration: first check // whether the setting was done explicitly bool doConfigure; if (upstreamMode == CreateBranchCommand.SetupUpstreamMode.SET_UPSTREAM || upstreamMode == CreateBranchCommand.SetupUpstreamMode.TRACK) { // explicitly set to configure doConfigure = true; } else { if (upstreamMode == CreateBranchCommand.SetupUpstreamMode.NOTRACK) { // explicitly set to not configure doConfigure = false; } else { // if there was no explicit setting, check the configuration string autosetupflag = repo.GetConfig().GetString(ConfigConstants.CONFIG_BRANCH_SECTION , null, ConfigConstants.CONFIG_KEY_AUTOSETUPMERGE); if ("false".Equals(autosetupflag)) { doConfigure = false; } else { if ("always".Equals(autosetupflag)) { doConfigure = true; } else { // in this case, the default is to configure // only in case the base branch was a remote branch doConfigure = baseBranch.StartsWith(Constants.R_REMOTES); } } } } if (doConfigure) { StoredConfig config = repo.GetConfig(); string[] tokens = baseBranch.RegexSplit("/", 4); bool isRemote = tokens[1].Equals("remotes"); if (isRemote) { // refs/remotes/<remote name>/<branch> string remoteName = tokens[2]; string branchName = tokens[3]; config.SetString(ConfigConstants.CONFIG_BRANCH_SECTION, name, ConfigConstants.CONFIG_KEY_REMOTE , remoteName); config.SetString(ConfigConstants.CONFIG_BRANCH_SECTION, name, ConfigConstants.CONFIG_KEY_MERGE , Constants.R_HEADS + branchName); } else { // set "." as remote config.SetString(ConfigConstants.CONFIG_BRANCH_SECTION, name, ConfigConstants.CONFIG_KEY_REMOTE , "."); config.SetString(ConfigConstants.CONFIG_BRANCH_SECTION, name, ConfigConstants.CONFIG_KEY_MERGE , baseBranch); } config.Save(); } return(result); } catch (IOException ioe) { throw new JGitInternalException(ioe.Message, ioe); } finally { revWalk.Release(); } }
/// <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); }