public void CheckSubmoduleStatus(GitModule submodule) { Status = SubmoduleStatus.NewSubmodule; if (submodule == null) return; Status = submodule.CheckSubmoduleStatus(Commit, OldCommit); }
public CommitData GetOldCommitData(GitModule submodule) { if (submodule == null || !submodule.IsValidGitWorkingDir()) return null; string error = ""; return CommitData.GetCommitData(submodule, OldCommit, ref error); }
private static Tuple<Dictionary<string, int>, int> GroupAllCommitsByContributor(GitModule module, DateTime since, DateTime until) { var sinceParam = since != DateTime.MinValue ? GetDateParameter(since, "since") : ""; var untilParam = until != DateTime.MaxValue ? GetDateParameter(since, "until") : ""; var unformattedCommitsPerContributor = module.RunGitCmd( "shortlog --all -s -n --no-merges" + sinceParam + untilParam) .Split('\n'); return ParseCommitsPerContributor(unformattedCommitsPerContributor); }
public FormProcess(string process, string arguments, GitModule module, bool useDialogSettings) : this(process, arguments, module, null, true) { }
private void execute(ILoadingTaskState taskState) { string authorName = this.RespectMailmap ? "%aN" : "%an"; string command = "log --pretty=tformat:\"--- %ad --- " + authorName + "\" --numstat --date=iso -C --all --no-merges"; LoadModuleInfo(command, Settings.WorkingDir, taskState); if (ShowSubmodules) { IList<string> submodules = Settings.Module.GetSubmodulesLocalPaths(); GitModule submodule = new GitModule(); foreach (var submoduleName in submodules) { submodule.WorkingDir = Settings.Module.GetSubmoduleFullPath(submoduleName); if (submodule.ValidWorkingDir()) LoadModuleInfo(command, submodule.WorkingDir, taskState); } } }
public static bool ShowDialog(IWin32Window owner, GitModule module, string process, string arguments) { return(ShowDialog(owner, process, arguments, module.WorkingDir, null, true)); }
public CommitAutoCompleteProvider(GitModule module) { _module = module; }
private void AddTopAndNodesToTree( ref Nodes nodes, List <SubmoduleNode> submoduleNodes, GitModule threadModule, SubmoduleInfoResult result) { // Create tree of SubmoduleFolderNode for each path directory and add input SubmoduleNodes as leaves. // Example of (SuperPath + LocalPath).ToPosixPath() for all nodes: // // C:/code/gitextensions2/Externals/conemu-inside // C:/code/gitextensions2/Externals/Git.hub // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor/gitextensions // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor/gitextensions/Externals/conemu-inside // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor/gitextensions/Externals/Git.hub // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor/gitextensions/Externals/ICSharpCode.TextEditor // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor/gitextensions/Externals/NBug // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor/gitextensions/GitExtensionsDoc // C:/code/gitextensions2/Externals/NBug // C:/code/gitextensions2/GitExtensionsDoc // // What we want to do is first remove the topModule portion, "C:/code/gitextensions2/", and // then build our tree by breaking up each path into parts, separated by '/'. // // Note that when we break up the paths, some parts are just directories, the others are submodule nodes: // // Externals / ICSharpCode.TextEditor / gitextensions / Externals / Git.hub // folder submodule submodule folder submodule // // Input 'nodes' is an array of SubmoduleNodes for all the submodules; now we need to create SubmoduleFolderNodes // and insert everything into a tree. var topModule = threadModule.GetTopModule(); // Build a mapping of top-module-relative path to node var pathToNodes = new Dictionary <string, Node>(); // Add existing SubmoduleNodes foreach (var node in submoduleNodes) { pathToNodes[GetNodeRelativePath(topModule, node)] = node; } // Create and add missing SubmoduleFolderNodes foreach (var node in submoduleNodes) { var parts = GetNodeRelativePath(topModule, node).Split('/'); for (int i = 0; i < parts.Length - 1; ++i) { var path = string.Join("/", parts.Take(i + 1)); if (!pathToNodes.ContainsKey(path)) { pathToNodes[path] = new SubmoduleFolderNode(this, parts[i]); } } } // Now build the tree var rootNode = new DummyNode(); var nodesInTree = new HashSet <Node>(); foreach (var node in submoduleNodes) { Node parentNode = rootNode; var parts = GetNodeRelativePath(topModule, node).Split('/'); for (int i = 0; i < parts.Length; ++i) { var path = string.Join("/", parts.Take(i + 1)); var nodeToAdd = pathToNodes[path]; // If node is not already in the tree, add it if (!nodesInTree.Contains(nodeToAdd)) { parentNode.Nodes.AddNode(nodeToAdd); nodesInTree.Add(nodeToAdd); } parentNode = nodeToAdd; } } Validates.NotNull(result.TopProject); // Add top-module node, and move children of root to it var topModuleNode = new SubmoduleNode( this, result.TopProject, result.TopProject.Bold, result.TopProject.Bold ? result.CurrentSubmoduleStatus : null, "", result.TopProject.Path); topModuleNode.Nodes.AddNodes(rootNode.Nodes); nodes.AddNode(topModuleNode); }
protected override void OnRuntimeLoad(EventArgs e) { base.OnRuntimeLoad(e); FillFromDropDown(); _NO_TRANSLATE_To.Text = AppSettings.DefaultCloneDestinationPath; if (CanBeGitURL(url) || GitModule.IsValidGitWorkingDir(url)) { _NO_TRANSLATE_From.Text = url; } else { // Try to be more helpful to the user. // Use the cliboard text as a potential source URL. try { if (Clipboard.ContainsText(TextDataFormat.Text)) { string text = Clipboard.GetText(TextDataFormat.Text) ?? string.Empty; // See if it's a valid URL. if (CanBeGitURL(text)) { _NO_TRANSLATE_From.Text = text; } } } catch (Exception) { // We tried. } //if the From field is empty, then fill it with the current repository remote URL in hope //that the cloned repository is hosted on the same server if (_NO_TRANSLATE_From.Text.IsNullOrWhiteSpace()) { var currentBranchRemote = Module.GetSetting(string.Format(SettingKeyString.BranchRemote, Module.GetSelectedBranch())); if (currentBranchRemote.IsNullOrEmpty()) { var remotes = Module.GetRemotes(); if (remotes.Any(s => s.Equals("origin", StringComparison.InvariantCultureIgnoreCase))) { currentBranchRemote = "origin"; } else { currentBranchRemote = remotes.FirstOrDefault(); } } string pushUrl = Module.GetSetting(string.Format(SettingKeyString.RemotePushUrl, currentBranchRemote)); if (pushUrl.IsNullOrEmpty()) { pushUrl = Module.GetSetting(string.Format(SettingKeyString.RemoteUrl, currentBranchRemote)); } _NO_TRANSLATE_From.Text = pushUrl; try { // If the from directory is filled with the pushUrl from current working directory, set the destination directory to the parent if (pushUrl.IsNotNullOrWhitespace() && _NO_TRANSLATE_To.Text.IsNullOrWhiteSpace() && Module.WorkingDir.IsNotNullOrWhitespace()) { _NO_TRANSLATE_To.Text = Path.GetDirectoryName(Module.WorkingDir.TrimEnd(Path.DirectorySeparatorChar)); } } catch (Exception) { // Exceptions on setting the destination directory can be ingnored } } } //if there is no destination directory, then use current working directory if (_NO_TRANSLATE_To.Text.IsNullOrWhiteSpace() && Module.WorkingDir.IsNotNullOrWhitespace()) { _NO_TRANSLATE_To.Text = Module.WorkingDir.TrimEnd(Path.DirectorySeparatorChar); } FromTextUpdate(null, null); cbLfs.Enabled = Module.HasLfsSupport(); if (!cbLfs.Enabled) { cbLfs.Checked = false; } }
private void OkClick(object sender, EventArgs e) { try { Cursor = Cursors.Default; _branchListLoader.Cancel(); var dirTo = Path.Combine(_NO_TRANSLATE_To.Text, _NO_TRANSLATE_NewDirectory.Text); Repositories.AddMostRecentRepository(_NO_TRANSLATE_From.Text); if (!Directory.Exists(dirTo)) { Directory.CreateDirectory(dirTo); } // Shallow clone params int? depth = null; bool?isSingleBranch = null; if (!cbDownloadFullHistory.Checked) { depth = 1; // Single branch considerations: // If neither depth nor single-branch family params are specified, then it's like no-single-branch by default. // If depth is specified, then single-branch is assumed. // But with single-branch it's really nontrivial to switch to another branch in the GUI, and it's very hard in cmdline (obvious choices to fetch another branch lead to local repo corruption). // So let's reset it to no-single-branch to (a) have the same branches behavior as with full clone, and (b) make it easier for users when switching branches. isSingleBranch = false; } // Branch name param string branch = _NO_TRANSLATE_Branches.Text; if (branch == _branchDefaultRemoteHead.Text) { branch = ""; } else if (branch == _branchNone.Text) { branch = null; } var cloneCmd = GitCommandHelpers.CloneCmd(_NO_TRANSLATE_From.Text, dirTo, CentralRepository.Checked, cbIntializeAllSubmodules.Checked, branch, depth, isSingleBranch, cbLfs.Checked); using (var fromProcess = new FormRemoteProcess(Module, AppSettings.GitCommand, cloneCmd)) { fromProcess.SetUrlTryingToConnect(_NO_TRANSLATE_From.Text); fromProcess.ShowDialog(this); if (fromProcess.ErrorOccurred() || Module.InTheMiddleOfPatch()) { return; } } Repositories.AddMostRecentRepository(dirTo); if (!String.IsNullOrEmpty(_puttySshKey)) { var clonedGitModule = new GitModule(dirTo); clonedGitModule.SetSetting(string.Format(SettingKeyString.RemotePuttySshKey, "origin"), _puttySshKey); clonedGitModule.LocalConfigFile.Save(); } if (openedFromProtocolHandler && AskIfNewRepositoryShouldBeOpened(dirTo)) { Hide(); GitUICommands uiCommands = new GitUICommands(dirTo); uiCommands.StartBrowseDialog(); } else if (ShowInTaskbar == false && GitModuleChanged != null && AskIfNewRepositoryShouldBeOpened(dirTo)) { GitModuleChanged(this, new GitModuleEventArgs(new GitModule(dirTo))); } Close(); } catch (Exception ex) { MessageBox.Show(this, "Exception: " + ex.Message, "Clone failed", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private bool CalculateLocalBranch(string remote, out string curLocalBranch, out string curRemoteBranch) { if (IsPullAll()) { curLocalBranch = null; curRemoteBranch = null; return(true); } curRemoteBranch = Branches.Text; if (GitModule.IsDetachedHead(_branch)) { curLocalBranch = null; return(true); } var currentBranchRemote = new Lazy <string>(() => Module.GetSetting(string.Format("branch.{0}.remote", localBranch.Text))); if (_branch == localBranch.Text) { if (remote.Equals(currentBranchRemote.Value) || currentBranchRemote.Value.IsNullOrEmpty()) { curLocalBranch = Branches.Text.IsNullOrEmpty() ? null : _branch; } else { curLocalBranch = localBranch.Text; } } else { curLocalBranch = localBranch.Text; } if (Branches.Text.IsNullOrEmpty() && !curLocalBranch.IsNullOrEmpty() && !remote.Equals(currentBranchRemote.Value) && !Fetch.Checked) { int idx = PSTaskDialog.cTaskDialog.ShowCommandBox(this, _noRemoteBranchCaption.Text, _noRemoteBranch.Text, string.Format(_noRemoteBranchMainInstruction.Text, remote), string.Format(_noRemoteBranchButtons.Text, remote + "/" + curLocalBranch), false); switch (idx) { case 0: curRemoteBranch = curLocalBranch; return(true); default: return(false); } } if (Branches.Text.IsNullOrEmpty() && !curLocalBranch.IsNullOrEmpty() && Fetch.Checked) { //if local branch eq to current branch and remote branch is not specified //then run fetch with no refspec if (_branch == curLocalBranch) { curLocalBranch = null; return(true); } int idx = PSTaskDialog.cTaskDialog.ShowCommandBox(this, _noRemoteBranchCaption.Text, _noRemoteBranch.Text, string.Format(_noRemoteBranchForFetchMainInstruction.Text, remote), string.Format(_noRemoteBranchForFetchButtons.Text, remote + "/" + curLocalBranch), false); switch (idx) { case 0: curRemoteBranch = curLocalBranch; return(true); default: return(false); } } return(true); }
public void GetSortedRefs_should_throw_on_git_warning() { GitModule module = GetGitModuleWithMockedResultOfGitCommand("refs/heads/master\nwarning: message"); ((Action)(() => module.GetSortedRefs())).Should().Throw <RefsWarningException>(); }
private void UpdateSelectedFileViewers(bool force = false) { var selectedRevisions = FileChanges.GetSelectedRevisions(); if (selectedRevisions.Count == 0) { return; } GitRevision revision = selectedRevisions[0]; var children = FileChanges.GetRevisionChildren(revision.ObjectId); var fileName = revision.Name; if (string.IsNullOrEmpty(fileName)) { fileName = FileName; } SetTitle(fileName); if (revision.IsArtificial) { tabControl1.SelectedTab = DiffTab; CommitInfoTabPage.Parent = null; BlameTab.Parent = null; ViewTab.Parent = null; } else { if (CommitInfoTabPage.Parent == null) { tabControl1.TabPages.Insert(0, CommitInfoTabPage); } if (ViewTab.Parent == null) { var index = tabControl1.TabPages.IndexOf(DiffTab); Debug.Assert(index != -1, "TabControl should contain diff tab page"); tabControl1.TabPages.Insert(index + 1, ViewTab); } if (BlameTab.Parent == null) { var index = tabControl1.TabPages.IndexOf(ViewTab); Debug.Assert(index != -1, "TabControl should contain view tab page"); tabControl1.TabPages.Insert(index + 1, BlameTab); } } if (tabControl1.SelectedTab == BlameTab) { Blame.LoadBlame(revision, children, fileName, FileChanges, BlameTab, Diff.Encoding, force: force); } else if (tabControl1.SelectedTab == ViewTab) { View.Encoding = Diff.Encoding; View.ViewGitItemRevisionAsync(fileName, revision.ObjectId); } else if (tabControl1.SelectedTab == DiffTab) { var file = new GitItemStatus { IsTracked = true, Name = fileName, IsSubmodule = GitModule.IsValidGitWorkingDir(_fullPathResolver.Resolve(fileName)) }; Diff.ViewChangesAsync(FileChanges.GetSelectedRevisions(), file, "You need to select at least one revision to view diff."); } else if (tabControl1.SelectedTab == CommitInfoTabPage) { CommitDiff.SetRevision(revision.ObjectId, fileName); } if (_buildReportTabPageExtension == null) { _buildReportTabPageExtension = new BuildReportTabPageExtension(() => Module, tabControl1, _buildReportTabCaption.Text); } _buildReportTabPageExtension.FillBuildReport(selectedRevisions.Count == 1 ? revision : null); }
public void SetUp() { _executable = new MockExecutable(); _gitModule = GetGitModuleWithExecutable(executable: _executable); }
[TestCase(@"\353\221\220\353\213\244\777.txt", @"\353\221\220\353\213\244\777.txt")] // valid and invalid in the same string public void UnescapeOctalCodePoints_handles_octal_codes(string input, string expected) { Assert.AreEqual(expected, GitModule.UnescapeOctalCodePoints(input)); }
/// <summary> /// Diff part of patch is printed verbatim, everything else (header, warnings, ...) is printed in git encoding (GitModule.SystemEncoding) /// Since patch may contain diff for more than one file, it would be nice to obtaining encoding for each of file /// from .gitattributes, for now there is used one encoding, common for every file in repo (Settings.FilesEncoding) /// File path can be quoted see core.quotepath, it is unquoted by GitCommandHelpers.ReEncodeFileNameFromLossless /// </summary> /// <param name="textReader"></param> /// <returns></returns> public List <Patch> CreatePatchesFromString(String patchText) { var patches = new List <Patch>(); Patch patch = null; PatchProcessorState state = PatchProcessorState.OutsidePatch; string[] lines = patchText.Split('\n'); for (int i = 0; i < lines.Length; i++) { string input = lines[i]; bool validate = true; bool combinedDiff; if (IsStartOfANewPatch(input, out combinedDiff)) { state = PatchProcessorState.InHeader; validate = false; patch = new Patch(); patches.Add(patch); input = GitModule.ReEncodeFileNameFromLossless(input); patch.PatchHeader = input; patch.Type = Patch.PatchType.ChangeFile; patch.CombinedDiff = combinedDiff; if (!combinedDiff) { ExtractPatchFilenames(patch); } } else if (state == PatchProcessorState.InHeader) { if (IsChunkHeader(input)) { state = PatchProcessorState.InBody; } else { //header lines are encoded in GitModule.SystemEncoding input = GitModule.ReEncodeStringFromLossless(input, GitModule.SystemEncoding); if (IsIndexLine(input)) { validate = false; patch.PatchIndex = input; } else { if (SetPatchType(input, patch)) { } else if (IsUnlistedBinaryFileDelete(input)) { if (patch.Type != Patch.PatchType.DeleteFile) { throw new FormatException("Change not parsed correct: " + input); } patch.File = Patch.FileType.Binary; patch = null; state = PatchProcessorState.OutsidePatch; } else if (IsUnlistedBinaryNewFile(input)) { if (patch.Type != Patch.PatchType.NewFile) { throw new FormatException("Change not parsed correct: " + input); } patch.File = Patch.FileType.Binary; //TODO: NOT SUPPORTED! patch.Apply = false; patch = null; state = PatchProcessorState.OutsidePatch; } else if (IsBinaryPatch(input)) { patch.File = Patch.FileType.Binary; //TODO: NOT SUPPORTED! patch.Apply = false; patch = null; state = PatchProcessorState.OutsidePatch; } } } } if (state != PatchProcessorState.OutsidePatch) { if (validate) { ValidateInput(ref input, patch, state); } patch.AppendText(input); if (i < lines.Length - 1) { patch.AppendText("\n"); } } } return(patches); }
private void ValidateInput(ref string input, Patch patch, PatchProcessorState state) { if (state == PatchProcessorState.InHeader) { //--- /dev/null //means there is no old file, so this should be a new file if (IsOldFileMissing(input)) { if (patch.Type != Patch.PatchType.NewFile) { throw new FormatException("Change not parsed correct: " + input); } } //line starts with --- means, old file name else if (input.StartsWith("--- ")) { input = GitModule.UnquoteFileName(input); Match regexMatch = Regex.Match(input, "[-]{3}[ ][\\\"]{0,1}[aiwco12]/(.*)[\\\"]{0,1}"); if (!regexMatch.Success || patch.FileNameA != (regexMatch.Groups[1].Value.Trim())) { if (!patch.CombinedDiff) { throw new FormatException("Old filename not parsed correct: " + input); } patch.FileNameA = regexMatch.Groups[1].Value.Trim(); } } else if (IsNewFileMissing(input)) { if (patch.Type != Patch.PatchType.DeleteFile) { throw new FormatException("Change not parsed correct: " + input); } } //line starts with +++ means, new file name //we expect a new file now! else if (input.StartsWith("+++ ")) { if (patch.CombinedDiff) { return; } input = GitModule.UnquoteFileName(input); Match regexMatch = Regex.Match(input, "[+]{3}[ ][\\\"]{0,1}[biwco12]/(.*)[\\\"]{0,1}"); if (!regexMatch.Success || patch.FileNameB != (regexMatch.Groups[1].Value.Trim())) { if (!patch.CombinedDiff) { throw new FormatException("New filename not parsed correct: " + input); } patch.FileNameB = regexMatch.Groups[1].Value.Trim(); } } } else { if (input.StartsWithAny(new string[] { " ", "-", "+", "@" })) { //diff content input = GitModule.ReEncodeStringFromLossless(input, FilesContentEncoding); } else { //warnings, messages ... input = GitModule.ReEncodeStringFromLossless(input, GitModule.SystemEncoding); } } }
public void Setup() { _module = new GitModule(""); }
private static string GetFilePath(GitModule module, string action) { return(Path.Combine(module.WorkingDirGitDir, action)); }
public FormProcess(GitModule module, string arguments) : this(module, arguments, true) { }
private string GetNodeRelativePath(GitModule topModule, SubmoduleNode node) { return(node.SuperPath.SubstringAfter(topModule.WorkingDir).ToPosixPath() + node.LocalPath); }
public FormProcess(GitModule module, string arguments, bool useDialogSettings) : this(null, arguments, module, useDialogSettings) { }
public GitItem(GitModule aModule) { Module = aModule; }
public static string ProcessSubmoduleStatus([NotNull] GitModule module, [NotNull] GitSubmoduleStatus status) { if (module == null) { throw new ArgumentNullException("module"); } if (status == null) { throw new ArgumentNullException("status"); } GitModule gitmodule = module.GetSubmodule(status.Name); StringBuilder sb = new StringBuilder(); sb.AppendLine("Submodule " + status.Name + " Change"); // TEMP, will be moved in the follow up refactor ICommitDataManager commitDataManager = new CommitDataManager(() => gitmodule); sb.AppendLine(); sb.AppendLine("From:\t" + (status.OldCommit ?? "null")); CommitData oldCommitData = null; if (gitmodule.IsValidGitWorkingDir()) { string error = ""; if (status.OldCommit != null) { oldCommitData = commitDataManager.GetCommitData(status.OldCommit, ref error); } if (oldCommitData != null) { sb.AppendLine("\t\t\t\t\t" + GetRelativeDateString(DateTime.UtcNow, oldCommitData.CommitDate.UtcDateTime) + " (" + GetFullDateString(oldCommitData.CommitDate) + ")"); var delim = new char[] { '\n', '\r' }; var lines = oldCommitData.Body.Trim(delim).Split(new string[] { "\r\n" }, 0); foreach (var curline in lines) { sb.AppendLine("\t\t" + curline); } } } else { sb.AppendLine(); } sb.AppendLine(); string dirty = !status.IsDirty ? "" : " (dirty)"; sb.AppendLine("To:\t\t" + (status.Commit ?? "null") + dirty); CommitData commitData = null; if (gitmodule.IsValidGitWorkingDir()) { string error = ""; if (status.Commit != null) { commitData = commitDataManager.GetCommitData(status.Commit, ref error); } if (commitData != null) { sb.AppendLine("\t\t\t\t\t" + GetRelativeDateString(DateTime.UtcNow, commitData.CommitDate.UtcDateTime) + " (" + GetFullDateString(commitData.CommitDate) + ")"); var delim = new char[] { '\n', '\r' }; var lines = commitData.Body.Trim(delim).Split(new string[] { "\r\n" }, 0); foreach (var curline in lines) { sb.AppendLine("\t\t" + curline); } } } else { sb.AppendLine(); } sb.AppendLine(); var submoduleStatus = gitmodule.CheckSubmoduleStatus(status.Commit, status.OldCommit, commitData, oldCommitData); sb.Append("Type: "); switch (submoduleStatus) { case SubmoduleStatus.NewSubmodule: sb.AppendLine("New submodule"); break; case SubmoduleStatus.FastForward: sb.AppendLine("Fast Forward"); break; case SubmoduleStatus.Rewind: sb.AppendLine("Rewind"); break; case SubmoduleStatus.NewerTime: sb.AppendLine("Newer commit time"); break; case SubmoduleStatus.OlderTime: sb.AppendLine("Older commit time"); break; case SubmoduleStatus.SameTime: sb.AppendLine("Same commit time"); break; default: sb.AppendLine("Unknown"); break; } if (status.AddedCommits != null && status.RemovedCommits != null && (status.AddedCommits != 0 || status.RemovedCommits != 0)) { sb.Append("\nCommits: "); if (status.RemovedCommits > 0) { sb.Append(status.RemovedCommits + " removed"); if (status.AddedCommits > 0) { sb.Append(", "); } } if (status.AddedCommits > 0) { sb.Append(status.AddedCommits + " added"); } sb.AppendLine(); } if (status.Commit != null && status.OldCommit != null) { if (status.IsDirty) { string statusText = gitmodule.GetStatusText(false); if (!String.IsNullOrEmpty(statusText)) { sb.AppendLine("\nStatus:"); sb.Append(statusText); } } string diffs = gitmodule.GetDiffFilesText(status.OldCommit, status.Commit); if (!String.IsNullOrEmpty(diffs)) { sb.AppendLine("\nDifferences:"); sb.Append(diffs); } } return(sb.ToString()); }
public static string ReadDialog(IWin32Window owner, string process, string arguments, GitModule module, string input, bool useDialogSettings) { using (var formProcess = new FormProcess(process, arguments, module.WorkingDir, input, useDialogSettings)) { formProcess.ShowDialog(owner); return(formProcess.GetOutputString()); } }
public static ConfigFileSettings CreateEffective(GitModule module) { return(CreateLocal(module, CreateGlobal(CreateSystemWide()), SettingLevel.Effective)); }
public static bool ShowDialog(IWin32Window owner, GitModule module, string arguments, bool useDialogSettings) { return(ShowDialog(owner, null, arguments, module.WorkingDir, null, useDialogSettings)); }
public static ConfigFileSettings CreateEffective(GitModule aModule) { return(CreateLocal(aModule, CreateGlobal())); }
/// <summary> /// Gets the commit info from CommitData. /// </summary> /// <returns></returns> public static CommitInformation GetCommitInfo(CommitData data, LinkFactory linkFactory, bool showRevisionsAsLinks, GitModule module = null) { if (data == null) { throw new ArgumentNullException("data"); } string header = data.GetHeader(linkFactory, showRevisionsAsLinks); string body = "\n" + WebUtility.HtmlEncode(data.Body.Trim()); if (showRevisionsAsLinks) { body = GitRevision.Sha1HashShortRegex.Replace(body, match => ProcessHashCandidate(module, linkFactory, hash: match.Value)); } return(new CommitInformation(header, body)); }
public static ConfigFileSettings CreateLocal(GitModule aModule, bool allowCache = true) { return(CreateLocal(aModule, null, allowCache)); }
public static Tuple<Dictionary<string, int>, int> GroupAllCommitsByContributor(GitModule module) { return GroupAllCommitsByContributor(module, DateTime.MinValue, DateTime.MaxValue); }
private static ConfigFileSettings CreateLocal(GitModule aModule, ConfigFileSettings aLowerPriority, bool allowCache = true) { return(new ConfigFileSettings(aLowerPriority, ConfigFileSettingsCache.Create(Path.Combine(aModule.GetGitDirectory(), "config"), true, allowCache))); }
public GitModule GetSubmodule(GitModule module) { return module.GetSubmodule(Name); }
public static string GetCommitMessagePath(GitModule module) { return(GetFilePath(module, "COMMITMESSAGE")); }
private static string GetAmendPath(GitModule module) { return(GetFilePath(module, "GitExtensions.amend")); }
public static GitSubmoduleStatus?ParseSubmoduleStatus(string?text, GitModule module, string?fileName) { if (string.IsNullOrEmpty(text)) { return(null); } string?name = null; string? oldName = null; bool isDirty = false; ObjectId?commitId = null; ObjectId?oldCommitId = null; int? addedCommits = null; int? removedCommits = null; using (StringReader reader = new(text)) { string?line = reader.ReadLine(); if (line is not null) { var match = Regex.Match(line, @"diff --git [abic]/(.+)\s[abwi]/(.+)"); if (match.Groups.Count > 1) { name = match.Groups[1].Value; oldName = match.Groups[2].Value; } else { match = Regex.Match(line, @"diff --cc (.+)"); if (match.Groups.Count > 1) { name = match.Groups[1].Value; oldName = match.Groups[1].Value; } } } while ((line = reader.ReadLine()) is not null) { // We are looking for lines resembling: // // -Subproject commit bfef4454fc51e345051ee5bf66686dc28deed627 // +Subproject commit 8b20498b954609770205c2cc794b868b4ac3ee69-dirty if (!line.Contains("Subproject")) { continue; } char c = line[0]; const string commitStr = "commit "; string hash = ""; int pos = line.IndexOf(commitStr); if (pos >= 0) { hash = line.Substring(pos + commitStr.Length); } bool endsWithDirty = hash.EndsWith("-dirty"); hash = hash.Replace("-dirty", ""); if (c == '-') { oldCommitId = ObjectId.Parse(hash); } else if (c == '+') { commitId = ObjectId.Parse(hash); isDirty = endsWithDirty; } // TODO: Support combined merge } } if (oldCommitId is not null && commitId is not null) { if (oldCommitId == commitId) { addedCommits = 0; removedCommits = 0; } else { var submodule = module.GetSubmodule(fileName); if (submodule.IsValidGitWorkingDir()) { addedCommits = submodule.GetCommitCount(commitId.ToString(), oldCommitId.ToString(), cache: true, throwOnErrorExit: false); removedCommits = submodule.GetCommitCount(oldCommitId.ToString(), commitId.ToString(), cache: true, throwOnErrorExit: false); } } } Validates.NotNull(name); return(new GitSubmoduleStatus(name, oldName, isDirty, commitId, oldCommitId, addedCommits, removedCommits)); }