From 65cf644bd8f7d1608e65607a4cb8960985164edb Mon Sep 17 00:00:00 2001 From: Philippe Miossec Date: Tue, 25 Aug 2015 14:24:37 +0200 Subject: [PATCH 1/3] When a ref name is already used, find a strategy to give another one An example of the case happening when cloning an existing tfs repository was a branch created in "$/project/dev/my_branch" when in the past was existing or still exists a branch with the path "$/project/dev" (the first refs created prevent to create a folder with the same name). The solution here is to add a `_` at the beginning of the expected ref name until we found a ref name which is not used. --- GitTfs/Core/GitRepository.cs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/GitTfs/Core/GitRepository.cs b/GitTfs/Core/GitRepository.cs index e92eaa5d..b7e39c74 100644 --- a/GitTfs/Core/GitRepository.cs +++ b/GitTfs/Core/GitRepository.cs @@ -61,6 +61,11 @@ namespace Sep.Git.Tfs.Core return "refs/heads/" + branchName; } + public static string ShortToTfsRemoteName(string branchName) + { + return "refs/remotes/tfs/" + branchName; + } + public string GitDir { get; set; } public string WorkingCopyPath { get; set; } public string WorkingCopySubdir { get; set; } @@ -508,9 +513,28 @@ namespace Sep.Git.Tfs.Core { if (!Reference.IsValidName(ShortToLocalName(gitBranchName))) throw new GitTfsException("The name specified for the new git branch is not allowed. Choose another one!"); + while (IsRefNameUsed(gitBranchName)) + { + gitBranchName = "_" + gitBranchName; + } return gitBranchName; } + private bool IsRefNameUsed(string gitBranchName) + { + var parts = gitBranchName.Split('/'); + var refName = parts.First(); + for (int i = 1; i <= parts.Length; i++) + { + if (HasRef(ShortToLocalName(refName)) || HasRef(ShortToTfsRemoteName(refName))) + return true; + if (i < parts.Length) + refName += '/' + parts[i]; + } + + return false; + } + public bool CreateBranch(string gitBranchName, string target) { Reference reference; From c41c484bc31ea59b19609a161e5194f9e9d2c4f1 Mon Sep 17 00:00:00 2001 From: Philippe Miossec Date: Sun, 4 Oct 2015 13:05:15 +0200 Subject: [PATCH 2/3] Remove the GitTfs.2010.sln file --- GitTfs.2010.sln | 85 ------------------------------------------------- 1 file changed, 85 deletions(-) delete mode 100644 GitTfs.2010.sln diff --git a/GitTfs.2010.sln b/GitTfs.2010.sln deleted file mode 100644 index 07fe5444..00000000 --- a/GitTfs.2010.sln +++ /dev/null @@ -1,85 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitTfs", "GitTfs\GitTfs.csproj", "{55C169E0-93CC-488C-9885-1D4EAF4EA236}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitTfsTest", "GitTfsTest\GitTfsTest.csproj", "{DDFB4746-2BCE-4B34-8E45-056324CF140D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitTfs.Vs2010", "GitTfs.Vs2010\GitTfs.Vs2010.csproj", "{C5A374D3-A2E1-407C-9D6D-541FDB53BD62}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitTfs.VsFake", "GitTfs.VsFake\GitTfs.VsFake.csproj", "{20C411E8-49C7-11E1-A776-3FE84824019B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitTfs.Vs2012", "GitTfs.Vs2012\GitTfs.Vs2012.csproj", "{699CE23D-8BBD-4C15-82E9-7A628ACCA4C6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F52EAF74-50FA-495E-8A4A-29F91F4C00C9}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.exe = .nuget\NuGet.exe - .nuget\nuget.targets = .nuget\nuget.targets - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{4A46FEEE-B8A2-4445-B9D1-8160520C7301}" - ProjectSection(SolutionItems) = preProject - doc\develop-on-mono.md = doc\develop-on-mono.md - doc\release-notes\NEXT.md = doc\release-notes\NEXT.md - README.md = README.md - doc\running-the-unit-tests.md = doc\running-the-unit-tests.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CDE05FFA-9DDB-4694-8CA6-6DB7B235CD7F}" - ProjectSection(SolutionItems) = preProject - CI.proj = CI.proj - Release.proj = Release.proj - Releasing.md = Releasing.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ChocolateyTemplates", "ChocolateyTemplates", "{AC0FE25D-D76B-4EE7-9EA8-470204451C9F}" - ProjectSection(SolutionItems) = preProject - ChocolateyTemplates\chocolateyInstall.ps1 = ChocolateyTemplates\chocolateyInstall.ps1 - ChocolateyTemplates\gittfs.nuspec = ChocolateyTemplates\gittfs.nuspec - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitTfs.Vs2013", "GitTfs.Vs2013\GitTfs.Vs2013.csproj", "{101D3C78-27CC-446A-98EC-E2DE88BF0641}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitTfs.Vs2015", "GitTfs.Vs2015\GitTfs.Vs2015.csproj", "{A7032F30-2C86-4BAF-8F62-33EB7BA917AF}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {55C169E0-93CC-488C-9885-1D4EAF4EA236}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {55C169E0-93CC-488C-9885-1D4EAF4EA236}.Debug|Any CPU.Build.0 = Debug|Any CPU - {55C169E0-93CC-488C-9885-1D4EAF4EA236}.Release|Any CPU.ActiveCfg = Release|Any CPU - {55C169E0-93CC-488C-9885-1D4EAF4EA236}.Release|Any CPU.Build.0 = Release|Any CPU - {DDFB4746-2BCE-4B34-8E45-056324CF140D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DDFB4746-2BCE-4B34-8E45-056324CF140D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DDFB4746-2BCE-4B34-8E45-056324CF140D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C5A374D3-A2E1-407C-9D6D-541FDB53BD62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C5A374D3-A2E1-407C-9D6D-541FDB53BD62}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C5A374D3-A2E1-407C-9D6D-541FDB53BD62}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C5A374D3-A2E1-407C-9D6D-541FDB53BD62}.Release|Any CPU.Build.0 = Release|Any CPU - {20C411E8-49C7-11E1-A776-3FE84824019B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {20C411E8-49C7-11E1-A776-3FE84824019B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {20C411E8-49C7-11E1-A776-3FE84824019B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {20C411E8-49C7-11E1-A776-3FE84824019B}.Release|Any CPU.Build.0 = Release|Any CPU - {699CE23D-8BBD-4C15-82E9-7A628ACCA4C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {699CE23D-8BBD-4C15-82E9-7A628ACCA4C6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {699CE23D-8BBD-4C15-82E9-7A628ACCA4C6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {699CE23D-8BBD-4C15-82E9-7A628ACCA4C6}.Release|Any CPU.Build.0 = Release|Any CPU - {101D3C78-27CC-446A-98EC-E2DE88BF0641}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {101D3C78-27CC-446A-98EC-E2DE88BF0641}.Debug|Any CPU.Build.0 = Debug|Any CPU - {101D3C78-27CC-446A-98EC-E2DE88BF0641}.Release|Any CPU.ActiveCfg = Release|Any CPU - {101D3C78-27CC-446A-98EC-E2DE88BF0641}.Release|Any CPU.Build.0 = Release|Any CPU - {A7032F30-2C86-4BAF-8F62-33EB7BA917AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A7032F30-2C86-4BAF-8F62-33EB7BA917AF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A7032F30-2C86-4BAF-8F62-33EB7BA917AF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A7032F30-2C86-4BAF-8F62-33EB7BA917AF}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(TestCaseManagementSettings) = postSolution - CategoryFile = GitTfs1.vsmdi - EndGlobalSection -EndGlobal From 34a0b5445f9cd76dccc1cb92de4f86d6eb312746 Mon Sep 17 00:00:00 2001 From: Philippe Miossec Date: Sun, 4 Oct 2015 16:55:57 +0200 Subject: [PATCH 3/3] Always display the git errors to help git-tfs users See problem describe here: https://mgrowan.wordpress.com/2015/05/06/git-tfs-pull-command-exited-with-error-code-128/ Include stderr of the git command run in GitCommandExceptions (All job done by @spraint ;) ) --- GitTfs/Core/GitHelpers.cs | 76 +++++++++++++++++++++++++++--------- GitTfs/Core/GitRepository.cs | 2 +- doc/release-notes/NEXT.md | 3 +- 3 files changed, 60 insertions(+), 21 deletions(-) diff --git a/GitTfs/Core/GitHelpers.cs b/GitTfs/Core/GitHelpers.cs index 707ea789..0dacbe89 100644 --- a/GitTfs/Core/GitHelpers.cs +++ b/GitTfs/Core/GitHelpers.cs @@ -76,12 +76,12 @@ namespace Sep.Git.Tfs.Core return new ProcessStdoutReader(this, process); } - public class ProcessStdoutReader : TextReader + class ProcessStdoutReader : TextReader { - private readonly Process process; + private readonly GitProcess process; private readonly GitHelpers helper; - public ProcessStdoutReader(GitHelpers helper, Process process) + public ProcessStdoutReader(GitHelpers helper, GitProcess process) { this.helper = helper; this.process = process; @@ -193,7 +193,7 @@ namespace Sep.Git.Tfs.Core } } - private void Close(Process process) + private void Close(GitProcess process) { // if caller doesn't read entire stdout to the EOF - it is possible that // child process will hang waiting until there will be free space in stdout @@ -208,7 +208,7 @@ namespace Sep.Git.Tfs.Core if (!process.WaitForExit((int)TimeSpan.FromSeconds(10).TotalMilliseconds)) throw new GitCommandException("Command did not terminate.", process); if(process.ExitCode != 0) - throw new GitCommandException(string.Format("Command exited with error code: {0}", process.ExitCode), process); + throw new GitCommandException(string.Format("Command exited with error code: {0}\n{1}", process.ExitCode, process.StandardErrorString), process); } private void RedirectStdout(ProcessStartInfo startInfo) @@ -229,12 +229,12 @@ namespace Sep.Git.Tfs.Core // there is no StandardInputEncoding property, use extension method StreamWriter.WithEncoding instead } - private Process Start(string[] command) + private GitProcess Start(string[] command) { return Start(command, x => {}); } - protected virtual Process Start(string [] command, Action initialize) + protected virtual GitProcess Start(string [] command, Action initialize) { var startInfo = new ProcessStartInfo(); startInfo.FileName = "git"; @@ -245,20 +245,11 @@ namespace Sep.Git.Tfs.Core RedirectStderr(startInfo); initialize(startInfo); Trace.WriteLine("Starting process: " + startInfo.FileName + " " + startInfo.Arguments, "git command"); - var process = Process.Start(startInfo); - process.ErrorDataReceived += StdErrReceived; - process.BeginErrorReadLine(); + var process = new GitProcess(Process.Start(startInfo)); + process.ConsumeStandardError(); return process; } - private void StdErrReceived(object sender, DataReceivedEventArgs e) - { - if(e.Data != null && e.Data.Trim() != "") - { - Trace.WriteLine(e.Data.TrimEnd(), "git stderr"); - } - } - /// /// WrapGitCommandErrors the actions, and if there are any git exceptions, rethrow a new exception with the given message. /// @@ -287,7 +278,54 @@ namespace Sep.Git.Tfs.Core private static void AssertValidCommand(string[] command) { if(command.Length < 1 || !ValidCommandName.IsMatch(command[0])) - throw new Exception("bad command: " + (command.Length == 0 ? "" : command[0])); + throw new Exception("bad git command: " + (command.Length == 0 ? "" : command[0])); + } + + protected class GitProcess + { + Process _process; + + public GitProcess(Process process) + { + _process = process; + } + + public static implicit operator Process(GitProcess process) + { + return process._process; + } + + public string StandardErrorString { get; private set; } + + public void ConsumeStandardError() + { + StandardErrorString = ""; + _process.ErrorDataReceived += StdErrReceived; + _process.BeginErrorReadLine(); + } + + private void StdErrReceived(object sender, DataReceivedEventArgs e) + { + if (e.Data != null && e.Data.Trim() != "") + { + var data = e.Data; + Trace.WriteLine(data.TrimEnd(), "git stderr"); + StandardErrorString += data; + } + } + + // Delegate a bunch of things to the Process. + + public ProcessStartInfo StartInfo { get { return _process.StartInfo; } } + public int ExitCode { get { return _process.ExitCode; } } + + public StreamWriter StandardInput { get { return _process.StandardInput; } } + public StreamReader StandardOutput { get { return _process.StandardOutput; } } + + public bool WaitForExit(int milliseconds) + { + return _process.WaitForExit(milliseconds); + } } } } diff --git a/GitTfs/Core/GitRepository.cs b/GitTfs/Core/GitRepository.cs index b7e39c74..8add3848 100644 --- a/GitTfs/Core/GitRepository.cs +++ b/GitTfs/Core/GitRepository.cs @@ -70,7 +70,7 @@ namespace Sep.Git.Tfs.Core public string WorkingCopyPath { get; set; } public string WorkingCopySubdir { get; set; } - protected override Process Start(string[] command, Action initialize) + protected override GitProcess Start(string[] command, Action initialize) { return base.Start(command, initialize.And(SetUpPaths)); } diff --git a/doc/release-notes/NEXT.md b/doc/release-notes/NEXT.md index 40de2e6a..9aec57de 100644 --- a/doc/release-notes/NEXT.md +++ b/doc/release-notes/NEXT.md @@ -1 +1,2 @@ -* Improve vrify command (check all remote option, add exit code, add ignore path case mismatch option) (#853, @pmiossec) \ No newline at end of file +* Improve verify command (check all remote option, add exit code, add ignore path case mismatch option) (#853, @pmiossec) +* Always display the git errors messages to help git-tfs users (#820, @spraint & @pmiossec) \ No newline at end of file