Skip to content
This repository was archived by the owner on Oct 4, 2021. It is now read-only.

Commit 945a094

Browse files
committed
Fixes VSTS #660470 - Incorrect, and inconsistent (with vs2017), behavior when creating a new project with git in a folder that's already a git repo
1 parent 08a7454 commit 945a094

File tree

6 files changed

+123
-40
lines changed

6 files changed

+123
-40
lines changed

main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/ProjectTemplateHandler.cs

+13-2
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,22 @@
2929
using MonoDevelop.Ide.Projects;
3030
using MonoDevelop.Ide.Templates;
3131
using MonoDevelop.Core;
32-
32+
using System;
33+
3334
namespace MonoDevelop.VersionControl.Git
3435
{
3536
public class ProjectTemplateHandler : IVersionControlProjectTemplateHandler
36-
{
37+
{
38+
public bool CanCreateRepository (FilePath filePath)
39+
{
40+
try {
41+
return String.IsNullOrEmpty (LibGit2Sharp.Repository.Discover (filePath.ResolveLinks ()));
42+
} catch (Exception ex) {
43+
LoggingService.LogInternalError ("Discovering Git repository failed", ex);
44+
return false;
45+
}
46+
}
47+
3748
public void Run (NewProjectConfiguration config)
3849
{
3950
if (config.UseGit) {

main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/FinalProjectConfigurationPage.cs

+59-9
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
// THE SOFTWARE.
2626

2727
using System;
28+
using System.Collections.Generic;
29+
using System.IO;
30+
using MonoDevelop.Core;
2831
using MonoDevelop.Core.StringParsing;
2932
using MonoDevelop.Ide.Templates;
3033
using ProjectCreateParameters = MonoDevelop.Projects.ProjectCreateParameters;
@@ -87,6 +90,7 @@ public string Location {
8790
set {
8891
config.Location = value;
8992
CheckIsValid ();
93+
OnParentFolderChanged ();
9094
}
9195
}
9296

@@ -178,12 +182,16 @@ public bool IsCreateProjectDirectoryInsideSolutionDirectoryEnabled {
178182
get { return HasProjects && IsNewSolution && createProjectDirectoryInsideSolutionDirectoryEnabled; }
179183
}
180184

181-
public bool IsGitIgnoreEnabled {
182-
get { return config.UseGit && IsUseGitEnabled && gitIgnoreEnabled; }
185+
public bool IsGitIgnoreEnabled {
186+
get { return !GitIgnoreFileExistsInSolutionFolder (); }
183187
}
184188

185189
public bool IsUseGitEnabled { get; set; }
186190

191+
public bool GitIgnoreExists {
192+
get { return GitIgnoreFileExistsInSolutionFolder () && GitIgnoreFileExistsInParentFolder (); }
193+
}
194+
187195
public bool IsNewSolution {
188196
get { return config.CreateSolution; }
189197
}
@@ -231,15 +239,19 @@ public bool IsValid {
231239
}
232240
}
233241

234-
public event EventHandler IsValidChanged;
242+
public event EventHandler IsValidChanged;
243+
public event EventHandler ParentFolderChanged;
235244

236245
void OnIsValidChanged ()
237-
{
238-
if (IsValidChanged != null) {
239-
IsValidChanged (this, new EventArgs ());
240-
}
241-
}
242-
246+
{
247+
IsValidChanged?.Invoke (this, new EventArgs ());
248+
}
249+
250+
void OnParentFolderChanged ()
251+
{
252+
ParentFolderChanged?.Invoke (this, new EventArgs ());
253+
}
254+
243255
public void UpdateFromParameters ()
244256
{
245257
ProjectName = Parameters ["ProjectName"];
@@ -259,6 +271,44 @@ public void UpdateFromParameters ()
259271
return Parameters.GetBoolValue (name);
260272
}
261273
return null;
274+
}
275+
276+
public bool GitIgnoreFileExistsInSolutionFolder ()
277+
{
278+
FilePath solutionPath = config.SolutionLocation;
279+
if (Location == solutionPath) {
280+
FilePath gitIgnoreFilePath = solutionPath.Combine (".gitignore");
281+
return File.Exists (gitIgnoreFilePath);
282+
}
283+
return false;
284+
}
285+
286+
public bool GitIgnoreFileExistsInParentFolder ()
287+
{
288+
IEnumerable<DirectoryInfo> di = GetAllParentDirectories (new DirectoryInfo(config.SolutionLocation));
289+
foreach (var directory in di) {
290+
FilePath solutionPath = directory.FullName;
291+
FilePath gitIgnoreFilePath = solutionPath.Combine (".gitignore");
292+
if (File.Exists (gitIgnoreFilePath))
293+
return true;
294+
}
295+
return false;
296+
}
297+
298+
IEnumerable<DirectoryInfo> GetAllParentDirectories (DirectoryInfo directoryToScan)
299+
{
300+
Stack<DirectoryInfo> ret = new Stack<DirectoryInfo> ();
301+
GetAllParentDirectories (directoryToScan, ref ret);
302+
return ret;
303+
}
304+
305+
void GetAllParentDirectories (DirectoryInfo directoryToScan, ref Stack<DirectoryInfo> directories)
306+
{
307+
if (directoryToScan == null || directoryToScan.Name == directoryToScan.Root.Name)
308+
return;
309+
310+
directories.Push (directoryToScan);
311+
GetAllParentDirectories (directoryToScan.Parent, ref directories);
262312
}
263313
}
264314
}

main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GtkProjectConfigurationWidget.cs

+10
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,17 @@ void OnLocationTextBoxChanged ()
152152
{
153153
projectConfiguration.Location = locationTextBox.Text;
154154
projectFolderPreviewWidget.UpdateLocation ();
155+
UpdateGitStatus ();
155156
}
156157

158+
void UpdateGitStatus ()
159+
{
160+
useGitCheckBox.Sensitive = projectConfiguration.IsUseGitEnabled;
161+
useGitCheckBox.Active = projectConfiguration.UseGit;
162+
createGitIgnoreFileCheckBox.Sensitive = projectConfiguration.IsGitIgnoreEnabled;
163+
createGitIgnoreFileCheckBox.Active = projectConfiguration.CreateGitIgnoreFile;
164+
}
165+
157166
void ProjectNameTextInserted (object o, TextInsertedArgs args)
158167
{
159168
if (args.Text.IndexOf ('\r') >= 0) {
@@ -185,6 +194,7 @@ void OnCreateGitIgnoreFileCheckBoxClicked ()
185194
void OnUseGitCheckBoxClicked ()
186195
{
187196
projectConfiguration.UseGit = useGitCheckBox.Active;
197+
createGitIgnoreFileCheckBox.Active = projectConfiguration.CreateGitIgnoreFile;
188198
createGitIgnoreFileCheckBox.Sensitive = projectConfiguration.IsGitIgnoreEnabled;
189199
projectFolderPreviewWidget.ShowGitFolder ();
190200
projectFolderPreviewWidget.ShowGitIgnoreFile ();

main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs

+9-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,15 @@ void CreateFinalConfigurationPage ()
283283
{
284284
finalConfigurationPage = new FinalProjectConfigurationPage (projectConfiguration);
285285
finalConfigurationPage.ParentFolder = ParentFolder;
286-
finalConfigurationPage.IsUseGitEnabled = IsNewSolution && (versionControlHandler != null);
286+
finalConfigurationPage.IsUseGitEnabled = IsNewSolution && (versionControlHandler != null);
287+
finalConfigurationPage.ParentFolderChanged += (sender, e) => {
288+
finalConfigurationPage.UseGit = versionControlHandler != null;
289+
finalConfigurationPage.IsUseGitEnabled = IsNewSolution && versionControlHandler != null &&
290+
versionControlHandler.CanCreateRepository (projectConfiguration.Location);
291+
finalConfigurationPage.CreateGitIgnoreFile = versionControlHandler != null &&
292+
!finalConfigurationPage.GitIgnoreFileExistsInSolutionFolder () &&
293+
!finalConfigurationPage.GitIgnoreFileExistsInParentFolder ();
294+
};
287295
finalConfigurationPage.IsValidChanged += (sender, e) => {
288296
dialog.CanMoveToNextPage = finalConfigurationPage.IsValid;
289297
};

main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/IVersionControlProjectTemplateHandler.cs

+29-27
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,37 @@
1-
//
2-
// IVersionControlTemplateHandler.cs
3-
//
4-
// Author:
5-
// Matt Ward <matt.ward@xamarin.com>
6-
//
7-
// Copyright (c) 2014 Xamarin Inc. (http://xamarin.com)
8-
//
9-
// Permission is hereby granted, free of charge, to any person obtaining a copy
10-
// of this software and associated documentation files (the "Software"), to deal
11-
// in the Software without restriction, including without limitation the rights
12-
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13-
// copies of the Software, and to permit persons to whom the Software is
14-
// furnished to do so, subject to the following conditions:
15-
//
16-
// The above copyright notice and this permission notice shall be included in
17-
// all copies or substantial portions of the Software.
18-
//
19-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20-
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21-
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22-
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23-
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25-
// THE SOFTWARE.
26-
1+
//
2+
// IVersionControlTemplateHandler.cs
3+
//
4+
// Author:
5+
// Matt Ward <matt.ward@xamarin.com>
6+
//
7+
// Copyright (c) 2014 Xamarin Inc. (http://xamarin.com)
8+
//
9+
// Permission is hereby granted, free of charge, to any person obtaining a copy
10+
// of this software and associated documentation files (the "Software"), to deal
11+
// in the Software without restriction, including without limitation the rights
12+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
// copies of the Software, and to permit persons to whom the Software is
14+
// furnished to do so, subject to the following conditions:
15+
//
16+
// The above copyright notice and this permission notice shall be included in
17+
// all copies or substantial portions of the Software.
18+
//
19+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
// THE SOFTWARE.
26+
27+
using MonoDevelop.Core;
2728
using MonoDevelop.Ide.Projects;
2829

2930
namespace MonoDevelop.Ide.Templates
3031
{
3132
public interface IVersionControlProjectTemplateHandler
32-
{
33+
{
34+
bool CanCreateRepository (FilePath filePath);
3335
void Run (NewProjectConfiguration config);
3436
}
3537
}

main/tests/Ide.Tests/MonoDevelop.Ide.Projects/NewProjectDialogTests.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,11 @@ public void Git_NewSolution_FinalConfigurationPage (bool useGit, bool createGitI
244244

245245
controller.Show ();
246246

247+
bool gitIgnoreExists = controller.FinalConfiguration.GitIgnoreExists;
248+
247249
Assert.AreEqual (useGit, controller.FinalConfiguration.UseGit);
248250
Assert.AreEqual (createGitIgnore, controller.FinalConfiguration.CreateGitIgnoreFile);
249-
Assert.AreEqual (useGit, controller.FinalConfiguration.IsGitIgnoreEnabled);
251+
Assert.AreEqual (!gitIgnoreExists, controller.FinalConfiguration.IsGitIgnoreEnabled);
250252
Assert.IsTrue (controller.FinalConfiguration.IsUseGitEnabled);
251253
}
252254

0 commit comments

Comments
 (0)