/// <summary> /// Find the list of branches a given commit is reachable from when following /// parent.s /// <p> /// Note that this method calls /// <see cref="RevWalk.Reset()">RevWalk.Reset()</see> /// at the beginning. /// <p> /// In order to improve performance this method assumes clock skew among /// committers is never larger than 24 hours. /// </summary> /// <param name="commit">the commit we are looking at</param> /// <param name="revWalk">The RevWalk to be used.</param> /// <param name="refs">the set of branches we want to see reachability from</param> /// <returns>the list of branches a given commit is reachable from</returns> /// <exception cref="NGit.Errors.MissingObjectException">NGit.Errors.MissingObjectException /// </exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException">NGit.Errors.IncorrectObjectTypeException /// </exception> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public static IList <Ref> FindBranchesReachableFrom(RevCommit commit, RevWalk revWalk , ICollection <Ref> refs) { IList <Ref> result = new AList <Ref>(); // searches from branches can be cut off early if any parent of the // search-for commit is found. This is quite likely, so optimize for this. revWalk.MarkStart(Arrays.AsList(commit.Parents)); ObjectIdSubclassMap <ObjectId> cutOff = new ObjectIdSubclassMap <ObjectId>(); int SKEW = 24 * 3600; // one day clock skew foreach (Ref @ref in refs) { RevObject maybehead = revWalk.ParseAny(@ref.GetObjectId()); if (!(maybehead is RevCommit)) { continue; } RevCommit headCommit = (RevCommit)maybehead; // if commit is in the ref branch, then the tip of ref should be // newer than the commit we are looking for. Allow for a large // clock skew. if (headCommit.CommitTime + SKEW < commit.CommitTime) { continue; } IList <ObjectId> maybeCutOff = new AList <ObjectId>(cutOff.Size()); // guess rough size revWalk.ResetRetain(); revWalk.MarkStart(headCommit); RevCommit current; Ref found = null; while ((current = revWalk.Next()) != null) { if (AnyObjectId.Equals(current, commit)) { found = @ref; break; } if (cutOff.Contains(current)) { break; } maybeCutOff.AddItem(current.ToObjectId()); } if (found != null) { result.AddItem(@ref); } else { foreach (ObjectId id in maybeCutOff) { cutOff.AddIfAbsent(id); } } } return(result); }
/// <exception cref="NGit.Errors.MissingObjectException"></exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"></exception> /// <exception cref="System.IO.IOException"></exception> private RevObject EnterTree(RevObject obj) { ObjectWalk.TreeVisit tv = NewTreeVisit(obj); tv.parent = currVisit; currVisit = tv; return(obj); }
/// <summary>Mark an object to not produce in the output.</summary> /// <remarks> /// Mark an object to not produce in the output. /// <p> /// Uninteresting objects denote not just themselves but also their entire /// reachable chain, back until the merge base of an uninteresting commit and /// an otherwise interesting commit. /// <p> /// Callers are encouraged to use /// <see cref="RevWalk.ParseAny(NGit.AnyObjectId)">RevWalk.ParseAny(NGit.AnyObjectId) /// </see> /// instead of /// <see cref="RevWalk.LookupAny(NGit.AnyObjectId, int)">RevWalk.LookupAny(NGit.AnyObjectId, int) /// </see> /// , as this method /// requires the object to be parsed before it can be added as a root for the /// traversal. /// <p> /// The method will automatically parse an unparsed object, but error /// handling may be more difficult for the application to explain why a /// RevObject is not actually valid. The object pool of this walker would /// also be 'poisoned' by the invalid RevObject. /// <p> /// This method will automatically call /// <see cref="RevWalk.MarkStart(RevCommit)">RevWalk.MarkStart(RevCommit)</see> /// if passed RevCommit instance, or a RevTag that directly (or indirectly) /// references a RevCommit. /// </remarks> /// <param name="o">the object to start traversing from. The object passed must be</param> /// <exception cref="NGit.Errors.MissingObjectException"> /// the object supplied is not available from the object /// database. This usually indicates the supplied object is /// invalid, but the reference was constructed during an earlier /// invocation to /// <see cref="RevWalk.LookupAny(NGit.AnyObjectId, int)">RevWalk.LookupAny(NGit.AnyObjectId, int) /// </see> /// . /// </exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"> /// the object was not parsed yet and it was discovered during /// parsing that it is not actually the type of the instance /// passed in. This usually indicates the caller used the wrong /// type in a /// <see cref="RevWalk.LookupAny(NGit.AnyObjectId, int)">RevWalk.LookupAny(NGit.AnyObjectId, int) /// </see> /// call. /// </exception> /// <exception cref="System.IO.IOException">a pack file or loose object could not be read. /// </exception> public virtual void MarkUninteresting(RevObject o) { while (o is RevTag) { o.flags |= UNINTERESTING; if (boundary) { AddObject(o); } o = ((RevTag)o).GetObject(); ParseHeaders(o); } if (o is RevCommit) { base.MarkUninteresting((RevCommit)o); } else { if (o is RevTree) { MarkTreeUninteresting((RevTree)o); } else { o.flags |= UNINTERESTING; } } if (o.Type != Constants.OBJ_COMMIT && boundary) { AddObject(o); } }
private void AddObject(RevObject o) { if ((o.flags & IN_PENDING) == 0) { o.flags |= IN_PENDING; rootObjects.AddItem(o); pendingObjects.Add(o); } }
public override void Dispose() { base.Dispose(); pendingObjects = new BlockObjQueue(); treeWalk = new CanonicalTreeParser(); currentTree = null; last = null; firstCommit = null; lastCommit = null; }
/// <exception cref="System.IO.IOException"></exception> private CanonicalTreeParser Enter(RevObject tree) { CanonicalTreeParser p = treeWalk.CreateSubtreeIterator0(reader, tree); if (p.Eof) { // We can't tolerate the subtree being an empty tree, as // that will break us out early before we visit all names. // If it is, advance to the parent's next record. // return(treeWalk.Next()); } return(p); }
protected internal override void Reset(int retainFlags) { base.Reset(retainFlags); foreach (RevObject obj in rootObjects) { obj.flags &= ~IN_PENDING; } rootObjects = new AList <RevObject>(); pendingObjects = new BlockObjQueue(); treeWalk = new CanonicalTreeParser(); currentTree = null; last = null; firstCommit = null; lastCommit = null; }
/// <summary>Mark an object or commit to start graph traversal from.</summary> /// <remarks> /// Mark an object or commit to start graph traversal from. /// <p> /// Callers are encouraged to use /// <see cref="RevWalk.ParseAny(NGit.AnyObjectId)">RevWalk.ParseAny(NGit.AnyObjectId) /// </see> /// instead of /// <see cref="RevWalk.LookupAny(NGit.AnyObjectId, int)">RevWalk.LookupAny(NGit.AnyObjectId, int) /// </see> /// , as this method /// requires the object to be parsed before it can be added as a root for the /// traversal. /// <p> /// The method will automatically parse an unparsed object, but error /// handling may be more difficult for the application to explain why a /// RevObject is not actually valid. The object pool of this walker would /// also be 'poisoned' by the invalid RevObject. /// <p> /// This method will automatically call /// <see cref="RevWalk.MarkStart(RevCommit)">RevWalk.MarkStart(RevCommit)</see> /// if passed RevCommit instance, or a RevTag that directly (or indirectly) /// references a RevCommit. /// </remarks> /// <param name="o"> /// the object to start traversing from. The object passed must be /// from this same revision walker. /// </param> /// <exception cref="NGit.Errors.MissingObjectException"> /// the object supplied is not available from the object /// database. This usually indicates the supplied object is /// invalid, but the reference was constructed during an earlier /// invocation to /// <see cref="RevWalk.LookupAny(NGit.AnyObjectId, int)">RevWalk.LookupAny(NGit.AnyObjectId, int) /// </see> /// . /// </exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"> /// the object was not parsed yet and it was discovered during /// parsing that it is not actually the type of the instance /// passed in. This usually indicates the caller used the wrong /// type in a /// <see cref="RevWalk.LookupAny(NGit.AnyObjectId, int)">RevWalk.LookupAny(NGit.AnyObjectId, int) /// </see> /// call. /// </exception> /// <exception cref="System.IO.IOException">a pack file or loose object could not be read. /// </exception> public virtual void MarkStart(RevObject o) { while (o is RevTag) { AddObject(o); o = ((RevTag)o).GetObject(); ParseHeaders(o); } if (o is RevCommit) { base.MarkStart((RevCommit)o); } else { AddObject(o); } }
/// <exception cref="NGit.Errors.LargeObjectException"></exception> /// <exception cref="NGit.Errors.MissingObjectException"></exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"></exception> /// <exception cref="System.IO.IOException"></exception> private ObjectWalk.TreeVisit NewTreeVisit(RevObject obj) { ObjectWalk.TreeVisit tv = freeVisit; if (tv != null) { freeVisit = tv.parent; tv.ptr = 0; tv.namePtr = 0; tv.nameEnd = 0; tv.pathLen = 0; } else { tv = new ObjectWalk.TreeVisit(); } tv.obj = obj; tv.buf = reader.Open(obj, Constants.OBJ_TREE).GetCachedBytes(); return(tv); }
internal virtual RevObject Next() { BlockObjQueue.Block b = head; if (b == null) { return(null); } RevObject c = b.Pop(); if (b.IsEmpty()) { head = b.next; if (head == null) { tail = null; } free.FreeBlock(b); } return(c); }
/// <exception cref="NGit.Errors.CorruptObjectException"></exception> internal virtual void ParseCanonical(RevWalk walk, byte[] rawTag) { MutableInteger pos = new MutableInteger(); int oType; pos.value = 53; // "object $sha1\ntype " oType = Constants.DecodeTypeString(this, rawTag, unchecked ((byte)'\n'), pos); walk.idBuffer.FromString(rawTag, 7); @object = walk.LookupAny(walk.idBuffer, oType); int p = pos.value += 4; // "tag " int nameEnd = RawParseUtils.NextLF(rawTag, p) - 1; tagName = RawParseUtils.Decode(Constants.CHARSET, rawTag, p, nameEnd); if (walk.IsRetainBody()) { buffer = rawTag; } flags |= PARSED; }
internal virtual void Add(RevObject c) { BlockObjQueue.Block b = tail; if (b == null) { b = free.NewBlock(); b.Add(c); head = b; tail = b; return; } else { if (b.IsFull()) { b = free.NewBlock(); tail.next = b; tail = b; } } b.Add(c); }
/// <summary>Verify all interesting objects are available, and reachable.</summary> /// <remarks> /// Verify all interesting objects are available, and reachable. /// <p> /// Callers should populate starting points and ending points with /// <see cref="MarkStart(RevObject)">MarkStart(RevObject)</see> /// and /// <see cref="MarkUninteresting(RevObject)">MarkUninteresting(RevObject)</see> /// and then use this method to verify all objects between those two points /// exist in the repository and are readable. /// <p> /// This method returns successfully if everything is connected; it throws an /// exception if there is a connectivity problem. The exception message /// provides some detail about the connectivity failure. /// </remarks> /// <exception cref="NGit.Errors.MissingObjectException"> /// one or or more of the next objects are not available from the /// object database, but were thought to be candidates for /// traversal. This usually indicates a broken link. /// </exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"> /// one or or more of the objects in a tree do not match the type /// indicated. /// </exception> /// <exception cref="System.IO.IOException">a pack file or loose object could not be read. /// </exception> public virtual void CheckConnectivity() { for (; ;) { RevCommit c = Next(); if (c == null) { break; } } for (; ;) { RevObject o = NextObject(); if (o == null) { break; } if (o is RevBlob && !reader.Has(o)) { throw new MissingObjectException(o, Constants.OBJ_BLOB); } } }
protected internal override void Reset(int retainFlags) { base.Reset(retainFlags); pendingObjects = new BlockObjQueue(); treeWalk = new CanonicalTreeParser(); currentTree = null; last = null; firstCommit = null; lastCommit = null; }
/// <exception cref="System.IO.IOException"></exception> private bool WantSatisfied(RevObject want) { if (want.Has(SATISFIED)) { return true; } walk.ResetRetain(SAVE); walk.MarkStart((RevCommit)want); if (oldestTime != 0) { walk.SetRevFilter(CommitTimeRevFilter.After(oldestTime * 1000L)); } for (; ; ) { RevCommit c = walk.Next(); if (c == null) { break; } if (c.Has(PEER_HAS)) { AddCommonBase(c); want.Add(SATISFIED); return true; } } return false; }
/// <summary> /// Mark an element which used to be shallow in the client, but which /// should now be considered a full commit. /// </summary> /// <remarks> /// Mark an element which used to be shallow in the client, but which /// should now be considered a full commit. Any ancestors of this commit /// should be included in the walk, even if they are the ancestor of an /// uninteresting commit. /// </remarks> /// <param name="c">Commit to mark</param> /// <exception cref="NGit.Errors.MissingObjectException">NGit.Errors.MissingObjectException /// </exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException">NGit.Errors.IncorrectObjectTypeException /// </exception> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual void MarkUnshallow(RevObject c) { if (c is RevCommit) { c.Add(UNSHALLOW); } base.MarkStart(c); }
/// <exception cref="System.IO.IOException"></exception> private CanonicalTreeParser Enter(RevObject tree) { CanonicalTreeParser p = treeWalk.CreateSubtreeIterator0(reader, tree); if (p.Eof) { // We can't tolerate the subtree being an empty tree, as // that will break us out early before we visit all names. // If it is, advance to the parent's next record. // return treeWalk.Next(); } return p; }
/// <exception cref="System.Exception"></exception> protected internal virtual RevTag Tag(string name, RevObject dst) { return(util.Tag(name, dst)); }
/// <exception cref="System.IO.IOException"></exception> private void AdvertiseAnyOnce(RevObject obj, string refName) { if (!obj.Has(ADVERTISED)) { AdvertiseAny(obj, refName); } }
/// <exception cref="NGit.Errors.TransportException"></exception> private void ProcessBlob(RevObject obj) { try { if (reader.Has(obj, Constants.OBJ_BLOB)) { obj.Add(COMPLETE); } else { throw new TransportException(MessageFormat.Format(JGitText.Get().cannotReadBlob, obj.Name), new MissingObjectException(obj, Constants.TYPE_BLOB)); } } catch (IOException error) { throw new TransportException(MessageFormat.Format(JGitText.Get().cannotReadBlob, obj.Name), error); } }
/// <summary>Pop the next most recent object.</summary> /// <remarks>Pop the next most recent object.</remarks> /// <returns>next most recent object; null if traversal is over.</returns> /// <exception cref="NGit.Errors.MissingObjectException"> /// one or or more of the next objects are not available from the /// object database, but were thought to be candidates for /// traversal. This usually indicates a broken link. /// </exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"> /// one or or more of the objects in a tree do not match the type /// indicated. /// </exception> /// <exception cref="System.IO.IOException">a pack file or loose object could not be read. /// </exception> public virtual RevObject NextObject() { pathLen = 0; ObjectWalk.TreeVisit tv = currVisit; while (tv != null) { byte[] buf = tv.buf; for (int ptr = tv.ptr; ptr < buf.Length;) { int startPtr = ptr; ptr = FindObjectId(buf, ptr); idBuffer.FromRaw(buf, ptr); ptr += ID_SZ; RevObject obj = objects.Get(idBuffer); if (obj != null && (obj.flags & SEEN) != 0) { continue; } int mode = ParseMode(buf, startPtr, ptr, tv); int flags; switch ((int)(((uint)mode) >> TYPE_SHIFT)) { case TYPE_FILE: case TYPE_SYMLINK: { if (obj == null) { obj = new RevBlob(idBuffer); obj.flags = SEEN; objects.Add(obj); return(obj); } if (!(obj is RevBlob)) { throw new IncorrectObjectTypeException(obj, Constants.OBJ_BLOB); } obj.flags = flags = obj.flags | SEEN; if ((flags & UNINTERESTING) == 0) { return(obj); } if (boundary) { return(obj); } continue; goto case TYPE_TREE; } case TYPE_TREE: { if (obj == null) { obj = new RevTree(idBuffer); obj.flags = SEEN; objects.Add(obj); return(EnterTree(obj)); } if (!(obj is RevTree)) { throw new IncorrectObjectTypeException(obj, Constants.OBJ_TREE); } obj.flags = flags = obj.flags | SEEN; if ((flags & UNINTERESTING) == 0) { return(EnterTree(obj)); } if (boundary) { return(EnterTree(obj)); } continue; goto case TYPE_GITLINK; } case TYPE_GITLINK: { continue; goto default; } default: { throw new CorruptObjectException(MessageFormat.Format(JGitText.Get().corruptObjectInvalidMode3 , string.Format("%o", Sharpen.Extensions.ValueOf(mode)), idBuffer.Name, RawParseUtils .Decode(buf, tv.namePtr, tv.nameEnd), tv.obj)); } } } currVisit = tv.parent; ReleaseTreeVisit(tv); tv = currVisit; } for (; ;) { RevObject o = pendingObjects.Next(); if (o == null) { reader.WalkAdviceEnd(); return(null); } int flags = o.flags; if ((flags & SEEN) != 0) { continue; } flags |= SEEN; o.flags = flags; if ((flags & UNINTERESTING) == 0 | boundary) { if (o is RevTree) { tv = NewTreeVisit(o); tv.parent = null; currVisit = tv; } return(o); } } }
internal void Add(RevObject c) { objects[tailIndex++] = c; }
/// <summary>Construct for the specified object.</summary> /// <remarks>Construct for the specified object.</remarks> /// <param name="obj"> /// identity of the object that will be packed. The object's /// parsed status is undefined here. Implementers must not rely on /// the object being parsed. /// </param> public ObjectToPack(RevObject obj) : this(obj, obj.Type) { }
protected internal override void Reset(int retainFlags) { base.Reset(retainFlags); foreach (RevObject obj in rootObjects) { obj.flags &= ~IN_PENDING; } rootObjects = new AList<RevObject>(); pendingObjects = new BlockObjQueue(); treeWalk = new CanonicalTreeParser(); currentTree = null; last = null; firstCommit = null; lastCommit = null; }
private bool ShouldSkipObject(RevObject o) { return (o.flags & UNINTERESTING) != 0 && !HasRevSort(RevSort.BOUNDARY); }
/// <exception cref="NGit.Errors.TransportException"></exception> private void ProcessCommit(RevObject obj) { RevCommit commit = (RevCommit)obj; MarkLocalCommitsComplete(commit.CommitTime); Needs(commit.Tree); foreach (RevCommit p in commit.Parents) { Needs(p); } obj.Add(COMPLETE); }
/// <exception cref="NGit.Errors.LargeObjectException"></exception> /// <exception cref="NGit.Errors.MissingObjectException"></exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"></exception> /// <exception cref="System.IO.IOException"></exception> private ObjectWalk.TreeVisit NewTreeVisit(RevObject obj) { ObjectWalk.TreeVisit tv = freeVisit; if (tv != null) { freeVisit = tv.parent; tv.ptr = 0; tv.namePtr = 0; tv.nameEnd = 0; tv.pathLen = 0; } else { tv = new ObjectWalk.TreeVisit(); } tv.obj = obj; tv.buf = reader.Open(obj, Constants.OBJ_TREE).GetCachedBytes(); return tv; }
private void Needs(RevObject obj) { if (obj.Has(COMPLETE)) { return; } if (!obj.Has(IN_WORK_QUEUE)) { obj.Add(IN_WORK_QUEUE); workQueue.AddItem(obj); } }
/// <exception cref="System.IO.IOException"></exception> private void AdvertiseAny(RevObject obj, string refName) { obj.Add(ADVERTISED); AdvertiseId(obj, refName); }
public ObjectToPack NewObjectToPack(RevObject obj) { return new LocalObjectToPack(obj); }
/// <exception cref="NGit.Errors.TransportException"></exception> private void ProcessTree(RevObject obj) { try { treeWalk.Reset(obj); while (treeWalk.Next()) { FileMode mode = treeWalk.GetFileMode(0); int sType = mode.GetObjectType(); switch (sType) { case Constants.OBJ_BLOB: case Constants.OBJ_TREE: { treeWalk.GetObjectId(idBuffer, 0); Needs(revWalk.LookupAny(idBuffer, sType)); continue; goto default; } default: { if (FileMode.GITLINK.Equals(mode)) { continue; } treeWalk.GetObjectId(idBuffer, 0); throw new CorruptObjectException(MessageFormat.Format(JGitText.Get().invalidModeFor , mode, idBuffer.Name, treeWalk.PathString, obj.Id.Name)); } } } } catch (IOException ioe) { throw new TransportException(MessageFormat.Format(JGitText.Get().cannotReadTree, obj.Name), ioe); } obj.Add(COMPLETE); }
/// <summary>Pop the next most recent object.</summary> /// <remarks>Pop the next most recent object.</remarks> /// <returns>next most recent object; null if traversal is over.</returns> /// <exception cref="NGit.Errors.MissingObjectException"> /// one or or more of the next objects are not available from the /// object database, but were thought to be candidates for /// traversal. This usually indicates a broken link. /// </exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"> /// one or or more of the objects in a tree do not match the type /// indicated. /// </exception> /// <exception cref="System.IO.IOException">a pack file or loose object could not be read. /// </exception> public virtual RevObject NextObject() { if (last != null) { treeWalk = last is RevTree ? Enter(last) : treeWalk.Next(); } while (!treeWalk.Eof) { FileMode mode = treeWalk.EntryFileMode; switch (mode.GetObjectType()) { case Constants.OBJ_BLOB: { treeWalk.GetEntryObjectId(idBuffer); RevBlob o = LookupBlob(idBuffer); if ((o.flags & SEEN) != 0) { break; } o.flags |= SEEN; if (ShouldSkipObject(o)) { break; } last = o; return o; } case Constants.OBJ_TREE: { treeWalk.GetEntryObjectId(idBuffer); RevTree o = LookupTree(idBuffer); if ((o.flags & SEEN) != 0) { break; } o.flags |= SEEN; if (ShouldSkipObject(o)) { break; } last = o; return o; } default: { if (FileMode.GITLINK.Equals(mode)) { break; } treeWalk.GetEntryObjectId(idBuffer); throw new CorruptObjectException(MessageFormat.Format(JGitText.Get().corruptObjectInvalidMode3 , mode, idBuffer.Name, treeWalk.EntryPathString, currentTree.Name)); } } treeWalk = treeWalk.Next(); } if (firstCommit != null) { reader.WalkAdviceBeginTrees(this, firstCommit, lastCommit); firstCommit = null; lastCommit = null; } last = null; for (; ; ) { RevObject o = pendingObjects.Next(); if (o == null) { reader.WalkAdviceEnd(); return null; } if ((o.flags & SEEN) != 0) { continue; } o.flags |= SEEN; if (ShouldSkipObject(o)) { continue; } if (o is RevTree) { currentTree = (RevTree)o; treeWalk = treeWalk.ResetRoot(reader, currentTree); } return o; } }
private void ProcessTag(RevObject obj) { RevTag tag = (RevTag)obj; Needs(tag.GetObject()); obj.Add(COMPLETE); }
private bool ShouldSkipObject(RevObject o) { return((o.flags & UNINTERESTING) != 0 && !HasRevSort(RevSort.BOUNDARY)); }
/// <exception cref="System.IO.IOException"></exception> private void MarkLocalObjComplete(RevObject obj) { while (obj.Type == Constants.OBJ_TAG) { obj.Add(COMPLETE); obj = ((RevTag)obj).GetObject(); revWalk.ParseHeaders(obj); } switch (obj.Type) { case Constants.OBJ_BLOB: { obj.Add(COMPLETE); break; } case Constants.OBJ_COMMIT: { PushLocalCommit((RevCommit)obj); break; } case Constants.OBJ_TREE: { MarkTreeComplete((RevTree)obj); break; } } }
/// <exception cref="System.IO.IOException"></exception> private bool WantSatisfied(RevObject want) { if (want.Has(SATISFIED)) { return true; } if (!(want is RevCommit)) { want.Add(SATISFIED); return true; } walk.ResetRetain(SAVE); walk.MarkStart((RevCommit)want); for (; ; ) { RevCommit c = walk.Next(); if (c == null) { break; } if (c.Has(PEER_HAS)) { AddCommonBase(c); want.Add(SATISFIED); return true; } } return false; }
/// <exception cref="NGit.Errors.CorruptObjectException"></exception> internal virtual void ParseCanonical(RevWalk walk, byte[] rawTag) { MutableInteger pos = new MutableInteger(); int oType; pos.value = 53; // "object $sha1\ntype " oType = Constants.DecodeTypeString(this, rawTag, unchecked((byte)'\n'), pos); walk.idBuffer.FromString(rawTag, 7); @object = walk.LookupAny(walk.idBuffer, oType); int p = pos.value += 4; // "tag " int nameEnd = RawParseUtils.NextLF(rawTag, p) - 1; tagName = RawParseUtils.Decode(Constants.CHARSET, rawTag, p, nameEnd); if (walk.IsRetainBody()) { buffer = rawTag; } flags |= PARSED; }
/// <summary>Set the object this tag refers to, and infer its type.</summary> /// <remarks>Set the object this tag refers to, and infer its type.</remarks> /// <param name="obj">the object the tag will refer to.</param> public virtual void SetObjectId(RevObject obj) { SetObjectId(obj, obj.Type); }
private void AddCommonBase(RevObject o) { if (!o.Has(COMMON)) { o.Add(COMMON); commonBase.AddItem(o); okToGiveUp = null; } }
/// <summary>Mark a root commit (i.e., one whose depth should be considered 0.)</summary> /// <param name="o">Commit to mark</param> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException">NGit.Errors.IncorrectObjectTypeException /// </exception> /// <exception cref="NGit.Errors.MissingObjectException">NGit.Errors.MissingObjectException /// </exception> public virtual void MarkRoot(RevObject o) { RevObject c = o; while (c is RevTag) { c = ((RevTag)c).GetObject(); ParseHeaders(c); } if (c is NGit.Revwalk.Depthwalk.Commit) { ((NGit.Revwalk.Depthwalk.Commit)c).depth = 0; } base.MarkStart(o); }
/// <summary>Pop the next most recent object.</summary> /// <remarks>Pop the next most recent object.</remarks> /// <returns>next most recent object; null if traversal is over.</returns> /// <exception cref="NGit.Errors.MissingObjectException"> /// one or or more of the next objects are not available from the /// object database, but were thought to be candidates for /// traversal. This usually indicates a broken link. /// </exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"> /// one or or more of the objects in a tree do not match the type /// indicated. /// </exception> /// <exception cref="System.IO.IOException">a pack file or loose object could not be read. /// </exception> public virtual RevObject NextObject() { if (last != null) { treeWalk = last is RevTree?Enter(last) : treeWalk.Next(); } while (!treeWalk.Eof) { FileMode mode = treeWalk.EntryFileMode; switch (mode.GetObjectType()) { case Constants.OBJ_BLOB: { treeWalk.GetEntryObjectId(idBuffer); RevBlob o = LookupBlob(idBuffer); if ((o.flags & SEEN) != 0) { break; } o.flags |= SEEN; if (ShouldSkipObject(o)) { break; } last = o; return(o); } case Constants.OBJ_TREE: { treeWalk.GetEntryObjectId(idBuffer); RevTree o = LookupTree(idBuffer); if ((o.flags & SEEN) != 0) { break; } o.flags |= SEEN; if (ShouldSkipObject(o)) { break; } last = o; return(o); } default: { if (FileMode.GITLINK.Equals(mode)) { break; } treeWalk.GetEntryObjectId(idBuffer); throw new CorruptObjectException(MessageFormat.Format(JGitText.Get().corruptObjectInvalidMode3 , mode, idBuffer.Name, treeWalk.EntryPathString, currentTree.Name)); } } treeWalk = treeWalk.Next(); } if (firstCommit != null) { reader.WalkAdviceBeginTrees(this, firstCommit, lastCommit); firstCommit = null; lastCommit = null; } last = null; for (; ;) { RevObject o = pendingObjects.Next(); if (o == null) { reader.WalkAdviceEnd(); return(null); } if ((o.flags & SEEN) != 0) { continue; } o.flags |= SEEN; if (ShouldSkipObject(o)) { continue; } if (o is RevTree) { currentTree = (RevTree)o; treeWalk = treeWalk.ResetRoot(reader, currentTree); } return(o); } }
/// <exception cref="NGit.Errors.MissingObjectException"></exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"></exception> /// <exception cref="System.IO.IOException"></exception> private RevObject EnterTree(RevObject obj) { ObjectWalk.TreeVisit tv = NewTreeVisit(obj); tv.parent = currVisit; currVisit = tv; return obj; }