/// <summary> /// Generates the blame for file. /// </summary> /// <param name="relativePath">The relative path.</param> /// <returns>Returns command line blame line.</returns> private GitBlame GenerateBlameForFile(string relativePath) { this.executor.ResetData(); this.executor.ExecuteCommand("git.exe", "blame --porcelain -M -w " + relativePath, new Dictionary <string, string>(), this.basePath); var lines = this.executor.GetStdOut(); return(GitExtensionsFunctions.GenerateBlameForFile(relativePath, lines)); }
/// <summary> /// Generates the blame for file. /// </summary> /// <param name="relativePath">The relative path.</param> /// <param name="lines">The lines.</param> /// <returns> /// Returns command line blame line. /// </returns> public static GitBlame GenerateBlameForFile(string relativePath, IList <string> lines) { GitBlame blame = new GitBlame(); GitBlameHeader blameHeader = null; GitBlameLine blameLine = null; foreach (var line in lines) { try { //The contents of the actual line is output after the above header, prefixed by a TAB. This is to allow adding more header elements later. if (line.StartsWith("\t")) { blameLine.LineText = line.Substring(1) //trim ONLY first tab .Trim(new char[] { '\r' }); //trim \r, this is a workaround for a \r\n bug blameLine.LineText = GitExtensionsFunctions.ReEncodeStringFromLossless(blameLine.LineText, Encoding.Default); } else if (line.StartsWith("author-mail")) { blameHeader.AuthorMail = GitExtensionsFunctions.ReEncodeStringFromLossless(line.Substring("author-mail".Length).Trim()); } else if (line.StartsWith("author-time")) { blameHeader.AuthorTime = DateTimeUtils.ParseUnixTime(line.Substring("author-time".Length).Trim()); } else if (line.StartsWith("author-tz")) { blameHeader.AuthorTimeZone = line.Substring("author-tz".Length).Trim(); } else if (line.StartsWith("author")) { blameHeader = new GitBlameHeader(); blameHeader.CommitGuid = blameLine.CommitGuid; blameHeader.Author = GitExtensionsFunctions.ReEncodeStringFromLossless(line.Substring("author".Length).Trim()); blame.Headers.Add(blameHeader); } else if (line.StartsWith("committer-mail")) { blameHeader.CommitterMail = line.Substring("committer-mail".Length).Trim(); } else if (line.StartsWith("committer-time")) { blameHeader.CommitterTime = DateTimeUtils.ParseUnixTime(line.Substring("committer-time".Length).Trim()); } else if (line.StartsWith("committer-tz")) { blameHeader.CommitterTimeZone = line.Substring("committer-tz".Length).Trim(); } else if (line.StartsWith("committer")) { blameHeader.Committer = GitExtensionsFunctions.ReEncodeStringFromLossless(line.Substring("committer".Length).Trim()); } else if (line.StartsWith("summary")) { blameHeader.Summary = GitExtensionsFunctions.ReEncodeStringFromLossless(line.Substring("summary".Length).Trim()); } else if (line.StartsWith("filename")) { blameHeader.FileName = GitExtensionsFunctions.ReEncodeFileNameFromLossless(line.Substring("filename".Length).Trim()); } else if (line.IndexOf(' ') == 40) //SHA1, create new line! { blameLine = new GitBlameLine(); var headerParams = line.Split(' '); blameLine.CommitGuid = headerParams[0]; if (headerParams.Length >= 3) { blameLine.OriginLineNumber = int.Parse(headerParams[1]); blameLine.FinalLineNumber = int.Parse(headerParams[2]); } blame.Lines.Add(blameLine); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } return(blame); }