public ReceivePackCommit(string id, string tree, IEnumerable <string> parents,
                          ReceivePackCommitSignature author, ReceivePackCommitSignature committer, string message)
 {
     this.Id        = id;
     this.Tree      = tree;
     this.Parents   = parents;
     this.Author    = author;
     this.Committer = committer;
     this.Message   = message;
 }
 public ReceivePackCommit(string id, string tree, IEnumerable<string> parents, 
     ReceivePackCommitSignature author, ReceivePackCommitSignature committer, string message)
 {
     this.Id = id;
     this.Tree = tree;
     this.Parents = parents;
     this.Author = author;
     this.Committer = committer;
     this.Message = message;
 }
示例#3
0
        public ReceivePackCommit ParseCommitDetails(byte[] buff, long commitMsgLengthLong)
        {
            if (commitMsgLengthLong > buff.Length)
            {
                // buff at the moment is 16KB, should be enough for commit messages
                // but break just in case this ever does happen so it could be addressed then
                throw new Exception("Encountered unexpectedly large commit message");
            }
            int commitMsgLength = (int)commitMsgLengthLong; // guaranteed no truncation because of above guard clause

            var    commitMsg    = Encoding.UTF8.GetString(buff, 0, commitMsgLength);
            string treeHash     = null;
            var    parentHashes = new List <string>();
            ReceivePackCommitSignature author    = null;
            ReceivePackCommitSignature committer = null;

            var commitLines = commitMsg.Split('\n');

            var commitHeadersEndIndex = 0;

            foreach (var commitLine in commitLines)
            {
                commitHeadersEndIndex += 1;

                // Make sure we have safe default values in case the string is empty.
                var commitHeaderType = "";
                var commitHeaderData = "";

                // Find the index of the first space.
                var firstSpace = commitLine.IndexOf(' ');
                if (firstSpace < 0)
                {
                    // Ensure that we always have a valid length for the type.
                    firstSpace = commitLine.Length;
                }

                // Take everything up to the first space as the type.
                commitHeaderType = commitLine.Substring(0, firstSpace);

                // Data starts immediately following the space (if there is any).
                var dataStart = firstSpace + 1;
                if (dataStart < commitLine.Length)
                {
                    commitHeaderData = commitLine.Substring(dataStart);
                }

                if (commitHeaderType == "tree")
                {
                    treeHash = commitHeaderData;
                }
                else if (commitHeaderType == "parent")
                {
                    parentHashes.Add(commitHeaderData);
                }
                else if (commitHeaderType == "author")
                {
                    author = ParseSignature(commitHeaderData);
                }
                else if (commitHeaderType == "committer")
                {
                    committer = ParseSignature(commitHeaderData);
                }
                else if (commitHeaderType == "")
                {
                    // The first empty type indicates the end of the headers.
                    break;
                }
                else
                {
                    // unrecognized header encountered, skip over it
                }
            }

            var commitComment = string.Join("\n", commitLines.Skip(commitHeadersEndIndex).ToArray()).TrimEnd('\n');


            // Compute commit hash
            using (var sha1 = new SHA1CryptoServiceProvider())
            {
                var commitHashHeader = Encoding.UTF8.GetBytes(string.Format("commit {0}\0", commitMsgLength));

                sha1.TransformBlock(commitHashHeader, 0, commitHashHeader.Length, commitHashHeader, 0);
                sha1.TransformFinalBlock(buff, 0, commitMsgLength);

                var commitHashBytes = sha1.Hash;

                var sb = new StringBuilder();
                foreach (byte b in commitHashBytes)
                {
                    var hex = b.ToString("x2");
                    sb.Append(hex);
                }
                var commitHash = sb.ToString();

                return(new ReceivePackCommit(commitHash, treeHash, parentHashes,
                                             author, committer, commitComment));
            }
        }