2024-03-17 18:37:06 -07:00
|
|
|
|
using System;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
2024-08-27 20:26:00 -07:00
|
|
|
|
using System.Text;
|
2024-11-05 20:35:55 -08:00
|
|
|
|
using System.Threading.Tasks;
|
2024-08-25 06:39:59 -07:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
using Avalonia.Controls;
|
|
|
|
|
using Avalonia.Platform.Storage;
|
2024-08-25 06:39:59 -07:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
|
|
|
|
|
|
namespace SourceGit.ViewModels
|
|
|
|
|
{
|
|
|
|
|
public class Histories : ObservableObject
|
|
|
|
|
{
|
2024-08-13 05:40:05 -07:00
|
|
|
|
public Repository Repo
|
|
|
|
|
{
|
|
|
|
|
get => _repo;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public bool IsLoading
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
get => _isLoading;
|
|
|
|
|
set => SetProperty(ref _isLoading, value);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public List<Models.Commit> Commits
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
get => _commits;
|
2024-03-17 18:37:06 -07:00
|
|
|
|
set
|
|
|
|
|
{
|
2024-06-06 05:25:16 -07:00
|
|
|
|
var lastSelected = AutoSelectedCommit;
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (SetProperty(ref _commits, value))
|
|
|
|
|
{
|
2024-06-06 05:25:16 -07:00
|
|
|
|
if (value.Count > 0 && lastSelected != null)
|
|
|
|
|
AutoSelectedCommit = value.Find(x => x.SHA == lastSelected.SHA);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public Models.CommitGraph Graph
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
get => _graph;
|
|
|
|
|
set => SetProperty(ref _graph, value);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public Models.Commit AutoSelectedCommit
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
get => _autoSelectedCommit;
|
2024-05-27 02:21:28 -07:00
|
|
|
|
set => SetProperty(ref _autoSelectedCommit, value);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-07 06:19:02 -07:00
|
|
|
|
public long NavigationId
|
|
|
|
|
{
|
|
|
|
|
get => _navigationId;
|
|
|
|
|
private set => SetProperty(ref _navigationId, value);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public object DetailContext
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
get => _detailContext;
|
2024-05-27 02:21:28 -07:00
|
|
|
|
set => SetProperty(ref _detailContext, value);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-14 02:22:29 -07:00
|
|
|
|
public GridLength LeftArea
|
|
|
|
|
{
|
|
|
|
|
get => _leftArea;
|
|
|
|
|
set => SetProperty(ref _leftArea, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public GridLength RightArea
|
|
|
|
|
{
|
|
|
|
|
get => _rightArea;
|
|
|
|
|
set => SetProperty(ref _rightArea, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public GridLength TopArea
|
|
|
|
|
{
|
|
|
|
|
get => _topArea;
|
|
|
|
|
set => SetProperty(ref _topArea, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public GridLength BottomArea
|
|
|
|
|
{
|
|
|
|
|
get => _bottomArea;
|
|
|
|
|
set => SetProperty(ref _bottomArea, value);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public Histories(Repository repo)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
_repo = repo;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public void Cleanup()
|
|
|
|
|
{
|
2024-02-20 02:27:59 -08:00
|
|
|
|
Commits = new List<Models.Commit>();
|
|
|
|
|
|
|
|
|
|
_repo = null;
|
|
|
|
|
_graph = null;
|
|
|
|
|
_autoSelectedCommit = null;
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (_detailContext is CommitDetail cd)
|
|
|
|
|
{
|
2024-02-20 02:27:59 -08:00
|
|
|
|
cd.Cleanup();
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else if (_detailContext is RevisionCompare rc)
|
|
|
|
|
{
|
2024-02-20 02:27:59 -08:00
|
|
|
|
rc.Cleanup();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_detailContext = null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public void NavigateTo(string commitSHA)
|
|
|
|
|
{
|
2024-03-13 20:09:05 -07:00
|
|
|
|
var commit = _commits.Find(x => x.SHA.StartsWith(commitSHA, StringComparison.Ordinal));
|
2024-09-18 23:38:11 -07:00
|
|
|
|
if (commit == null)
|
|
|
|
|
{
|
|
|
|
|
AutoSelectedCommit = null;
|
|
|
|
|
commit = new Commands.QuerySingleCommit(_repo.FullPath, commitSHA).Result();
|
|
|
|
|
}
|
|
|
|
|
else
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
AutoSelectedCommit = commit;
|
2024-04-07 06:19:02 -07:00
|
|
|
|
NavigationId = _navigationId + 1;
|
2024-09-18 23:38:11 -07:00
|
|
|
|
}
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
2024-09-18 23:38:11 -07:00
|
|
|
|
if (commit != null)
|
|
|
|
|
{
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (_detailContext is CommitDetail detail)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
detail.Commit = commit;
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-08-13 02:15:17 -07:00
|
|
|
|
var commitDetail = new CommitDetail(_repo);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
commitDetail.Commit = commit;
|
|
|
|
|
DetailContext = commitDetail;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-18 23:38:11 -07:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DetailContext = null;
|
|
|
|
|
}
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public void Select(IList commits)
|
|
|
|
|
{
|
|
|
|
|
if (commits.Count == 0)
|
|
|
|
|
{
|
2024-05-10 01:30:34 -07:00
|
|
|
|
_repo.SearchResultSelectedCommit = null;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
DetailContext = null;
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else if (commits.Count == 1)
|
|
|
|
|
{
|
2024-11-09 21:19:25 -08:00
|
|
|
|
var commit = (commits[0] as Models.Commit)!;
|
2024-10-10 20:04:27 -07:00
|
|
|
|
if (_repo.SearchResultSelectedCommit == null || _repo.SearchResultSelectedCommit.SHA != commit.SHA)
|
2024-10-14 18:39:01 -07:00
|
|
|
|
_repo.SearchResultSelectedCommit = _repo.SearchedCommits.Find(x => x.SHA == commit.SHA);
|
2024-05-10 01:30:34 -07:00
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
AutoSelectedCommit = commit;
|
2024-04-11 05:50:19 -07:00
|
|
|
|
NavigationId = _navigationId + 1;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (_detailContext is CommitDetail detail)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
detail.Commit = commit;
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-08-13 02:15:17 -07:00
|
|
|
|
var commitDetail = new CommitDetail(_repo);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
commitDetail.Commit = commit;
|
|
|
|
|
DetailContext = commitDetail;
|
|
|
|
|
}
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else if (commits.Count == 2)
|
|
|
|
|
{
|
2024-05-10 01:30:34 -07:00
|
|
|
|
_repo.SearchResultSelectedCommit = null;
|
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var end = commits[0] as Models.Commit;
|
|
|
|
|
var start = commits[1] as Models.Commit;
|
|
|
|
|
DetailContext = new RevisionCompare(_repo.FullPath, start, end);
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-10 01:30:34 -07:00
|
|
|
|
_repo.SearchResultSelectedCommit = null;
|
2024-07-23 20:44:13 -07:00
|
|
|
|
DetailContext = commits.Count;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-29 20:47:58 -07:00
|
|
|
|
public void DoubleTapped(Models.Commit commit)
|
|
|
|
|
{
|
|
|
|
|
if (commit == null || commit.IsCurrentHead)
|
|
|
|
|
return;
|
|
|
|
|
|
2024-08-01 01:59:39 -07:00
|
|
|
|
var firstRemoteBranch = null as Models.Branch;
|
2024-07-29 20:47:58 -07:00
|
|
|
|
foreach (var d in commit.Decorators)
|
|
|
|
|
{
|
|
|
|
|
if (d.Type == Models.DecoratorType.LocalBranchHead)
|
|
|
|
|
{
|
|
|
|
|
var b = _repo.Branches.Find(x => x.FriendlyName == d.Name);
|
|
|
|
|
if (b != null)
|
|
|
|
|
{
|
|
|
|
|
_repo.CheckoutBranch(b);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-08-01 01:59:39 -07:00
|
|
|
|
else if (d.Type == Models.DecoratorType.RemoteBranchHead && firstRemoteBranch == null)
|
|
|
|
|
{
|
|
|
|
|
firstRemoteBranch = _repo.Branches.Find(x => x.FriendlyName == d.Name);
|
|
|
|
|
}
|
2024-07-29 20:47:58 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (PopupHost.CanCreatePopup())
|
2024-08-01 01:59:39 -07:00
|
|
|
|
{
|
|
|
|
|
if (firstRemoteBranch != null)
|
|
|
|
|
PopupHost.ShowPopup(new CreateBranch(_repo, firstRemoteBranch));
|
|
|
|
|
else
|
|
|
|
|
PopupHost.ShowPopup(new CheckoutCommit(_repo, commit));
|
|
|
|
|
}
|
2024-07-29 20:47:58 -07:00
|
|
|
|
}
|
|
|
|
|
|
2024-08-27 19:02:14 -07:00
|
|
|
|
public ContextMenu MakeContextMenu(ListBox list)
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-07-24 00:36:26 -07:00
|
|
|
|
var current = _repo.CurrentBranch;
|
2024-11-09 21:19:25 -08:00
|
|
|
|
if (current == null || list.SelectedItems == null)
|
2024-03-31 01:54:29 -07:00
|
|
|
|
return null;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
2024-08-27 20:26:00 -07:00
|
|
|
|
if (list.SelectedItems.Count > 1)
|
|
|
|
|
{
|
|
|
|
|
var selected = new List<Models.Commit>();
|
|
|
|
|
var canCherryPick = true;
|
|
|
|
|
foreach (var item in list.SelectedItems)
|
|
|
|
|
{
|
|
|
|
|
if (item is Models.Commit c)
|
|
|
|
|
{
|
|
|
|
|
selected.Add(c);
|
|
|
|
|
|
|
|
|
|
if (c.IsMerged || c.Parents.Count > 1)
|
|
|
|
|
canCherryPick = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var multipleMenu = new ContextMenu();
|
|
|
|
|
|
|
|
|
|
if (canCherryPick)
|
|
|
|
|
{
|
|
|
|
|
var cherryPickMultiple = new MenuItem();
|
|
|
|
|
cherryPickMultiple.Header = App.Text("CommitCM.CherryPickMultiple");
|
|
|
|
|
cherryPickMultiple.Icon = App.CreateMenuIcon("Icons.CherryPick");
|
|
|
|
|
cherryPickMultiple.Click += (_, e) =>
|
|
|
|
|
{
|
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new CherryPick(_repo, selected));
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
multipleMenu.Items.Add(cherryPickMultiple);
|
|
|
|
|
multipleMenu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-05 20:35:55 -08:00
|
|
|
|
var saveToPatchMultiple = new MenuItem();
|
|
|
|
|
saveToPatchMultiple.Icon = App.CreateMenuIcon("Icons.Diff");
|
|
|
|
|
saveToPatchMultiple.Header = App.Text("CommitCM.SaveAsPatch");
|
|
|
|
|
saveToPatchMultiple.Click += async (_, e) =>
|
|
|
|
|
{
|
|
|
|
|
var storageProvider = App.GetStorageProvider();
|
|
|
|
|
if (storageProvider == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var options = new FolderPickerOpenOptions() { AllowMultiple = false };
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var picker = await storageProvider.OpenFolderPickerAsync(options);
|
|
|
|
|
if (picker.Count == 1)
|
|
|
|
|
{
|
|
|
|
|
var saveTo = $"{picker[0].Path.LocalPath}/patches";
|
|
|
|
|
var succ = false;
|
|
|
|
|
foreach (var c in selected)
|
|
|
|
|
{
|
|
|
|
|
succ = await Task.Run(() => new Commands.FormatPatch(_repo.FullPath, c.SHA, saveTo).Exec());
|
|
|
|
|
if (!succ)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (succ)
|
|
|
|
|
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception exception)
|
|
|
|
|
{
|
|
|
|
|
App.RaiseException(_repo.FullPath, $"Failed to save as patch: {exception.Message}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
multipleMenu.Items.Add(saveToPatchMultiple);
|
|
|
|
|
multipleMenu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
|
2024-08-27 20:26:00 -07:00
|
|
|
|
var copyMultipleSHAs = new MenuItem();
|
|
|
|
|
copyMultipleSHAs.Header = App.Text("CommitCM.CopySHA");
|
|
|
|
|
copyMultipleSHAs.Icon = App.CreateMenuIcon("Icons.Copy");
|
|
|
|
|
copyMultipleSHAs.Click += (_, e) =>
|
|
|
|
|
{
|
|
|
|
|
var builder = new StringBuilder();
|
|
|
|
|
foreach (var c in selected)
|
|
|
|
|
builder.AppendLine(c.SHA);
|
|
|
|
|
|
|
|
|
|
App.CopyText(builder.ToString());
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
multipleMenu.Items.Add(copyMultipleSHAs);
|
|
|
|
|
|
|
|
|
|
var copyMultipleInfo = new MenuItem();
|
|
|
|
|
copyMultipleInfo.Header = App.Text("CommitCM.CopyInfo");
|
|
|
|
|
copyMultipleInfo.Icon = App.CreateMenuIcon("Icons.Copy");
|
|
|
|
|
copyMultipleInfo.Click += (_, e) =>
|
|
|
|
|
{
|
|
|
|
|
var builder = new StringBuilder();
|
|
|
|
|
foreach (var c in selected)
|
|
|
|
|
builder.AppendLine($"{c.SHA.Substring(0, 10)} - {c.Subject}");
|
|
|
|
|
|
|
|
|
|
App.CopyText(builder.ToString());
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
multipleMenu.Items.Add(copyMultipleInfo);
|
|
|
|
|
|
|
|
|
|
return multipleMenu;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-27 19:02:14 -07:00
|
|
|
|
var commit = (list.SelectedItem as Models.Commit)!;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var menu = new ContextMenu();
|
|
|
|
|
var tags = new List<Models.Tag>();
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (commit.HasDecorators)
|
|
|
|
|
{
|
|
|
|
|
foreach (var d in commit.Decorators)
|
|
|
|
|
{
|
|
|
|
|
if (d.Type == Models.DecoratorType.CurrentBranchHead)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
FillCurrentBranchMenu(menu, current);
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else if (d.Type == Models.DecoratorType.LocalBranchHead)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var b = _repo.Branches.Find(x => x.IsLocal && d.Name == x.Name);
|
|
|
|
|
FillOtherLocalBranchMenu(menu, b, current, commit.IsMerged);
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else if (d.Type == Models.DecoratorType.RemoteBranchHead)
|
|
|
|
|
{
|
2024-07-01 19:23:21 -07:00
|
|
|
|
var b = _repo.Branches.Find(x => !x.IsLocal && d.Name == x.FriendlyName);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
FillRemoteBranchMenu(menu, b, current, commit.IsMerged);
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else if (d.Type == Models.DecoratorType.Tag)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var t = _repo.Tags.Find(x => x.Name == d.Name);
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (t != null)
|
|
|
|
|
tags.Add(t);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (menu.Items.Count > 0)
|
|
|
|
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (tags.Count > 0)
|
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
foreach (var tag in tags)
|
2024-11-09 20:51:15 -08:00
|
|
|
|
FillTagMenu(menu, tag, current, commit.IsMerged);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (current.Head != commit.SHA)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var reset = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
reset.Header = new Views.NameHighlightedTextBlock("CommitCM.Reset", current.Name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
reset.Icon = App.CreateMenuIcon("Icons.Reset");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
reset.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new Reset(_repo, current, commit));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(reset);
|
2024-08-27 22:42:25 -07:00
|
|
|
|
|
2024-08-25 06:39:59 -07:00
|
|
|
|
var squash = new MenuItem();
|
|
|
|
|
squash.Header = App.Text("CommitCM.SquashCommitsSinceThis");
|
|
|
|
|
squash.Icon = App.CreateMenuIcon("Icons.SquashIntoParent");
|
|
|
|
|
squash.IsVisible = commit.IsMerged;
|
|
|
|
|
squash.Click += (_, e) =>
|
|
|
|
|
{
|
|
|
|
|
if (_repo.LocalChangesCount > 0)
|
|
|
|
|
{
|
|
|
|
|
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-08-27 22:42:25 -07:00
|
|
|
|
|
2024-08-25 06:39:59 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new Squash(_repo, commit, commit.SHA));
|
|
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(squash);
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var reword = new MenuItem();
|
|
|
|
|
reword.Header = App.Text("CommitCM.Reword");
|
2024-02-27 02:26:05 -08:00
|
|
|
|
reword.Icon = App.CreateMenuIcon("Icons.Edit");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
reword.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-08-13 02:38:58 -07:00
|
|
|
|
if (_repo.LocalChangesCount > 0)
|
2024-06-24 19:26:31 -07:00
|
|
|
|
{
|
|
|
|
|
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new Reword(_repo, commit));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(reword);
|
|
|
|
|
|
|
|
|
|
var squash = new MenuItem();
|
|
|
|
|
squash.Header = App.Text("CommitCM.Squash");
|
2024-02-27 02:26:05 -08:00
|
|
|
|
squash.Icon = App.CreateMenuIcon("Icons.SquashIntoParent");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
squash.IsEnabled = commit.Parents.Count == 1;
|
2024-07-14 09:30:31 -07:00
|
|
|
|
squash.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-08-13 02:38:58 -07:00
|
|
|
|
if (_repo.LocalChangesCount > 0)
|
2024-06-24 19:26:31 -07:00
|
|
|
|
{
|
|
|
|
|
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (commit.Parents.Count == 1)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var parent = _commits.Find(x => x.SHA == commit.Parents[0]);
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (parent != null && PopupHost.CanCreatePopup())
|
2024-08-25 06:39:59 -07:00
|
|
|
|
PopupHost.ShowPopup(new Squash(_repo, parent, commit.SHA));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
2024-03-17 18:37:06 -07:00
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(squash);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (!commit.IsMerged)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var rebase = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
rebase.Header = new Views.NameHighlightedTextBlock("CommitCM.Rebase", current.Name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
rebase.Icon = App.CreateMenuIcon("Icons.Rebase");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
rebase.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new Rebase(_repo, current, commit));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(rebase);
|
|
|
|
|
|
|
|
|
|
var cherryPick = new MenuItem();
|
|
|
|
|
cherryPick.Header = App.Text("CommitCM.CherryPick");
|
2024-02-27 02:26:05 -08:00
|
|
|
|
cherryPick.Icon = App.CreateMenuIcon("Icons.CherryPick");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
cherryPick.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
2024-10-14 00:18:29 -07:00
|
|
|
|
{
|
|
|
|
|
if (commit.Parents.Count <= 1)
|
|
|
|
|
{
|
|
|
|
|
PopupHost.ShowPopup(new CherryPick(_repo, [commit]));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var parents = new List<Models.Commit>();
|
|
|
|
|
foreach (var sha in commit.Parents)
|
|
|
|
|
{
|
|
|
|
|
var parent = _commits.Find(x => x.SHA == sha);
|
|
|
|
|
if (parent == null)
|
|
|
|
|
parent = new Commands.QuerySingleCommit(_repo.FullPath, sha).Result();
|
|
|
|
|
|
|
|
|
|
if (parent != null)
|
|
|
|
|
parents.Add(parent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PopupHost.ShowPopup(new CherryPick(_repo, commit, parents));
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-14 18:39:01 -07:00
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(cherryPick);
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var revert = new MenuItem();
|
|
|
|
|
revert.Header = App.Text("CommitCM.Revert");
|
2024-02-27 02:26:05 -08:00
|
|
|
|
revert.Icon = App.CreateMenuIcon("Icons.Undo");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
revert.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new Revert(_repo, commit));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(revert);
|
2024-06-20 02:02:12 -07:00
|
|
|
|
|
|
|
|
|
var interactiveRebase = new MenuItem();
|
|
|
|
|
interactiveRebase.Header = new Views.NameHighlightedTextBlock("CommitCM.InteractiveRebase", current.Name);
|
|
|
|
|
interactiveRebase.Icon = App.CreateMenuIcon("Icons.InteractiveRebase");
|
|
|
|
|
interactiveRebase.IsVisible = current.Head != commit.SHA;
|
2024-07-14 09:30:31 -07:00
|
|
|
|
interactiveRebase.Click += (_, e) =>
|
2024-06-20 02:02:12 -07:00
|
|
|
|
{
|
2024-08-13 02:38:58 -07:00
|
|
|
|
if (_repo.LocalChangesCount > 0)
|
2024-06-24 19:32:53 -07:00
|
|
|
|
{
|
|
|
|
|
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-27 19:02:14 -07:00
|
|
|
|
App.OpenDialog(new Views.InteractiveRebase()
|
|
|
|
|
{
|
|
|
|
|
DataContext = new InteractiveRebase(_repo, current, commit)
|
|
|
|
|
});
|
2024-07-14 09:30:31 -07:00
|
|
|
|
|
2024-06-20 02:02:12 -07:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(interactiveRebase);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-11 20:42:22 -07:00
|
|
|
|
if (current.Head != commit.SHA)
|
|
|
|
|
{
|
|
|
|
|
var checkoutCommit = new MenuItem();
|
|
|
|
|
checkoutCommit.Header = App.Text("CommitCM.Checkout");
|
|
|
|
|
checkoutCommit.Icon = App.CreateMenuIcon("Icons.Detached");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
checkoutCommit.Click += (_, e) =>
|
2024-06-11 20:42:22 -07:00
|
|
|
|
{
|
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new CheckoutCommit(_repo, commit));
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(checkoutCommit);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
|
2024-05-27 02:21:28 -07:00
|
|
|
|
if (current.Head != commit.SHA)
|
|
|
|
|
{
|
2024-05-27 06:05:15 -07:00
|
|
|
|
var compareWithHead = new MenuItem();
|
|
|
|
|
compareWithHead.Header = App.Text("CommitCM.CompareWithHead");
|
|
|
|
|
compareWithHead.Icon = App.CreateMenuIcon("Icons.Compare");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
compareWithHead.Click += (_, e) =>
|
2024-05-27 02:21:28 -07:00
|
|
|
|
{
|
|
|
|
|
var head = _commits.Find(x => x.SHA == current.Head);
|
|
|
|
|
if (head == null)
|
|
|
|
|
{
|
|
|
|
|
_repo.SearchResultSelectedCommit = null;
|
|
|
|
|
head = new Commands.QuerySingleCommit(_repo.FullPath, current.Head).Result();
|
|
|
|
|
if (head != null)
|
|
|
|
|
DetailContext = new RevisionCompare(_repo.FullPath, commit, head);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-08-27 19:02:14 -07:00
|
|
|
|
list.SelectedItems.Add(head);
|
2024-05-27 02:21:28 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
2024-05-27 06:05:15 -07:00
|
|
|
|
menu.Items.Add(compareWithHead);
|
|
|
|
|
|
2024-08-13 02:38:58 -07:00
|
|
|
|
if (_repo.LocalChangesCount > 0)
|
2024-05-27 06:05:15 -07:00
|
|
|
|
{
|
|
|
|
|
var compareWithWorktree = new MenuItem();
|
|
|
|
|
compareWithWorktree.Header = App.Text("CommitCM.CompareWithWorktree");
|
|
|
|
|
compareWithWorktree.Icon = App.CreateMenuIcon("Icons.Compare");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
compareWithWorktree.Click += (_, e) =>
|
2024-05-27 06:05:15 -07:00
|
|
|
|
{
|
|
|
|
|
DetailContext = new RevisionCompare(_repo.FullPath, commit, null);
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(compareWithWorktree);
|
|
|
|
|
}
|
2024-05-27 02:21:28 -07:00
|
|
|
|
|
|
|
|
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var createBranch = new MenuItem();
|
2024-02-27 02:26:05 -08:00
|
|
|
|
createBranch.Icon = App.CreateMenuIcon("Icons.Branch.Add");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
createBranch.Header = App.Text("CreateBranch");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
createBranch.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new CreateBranch(_repo, commit));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(createBranch);
|
|
|
|
|
|
|
|
|
|
var createTag = new MenuItem();
|
2024-02-27 02:26:05 -08:00
|
|
|
|
createTag.Icon = App.CreateMenuIcon("Icons.Tag.Add");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
createTag.Header = App.Text("CreateTag");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
createTag.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new CreateTag(_repo, commit));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(createTag);
|
|
|
|
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
|
|
|
|
|
var saveToPatch = new MenuItem();
|
2024-02-27 02:26:05 -08:00
|
|
|
|
saveToPatch.Icon = App.CreateMenuIcon("Icons.Diff");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
saveToPatch.Header = App.Text("CommitCM.SaveAsPatch");
|
2024-03-17 18:37:06 -07:00
|
|
|
|
saveToPatch.Click += async (_, e) =>
|
|
|
|
|
{
|
2024-08-18 21:49:04 -07:00
|
|
|
|
var storageProvider = App.GetStorageProvider();
|
|
|
|
|
if (storageProvider == null)
|
2024-03-31 01:54:29 -07:00
|
|
|
|
return;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
|
|
|
|
var options = new FolderPickerOpenOptions() { AllowMultiple = false };
|
2024-08-26 19:40:49 -07:00
|
|
|
|
try
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-08-26 19:40:49 -07:00
|
|
|
|
var selected = await storageProvider.OpenFolderPickerAsync(options);
|
|
|
|
|
if (selected.Count == 1)
|
|
|
|
|
{
|
|
|
|
|
var succ = new Commands.FormatPatch(_repo.FullPath, commit.SHA, selected[0].Path.LocalPath).Exec();
|
|
|
|
|
if (succ)
|
|
|
|
|
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception exception)
|
|
|
|
|
{
|
|
|
|
|
App.RaiseException(_repo.FullPath, $"Failed to save as patch: {exception.Message}");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(saveToPatch);
|
|
|
|
|
|
|
|
|
|
var archive = new MenuItem();
|
2024-02-27 02:26:05 -08:00
|
|
|
|
archive.Icon = App.CreateMenuIcon("Icons.Archive");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
archive.Header = App.Text("Archive");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
archive.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new Archive(_repo, commit));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(archive);
|
|
|
|
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
|
2024-11-01 02:23:31 -07:00
|
|
|
|
var actions = new List<Models.CustomAction>();
|
|
|
|
|
foreach (var action in _repo.Settings.CustomActions)
|
|
|
|
|
{
|
|
|
|
|
if (action.Scope == Models.CustomActionScope.Commit)
|
|
|
|
|
actions.Add(action);
|
|
|
|
|
}
|
|
|
|
|
if (actions.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var custom = new MenuItem();
|
|
|
|
|
custom.Header = App.Text("CommitCM.CustomAction");
|
|
|
|
|
custom.Icon = App.CreateMenuIcon("Icons.Action");
|
|
|
|
|
|
|
|
|
|
foreach (var action in actions)
|
|
|
|
|
{
|
|
|
|
|
var dup = action;
|
|
|
|
|
var item = new MenuItem();
|
|
|
|
|
item.Icon = App.CreateMenuIcon("Icons.Action");
|
|
|
|
|
item.Header = dup.Name;
|
|
|
|
|
item.Click += (_, e) =>
|
|
|
|
|
{
|
|
|
|
|
if (PopupHost.CanCreatePopup())
|
2024-11-01 03:10:22 -07:00
|
|
|
|
PopupHost.ShowAndStartPopup(new ExecuteCustomAction(_repo, dup, commit));
|
2024-11-01 02:23:31 -07:00
|
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
custom.Items.Add(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
menu.Items.Add(custom);
|
|
|
|
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var copySHA = new MenuItem();
|
|
|
|
|
copySHA.Header = App.Text("CommitCM.CopySHA");
|
2024-02-27 02:26:05 -08:00
|
|
|
|
copySHA.Icon = App.CreateMenuIcon("Icons.Copy");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
copySHA.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
App.CopyText(commit.SHA);
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(copySHA);
|
2024-07-23 20:45:16 -07:00
|
|
|
|
|
2024-07-23 11:00:54 -07:00
|
|
|
|
var copyInfo = new MenuItem();
|
|
|
|
|
copyInfo.Header = App.Text("CommitCM.CopyInfo");
|
|
|
|
|
copyInfo.Icon = App.CreateMenuIcon("Icons.Copy");
|
|
|
|
|
copyInfo.Click += (_, e) =>
|
|
|
|
|
{
|
2024-07-23 19:42:58 -07:00
|
|
|
|
App.CopyText($"{commit.SHA.Substring(0, 10)} - {commit.Subject}");
|
2024-07-23 11:00:54 -07:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
menu.Items.Add(copyInfo);
|
2024-07-23 20:45:16 -07:00
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
return menu;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
private void FillCurrentBranchMenu(ContextMenu menu, Models.Branch current)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var submenu = new MenuItem();
|
2024-02-27 02:26:05 -08:00
|
|
|
|
submenu.Icon = App.CreateMenuIcon("Icons.Branch");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
submenu.Header = current.Name;
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (!string.IsNullOrEmpty(current.Upstream))
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var upstream = current.Upstream.Substring(13);
|
|
|
|
|
|
|
|
|
|
var fastForward = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
fastForward.Header = new Views.NameHighlightedTextBlock("BranchCM.FastForward", upstream);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
fastForward.Icon = App.CreateMenuIcon("Icons.FastForward");
|
2024-07-18 18:29:16 -07:00
|
|
|
|
fastForward.IsEnabled = current.TrackStatus.Ahead.Count == 0;
|
2024-07-14 09:30:31 -07:00
|
|
|
|
fastForward.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowAndStartPopup(new Merge(_repo, upstream, current.Name));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(fastForward);
|
|
|
|
|
|
|
|
|
|
var pull = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
pull.Header = new Views.NameHighlightedTextBlock("BranchCM.Pull", upstream);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
pull.Icon = App.CreateMenuIcon("Icons.Pull");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
pull.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new Pull(_repo, null));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(pull);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var push = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
push.Header = new Views.NameHighlightedTextBlock("BranchCM.Push", current.Name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
push.Icon = App.CreateMenuIcon("Icons.Push");
|
2024-03-01 03:12:22 -08:00
|
|
|
|
push.IsEnabled = _repo.Remotes.Count > 0;
|
2024-07-14 09:30:31 -07:00
|
|
|
|
push.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new Push(_repo, current));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(push);
|
|
|
|
|
submenu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
|
2024-06-14 21:44:35 -07:00
|
|
|
|
var detect = Commands.GitFlow.DetectType(_repo.FullPath, _repo.Branches, current.Name);
|
|
|
|
|
if (detect.IsGitFlowBranch)
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var finish = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
finish.Header = new Views.NameHighlightedTextBlock("BranchCM.Finish", current.Name);
|
2024-06-26 00:51:49 -07:00
|
|
|
|
finish.Icon = App.CreateMenuIcon("Icons.GitFlow");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
finish.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
2024-06-14 21:44:35 -07:00
|
|
|
|
PopupHost.ShowPopup(new GitFlowFinish(_repo, current, detect.Type, detect.Prefix));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(finish);
|
|
|
|
|
submenu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var rename = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
rename.Header = new Views.NameHighlightedTextBlock("BranchCM.Rename", current.Name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
rename.Icon = App.CreateMenuIcon("Icons.Rename");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
rename.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new RenameBranch(_repo, current));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(rename);
|
|
|
|
|
|
|
|
|
|
menu.Items.Add(submenu);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
private void FillOtherLocalBranchMenu(ContextMenu menu, Models.Branch branch, Models.Branch current, bool merged)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var submenu = new MenuItem();
|
2024-02-27 02:26:05 -08:00
|
|
|
|
submenu.Icon = App.CreateMenuIcon("Icons.Branch");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
submenu.Header = branch.Name;
|
|
|
|
|
|
|
|
|
|
var checkout = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
checkout.Header = new Views.NameHighlightedTextBlock("BranchCM.Checkout", branch.Name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
checkout.Icon = App.CreateMenuIcon("Icons.Check");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
checkout.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-05-29 01:42:47 -07:00
|
|
|
|
_repo.CheckoutBranch(branch);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(checkout);
|
|
|
|
|
|
|
|
|
|
var merge = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", branch.Name, current.Name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
merge.Icon = App.CreateMenuIcon("Icons.Merge");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
merge.IsEnabled = !merged;
|
2024-07-14 09:30:31 -07:00
|
|
|
|
merge.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new Merge(_repo, branch.Name, current.Name));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(merge);
|
|
|
|
|
submenu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
|
2024-06-14 21:44:35 -07:00
|
|
|
|
var detect = Commands.GitFlow.DetectType(_repo.FullPath, _repo.Branches, branch.Name);
|
|
|
|
|
if (detect.IsGitFlowBranch)
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var finish = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
finish.Header = new Views.NameHighlightedTextBlock("BranchCM.Finish", branch.Name);
|
2024-06-26 00:51:49 -07:00
|
|
|
|
finish.Icon = App.CreateMenuIcon("Icons.GitFlow");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
finish.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
2024-06-14 21:44:35 -07:00
|
|
|
|
PopupHost.ShowPopup(new GitFlowFinish(_repo, branch, detect.Type, detect.Prefix));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(finish);
|
|
|
|
|
submenu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var rename = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
rename.Header = new Views.NameHighlightedTextBlock("BranchCM.Rename", branch.Name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
rename.Icon = App.CreateMenuIcon("Icons.Rename");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
rename.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new RenameBranch(_repo, branch));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(rename);
|
|
|
|
|
|
|
|
|
|
var delete = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
delete.Header = new Views.NameHighlightedTextBlock("BranchCM.Delete", branch.Name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
delete.Icon = App.CreateMenuIcon("Icons.Clear");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
delete.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new DeleteBranch(_repo, branch));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(delete);
|
|
|
|
|
|
|
|
|
|
menu.Items.Add(submenu);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
private void FillRemoteBranchMenu(ContextMenu menu, Models.Branch branch, Models.Branch current, bool merged)
|
|
|
|
|
{
|
2024-07-01 19:23:21 -07:00
|
|
|
|
var name = branch.FriendlyName;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
|
|
|
|
var submenu = new MenuItem();
|
2024-02-27 02:26:05 -08:00
|
|
|
|
submenu.Icon = App.CreateMenuIcon("Icons.Branch");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
submenu.Header = name;
|
|
|
|
|
|
|
|
|
|
var checkout = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
checkout.Header = new Views.NameHighlightedTextBlock("BranchCM.Checkout", name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
checkout.Icon = App.CreateMenuIcon("Icons.Check");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
checkout.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-05-29 01:42:47 -07:00
|
|
|
|
_repo.CheckoutBranch(branch);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(checkout);
|
|
|
|
|
|
|
|
|
|
var merge = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", name, current.Name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
merge.Icon = App.CreateMenuIcon("Icons.Merge");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
merge.IsEnabled = !merged;
|
2024-07-14 09:30:31 -07:00
|
|
|
|
merge.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new Merge(_repo, name, current.Name));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
submenu.Items.Add(merge);
|
|
|
|
|
submenu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
|
|
|
|
|
var delete = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
delete.Header = new Views.NameHighlightedTextBlock("BranchCM.Delete", name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
delete.Icon = App.CreateMenuIcon("Icons.Clear");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
delete.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new DeleteBranch(_repo, branch));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(delete);
|
|
|
|
|
|
|
|
|
|
menu.Items.Add(submenu);
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-09 20:51:15 -08:00
|
|
|
|
private void FillTagMenu(ContextMenu menu, Models.Tag tag, Models.Branch current, bool merged)
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var submenu = new MenuItem();
|
|
|
|
|
submenu.Header = tag.Name;
|
2024-02-27 02:26:05 -08:00
|
|
|
|
submenu.Icon = App.CreateMenuIcon("Icons.Tag");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
submenu.MinWidth = 200;
|
|
|
|
|
|
|
|
|
|
var push = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
push.Header = new Views.NameHighlightedTextBlock("TagCM.Push", tag.Name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
push.Icon = App.CreateMenuIcon("Icons.Push");
|
2024-02-05 23:08:37 -08:00
|
|
|
|
push.IsEnabled = _repo.Remotes.Count > 0;
|
2024-07-14 09:30:31 -07:00
|
|
|
|
push.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new PushTag(_repo, tag));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(push);
|
|
|
|
|
|
2024-11-09 20:51:15 -08:00
|
|
|
|
var merge = new MenuItem();
|
|
|
|
|
merge.Header = new Views.NameHighlightedTextBlock("TagCM.Merge", tag.Name, current.Name);
|
|
|
|
|
merge.Icon = App.CreateMenuIcon("Icons.Merge");
|
|
|
|
|
merge.IsEnabled = !merged;
|
|
|
|
|
merge.Click += (_, e) =>
|
|
|
|
|
{
|
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new Merge(_repo, tag.Name, current.Name));
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(merge);
|
|
|
|
|
submenu.Items.Add(new MenuItem() { Header = "-" });
|
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var delete = new MenuItem();
|
2024-02-28 02:55:23 -08:00
|
|
|
|
delete.Header = new Views.NameHighlightedTextBlock("TagCM.Delete", tag.Name);
|
2024-02-27 02:26:05 -08:00
|
|
|
|
delete.Icon = App.CreateMenuIcon("Icons.Clear");
|
2024-07-14 09:30:31 -07:00
|
|
|
|
delete.Click += (_, e) =>
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (PopupHost.CanCreatePopup())
|
|
|
|
|
PopupHost.ShowPopup(new DeleteTag(_repo, tag));
|
2024-02-05 23:08:37 -08:00
|
|
|
|
e.Handled = true;
|
|
|
|
|
};
|
|
|
|
|
submenu.Items.Add(delete);
|
|
|
|
|
|
|
|
|
|
menu.Items.Add(submenu);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Repository _repo = null;
|
|
|
|
|
private bool _isLoading = true;
|
|
|
|
|
private List<Models.Commit> _commits = new List<Models.Commit>();
|
|
|
|
|
private Models.CommitGraph _graph = null;
|
|
|
|
|
private Models.Commit _autoSelectedCommit = null;
|
2024-04-07 06:19:02 -07:00
|
|
|
|
private long _navigationId = 0;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
private object _detailContext = null;
|
2024-09-14 02:22:29 -07:00
|
|
|
|
|
|
|
|
|
private GridLength _leftArea = new GridLength(1, GridUnitType.Star);
|
|
|
|
|
private GridLength _rightArea = new GridLength(1, GridUnitType.Star);
|
|
|
|
|
private GridLength _topArea = new GridLength(1, GridUnitType.Star);
|
|
|
|
|
private GridLength _bottomArea = new GridLength(1, GridUnitType.Star);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
2024-03-31 01:54:29 -07:00
|
|
|
|
}
|