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);
        }
示例#3
0
        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);
        }
示例#4
0
 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);
                }
            }
        }
示例#6
0
 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;
 }
示例#8
0
            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);
            }
示例#9
0
        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;
            }
        }
示例#10
0
        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);
            }
        }
示例#11
0
        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);
        }
示例#12
0
        public void GetSortedRefs_should_throw_on_git_warning()
        {
            GitModule module = GetGitModuleWithMockedResultOfGitCommand("refs/heads/master\nwarning: message");

            ((Action)(() => module.GetSortedRefs())).Should().Throw <RefsWarningException>();
        }
示例#13
0
        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);
        }
示例#14
0
        public void SetUp()
        {
            _executable = new MockExecutable();

            _gitModule = GetGitModuleWithExecutable(executable: _executable);
        }
示例#15
0
 [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));
 }
示例#16
0
        /// <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);
        }
示例#17
0
        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("");
 }
示例#19
0
 private static string GetFilePath(GitModule module, string action)
 {
     return(Path.Combine(module.WorkingDirGitDir, action));
 }
示例#20
0
 public FormProcess(GitModule module, string arguments)
     : this(module, arguments, true)
 {
 }
示例#21
0
 private string GetNodeRelativePath(GitModule topModule, SubmoduleNode node)
 {
     return(node.SuperPath.SubstringAfter(topModule.WorkingDir).ToPosixPath() + node.LocalPath);
 }
示例#22
0
 public FormProcess(GitModule module, string arguments, bool useDialogSettings)
     : this(null, arguments, module, useDialogSettings)
 {
 }
示例#23
0
 public GitItem(GitModule aModule)
 {
     Module = aModule;
 }
示例#24
0
        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());
        }
示例#25
0
 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));
 }
示例#27
0
 public static bool ShowDialog(IWin32Window owner, GitModule module, string arguments, bool useDialogSettings)
 {
     return(ShowDialog(owner, null, arguments, module.WorkingDir, null, useDialogSettings));
 }
示例#28
0
 public static ConfigFileSettings CreateEffective(GitModule aModule)
 {
     return(CreateLocal(aModule, CreateGlobal()));
 }
示例#29
0
        /// <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));
        }
示例#30
0
 public static ConfigFileSettings CreateLocal(GitModule aModule, bool allowCache = true)
 {
     return(CreateLocal(aModule, null, allowCache));
 }
示例#31
0
 public static Tuple<Dictionary<string, int>, int> GroupAllCommitsByContributor(GitModule module)
 {
     return GroupAllCommitsByContributor(module, DateTime.MinValue, DateTime.MaxValue);
 }
示例#32
0
 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);
 }
示例#34
0
 public static string GetCommitMessagePath(GitModule module)
 {
     return(GetFilePath(module, "COMMITMESSAGE"));
 }
示例#35
0
 private static string GetAmendPath(GitModule module)
 {
     return(GetFilePath(module, "GitExtensions.amend"));
 }
示例#36
0
        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));
        }