feature: git bisect support

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo 2025-04-22 15:45:15 +08:00
parent 9eae1eeb81
commit df5294bcb7
No known key found for this signature in database
16 changed files with 397 additions and 7 deletions

View file

@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
@ -62,6 +63,12 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _detailContext, value);
}
public Models.Bisect Bisect
{
get => _bisect;
private set => SetProperty(ref _bisect, value);
}
public GridLength LeftArea
{
get => _leftArea;
@ -111,6 +118,37 @@ namespace SourceGit.ViewModels
_detailContext = null;
}
public Models.BisectState UpdateBisectInfo()
{
var test = Path.Combine(_repo.GitDir, "BISECT_START");
if (!File.Exists(test))
{
Bisect = null;
return Models.BisectState.None;
}
var info = new Models.Bisect();
var dir = Path.Combine(_repo.GitDir, "refs", "bisect");
if (Directory.Exists(dir))
{
var files = new DirectoryInfo(dir).GetFiles();
foreach (var file in files)
{
if (file.Name.StartsWith("bad"))
info.Bads.Add(File.ReadAllText(file.FullName).Trim());
else if (file.Name.StartsWith("good"))
info.Goods.Add(File.ReadAllText(file.FullName).Trim());
}
}
Bisect = info;
if (info.Bads.Count == 0 || info.Goods.Count == 0)
return Models.BisectState.WaitingForRange;
else
return Models.BisectState.Detecting;
}
public void NavigateTo(string commitSHA)
{
var commit = _commits.Find(x => x.SHA.StartsWith(commitSHA, StringComparison.Ordinal));
@ -1209,7 +1247,7 @@ namespace SourceGit.ViewModels
}
builder.Append(".patch");
return System.IO.Path.Combine(dir, builder.ToString());
return Path.Combine(dir, builder.ToString());
}
private Repository _repo = null;
@ -1220,6 +1258,8 @@ namespace SourceGit.ViewModels
private long _navigationId = 0;
private object _detailContext = null;
private Models.Bisect _bisect = null;
private GridLength _leftArea = new GridLength(1, GridUnitType.Star);
private GridLength _rightArea = new GridLength(1, GridUnitType.Star);
private GridLength _topArea = new GridLength(1, GridUnitType.Star);

View file

@ -398,6 +398,18 @@ namespace SourceGit.ViewModels
get => _workingCopy?.InProgressContext;
}
public Models.BisectState BisectState
{
get => _bisectState;
private set => SetProperty(ref _bisectState, value);
}
public bool IsBisectCommandRunning
{
get => _isBisectCommandRunning;
private set => SetProperty(ref _isBisectCommandRunning, value);
}
public bool IsAutoFetching
{
get => _isAutoFetching;
@ -939,6 +951,31 @@ namespace SourceGit.ViewModels
return actions;
}
public void Bisect(string subcmd)
{
IsBisectCommandRunning = true;
SetWatcherEnabled(false);
var log = CreateLog($"Bisect({subcmd})");
Task.Run(() =>
{
var succ = new Commands.Bisect(_fullpath, subcmd).Use(log).Exec();
log.Complete();
Dispatcher.UIThread.Invoke(() =>
{
if (!succ)
App.RaiseException(_fullpath, log.Content);
else if (log.Content.Contains("is the first bad commit"))
App.SendNotification(_fullpath, log.Content);
MarkBranchesDirtyManually();
SetWatcherEnabled(true);
IsBisectCommandRunning = false;
});
});
}
public void RefreshBranches()
{
var branches = new Commands.QueryBranches(_fullpath).Result();
@ -1023,6 +1060,8 @@ namespace SourceGit.ViewModels
_histories.Commits = commits;
_histories.Graph = graph;
BisectState = _histories.UpdateBisectInfo();
if (!string.IsNullOrEmpty(_navigateToBranchDelayed))
{
var branch = _branches.Find(x => x.FullName == _navigateToBranchDelayed);
@ -2627,6 +2666,9 @@ namespace SourceGit.ViewModels
private Timer _autoFetchTimer = null;
private DateTime _lastFetchTime = DateTime.MinValue;
private Models.BisectState _bisectState = Models.BisectState.None;
private bool _isBisectCommandRunning = false;
private string _navigateToBranchDelayed = string.Empty;
}
}