public ReferencesData ParseReferences(QueryReferencesParameters parameters, GitOutput output) { Assert.IsNotNull(parameters); Assert.IsNotNull(output); var refTypes = parameters.ReferenceTypes; bool needHeads = (refTypes & ReferenceType.LocalBranch) == ReferenceType.LocalBranch; bool needRemotes = (refTypes & ReferenceType.RemoteBranch) == ReferenceType.RemoteBranch; bool needTags = (refTypes & ReferenceType.Tag) == ReferenceType.Tag; bool needStash = (refTypes & ReferenceType.Stash) == ReferenceType.Stash; var heads = needHeads ? new List<BranchData>() : null; var remotes = needRemotes ? new List<BranchData>() : null; var tags = needTags ? new List<TagData>() : null; RevisionData stash = null; bool encounteredRemoteBranch = false; bool encounteredStash = false; bool encounteredTag = false; var refs = output.Output; int pos = 0; int l = refs.Length; while(pos < l) { var hash = new Hash(refs, pos); pos += 41; var end = refs.IndexOf('\n', pos); if(end == -1) end = l; if(!encounteredRemoteBranch && StringUtility.CheckValue(refs, pos, GitConstants.LocalBranchPrefix)) { if(needHeads) { pos += GitConstants.LocalBranchPrefix.Length; var name = refs.Substring(pos, end - pos); var branch = new BranchData(name, hash, false, false, false); heads.Add(branch); } } else if(!encounteredStash && StringUtility.CheckValue(refs, pos, GitConstants.RemoteBranchPrefix)) { encounteredRemoteBranch = true; if(needRemotes) { pos += GitConstants.RemoteBranchPrefix.Length; var name = refs.Substring(pos, end - pos); if(!name.EndsWith("/HEAD")) { var branch = new BranchData(name, hash, false, true, false); remotes.Add(branch); } } } else if(!encounteredTag && !encounteredStash && StringUtility.CheckValue(refs, pos, GitConstants.StashFullName)) { encounteredRemoteBranch = true; encounteredStash = true; if(needStash) { stash = new RevisionData(hash); } } else if(StringUtility.CheckValue(refs, pos, GitConstants.TagPrefix)) { encounteredRemoteBranch = true; encounteredStash = true; encounteredTag = true; if(needTags) { pos += GitConstants.TagPrefix.Length; var name = refs.Substring(pos, end - pos); var type = TagType.Lightweight; if(end < l - 1) { int s2 = end + 1; int pos2 = s2 + 41 + GitConstants.TagPrefix.Length; var end2 = refs.IndexOf('\n', pos2); if(end2 == -1) end2 = l; if(end2 - pos2 == end - pos + 3) { if(StringUtility.CheckValue(refs, pos2, name) && StringUtility.CheckValue(refs, pos2 + name.Length, GitConstants.DereferencedTagPostfix)) { type = TagType.Annotated; hash = new Hash(refs, s2); end = end2; } } } var tag = new TagData(name, hash, type); tags.Add(tag); } else break; } pos = end + 1; } return new ReferencesData(heads, remotes, tags, stash); }
public Command GetQueryReferencesCommand(QueryReferencesParameters parameters) { Assert.IsNotNull(parameters); switch(parameters.ReferenceTypes) { case ReferenceType.LocalBranch | ReferenceType.Tag: return new ShowRefCommand( ShowRefCommand.Heads(), ShowRefCommand.Tags(), ShowRefCommand.Dereference()); case ReferenceType.LocalBranch: return new ShowRefCommand( ShowRefCommand.Heads(), ShowRefCommand.Dereference()); case ReferenceType.Tag: return new ShowRefCommand( ShowRefCommand.Tags(), ShowRefCommand.Dereference()); default: return new ShowRefCommand( ShowRefCommand.Dereference()); } }