예제 #1
0
        /// <summary>
        /// Parses the output of git status --porcelain=v2
        /// </summary>
        /// <param name="lines">Output lines</param>
        /// <returns>Parsed <see cref="GitPorcelainInfo"/> object</returns>
        public static GitPorcelainInfo ParseGitPorcelain(string lines)
        {
            if (string.IsNullOrEmpty(lines))
            {
                return(null);
            }

            //Definition of parsers per line type
            var parsers = new Dictionary <char, GitPorcelainLineParser>()
            {
                { '1', GitPorcelainItemType1Parser },
                { '#', GitPorcelainItemHeaderParser },
                { '?', GitPorcelainItemUnTrackedParser },
                { '!', GitPorcelainItemIgnoredParser }
            };

            var gitPorcelainInfo = new GitPorcelainInfo();

            foreach (var lineRaw in lines.Split(new[] { Environment.NewLine }, StringSplitOptions.None))
            {
                var line = lineRaw.Trim();
                if (string.IsNullOrEmpty(line))
                {
                    continue;
                }

                //Get line type
                var lineType = line[0];
                line = line.Substring(1).Trim();
                //Try to get the parser based on the line type
                if (!parsers.TryGetValue(lineType, out var parser))
                {
                    continue;
                }

                //Call parser and add the new file item if available. Parser can also modify the root gitPorcelainInfo object if needed
                var newItem = parser(line, gitPorcelainInfo);
                if (newItem != null)
                {
                    gitPorcelainInfo.Files.Add(newItem);
                }
            }
            return(gitPorcelainInfo);
        }
예제 #2
0
        /// <summary>
        /// Parser of header porcelain line(line type "#")
        /// Currently supports #branch.xxxxx headers
        /// </summary>
        /// <param name="lineWithoutType">Single line from git status --porcelain=v2 without the leading char (line/parser type)</param>
        /// <param name="gitInfo">Reference to the root git info object as the parser manipulates root data</param>
        /// <returns>Always null</returns>
        private static GitPorcelainFileItemInfo GitPorcelainItemHeaderParser(string lineWithoutType, GitPorcelainInfo gitInfo)
        {
            if (string.IsNullOrEmpty(lineWithoutType))
            {
                return(null);
            }
            var key = lineWithoutType.SplitByFirstSpace(out var value);

            // ReSharper disable once SwitchStatementMissingSomeCases
            switch (key)
            {
            case "branch.oid":
                gitInfo.Commit = value;
                break;

            case "branch.head":
                gitInfo.Branch = value;
                break;

            case "branch.upstream":
                gitInfo.Upstream = value;
                break;

            case "branch.ab":
                gitInfo.AB = value;
                break;
            }
            return(null);
        }
예제 #3
0
        /// <summary>
        /// Parser of porcelain line for ignored files (line type "!")
        /// </summary>
        /// <param name="lineWithoutType">Single line from git status --porcelain=v2 without the leading char (line/parser type)</param>
        /// <param name="gitInfo">(Not used) Reference to the root git info object in case the parser needs to manipulate root data</param>
        /// <returns>New instance of file item info if created by line parser otherwise null (when the <paramref name="lineWithoutType"/> is empty)</returns>
        private static GitPorcelainFileItemInfo GitPorcelainItemIgnoredParser(string lineWithoutType, GitPorcelainInfo gitInfo)
        {
            if (string.IsNullOrEmpty(lineWithoutType))
            {
                return(null);
            }
            var item = new GitPorcelainFileItemInfo
            {
                FileName       = lineWithoutType,
                ChangeCode     = "!",
                StatusIndex    = GitChangeTypeEnum.Ignored,
                StatusWorkTree = GitChangeTypeEnum.Ignored,
                IsIgnored      = true
            };

            return(item);
        }
예제 #4
0
        /// <summary>
        /// Parser of porcelain line for modified files (line type "1")
        /// </summary>
        /// <param name="lineWithoutType">Single line from git status --porcelain=v2 without the leading char (line/parser type)</param>
        /// <param name="gitInfo">(Not used) Reference to the root git info object in case the parser needs to manipulate root data</param>
        /// <returns>New instance of file item info if created by line parser otherwise null (when the <paramref name="lineWithoutType"/> is empty)</returns>
        private static GitPorcelainFileItemInfo GitPorcelainItemType1Parser(string lineWithoutType, GitPorcelainInfo gitInfo)
        {
            if (string.IsNullOrEmpty(lineWithoutType))
            {
                return(null);
            }
            var item = new GitPorcelainFileItemInfo();

            var line     = lineWithoutType;
            var xy       = line.SplitByFirstSpace(out line) + "  "; //ensure at least two chars
            var fileName = line.LastPart(" ").Trim();

            if (string.IsNullOrEmpty(fileName))
            {
                return(null);
            }

            item.ChangeCode     = xy.Trim();
            item.StatusIndex    = GetGitChangeType(xy[0]);
            item.StatusWorkTree = GetGitChangeType(xy[1]);

            item.IsUnMerged   = xy.Contains("U") || xy == "AA" || xy == "DD";
            item.IsNotTracked = xy.Contains("?");
            item.IsIgnored    = xy.Contains("!");

            item.FileName = fileName;

            return(item);
        }