diff --git a/src/Commands/InitGit.cs b/src/Commands/InitGit.cs
new file mode 100644
index 000000000..58df0db78
--- /dev/null
+++ b/src/Commands/InitGit.cs
@@ -0,0 +1,28 @@
+using System.Text;
+
+namespace SourceGit.Commands
+{
+ public class InitGit : Command
+ {
+ public InitGit(string ctx, string path, string localName, string branchName, bool bareRepo)
+ {
+ Context = ctx;
+ WorkingDirectory = path;
+
+ var builder = new StringBuilder(1024);
+ builder.Append("init ");
+
+ if (bareRepo)
+ builder.Append("--bare ");
+ else
+ {
+ if (!string.IsNullOrEmpty(branchName))
+ builder.Append("-b " + branchName + " ");
+ }
+
+ builder.Append(localName.Quoted());
+
+ Args = builder.ToString();
+ }
+ }
+}
diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml
index d5843d79f..9f2217db5 100644
--- a/src/Resources/Locales/en_US.axaml
+++ b/src/Resources/Locales/en_US.axaml
@@ -540,6 +540,15 @@
Do you want to run `git init` command under this path?
Open repository failed. Reason:
Path:
+ Initialize Git Repository
+ Create Bare Repository
+ Bookmark:
+ Group:
+ Initial Branch Name
+ main
+ Parent Folder
+ Project Name
+ new_git_project
Cherry-Pick in progress.
Processing commit
Merge in progress.
@@ -945,6 +954,7 @@
Delete
DRAG & DROP FOLDER SUPPORTED. CUSTOM GROUPING SUPPORTED.
Edit
+ Initialize Git Repository
Move to Another Group
Open All Repositories
Open Repository
diff --git a/src/ViewModels/InitGit.cs b/src/ViewModels/InitGit.cs
new file mode 100644
index 000000000..b3ad5d257
--- /dev/null
+++ b/src/ViewModels/InitGit.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.IO;
+using System.Threading.Tasks;
+using System.Globalization;
+
+namespace SourceGit.ViewModels
+{
+ public class InitGit : Popup
+ {
+ [Required(ErrorMessage = "Parent folder is required")]
+ [CustomValidation(typeof(InitGit), nameof(ValidateParentFolder))]
+ public string ParentFolder
+ {
+ get => _parentFolder;
+ set => SetProperty(ref _parentFolder, value, true);
+ }
+
+ public string ProjectName
+ {
+ get => null;
+ set => SetProperty(ref _projectName, value);
+ }
+
+ public List Groups
+ {
+ get;
+ }
+
+ public RepositoryNode SelectedGroup
+ {
+ get => _selectedGroup;
+ set => SetProperty(ref _selectedGroup, value);
+ }
+
+ public List Bookmarks
+ {
+ get;
+ }
+
+ public int Bookmark
+ {
+ get => _bookmark;
+ set => SetProperty(ref _bookmark, value);
+ }
+
+ public string InitialBranch
+ {
+ get => null;
+ set => SetProperty(ref _initialBranch, value);
+ }
+
+ public bool BareRepo
+ {
+ get;
+ set;
+ } = false;
+
+ public InitGit(string pageId)
+ {
+ _pageId = pageId;
+
+ Groups = new List();
+ Groups.Add(new RepositoryNode { Name = "No Group (Uncategorized)", Id = string.Empty });
+ SelectedGroup = Groups[0];
+ CollectGroups(Groups, Preferences.Instance.RepositoryNodes);
+
+ Bookmarks = new List();
+ for (var i = 0; i < Models.Bookmarks.Brushes.Length; i++)
+ Bookmarks.Add(i);
+
+ var activeWorkspace = Preferences.Instance.GetActiveWorkspace();
+ _parentFolder = activeWorkspace?.DefaultCloneDir;
+ if (string.IsNullOrEmpty(ParentFolder))
+ _parentFolder = Preferences.Instance.GitDefaultCloneDir;
+ }
+
+ public static ValidationResult ValidateParentFolder(string folder, ValidationContext _)
+ {
+ if (!Directory.Exists(folder))
+ return new ValidationResult("Given path can NOT be found");
+ return ValidationResult.Success;
+ }
+
+ public override async Task Sure()
+ {
+ ProgressDescription = "Init ...";
+
+ var log = new CommandLog("Init");
+ Use(log);
+
+ var succ = await new Commands.InitGit(_pageId, _parentFolder, _projectName, _initialBranch, BareRepo)
+ .Use(log)
+ .ExecAsync();
+ if (!succ)
+ return false;
+
+ var path = _parentFolder;
+ if (!string.IsNullOrEmpty(_projectName))
+ {
+ path = Path.GetFullPath(Path.Combine(path, _projectName));
+ }
+ else
+ {
+ path = Path.GetFullPath(Path.Combine(path, "new_git_project"));
+ }
+
+ if (!Directory.Exists(path))
+ {
+ Models.Notification.Send(_pageId, $"Folder '{path}' can NOT be found", true);
+ return false;
+ }
+
+ log.Complete();
+
+ var parent = _selectedGroup is { Id: not "" } ? _selectedGroup : null;
+ var node = Preferences.Instance.FindOrAddNodeByRepositoryPath(path, parent, true);
+ node.Bookmark = _bookmark;
+ await node.UpdateStatusAsync(false, null);
+
+ var launcher = App.GetLauncher();
+ LauncherPage page = null;
+ foreach (var one in launcher.Pages)
+ {
+ if (one.Node.Id == _pageId)
+ {
+ page = one;
+ break;
+ }
+ }
+
+ Welcome.Instance.Refresh();
+ launcher.OpenRepositoryInTab(node, page);
+ return true;
+ }
+
+ private void CollectGroups(List outs, List collections)
+ {
+ foreach (var node in collections)
+ {
+ if (!node.IsRepository)
+ {
+ outs.Add(node);
+ CollectGroups(outs, node.SubNodes);
+ }
+ }
+ }
+
+ private string _pageId = string.Empty;
+ private string _parentFolder = string.Empty;
+ private string _projectName = App.Text("InitGit.ProjectName.Placeholder");
+ private string _initialBranch = App.Text("InitGit.InitialBranch.Placeholder");
+ private RepositoryNode _selectedGroup = null;
+ private int _bookmark = 0;
+ }
+}
diff --git a/src/ViewModels/Welcome.cs b/src/ViewModels/Welcome.cs
index 49539292d..2d052d314 100644
--- a/src/ViewModels/Welcome.cs
+++ b/src/ViewModels/Welcome.cs
@@ -171,6 +171,19 @@ public void OpenTerminal()
Native.OS.OpenTerminal(null);
}
+ public void InitGit()
+ {
+ if (!Preferences.Instance.IsGitConfigured())
+ {
+ Models.Notification.Send(null, App.Text("NotConfigured"), true);
+ return;
+ }
+
+ var activePage = App.GetLauncher().ActivePage;
+ if (activePage != null && activePage.CanCreatePopup())
+ activePage.Popup = new InitGit(activePage.Node.Id);
+ }
+
public void ScanDefaultCloneDir()
{
if (!Preferences.Instance.IsGitConfigured())
diff --git a/src/Views/InitGit.axaml b/src/Views/InitGit.axaml
new file mode 100644
index 000000000..e0262ba4a
--- /dev/null
+++ b/src/Views/InitGit.axaml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Views/InitGit.axaml.cs b/src/Views/InitGit.axaml.cs
new file mode 100644
index 000000000..21e3ce84a
--- /dev/null
+++ b/src/Views/InitGit.axaml.cs
@@ -0,0 +1,46 @@
+using System;
+using Avalonia.Controls;
+using Avalonia.Input.Platform;
+using Avalonia.Interactivity;
+using Avalonia.Platform.Storage;
+
+namespace SourceGit.Views
+{
+ public partial class InitGit : UserControl
+ {
+ public InitGit()
+ {
+ InitializeComponent();
+ }
+
+ protected override async void OnLoaded(RoutedEventArgs e)
+ {
+ base.OnLoaded(e);
+ }
+
+ private async void SelectParentFolder(object _, RoutedEventArgs e)
+ {
+ var options = new FolderPickerOpenOptions() { AllowMultiple = false };
+ var toplevel = TopLevel.GetTopLevel(this);
+ if (toplevel == null)
+ return;
+
+ try
+ {
+ var selected = await toplevel.StorageProvider.OpenFolderPickerAsync(options);
+ if (selected.Count == 1)
+ {
+ var folder = selected[0];
+ var folderPath = folder is { Path: { IsAbsoluteUri: true } path } ? path.LocalPath : folder?.Path.ToString();
+ TxtParentFolder.Text = folderPath;
+ }
+ }
+ catch (Exception exception)
+ {
+ Models.Notification.Send(null, $"Failed to select parent folder: {exception.Message}", true);
+ }
+
+ e.Handled = true;
+ }
+ }
+}
diff --git a/src/Views/WelcomeToolbar.axaml b/src/Views/WelcomeToolbar.axaml
index 91f2064fa..ef662fa1b 100644
--- a/src/Views/WelcomeToolbar.axaml
+++ b/src/Views/WelcomeToolbar.axaml
@@ -33,6 +33,10 @@
+
+