Пример #1
0
 public string ToYamlString()
 {
     return(Name +
            (string.IsNullOrEmpty(Configuration) ? "" : Helper.ConfigurationDelimiter + Configuration) +
            (string.IsNullOrEmpty(Treeish) ? "" : "@" + Treeish.Replace("@", "\\@").Replace("/", "\\/")));
 }
Пример #2
0
        ///	<summary>
        /// Parse a git revision string and return an object id.
        ///	<para />
        ///	Currently supported is combinations of these.
        ///	<ul>
        ///	 <li>SHA-1 - a SHA-1</li>
        ///	 <li>refs/... - a ref name</li>
        ///	 <li>ref^n - nth parent reference</li>
        ///	 <li>ref~n - distance via parent reference</li>
        ///	 <li>ref@{n} - nth version of ref</li>
        ///	 <li>ref^{tree} - tree references by ref</li>
        ///	 <li>ref^{commit} - commit references by ref</li>
        ///	</ul>
        ///	<para />
        ///	Not supported is
        ///	<ul>
        ///	 <li>timestamps in reflogs, ref@{full or relative timestamp}</li>
        ///	 <li>abbreviated SHA-1's</li>
        ///	</ul>
        ///	</summary>
        ///	<param name="revision">A git object references expression.</param>
        ///	<returns>
        /// An <see cref="ObjectId"/> or null if revstr can't be resolved to any <see cref="ObjectId"/>.
        /// </returns>
        ///	<exception cref="IOException">On serious errors.</exception>
        public ObjectId Resolve(string revision)
        {
            object   oref  = null;
            ObjectId refId = null;

            // [ammachado] Avoid the loop if the reference is not a special one.
            if (revision.IndexOfAny(new[] { '^', '~', '@' }) == -1)
            {
                return(ResolveSimple(revision));
            }

            for (int i = 0; i < revision.Length; ++i)
            {
                switch (revision[i])
                {
                case '^':
                    if (refId == null)
                    {
                        var refstr = new string(revision.ToCharArray(0, i));
                        refId = ResolveSimple(refstr);
                        if (refId == null)
                        {
                            return(null);
                        }
                    }

                    if (i + 1 < revision.Length)
                    {
                        switch (revision[i + 1])
                        {
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                        case '8':
                        case '9':

                            int j;
                            oref = MapObject(refId, null);

                            while (oref is Tag)
                            {
                                var tag = (Tag)oref;
                                refId = tag.Id;
                                oref  = MapObject(refId, null);
                            }

                            Commit oCom = (oref as Commit);
                            if (oCom == null)
                            {
                                throw new IncorrectObjectTypeException(refId, ObjectType.Commit);
                            }

                            for (j = i + 1; j < revision.Length; ++j)
                            {
                                if (!Char.IsDigit(revision[j]))
                                {
                                    break;
                                }
                            }

                            var parentnum = new string(revision.ToCharArray(i + 1, j - i - 1));

                            int pnum;

                            try
                            {
                                pnum = Convert.ToInt32(parentnum);
                            }
                            catch (FormatException)
                            {
                                throw new RevisionSyntaxException(revision, "Invalid commit parent number");
                            }
                            if (pnum != 0)
                            {
                                ObjectId[] parents = oCom.ParentIds;
                                if (pnum > parents.Length)
                                {
                                    refId = null;
                                }
                                else
                                {
                                    refId = parents[pnum - 1];
                                }
                            }

                            i = j - 1;
                            break;

                        case '{':
                            int    k;
                            string item = null;
                            for (k = i + 2; k < revision.Length; ++k)
                            {
                                if (revision[k] != '}')
                                {
                                    continue;
                                }
                                item = new string(revision.ToCharArray(i + 2, k - i - 2));
                                break;
                            }

                            i = k;
                            if (item != null)
                            {
                                if (item.Equals("tree"))
                                {
                                    oref = MapObject(refId, null);
                                    while (oref is Tag)
                                    {
                                        var t = (Tag)oref;
                                        refId = t.Id;
                                        oref  = MapObject(refId, null);
                                    }
                                    Treeish oTree = (oref as Treeish);
                                    if (oTree != null)
                                    {
                                        refId = oTree.TreeId;
                                    }
                                    else
                                    {
                                        throw new IncorrectObjectTypeException(refId, ObjectType.Tree);
                                    }
                                }
                                else if (item.Equals("commit"))
                                {
                                    oref = MapObject(refId, null);
                                    while (oref is Tag)
                                    {
                                        var t = (Tag)oref;
                                        refId = t.Id;
                                        oref  = MapObject(refId, null);
                                    }
                                    if (!(oref is Commit))
                                    {
                                        throw new IncorrectObjectTypeException(refId, ObjectType.Commit);
                                    }
                                }
                                else if (item.Equals("blob"))
                                {
                                    oref = MapObject(refId, null);
                                    while (oref is Tag)
                                    {
                                        var t = (Tag)oref;
                                        refId = t.Id;
                                        oref  = MapObject(refId, null);
                                    }
                                    if (!(oref is byte[]))
                                    {
                                        throw new IncorrectObjectTypeException(refId, ObjectType.Commit);
                                    }
                                }
                                else if (string.Empty.Equals(item))
                                {
                                    oref = MapObject(refId, null);
                                    while (oref is Tag)
                                    {
                                        var t = (Tag)oref;
                                        refId = t.Id;
                                        oref  = MapObject(refId, null);
                                    }
                                }
                                else
                                {
                                    throw new RevisionSyntaxException(revision);
                                }
                            }
                            else
                            {
                                throw new RevisionSyntaxException(revision);
                            }
                            break;

                        default:
                            oref = MapObject(refId, null);
                            Commit oComm = (oref as Commit);
                            if (oComm != null)
                            {
                                ObjectId[] parents = oComm.ParentIds;
                                refId = parents.Length == 0 ? null : parents[0];
                            }
                            else
                            {
                                throw new IncorrectObjectTypeException(refId, ObjectType.Commit);
                            }
                            break;
                        }
                    }
                    else
                    {
                        oref = MapObject(refId, null);
                        while (oref is Tag)
                        {
                            var tag = (Tag)oref;
                            refId = tag.Id;
                            oref  = MapObject(refId, null);
                        }

                        Commit oCom = (oref as Commit);
                        if (oCom != null)
                        {
                            ObjectId[] parents = oCom.ParentIds;
                            refId = parents.Length == 0 ? null : parents[0];
                        }
                        else
                        {
                            throw new IncorrectObjectTypeException(refId, Constants.TYPE_COMMIT);
                        }
                    }
                    break;

                case '~':
                    if (oref == null)
                    {
                        var refstr = new string(revision.ToCharArray(0, i));
                        refId = ResolveSimple(refstr);
                        if (refId == null)
                        {
                            return(null);
                        }
                        oref = MapObject(refId, null);
                    }

                    while (oref is Tag)
                    {
                        var tag = (Tag)oref;
                        refId = tag.Id;
                        oref  = MapObject(refId, null);
                    }

                    if (!(oref is Commit))
                    {
                        throw new IncorrectObjectTypeException(refId, Constants.TYPE_COMMIT);
                    }

                    int l;
                    for (l = i + 1; l < revision.Length; ++l)
                    {
                        if (!Char.IsDigit(revision[l]))
                        {
                            break;
                        }
                    }

                    var distnum = new string(revision.ToCharArray(i + 1, l - i - 1));
                    int dist;

                    try
                    {
                        dist = Convert.ToInt32(distnum);
                    }
                    catch (FormatException)
                    {
                        throw new RevisionSyntaxException("Invalid ancestry length", revision);
                    }
                    while (dist > 0)
                    {
                        ObjectId[] parents = ((Commit)oref).ParentIds;
                        if (parents.Length == 0)
                        {
                            refId = null;
                            break;
                        }
                        refId = parents[0];
                        oref  = MapCommit(refId);
                        --dist;
                    }
                    i = l - 1;
                    break;

                case '@':
                    int    m;
                    string time = null;
                    for (m = i + 2; m < revision.Length; ++m)
                    {
                        if (revision[m] != '}')
                        {
                            continue;
                        }
                        time = new string(revision.ToCharArray(i + 2, m - i - 2));
                        break;
                    }

                    if (time != null)
                    {
                        throw new RevisionSyntaxException("reflogs not yet supported by revision parser yet", revision);
                    }
                    i = m - 1;
                    break;

                default:
                    if (refId != null)
                    {
                        throw new RevisionSyntaxException(revision);
                    }
                    break;
                }
            }

            if (refId == null)
            {
                refId = ResolveSimple(revision);
            }

            return(refId);
        }