Пример #1
0
        static void Main(string[] args)
        {
            Console.OutputEncoding = System.Text.Encoding.UTF8;

            string path = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "autogit");

            path = @"C:\DEV\github\automark\Source\Extensions\automark.VisualStudio\.HistoryData\LocalHistory";
            //path = @"C:\dev\github\automark\Source\automark\.HistoryData\LocalHistory";
            //fatal: bad default revision 'HEAD'
            //path = @"C:\Users\Chris\Downloads\HistoryData\.HistoryData\LocalHistory";
            var reverse = false;
            var html    = false;
            var fuzz    = false;
            var export  = false;

            if (args.Length > 0)
            {
                path = args[0];
            }
            if (args.Any(a => a == "-r"))
            {
                reverse = true;
            }
            if (args.Any(a => a == "-html"))
            {
                html = true;
            }
            if (args.Any(a => a == "-fuzz"))
            {
                fuzz = true;
            }
            if (args.Any(a => a == "-export"))
            {
                export = true;
            }

            var output = GitCommands.ListShaWithFiles(path);

            if (output == "")
            {
                Console.Error.WriteLine("There are no commits to report yet.");
            }

            var parser     = new ParseGitLog();
            var diffParser = new GitDiffParser();
            var commits    = parser.Parse(output);

            // commit for files not yet in repository, skip.
            // in future can be smarter with this with tags, etc.
            commits = commits.Where(c => !c.Message.Contains("pre save")).ToList();

            if (export)
            {
                ExportHistory(path, output, commits);
                return;
            }

            foreach (var commit in commits)
            {
                commit.UnifiedDiff = GitCommands.ShowSha(path, commit.Sha);

                // skip big files for arbiturary definition of big.
                if (commit.UnifiedDiff.Length > 500000)
                {
                    continue;
                }

                ParseUnifiedDiff(path, diffParser, commit);

                //commit.Print();
            }

            // Temporal fuzz
            if (fuzz)
            {
                var commitsToPrune = new List <GitCommit>();
                // Do processing of commits in order, just easier on the brain...
                var inOrderCommits = commits.ToList();
                inOrderCommits.Reverse();

                var prevCommit            = inOrderCommits.FirstOrDefault();
                var accumalatedDifference = new TimeSpan();
                var startOfFuzz           = prevCommit;
                var endOfFuzz             = prevCommit;
                foreach (var commit in inOrderCommits.Skip(1))
                {
                    var lastTime   = ParseGitLog.GetDateFromGitFormat(prevCommit.Headers["Date"]);
                    var commitTime = ParseGitLog.GetDateFromGitFormat(commit.Headers["Date"]);
                    var span       = (lastTime - commitTime).Duration();
                    accumalatedDifference += span;
                    if (accumalatedDifference.TotalMinutes <= 3 &&
                        prevCommit.Files.All(f => commit.Files.Select(c => c.File).Contains(f.File)) &&
                        prevCommit.Files.Any(f => f.Status != "A" || f.Status != "D"))
                    {
                        commitsToPrune.Add(prevCommit);
                        endOfFuzz = commit;
                    }
                    else
                    {
                        // endOfFuzz will be only surviving commit in range, others will be pruned.
                        // Get a new unified diff, and then reparse.
                        if (startOfFuzz != endOfFuzz)
                        {
                            try
                            {
                                endOfFuzz.UnifiedDiff = GitCommands.ShowDiffRange(path, startOfFuzz.Sha + "~1", endOfFuzz.Sha);
                                ParseUnifiedDiff(path, diffParser, endOfFuzz);
                            }
                            catch (Exception ex)
                            {
                                Trace.WriteLine(ex.Message);
                            }
                        }
                        accumalatedDifference = new TimeSpan();
                        startOfFuzz           = commit;
                        endOfFuzz             = commit;
                    }

                    prevCommit = commit;
                }

                if (startOfFuzz != endOfFuzz)
                {
                    try
                    {
                        endOfFuzz.UnifiedDiff = GitCommands.ShowDiffRange(path, startOfFuzz.Sha + "~1", endOfFuzz.Sha);
                        ParseUnifiedDiff(path, diffParser, endOfFuzz);
                    }
                    catch (Exception ex)
                    {
                        Trace.WriteLine(ex.Message);
                    }
                }

                foreach (var commitToRemove in commitsToPrune)
                {
                    commits.Remove(commitToRemove);
                }
            }

            //////////////////
            // CUSTOM FILTERS
            //////////////////
            commits = commits.Where(c => c.Difflets.Count > 0 && !c.Difflets[0].FileName.EndsWith(".csproj")).ToList();

            // Remove hunks that are only from newline.
            foreach (var commit in commits)
            {
                foreach (var fileDiff in commit.Difflets)
                {
                    fileDiff.Hunks = fileDiff.Hunks.Where(hunk =>
                                                          !(hunk.DiffLines
                                                            .Where(l => l.Trim().StartsWith("+"))
                                                            .All(l => l.Trim() == "+") && hunk.IsAddition)
                                                          &&
                                                          !(hunk.DiffLines
                                                            .Where(l => l.Trim().StartsWith("-"))
                                                            .All(l => l.Trim() == "-") && hunk.IsDeletion)
                                                          ).ToList();
                }
            }
            // Remove commits that now have 0 hunks.
            commits = commits.Where(c => c.Difflets.All(f => f.Hunks.Count > 0)).ToList();

            //commits = FixOnFix(commits);
            CodeWebHistory(commits);

            if (reverse)
            {
                commits.Reverse();
            }
            if (html)
            {
                var formatter = new AsMarkdownHtml();
                Console.WriteLine(formatter.Export(commits));
            }
            else
            {
                var formatter = new AsMarkdown();
                Console.WriteLine(formatter.Export(commits, args.Length == 0));
            }

            //var html = new AsMarkdownHtml();
            //Console.WriteLine(html.Export(commits));
            if (args.Length == 0)
            {
                Thread.CurrentThread.CurrentCulture   = CultureInfo.CreateSpecificCulture("sv-SE");
                Thread.CurrentThread.CurrentUICulture = new CultureInfo("sv-SE");

                Console.WriteLine(string.Format("## {0:dddd, MMMM dd, yyyy}\u00e5", DateTime.Now.AddDays(-2)));

                Console.ReadKey();
            }
        }