mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2025-01-23 01:36:57 -08:00
Merge branch 'release/v2025.03'
This commit is contained in:
commit
0f13c002f5
41 changed files with 714 additions and 694 deletions
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
## Translation Status
|
## Translation Status
|
||||||
|
|
||||||
[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-97.55%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-100.00%25-brightgreen)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-94.69%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-93.33%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-94.42%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md)
|
[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-100.00%25-brightgreen)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-100.00%25-brightgreen)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-94.69%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-93.32%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-94.41%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md)
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> You can find the missing keys in [TRANSLATION.md](TRANSLATION.md)
|
> You can find the missing keys in [TRANSLATION.md](TRANSLATION.md)
|
||||||
|
@ -62,7 +62,7 @@ This software creates a folder `$"{System.Environment.SpecialFolder.ApplicationD
|
||||||
|
|
||||||
| OS | PATH |
|
| OS | PATH |
|
||||||
|---------|-----------------------------------------------------|
|
|---------|-----------------------------------------------------|
|
||||||
| Windows | `C:\Users\USER_NAME\AppData\Roaming\SourceGit` |
|
| Windows | `%APPDATA%\SourceGit` |
|
||||||
| Linux | `${HOME}/.config/SourceGit` or `${HOME}/.sourcegit` |
|
| Linux | `${HOME}/.config/SourceGit` or `${HOME}/.sourcegit` |
|
||||||
| macOS | `${HOME}/Library/Application Support/SourceGit` |
|
| macOS | `${HOME}/Library/Application Support/SourceGit` |
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ For **Linux** users:
|
||||||
`deb` how to:
|
`deb` how to:
|
||||||
```shell
|
```shell
|
||||||
curl https://codeberg.org/api/packages/yataro/debian/repository.key | sudo tee /etc/apt/keyrings/sourcegit.asc
|
curl https://codeberg.org/api/packages/yataro/debian/repository.key | sudo tee /etc/apt/keyrings/sourcegit.asc
|
||||||
echo "deb [signed-by=/etc/apt/keyrings/sourcegit.asc] https://codeberg.org/api/packages/yataro/debian generic main" | sudo tee /etc/apt/sources.list.d/sourcegit.list
|
echo "deb [signed-by=/etc/apt/keyrings/sourcegit.asc, arch=amd64,arm64] https://codeberg.org/api/packages/yataro/debian generic main" | sudo tee /etc/apt/sources.list.d/sourcegit.list
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install sourcegit
|
sudo apt install sourcegit
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,27 +1,10 @@
|
||||||
### de_DE.axaml: 97.55%
|
### de_DE.axaml: 100.00%
|
||||||
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Missing Keys</summary>
|
<summary>Missing Keys</summary>
|
||||||
|
|
||||||
- Text.Configure.IssueTracker.AddSampleGiteeIssue
|
|
||||||
- Text.Configure.IssueTracker.AddSampleGiteePullRequest
|
|
||||||
- Text.Preferences.General.DateFormat
|
|
||||||
- Text.Preferences.Git.SSLVerify
|
|
||||||
- Text.Repository.HistoriesLayout
|
|
||||||
- Text.Repository.HistoriesLayout.Horizontal
|
|
||||||
- Text.Repository.HistoriesLayout.Vertical
|
|
||||||
- Text.Repository.HistoriesOrder
|
|
||||||
- Text.Repository.OnlyHighlightCurrentBranchInHistories
|
|
||||||
- Text.Repository.Tags.OrderByCreatorDate
|
|
||||||
- Text.Repository.Tags.OrderByNameAsc
|
|
||||||
- Text.Repository.Tags.OrderByNameDes
|
|
||||||
- Text.Repository.Tags.Sort
|
|
||||||
- Text.Repository.UseRelativeTimeInHistories
|
|
||||||
- Text.SetUpstream
|
|
||||||
- Text.SetUpstream.Local
|
|
||||||
- Text.SetUpstream.Unset
|
|
||||||
- Text.SetUpstream.Upstream
|
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
@ -83,7 +66,7 @@
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### it_IT.axaml: 93.33%
|
### it_IT.axaml: 93.32%
|
||||||
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
@ -141,7 +124,7 @@
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### pt_BR.axaml: 94.42%
|
### pt_BR.axaml: 94.41%
|
||||||
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
2025.02
|
2025.03
|
|
@ -7,7 +7,7 @@ namespace SourceGit.Commands
|
||||||
{
|
{
|
||||||
public partial class LFS
|
public partial class LFS
|
||||||
{
|
{
|
||||||
[GeneratedRegex(@"^(.+)\s+(\w+)\s+\w+:(\d+)$")]
|
[GeneratedRegex(@"^(.+)\s+([\w.]+)\s+\w+:(\d+)$")]
|
||||||
private static partial Regex REG_LOCK();
|
private static partial Regex REG_LOCK();
|
||||||
|
|
||||||
class SubCmd : Command
|
class SubCmd : Command
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace SourceGit.Commands
|
|
||||||
{
|
|
||||||
public partial class QueryStashChanges : Command
|
|
||||||
{
|
|
||||||
[GeneratedRegex(@"^(\s?[\w\?]{1,4})\s+(.+)$")]
|
|
||||||
private static partial Regex REG_FORMAT();
|
|
||||||
|
|
||||||
public QueryStashChanges(string repo, string sha)
|
|
||||||
{
|
|
||||||
WorkingDirectory = repo;
|
|
||||||
Context = repo;
|
|
||||||
Args = $"diff --name-status --pretty=format: {sha}^ {sha}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Models.Change> Result()
|
|
||||||
{
|
|
||||||
Exec();
|
|
||||||
return _changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnReadline(string line)
|
|
||||||
{
|
|
||||||
var match = REG_FORMAT().Match(line);
|
|
||||||
if (!match.Success)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var change = new Models.Change() { Path = match.Groups[2].Value };
|
|
||||||
var status = match.Groups[1].Value;
|
|
||||||
|
|
||||||
switch (status[0])
|
|
||||||
{
|
|
||||||
case 'M':
|
|
||||||
change.Set(Models.ChangeState.Modified);
|
|
||||||
_changes.Add(change);
|
|
||||||
break;
|
|
||||||
case 'A':
|
|
||||||
change.Set(Models.ChangeState.Added);
|
|
||||||
_changes.Add(change);
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
change.Set(Models.ChangeState.Deleted);
|
|
||||||
_changes.Add(change);
|
|
||||||
break;
|
|
||||||
case 'R':
|
|
||||||
change.Set(Models.ChangeState.Renamed);
|
|
||||||
_changes.Add(change);
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
change.Set(Models.ChangeState.Copied);
|
|
||||||
_changes.Add(change);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly List<Models.Change> _changes = new List<Models.Change>();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace SourceGit.Commands
|
namespace SourceGit.Commands
|
||||||
{
|
{
|
||||||
|
@ -8,7 +9,7 @@ namespace SourceGit.Commands
|
||||||
{
|
{
|
||||||
WorkingDirectory = repo;
|
WorkingDirectory = repo;
|
||||||
Context = repo;
|
Context = repo;
|
||||||
Args = "stash list --pretty=format:%H%n%ct%n%gd%n%s";
|
Args = "stash list --pretty=format:%H%n%P%n%ct%n%gd%n%s";
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Models.Stash> Result()
|
public List<Models.Stash> Result()
|
||||||
|
@ -26,21 +27,32 @@ namespace SourceGit.Commands
|
||||||
_stashes.Add(_current);
|
_stashes.Add(_current);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
_current.Time = ulong.Parse(line);
|
ParseParent(line);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
_current.Name = line;
|
_current.Time = ulong.Parse(line);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
_current.Name = line;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
_current.Message = line;
|
_current.Message = line;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_nextLineIdx++;
|
_nextLineIdx++;
|
||||||
if (_nextLineIdx > 3)
|
if (_nextLineIdx > 4)
|
||||||
_nextLineIdx = 0;
|
_nextLineIdx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ParseParent(string data)
|
||||||
|
{
|
||||||
|
if (data.Length < 8)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_current.Parents.AddRange(data.Split(separator: ' ', options: StringSplitOptions.RemoveEmptyEntries));
|
||||||
|
}
|
||||||
|
|
||||||
private readonly List<Models.Stash> _stashes = new List<Models.Stash>();
|
private readonly List<Models.Stash> _stashes = new List<Models.Stash>();
|
||||||
private Models.Stash _current = null;
|
private Models.Stash _current = null;
|
||||||
private int _nextLineIdx = 0;
|
private int _nextLineIdx = 0;
|
||||||
|
|
|
@ -11,9 +11,19 @@ namespace SourceGit.Commands
|
||||||
Context = repo;
|
Context = repo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Push(string message)
|
public bool Push(string message, bool includeUntracked = true, bool keepIndex = false)
|
||||||
{
|
{
|
||||||
Args = $"stash push -m \"{message}\"";
|
var builder = new StringBuilder();
|
||||||
|
builder.Append("stash push ");
|
||||||
|
if (includeUntracked)
|
||||||
|
builder.Append("--include-untracked ");
|
||||||
|
if (keepIndex)
|
||||||
|
builder.Append("--keep-index ");
|
||||||
|
builder.Append("-m \"");
|
||||||
|
builder.Append(message);
|
||||||
|
builder.Append("\"");
|
||||||
|
|
||||||
|
Args = builder.ToString();
|
||||||
return Exec();
|
return Exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,13 +75,13 @@ namespace SourceGit.Commands
|
||||||
|
|
||||||
public bool Apply(string name)
|
public bool Apply(string name)
|
||||||
{
|
{
|
||||||
Args = $"stash apply -q {name}";
|
Args = $"stash apply --index -q {name}";
|
||||||
return Exec();
|
return Exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Pop(string name)
|
public bool Pop(string name)
|
||||||
{
|
{
|
||||||
Args = $"stash pop -q {name}";
|
Args = $"stash pop --index -q {name}";
|
||||||
return Exec();
|
return Exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace SourceGit.Models
|
namespace SourceGit.Models
|
||||||
{
|
{
|
||||||
|
@ -6,8 +7,10 @@ namespace SourceGit.Models
|
||||||
{
|
{
|
||||||
public string Name { get; set; } = "";
|
public string Name { get; set; } = "";
|
||||||
public string SHA { get; set; } = "";
|
public string SHA { get; set; } = "";
|
||||||
|
public List<string> Parents { get; set; } = [];
|
||||||
public ulong Time { get; set; } = 0;
|
public ulong Time { get; set; } = 0;
|
||||||
public string Message { get; set; } = "";
|
public string Message { get; set; } = "";
|
||||||
|
public bool HasUntracked => Parents.Count == 3;
|
||||||
|
|
||||||
public string TimeStr => DateTime.UnixEpoch.AddSeconds(Time).ToLocalTime().ToString(DateTimeFormat.Actived.DateTime);
|
public string TimeStr => DateTime.UnixEpoch.AddSeconds(Time).ToLocalTime().ToString(DateTimeFormat.Actived.DateTime);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,11 @@ namespace SourceGit.Models
|
||||||
_updateBranch = DateTime.Now.ToFileTime() - 1;
|
_updateBranch = DateTime.Now.ToFileTime() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void MarkTagDirtyManually()
|
||||||
|
{
|
||||||
|
_updateTags = DateTime.Now.ToFileTime() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
public void MarkWorkingCopyDirtyManually()
|
public void MarkWorkingCopyDirtyManually()
|
||||||
{
|
{
|
||||||
_updateWC = DateTime.Now.ToFileTime() - 1;
|
_updateWC = DateTime.Now.ToFileTime() - 1;
|
||||||
|
|
|
@ -86,6 +86,7 @@
|
||||||
<StreamGeometry x:Key="Icons.Plus">m186 532 287 0 0 287c0 11 9 20 20 20s20-9 20-20l0-287 287 0c11 0 20-9 20-20s-9-20-20-20l-287 0 0-287c0-11-9-20-20-20s-20 9-20 20l0 287-287 0c-11 0-20 9-20 20s9 20 20 20z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Plus">m186 532 287 0 0 287c0 11 9 20 20 20s20-9 20-20l0-287 287 0c11 0 20-9 20-20s-9-20-20-20l-287 0 0-287c0-11-9-20-20-20s-20 9-20 20l0 287-287 0c-11 0-20 9-20 20s9 20 20 20z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Pull">M432 0h160c27 0 48 21 48 48v336h175c36 0 53 43 28 68L539 757c-15 15-40 15-55 0L180 452c-25-25-7-68 28-68H384V48c0-27 21-48 48-48zm592 752v224c0 27-21 48-48 48H48c-27 0-48-21-48-48V752c0-27 21-48 48-48h293l98 98c40 40 105 40 145 0l98-98H976c27 0 48 21 48 48zm-248 176c0-22-18-40-40-40s-40 18-40 40s18 40 40 40s40-18 40-40zm128 0c0-22-18-40-40-40s-40 18-40 40s18 40 40 40s40-18 40-40z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Pull">M432 0h160c27 0 48 21 48 48v336h175c36 0 53 43 28 68L539 757c-15 15-40 15-55 0L180 452c-25-25-7-68 28-68H384V48c0-27 21-48 48-48zm592 752v224c0 27-21 48-48 48H48c-27 0-48-21-48-48V752c0-27 21-48 48-48h293l98 98c40 40 105 40 145 0l98-98H976c27 0 48 21 48 48zm-248 176c0-22-18-40-40-40s-40 18-40 40s18 40 40 40s40-18 40-40zm128 0c0-22-18-40-40-40s-40 18-40 40s18 40 40 40s40-18 40-40z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Push">M592 768h-160c-27 0-48-21-48-48V384h-175c-36 0-53-43-28-68L485 11c15-15 40-15 55 0l304 304c25 25 7 68-28 68H640v336c0 27-21 48-48 48zm432-16v224c0 27-21 48-48 48H48c-27 0-48-21-48-48V752c0-27 21-48 48-48h272v16c0 62 50 112 112 112h160c62 0 112-50 112-112v-16h272c27 0 48 21 48 48zm-248 176c0-22-18-40-40-40s-40 18-40 40s18 40 40 40s40-18 40-40zm128 0c0-22-18-40-40-40s-40 18-40 40s18 40 40 40s40-18 40-40z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Push">M592 768h-160c-27 0-48-21-48-48V384h-175c-36 0-53-43-28-68L485 11c15-15 40-15 55 0l304 304c25 25 7 68-28 68H640v336c0 27-21 48-48 48zm432-16v224c0 27-21 48-48 48H48c-27 0-48-21-48-48V752c0-27 21-48 48-48h272v16c0 62 50 112 112 112h160c62 0 112-50 112-112v-16h272c27 0 48 21 48 48zm-248 176c0-22-18-40-40-40s-40 18-40 40s18 40 40 40s40-18 40-40zm128 0c0-22-18-40-40-40s-40 18-40 40s18 40 40 40s40-18 40-40z</StreamGeometry>
|
||||||
|
<StreamGeometry x:Key="Icons.Quit">M563 555c0 28-23 51-51 51-28 0-51-23-51-51L461 113c0-28 23-51 51-51s51 23 51 51L563 555 563 555zM85 535c0-153 81-287 201-362 24-15 55-8 70 16C371 214 363 245 340 260 248 318 187 419 187 535c0 180 146 325 325 325 180-0 325-146 325-325 0-119-64-223-160-280-24-14-32-46-18-70 14-24 46-32 70-18 125 74 210 211 210 367 0 236-191 427-427 427C276 963 85 772 85 535</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Rebase">M277 85a149 149 0 00-43 292v230a32 32 0 0064 0V555h267A160 160 0 00725 395v-12a149 149 0 10-64-5v17a96 96 0 01-96 96H299V383A149 149 0 00277 85zM228 720a32 32 0 00-37-52 150 150 0 00-53 68 32 32 0 1060 23 85 85 0 0130-39zm136-52a32 32 0 00-37 52 86 86 0 0130 39 32 32 0 1060-23 149 149 0 00-53-68zM204 833a32 32 0 10-55 32 149 149 0 0063 58 32 32 0 0028-57 85 85 0 01-36-33zm202 32a32 32 0 00-55-32 85 85 0 01-36 33 32 32 0 0028 57 149 149 0 0063-58z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Rebase">M277 85a149 149 0 00-43 292v230a32 32 0 0064 0V555h267A160 160 0 00725 395v-12a149 149 0 10-64-5v17a96 96 0 01-96 96H299V383A149 149 0 00277 85zM228 720a32 32 0 00-37-52 150 150 0 00-53 68 32 32 0 1060 23 85 85 0 0130-39zm136-52a32 32 0 00-37 52 86 86 0 0130 39 32 32 0 1060-23 149 149 0 00-53-68zM204 833a32 32 0 10-55 32 149 149 0 0063 58 32 32 0 0028-57 85 85 0 01-36-33zm202 32a32 32 0 00-55-32 85 85 0 01-36 33 32 32 0 0028 57 149 149 0 0063-58z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Reference">M467 556c0-0 0-1 0-1C467 555 467 556 467 556zM467 556c0-0 0-0 0-0C467 556 467 556 467 556zM467 556c-0 0-0 0-0 0C467 557 467 557 467 556zM468 549C468 532 468 541 468 549L468 549zM468 549c0 1-0 1-0 2C468 551 468 550 468 549zM468 552c-0 1-0 2-0 3C467 554 468 553 468 552zM736 549C736 532 736 541 736 549L736 549zM289 378l0 179 89 0c-1 80-89 89-89 89l45 45c0 0 129-15 134-134L467 378 289 378zM959 244l0 536c0 99-80 179-179 179L244 959c-99 0-179-80-179-179L65 244c0-99 80-179 179-179l536 0C879 65 959 145 959 244zM869 289c0-74-60-134-134-134L289 155c-74 0-134 60-134 134l0 447c0 74 60 134 134 134l447 0c74 0 134-60 134-134L869 289zM557 557l89 0c-1 80-89 89-89 89l45 45c0 0 129-15 134-134L735 378 557 378 557 557z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Reference">M467 556c0-0 0-1 0-1C467 555 467 556 467 556zM467 556c0-0 0-0 0-0C467 556 467 556 467 556zM467 556c-0 0-0 0-0 0C467 557 467 557 467 556zM468 549C468 532 468 541 468 549L468 549zM468 549c0 1-0 1-0 2C468 551 468 550 468 549zM468 552c-0 1-0 2-0 3C467 554 468 553 468 552zM736 549C736 532 736 541 736 549L736 549zM289 378l0 179 89 0c-1 80-89 89-89 89l45 45c0 0 129-15 134-134L467 378 289 378zM959 244l0 536c0 99-80 179-179 179L244 959c-99 0-179-80-179-179L65 244c0-99 80-179 179-179l536 0C879 65 959 145 959 244zM869 289c0-74-60-134-134-134L289 155c-74 0-134 60-134 134l0 447c0 74 60 134 134 134l447 0c74 0 134-60 134-134L869 289zM557 557l89 0c-1 80-89 89-89 89l45 45c0 0 129-15 134-134L735 378 557 378 557 557z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Relation">m224 154a166 166 0 00-166 166v192a166 166 0 00166 166h64v-76h-64a90 90 0 01-90-90v-192a90 90 0 0190-90h320a90 90 0 0190 90v192a90 90 0 01-90 90h-128v77h128a166 166 0 00166-167v-192a166 166 0 00-166-166h-320zm166 390a90 90 0 0190-90h128v-76h-128a166 166 0 00-166 166v192a166 166 0 00166 166h320a166 166 0 00166-166v-192a166 166 0 00-166-166h-64v77h64a90 90 0 0190 90v192a90 90 0 01-90 90h-320a90 90 0 01-90-90v-192z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Relation">m224 154a166 166 0 00-166 166v192a166 166 0 00166 166h64v-76h-64a90 90 0 01-90-90v-192a90 90 0 0190-90h320a90 90 0 0190 90v192a90 90 0 01-90 90h-128v77h128a166 166 0 00166-167v-192a166 166 0 00-166-166h-320zm166 390a90 90 0 0190-90h128v-76h-128a166 166 0 00-166 166v192a166 166 0 00166 166h320a166 166 0 00166-166v-192a166 166 0 00-166-166h-64v77h64a90 90 0 0190 90v192a90 90 0 01-90 90h-320a90 90 0 01-90-90v-192z</StreamGeometry>
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
<x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String>
|
<x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String>
|
||||||
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">BLAME WIRD BEI DIESER DATEI NICHT UNTERSTÜTZT!!!</x:String>
|
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">BLAME WIRD BEI DIESER DATEI NICHT UNTERSTÜTZT!!!</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Auschecken von ${0}$...</x:String>
|
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Auschecken von ${0}$...</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">Mit Branch vergleichen</x:String>
|
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Mit HEAD vergleichen</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Mit HEAD vergleichen</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Mit Worktree vergleichen</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Mit Worktree vergleichen</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Branch-Namen kopieren</x:String>
|
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Branch-Namen kopieren</x:String>
|
||||||
|
@ -164,6 +163,8 @@
|
||||||
<x:String x:Key="Text.Configure.Git.EnablePruneOnFetch" xml:space="preserve">Aktivere --prune beim fetchen</x:String>
|
<x:String x:Key="Text.Configure.Git.EnablePruneOnFetch" xml:space="preserve">Aktivere --prune beim fetchen</x:String>
|
||||||
<x:String x:Key="Text.Configure.Git.EnableSignOff" xml:space="preserve">Aktiviere --signoff für Commits</x:String>
|
<x:String x:Key="Text.Configure.Git.EnableSignOff" xml:space="preserve">Aktiviere --signoff für Commits</x:String>
|
||||||
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">TICKETSYSTEM</x:String>
|
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">TICKETSYSTEM</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGiteeIssue" xml:space="preserve">Beispiel für Gitee Issue Regel einfügen</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGiteePullRequest" xml:space="preserve">Beispiel für Gitee Pull Request Regel einfügen</x:String>
|
||||||
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">Beispiel für Github-Regel hinzufügen</x:String>
|
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">Beispiel für Github-Regel hinzufügen</x:String>
|
||||||
<x:String x:Key="Text.Configure.IssueTracker.AddSampleJira" xml:space="preserve">Beispiel für Jira-Regel hinzufügen</x:String>
|
<x:String x:Key="Text.Configure.IssueTracker.AddSampleJira" xml:space="preserve">Beispiel für Jira-Regel hinzufügen</x:String>
|
||||||
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGitLabIssue" xml:space="preserve">Beispiel für Gitlab Issue Regel einfügen</x:String>
|
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGitLabIssue" xml:space="preserve">Beispiel für Gitlab Issue Regel einfügen</x:String>
|
||||||
|
@ -466,6 +467,7 @@
|
||||||
<x:String x:Key="Text.Preferences.DiffMerge.Type" xml:space="preserve">Tool</x:String>
|
<x:String x:Key="Text.Preferences.DiffMerge.Type" xml:space="preserve">Tool</x:String>
|
||||||
<x:String x:Key="Text.Preferences.General" xml:space="preserve">ALLGEMEIN</x:String>
|
<x:String x:Key="Text.Preferences.General" xml:space="preserve">ALLGEMEIN</x:String>
|
||||||
<x:String x:Key="Text.Preferences.General.Check4UpdatesOnStartup" xml:space="preserve">Beim Starten nach Updates suchen</x:String>
|
<x:String x:Key="Text.Preferences.General.Check4UpdatesOnStartup" xml:space="preserve">Beim Starten nach Updates suchen</x:String>
|
||||||
|
<x:String x:Key="Text.Preferences.General.DateFormat" xml:space="preserve">Datumsformat</x:String>
|
||||||
<x:String x:Key="Text.Preferences.General.Locale" xml:space="preserve">Sprache</x:String>
|
<x:String x:Key="Text.Preferences.General.Locale" xml:space="preserve">Sprache</x:String>
|
||||||
<x:String x:Key="Text.Preferences.General.MaxHistoryCommits" xml:space="preserve">Commit-Historie</x:String>
|
<x:String x:Key="Text.Preferences.General.MaxHistoryCommits" xml:space="preserve">Commit-Historie</x:String>
|
||||||
<x:String x:Key="Text.Preferences.General.ShowAuthorTime" xml:space="preserve">Zeige Autor Zeitpunkt anstatt Commit Zeitpunkt</x:String>
|
<x:String x:Key="Text.Preferences.General.ShowAuthorTime" xml:space="preserve">Zeige Autor Zeitpunkt anstatt Commit Zeitpunkt</x:String>
|
||||||
|
@ -477,6 +479,7 @@
|
||||||
<x:String x:Key="Text.Preferences.Git.Email" xml:space="preserve">Benutzer Email</x:String>
|
<x:String x:Key="Text.Preferences.Git.Email" xml:space="preserve">Benutzer Email</x:String>
|
||||||
<x:String x:Key="Text.Preferences.Git.Email.Placeholder" xml:space="preserve">Globale Git Benutzer Email</x:String>
|
<x:String x:Key="Text.Preferences.Git.Email.Placeholder" xml:space="preserve">Globale Git Benutzer Email</x:String>
|
||||||
<x:String x:Key="Text.Preferences.Git.Path" xml:space="preserve">Installationspfad</x:String>
|
<x:String x:Key="Text.Preferences.Git.Path" xml:space="preserve">Installationspfad</x:String>
|
||||||
|
<x:String x:Key="Text.Preferences.Git.SSLVerify" xml:space="preserve">Aktiviere HTTP SSL Verifizierung</x:String>
|
||||||
<x:String x:Key="Text.Preferences.Git.User" xml:space="preserve">Benutzername</x:String>
|
<x:String x:Key="Text.Preferences.Git.User" xml:space="preserve">Benutzername</x:String>
|
||||||
<x:String x:Key="Text.Preferences.Git.User.Placeholder" xml:space="preserve">Globaler Git Benutzername</x:String>
|
<x:String x:Key="Text.Preferences.Git.User.Placeholder" xml:space="preserve">Globaler Git Benutzername</x:String>
|
||||||
<x:String x:Key="Text.Preferences.Git.Version" xml:space="preserve">Git Version</x:String>
|
<x:String x:Key="Text.Preferences.Git.Version" xml:space="preserve">Git Version</x:String>
|
||||||
|
@ -563,12 +566,17 @@
|
||||||
<x:String x:Key="Text.Repository.FilterCommits.Default" xml:space="preserve">Aufheben</x:String>
|
<x:String x:Key="Text.Repository.FilterCommits.Default" xml:space="preserve">Aufheben</x:String>
|
||||||
<x:String x:Key="Text.Repository.FilterCommits.Exclude" xml:space="preserve">Im Graph ausblenden</x:String>
|
<x:String x:Key="Text.Repository.FilterCommits.Exclude" xml:space="preserve">Im Graph ausblenden</x:String>
|
||||||
<x:String x:Key="Text.Repository.FilterCommits.Include" xml:space="preserve">Im Graph filtern</x:String>
|
<x:String x:Key="Text.Repository.FilterCommits.Include" xml:space="preserve">Im Graph filtern</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.HistoriesLayout" xml:space="preserve">LAYOUT</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.HistoriesLayout.Horizontal" xml:space="preserve">Horizontal</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.HistoriesLayout.Vertical" xml:space="preserve">Vertikal</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.HistoriesOrder" xml:space="preserve">COMMIT SORTIERUNG</x:String>
|
||||||
<x:String x:Key="Text.Repository.HistoriesOrder.ByDate" xml:space="preserve">Commit Zeitpunkt (--date-order)</x:String>
|
<x:String x:Key="Text.Repository.HistoriesOrder.ByDate" xml:space="preserve">Commit Zeitpunkt (--date-order)</x:String>
|
||||||
<x:String x:Key="Text.Repository.HistoriesOrder.Topo" xml:space="preserve">Topologie (--topo-order)</x:String>
|
<x:String x:Key="Text.Repository.HistoriesOrder.Topo" xml:space="preserve">Topologie (--topo-order)</x:String>
|
||||||
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">LOKALE BRANCHES</x:String>
|
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">LOKALE BRANCHES</x:String>
|
||||||
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Zum HEAD wechseln</x:String>
|
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Zum HEAD wechseln</x:String>
|
||||||
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Aktiviere '--first-parent' Option</x:String>
|
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Aktiviere '--first-parent' Option</x:String>
|
||||||
<x:String x:Key="Text.Repository.NewBranch" xml:space="preserve">Erstelle Branch</x:String>
|
<x:String x:Key="Text.Repository.NewBranch" xml:space="preserve">Erstelle Branch</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.OnlyHighlightCurrentBranchInHistories" xml:space="preserve">Nur aktuellen Branch im Graphen hervorheben</x:String>
|
||||||
<x:String x:Key="Text.Repository.OpenIn" xml:space="preserve">Öffne in {0}</x:String>
|
<x:String x:Key="Text.Repository.OpenIn" xml:space="preserve">Öffne in {0}</x:String>
|
||||||
<x:String x:Key="Text.Repository.OpenWithExternalTools" xml:space="preserve">Öffne in externen Tools</x:String>
|
<x:String x:Key="Text.Repository.OpenWithExternalTools" xml:space="preserve">Öffne in externen Tools</x:String>
|
||||||
<x:String x:Key="Text.Repository.Refresh" xml:space="preserve">Aktualisiern</x:String>
|
<x:String x:Key="Text.Repository.Refresh" xml:space="preserve">Aktualisiern</x:String>
|
||||||
|
@ -588,7 +596,12 @@
|
||||||
<x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">SUBMODUL AKTUALISIEREN</x:String>
|
<x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">SUBMODUL AKTUALISIEREN</x:String>
|
||||||
<x:String x:Key="Text.Repository.Tags" xml:space="preserve">TAGS</x:String>
|
<x:String x:Key="Text.Repository.Tags" xml:space="preserve">TAGS</x:String>
|
||||||
<x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">NEUER TAG</x:String>
|
<x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">NEUER TAG</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.Tags.OrderByCreatorDate" xml:space="preserve">Nach Erstellungsdatum</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.Tags.OrderByNameAsc" xml:space="preserve">Nach Namen (Aufsteigend)</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.Tags.OrderByNameDes" xml:space="preserve">Nach Namen (Absteigend)</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.Tags.Sort" xml:space="preserve">Sortiere</x:String>
|
||||||
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Öffne im Terminal</x:String>
|
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Öffne im Terminal</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">Verwende relative Zeitangaben in Verlauf</x:String>
|
||||||
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">WORKTREES</x:String>
|
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">WORKTREES</x:String>
|
||||||
<x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">WORKTREE HINZUFÜGEN</x:String>
|
<x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">WORKTREE HINZUFÜGEN</x:String>
|
||||||
<x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">PRUNE</x:String>
|
<x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">PRUNE</x:String>
|
||||||
|
@ -616,6 +629,10 @@
|
||||||
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">Diese Version überspringen</x:String>
|
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">Diese Version überspringen</x:String>
|
||||||
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">Software Update</x:String>
|
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">Software Update</x:String>
|
||||||
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">Es sind momentan kein Updates verfügbar.</x:String>
|
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">Es sind momentan kein Updates verfügbar.</x:String>
|
||||||
|
<x:String x:Key="Text.SetUpstream" xml:space="preserve">Setze verfolgten Branch</x:String>
|
||||||
|
<x:String x:Key="Text.SetUpstream.Local" xml:space="preserve">Branch:</x:String>
|
||||||
|
<x:String x:Key="Text.SetUpstream.Unset" xml:space="preserve">Upstream Verfolgung aufheben</x:String>
|
||||||
|
<x:String x:Key="Text.SetUpstream.Upstream" xml:space="preserve">Upstream:</x:String>
|
||||||
<x:String x:Key="Text.SHALinkCM.CopySHA" xml:space="preserve">SHA kopieren</x:String>
|
<x:String x:Key="Text.SHALinkCM.CopySHA" xml:space="preserve">SHA kopieren</x:String>
|
||||||
<x:String x:Key="Text.SHALinkCM.NavigateTo" xml:space="preserve">Zum Commit wechseln</x:String>
|
<x:String x:Key="Text.SHALinkCM.NavigateTo" xml:space="preserve">Zum Commit wechseln</x:String>
|
||||||
<x:String x:Key="Text.Squash" xml:space="preserve">Squash Commits</x:String>
|
<x:String x:Key="Text.Squash" xml:space="preserve">Squash Commits</x:String>
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
<x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String>
|
<x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String>
|
||||||
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">BLAME ON THIS FILE IS NOT SUPPORTED!!!</x:String>
|
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">BLAME ON THIS FILE IS NOT SUPPORTED!!!</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Checkout ${0}$...</x:String>
|
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Checkout ${0}$...</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">Compare with Branch</x:String>
|
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Compare with HEAD</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Compare with HEAD</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Compare with Worktree</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Compare with Worktree</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copy Branch Name</x:String>
|
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copy Branch Name</x:String>
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
<x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String>
|
<x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String>
|
||||||
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">¡BLAME EN ESTE ARCHIVO NO SOPORTADO!</x:String>
|
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">¡BLAME EN ESTE ARCHIVO NO SOPORTADO!</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Checkout ${0}$...</x:String>
|
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Checkout ${0}$...</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">Comparar con Rama</x:String>
|
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Comparar con HEAD</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Comparar con HEAD</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Comparar con Worktree</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Comparar con Worktree</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copiar Nombre de Rama</x:String>
|
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copiar Nombre de Rama</x:String>
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
<x:String x:Key="Text.Blame" xml:space="preserve">Blâme</x:String>
|
<x:String x:Key="Text.Blame" xml:space="preserve">Blâme</x:String>
|
||||||
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">LE BLÂME SUR CE FICHIER N'EST PAS SUPPORTÉ!!!</x:String>
|
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">LE BLÂME SUR CE FICHIER N'EST PAS SUPPORTÉ!!!</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Récupérer ${0}$...</x:String>
|
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Récupérer ${0}$...</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">Comparer avec la branche</x:String>
|
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Comparer avec HEAD</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Comparer avec HEAD</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Comparer avec le worktree</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Comparer avec le worktree</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copier le nom de la branche</x:String>
|
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copier le nom de la branche</x:String>
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
<x:String x:Key="Text.Blame" xml:space="preserve">Attribuisci</x:String>
|
<x:String x:Key="Text.Blame" xml:space="preserve">Attribuisci</x:String>
|
||||||
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">L'ATTRIBUZIONE SU QUESTO FILE NON È SUPPORTATA!!!</x:String>
|
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">L'ATTRIBUZIONE SU QUESTO FILE NON È SUPPORTATA!!!</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Checkout ${0}$...</x:String>
|
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Checkout ${0}$...</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">Confronta con Branch</x:String>
|
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Confronta con HEAD</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Confronta con HEAD</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Confronta con Worktree</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Confronta con Worktree</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copia Nome Branch</x:String>
|
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copia Nome Branch</x:String>
|
||||||
|
|
|
@ -75,7 +75,6 @@
|
||||||
<x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String>
|
<x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String>
|
||||||
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">BLAME NESTE ARQUIVO NÃO É SUPORTADO!!!</x:String>
|
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">BLAME NESTE ARQUIVO NÃO É SUPORTADO!!!</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Checkout ${0}$...</x:String>
|
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Checkout ${0}$...</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">Comparar com Branch</x:String>
|
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Comparar com HEAD</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Comparar com HEAD</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Comparar com Worktree</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Comparar com Worktree</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copiar Nome do Branch</x:String>
|
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copiar Nome do Branch</x:String>
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
<x:String x:Key="Text.Blame" xml:space="preserve">Расследование</x:String>
|
<x:String x:Key="Text.Blame" xml:space="preserve">Расследование</x:String>
|
||||||
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">РАССЛЕДОВАНИЕ В ЭТОМ ФАЙЛЕ НЕ ПОДДЕРЖИВАЕТСЯ!!!</x:String>
|
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">РАССЛЕДОВАНИЕ В ЭТОМ ФАЙЛЕ НЕ ПОДДЕРЖИВАЕТСЯ!!!</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Проверить ${0}$...</x:String>
|
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Проверить ${0}$...</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">Сравнить с веткой</x:String>
|
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Сравнить с ГОЛОВОЙ (HEAD)</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Сравнить с ГОЛОВОЙ (HEAD)</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Сравнить с рабочим каталогом</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Сравнить с рабочим каталогом</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Копировать имя ветки</x:String>
|
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Копировать имя ветки</x:String>
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
<x:String x:Key="Text.Blame" xml:space="preserve">逐行追溯(blame)</x:String>
|
<x:String x:Key="Text.Blame" xml:space="preserve">逐行追溯(blame)</x:String>
|
||||||
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">选中文件不支持该操作!!!</x:String>
|
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">选中文件不支持该操作!!!</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">检出(checkout) ${0}$...</x:String>
|
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">检出(checkout) ${0}$...</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">与其他分支对比</x:String>
|
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">与当前HEAD比较</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">与当前HEAD比较</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">与本地工作树比较</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">与本地工作树比较</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">复制分支名</x:String>
|
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">复制分支名</x:String>
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
<x:String x:Key="Text.Blame" xml:space="preserve">逐行溯源 (blame)</x:String>
|
<x:String x:Key="Text.Blame" xml:space="preserve">逐行溯源 (blame)</x:String>
|
||||||
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">所選擇的檔案不支援該操作!</x:String>
|
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">所選擇的檔案不支援該操作!</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">簽出 (checkout) ${0}$...</x:String>
|
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">簽出 (checkout) ${0}$...</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">與其他分支比較</x:String>
|
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">與目前 HEAD 比較</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">與目前 HEAD 比較</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">與本機工作區比較</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">與本機工作區比較</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">複製分支名稱</x:String>
|
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">複製分支名稱</x:String>
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.1.0" />
|
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.1.0" />
|
||||||
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.1.0" />
|
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.1.0" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" />
|
||||||
<PackageReference Include="LiveChartsCore.SkiaSharpView.Avalonia" Version="2.0.0-rc4.5" />
|
<PackageReference Include="LiveChartsCore.SkiaSharpView.Avalonia" Version="2.0.0-rc5" />
|
||||||
<PackageReference Include="TextMateSharp" Version="1.0.65" />
|
<PackageReference Include="TextMateSharp" Version="1.0.65" />
|
||||||
<PackageReference Include="TextMateSharp.Grammars" Version="1.0.65" />
|
<PackageReference Include="TextMateSharp.Grammars" Version="1.0.65" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -420,34 +420,37 @@ namespace SourceGit.ViewModels
|
||||||
menu.Items.Add(patch);
|
menu.Items.Add(patch);
|
||||||
menu.Items.Add(new MenuItem { Header = "-" });
|
menu.Items.Add(new MenuItem { Header = "-" });
|
||||||
|
|
||||||
var resetToThisRevision = new MenuItem();
|
if (!_repo.IsBare)
|
||||||
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
|
|
||||||
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
|
||||||
resetToThisRevision.Click += (_, ev) =>
|
|
||||||
{
|
{
|
||||||
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_commit.SHA}");
|
var resetToThisRevision = new MenuItem();
|
||||||
ev.Handled = true;
|
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
|
||||||
};
|
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||||
|
resetToThisRevision.Click += (_, ev) =>
|
||||||
|
{
|
||||||
|
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_commit.SHA}");
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
var resetToFirstParent = new MenuItem();
|
var resetToFirstParent = new MenuItem();
|
||||||
resetToFirstParent.Header = App.Text("ChangeCM.CheckoutFirstParentRevision");
|
resetToFirstParent.Header = App.Text("ChangeCM.CheckoutFirstParentRevision");
|
||||||
resetToFirstParent.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
resetToFirstParent.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||||
resetToFirstParent.IsEnabled = _commit.Parents.Count > 0;
|
resetToFirstParent.IsEnabled = _commit.Parents.Count > 0;
|
||||||
resetToFirstParent.Click += (_, ev) =>
|
resetToFirstParent.Click += (_, ev) =>
|
||||||
{
|
{
|
||||||
if (change.Index == Models.ChangeState.Renamed)
|
if (change.Index == Models.ChangeState.Renamed)
|
||||||
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.OriginalPath, $"{_commit.SHA}~1");
|
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.OriginalPath, $"{_commit.SHA}~1");
|
||||||
|
|
||||||
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_commit.SHA}~1");
|
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_commit.SHA}~1");
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
menu.Items.Add(resetToThisRevision);
|
menu.Items.Add(resetToThisRevision);
|
||||||
menu.Items.Add(resetToFirstParent);
|
menu.Items.Add(resetToFirstParent);
|
||||||
menu.Items.Add(new MenuItem { Header = "-" });
|
menu.Items.Add(new MenuItem { Header = "-" });
|
||||||
|
|
||||||
if (File.Exists(Path.Combine(fullPath)))
|
if (File.Exists(Path.Combine(fullPath)))
|
||||||
TryToAddContextMenuItemsForGitLFS(menu, change.Path);
|
TryToAddContextMenuItemsForGitLFS(menu, change.Path);
|
||||||
|
}
|
||||||
|
|
||||||
var copyPath = new MenuItem();
|
var copyPath = new MenuItem();
|
||||||
copyPath.Header = App.Text("CopyPath");
|
copyPath.Header = App.Text("CopyPath");
|
||||||
|
|
|
@ -31,6 +31,11 @@ namespace SourceGit.ViewModels
|
||||||
set => _repo.Settings.CheckoutBranchOnCreateBranch = value;
|
set => _repo.Settings.CheckoutBranchOnCreateBranch = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsBareRepository
|
||||||
|
{
|
||||||
|
get => _repo.IsBare;
|
||||||
|
}
|
||||||
|
|
||||||
public CreateBranch(Repository repo, Models.Branch branch)
|
public CreateBranch(Repository repo, Models.Branch branch)
|
||||||
{
|
{
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
|
@ -84,7 +89,7 @@ namespace SourceGit.ViewModels
|
||||||
return Task.Run(() =>
|
return Task.Run(() =>
|
||||||
{
|
{
|
||||||
var succ = false;
|
var succ = false;
|
||||||
if (CheckoutAfterCreated)
|
if (CheckoutAfterCreated && !_repo.IsBare)
|
||||||
{
|
{
|
||||||
var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result();
|
var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result();
|
||||||
var needPopStash = false;
|
var needPopStash = false;
|
||||||
|
|
|
@ -33,7 +33,11 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
var remotes = ShouldPushToRemote ? _repo.Remotes : null;
|
var remotes = ShouldPushToRemote ? _repo.Remotes : null;
|
||||||
var succ = Commands.Tag.Delete(_repo.FullPath, Target.Name, remotes);
|
var succ = Commands.Tag.Delete(_repo.FullPath, Target.Name, remotes);
|
||||||
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
CallUIThread(() =>
|
||||||
|
{
|
||||||
|
_repo.MarkTagsDirtyManually();
|
||||||
|
_repo.SetWatcherEnabled(true);
|
||||||
|
});
|
||||||
return succ;
|
return succ;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,7 +213,7 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
if (firstRemoteBranch != null)
|
if (firstRemoteBranch != null)
|
||||||
_repo.ShowPopup(new CreateBranch(_repo, firstRemoteBranch));
|
_repo.ShowPopup(new CreateBranch(_repo, firstRemoteBranch));
|
||||||
else
|
else if (!_repo.IsBare)
|
||||||
_repo.ShowPopup(new CheckoutCommit(_repo, commit));
|
_repo.ShowPopup(new CheckoutCommit(_repo, commit));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,36 +253,39 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
var multipleMenu = new ContextMenu();
|
var multipleMenu = new ContextMenu();
|
||||||
|
|
||||||
if (canCherryPick)
|
if (!_repo.IsBare)
|
||||||
{
|
{
|
||||||
var cherryPickMultiple = new MenuItem();
|
if (canCherryPick)
|
||||||
cherryPickMultiple.Header = App.Text("CommitCM.CherryPickMultiple");
|
|
||||||
cherryPickMultiple.Icon = App.CreateMenuIcon("Icons.CherryPick");
|
|
||||||
cherryPickMultiple.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (_repo.CanCreatePopup())
|
var cherryPickMultiple = new MenuItem();
|
||||||
_repo.ShowPopup(new CherryPick(_repo, selected));
|
cherryPickMultiple.Header = App.Text("CommitCM.CherryPickMultiple");
|
||||||
e.Handled = true;
|
cherryPickMultiple.Icon = App.CreateMenuIcon("Icons.CherryPick");
|
||||||
};
|
cherryPickMultiple.Click += (_, e) =>
|
||||||
multipleMenu.Items.Add(cherryPickMultiple);
|
{
|
||||||
}
|
if (_repo.CanCreatePopup())
|
||||||
|
_repo.ShowPopup(new CherryPick(_repo, selected));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
multipleMenu.Items.Add(cherryPickMultiple);
|
||||||
|
}
|
||||||
|
|
||||||
if (canMerge)
|
if (canMerge)
|
||||||
{
|
|
||||||
var mergeMultiple = new MenuItem();
|
|
||||||
mergeMultiple.Header = App.Text("CommitCM.MergeMultiple");
|
|
||||||
mergeMultiple.Icon = App.CreateMenuIcon("Icons.Merge");
|
|
||||||
mergeMultiple.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (_repo.CanCreatePopup())
|
var mergeMultiple = new MenuItem();
|
||||||
_repo.ShowPopup(new MergeMultiple(_repo, selected));
|
mergeMultiple.Header = App.Text("CommitCM.MergeMultiple");
|
||||||
e.Handled = true;
|
mergeMultiple.Icon = App.CreateMenuIcon("Icons.Merge");
|
||||||
};
|
mergeMultiple.Click += (_, e) =>
|
||||||
multipleMenu.Items.Add(mergeMultiple);
|
{
|
||||||
}
|
if (_repo.CanCreatePopup())
|
||||||
|
_repo.ShowPopup(new MergeMultiple(_repo, selected));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
multipleMenu.Items.Add(mergeMultiple);
|
||||||
|
}
|
||||||
|
|
||||||
if (canCherryPick || canMerge)
|
if (canCherryPick || canMerge)
|
||||||
multipleMenu.Items.Add(new MenuItem() { Header = "-" });
|
multipleMenu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
}
|
||||||
|
|
||||||
var saveToPatchMultiple = new MenuItem();
|
var saveToPatchMultiple = new MenuItem();
|
||||||
saveToPatchMultiple.Icon = App.CreateMenuIcon("Icons.Diff");
|
saveToPatchMultiple.Icon = App.CreateMenuIcon("Icons.Diff");
|
||||||
|
@ -394,25 +397,48 @@ namespace SourceGit.ViewModels
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current.Head != commit.SHA)
|
if (!_repo.IsBare)
|
||||||
{
|
{
|
||||||
var reset = new MenuItem();
|
if (current.Head != commit.SHA)
|
||||||
reset.Header = new Views.NameHighlightedTextBlock("CommitCM.Reset", current.Name);
|
|
||||||
reset.Icon = App.CreateMenuIcon("Icons.Reset");
|
|
||||||
reset.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (_repo.CanCreatePopup())
|
var reset = new MenuItem();
|
||||||
_repo.ShowPopup(new Reset(_repo, current, commit));
|
reset.Header = new Views.NameHighlightedTextBlock("CommitCM.Reset", current.Name);
|
||||||
e.Handled = true;
|
reset.Icon = App.CreateMenuIcon("Icons.Reset");
|
||||||
};
|
reset.Click += (_, e) =>
|
||||||
menu.Items.Add(reset);
|
{
|
||||||
|
if (_repo.CanCreatePopup())
|
||||||
|
_repo.ShowPopup(new Reset(_repo, current, commit));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(reset);
|
||||||
|
|
||||||
if (commit.IsMerged)
|
if (commit.IsMerged)
|
||||||
|
{
|
||||||
|
var squash = new MenuItem();
|
||||||
|
squash.Header = App.Text("CommitCM.SquashCommitsSinceThis");
|
||||||
|
squash.Icon = App.CreateMenuIcon("Icons.SquashIntoParent");
|
||||||
|
squash.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
if (_repo.LocalChangesCount > 0)
|
||||||
|
{
|
||||||
|
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_repo.CanCreatePopup())
|
||||||
|
_repo.ShowPopup(new Squash(_repo, commit, commit.SHA));
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(squash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
var squash = new MenuItem();
|
var reword = new MenuItem();
|
||||||
squash.Header = App.Text("CommitCM.SquashCommitsSinceThis");
|
reword.Header = App.Text("CommitCM.Reword");
|
||||||
squash.Icon = App.CreateMenuIcon("Icons.SquashIntoParent");
|
reword.Icon = App.CreateMenuIcon("Icons.Edit");
|
||||||
squash.Click += (_, e) =>
|
reword.Click += (_, e) =>
|
||||||
{
|
{
|
||||||
if (_repo.LocalChangesCount > 0)
|
if (_repo.LocalChangesCount > 0)
|
||||||
{
|
{
|
||||||
|
@ -421,169 +447,149 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_repo.CanCreatePopup())
|
if (_repo.CanCreatePopup())
|
||||||
_repo.ShowPopup(new Squash(_repo, commit, commit.SHA));
|
_repo.ShowPopup(new Reword(_repo, commit));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(reword);
|
||||||
|
|
||||||
|
var squash = new MenuItem();
|
||||||
|
squash.Header = App.Text("CommitCM.Squash");
|
||||||
|
squash.Icon = App.CreateMenuIcon("Icons.SquashIntoParent");
|
||||||
|
squash.IsEnabled = commit.Parents.Count == 1;
|
||||||
|
squash.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
if (_repo.LocalChangesCount > 0)
|
||||||
|
{
|
||||||
|
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commit.Parents.Count == 1)
|
||||||
|
{
|
||||||
|
var parent = _commits.Find(x => x.SHA == commit.Parents[0]);
|
||||||
|
if (parent != null && _repo.CanCreatePopup())
|
||||||
|
_repo.ShowPopup(new Squash(_repo, parent, commit.SHA));
|
||||||
|
}
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
};
|
};
|
||||||
menu.Items.Add(squash);
|
menu.Items.Add(squash);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
if (!commit.IsMerged)
|
||||||
{
|
|
||||||
var reword = new MenuItem();
|
|
||||||
reword.Header = App.Text("CommitCM.Reword");
|
|
||||||
reword.Icon = App.CreateMenuIcon("Icons.Edit");
|
|
||||||
reword.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (_repo.LocalChangesCount > 0)
|
var rebase = new MenuItem();
|
||||||
{
|
rebase.Header = new Views.NameHighlightedTextBlock("CommitCM.Rebase", current.Name);
|
||||||
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
rebase.Icon = App.CreateMenuIcon("Icons.Rebase");
|
||||||
return;
|
rebase.Click += (_, e) =>
|
||||||
}
|
|
||||||
|
|
||||||
if (_repo.CanCreatePopup())
|
|
||||||
_repo.ShowPopup(new Reword(_repo, commit));
|
|
||||||
e.Handled = true;
|
|
||||||
};
|
|
||||||
menu.Items.Add(reword);
|
|
||||||
|
|
||||||
var squash = new MenuItem();
|
|
||||||
squash.Header = App.Text("CommitCM.Squash");
|
|
||||||
squash.Icon = App.CreateMenuIcon("Icons.SquashIntoParent");
|
|
||||||
squash.IsEnabled = commit.Parents.Count == 1;
|
|
||||||
squash.Click += (_, e) =>
|
|
||||||
{
|
|
||||||
if (_repo.LocalChangesCount > 0)
|
|
||||||
{
|
|
||||||
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (commit.Parents.Count == 1)
|
|
||||||
{
|
|
||||||
var parent = _commits.Find(x => x.SHA == commit.Parents[0]);
|
|
||||||
if (parent != null && _repo.CanCreatePopup())
|
|
||||||
_repo.ShowPopup(new Squash(_repo, parent, commit.SHA));
|
|
||||||
}
|
|
||||||
|
|
||||||
e.Handled = true;
|
|
||||||
};
|
|
||||||
menu.Items.Add(squash);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!commit.IsMerged)
|
|
||||||
{
|
|
||||||
var rebase = new MenuItem();
|
|
||||||
rebase.Header = new Views.NameHighlightedTextBlock("CommitCM.Rebase", current.Name);
|
|
||||||
rebase.Icon = App.CreateMenuIcon("Icons.Rebase");
|
|
||||||
rebase.Click += (_, e) =>
|
|
||||||
{
|
|
||||||
if (_repo.CanCreatePopup())
|
|
||||||
_repo.ShowPopup(new Rebase(_repo, current, commit));
|
|
||||||
e.Handled = true;
|
|
||||||
};
|
|
||||||
menu.Items.Add(rebase);
|
|
||||||
|
|
||||||
if (!commit.HasDecorators)
|
|
||||||
{
|
|
||||||
var merge = new MenuItem();
|
|
||||||
merge.Header = new Views.NameHighlightedTextBlock("CommitCM.Merge", current.Name);
|
|
||||||
merge.Icon = App.CreateMenuIcon("Icons.Merge");
|
|
||||||
merge.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (_repo.CanCreatePopup())
|
if (_repo.CanCreatePopup())
|
||||||
_repo.ShowPopup(new Merge(_repo, commit, current.Name));
|
_repo.ShowPopup(new Rebase(_repo, current, commit));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(rebase);
|
||||||
|
|
||||||
|
if (!commit.HasDecorators)
|
||||||
|
{
|
||||||
|
var merge = new MenuItem();
|
||||||
|
merge.Header = new Views.NameHighlightedTextBlock("CommitCM.Merge", current.Name);
|
||||||
|
merge.Icon = App.CreateMenuIcon("Icons.Merge");
|
||||||
|
merge.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
if (_repo.CanCreatePopup())
|
||||||
|
_repo.ShowPopup(new Merge(_repo, commit, current.Name));
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(merge);
|
||||||
|
}
|
||||||
|
|
||||||
|
var cherryPick = new MenuItem();
|
||||||
|
cherryPick.Header = App.Text("CommitCM.CherryPick");
|
||||||
|
cherryPick.Icon = App.CreateMenuIcon("Icons.CherryPick");
|
||||||
|
cherryPick.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
if (_repo.CanCreatePopup())
|
||||||
|
{
|
||||||
|
if (commit.Parents.Count <= 1)
|
||||||
|
{
|
||||||
|
_repo.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
_repo.ShowPopup(new CherryPick(_repo, commit, parents));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
};
|
};
|
||||||
menu.Items.Add(merge);
|
menu.Items.Add(cherryPick);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var revert = new MenuItem();
|
||||||
|
revert.Header = App.Text("CommitCM.Revert");
|
||||||
|
revert.Icon = App.CreateMenuIcon("Icons.Undo");
|
||||||
|
revert.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
if (_repo.CanCreatePopup())
|
||||||
|
_repo.ShowPopup(new Revert(_repo, commit));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(revert);
|
||||||
}
|
}
|
||||||
|
|
||||||
var cherryPick = new MenuItem();
|
if (current.Head != commit.SHA)
|
||||||
cherryPick.Header = App.Text("CommitCM.CherryPick");
|
|
||||||
cherryPick.Icon = App.CreateMenuIcon("Icons.CherryPick");
|
|
||||||
cherryPick.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (_repo.CanCreatePopup())
|
var checkoutCommit = new MenuItem();
|
||||||
|
checkoutCommit.Header = App.Text("CommitCM.Checkout");
|
||||||
|
checkoutCommit.Icon = App.CreateMenuIcon("Icons.Detached");
|
||||||
|
checkoutCommit.Click += (_, e) =>
|
||||||
{
|
{
|
||||||
if (commit.Parents.Count <= 1)
|
if (_repo.CanCreatePopup())
|
||||||
{
|
_repo.ShowPopup(new CheckoutCommit(_repo, commit));
|
||||||
_repo.ShowPopup(new CherryPick(_repo, [commit]));
|
e.Handled = true;
|
||||||
}
|
};
|
||||||
else
|
menu.Items.Add(checkoutCommit);
|
||||||
{
|
}
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
_repo.ShowPopup(new CherryPick(_repo, commit, parents));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e.Handled = true;
|
|
||||||
};
|
|
||||||
menu.Items.Add(cherryPick);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var revert = new MenuItem();
|
|
||||||
revert.Header = App.Text("CommitCM.Revert");
|
|
||||||
revert.Icon = App.CreateMenuIcon("Icons.Undo");
|
|
||||||
revert.Click += (_, e) =>
|
|
||||||
{
|
|
||||||
if (_repo.CanCreatePopup())
|
|
||||||
_repo.ShowPopup(new Revert(_repo, commit));
|
|
||||||
e.Handled = true;
|
|
||||||
};
|
|
||||||
menu.Items.Add(revert);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current.Head != commit.SHA)
|
|
||||||
{
|
|
||||||
var checkoutCommit = new MenuItem();
|
|
||||||
checkoutCommit.Header = App.Text("CommitCM.Checkout");
|
|
||||||
checkoutCommit.Icon = App.CreateMenuIcon("Icons.Detached");
|
|
||||||
checkoutCommit.Click += (_, e) =>
|
|
||||||
{
|
|
||||||
if (_repo.CanCreatePopup())
|
|
||||||
_repo.ShowPopup(new CheckoutCommit(_repo, commit));
|
|
||||||
e.Handled = true;
|
|
||||||
};
|
|
||||||
menu.Items.Add(checkoutCommit);
|
|
||||||
}
|
|
||||||
|
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
||||||
|
|
||||||
if (commit.IsMerged && current.Head != commit.SHA)
|
|
||||||
{
|
|
||||||
var interactiveRebase = new MenuItem();
|
|
||||||
interactiveRebase.Header = new Views.NameHighlightedTextBlock("CommitCM.InteractiveRebase", current.Name);
|
|
||||||
interactiveRebase.Icon = App.CreateMenuIcon("Icons.InteractiveRebase");
|
|
||||||
interactiveRebase.Click += (_, e) =>
|
|
||||||
{
|
|
||||||
if (_repo.LocalChangesCount > 0)
|
|
||||||
{
|
|
||||||
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
App.OpenDialog(new Views.InteractiveRebase()
|
|
||||||
{
|
|
||||||
DataContext = new InteractiveRebase(_repo, current, commit)
|
|
||||||
});
|
|
||||||
|
|
||||||
e.Handled = true;
|
|
||||||
};
|
|
||||||
menu.Items.Add(interactiveRebase);
|
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
}
|
|
||||||
|
if (commit.IsMerged && current.Head != commit.SHA)
|
||||||
|
{
|
||||||
|
var interactiveRebase = new MenuItem();
|
||||||
|
interactiveRebase.Header = new Views.NameHighlightedTextBlock("CommitCM.InteractiveRebase", current.Name);
|
||||||
|
interactiveRebase.Icon = App.CreateMenuIcon("Icons.InteractiveRebase");
|
||||||
|
interactiveRebase.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
if (_repo.LocalChangesCount > 0)
|
||||||
|
{
|
||||||
|
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
App.OpenDialog(new Views.InteractiveRebase()
|
||||||
|
{
|
||||||
|
DataContext = new InteractiveRebase(_repo, current, commit)
|
||||||
|
});
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(interactiveRebase);
|
||||||
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (current.Head != commit.SHA)
|
if (current.Head != commit.SHA)
|
||||||
{
|
{
|
||||||
|
@ -914,21 +920,24 @@ namespace SourceGit.ViewModels
|
||||||
submenu.Items.Add(rename);
|
submenu.Items.Add(rename);
|
||||||
submenu.Items.Add(new MenuItem() { Header = "-" });
|
submenu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
|
||||||
var detect = Commands.GitFlow.DetectType(_repo.FullPath, _repo.Branches, current.Name);
|
if (!_repo.IsBare)
|
||||||
if (detect.IsGitFlowBranch)
|
|
||||||
{
|
{
|
||||||
var finish = new MenuItem();
|
var detect = Commands.GitFlow.DetectType(_repo.FullPath, _repo.Branches, current.Name);
|
||||||
finish.Header = new Views.NameHighlightedTextBlock("BranchCM.Finish", current.Name);
|
if (detect.IsGitFlowBranch)
|
||||||
finish.Icon = App.CreateMenuIcon("Icons.GitFlow");
|
|
||||||
finish.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (_repo.CanCreatePopup())
|
var finish = new MenuItem();
|
||||||
_repo.ShowPopup(new GitFlowFinish(_repo, current, detect.Type, detect.Prefix));
|
finish.Header = new Views.NameHighlightedTextBlock("BranchCM.Finish", current.Name);
|
||||||
e.Handled = true;
|
finish.Icon = App.CreateMenuIcon("Icons.GitFlow");
|
||||||
};
|
finish.Click += (_, e) =>
|
||||||
submenu.Items.Add(finish);
|
{
|
||||||
submenu.Items.Add(new MenuItem() { Header = "-" });
|
if (_repo.CanCreatePopup())
|
||||||
}
|
_repo.ShowPopup(new GitFlowFinish(_repo, current, detect.Type, detect.Prefix));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
submenu.Items.Add(finish);
|
||||||
|
submenu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var copy = new MenuItem();
|
var copy = new MenuItem();
|
||||||
copy.Header = App.Text("BranchCM.CopyName");
|
copy.Header = App.Text("BranchCM.CopyName");
|
||||||
|
@ -951,27 +960,30 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
FillBranchVisibilityMenu(submenu, branch);
|
FillBranchVisibilityMenu(submenu, branch);
|
||||||
|
|
||||||
var checkout = new MenuItem();
|
if (!_repo.IsBare)
|
||||||
checkout.Header = new Views.NameHighlightedTextBlock("BranchCM.Checkout", branch.Name);
|
|
||||||
checkout.Icon = App.CreateMenuIcon("Icons.Check");
|
|
||||||
checkout.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
_repo.CheckoutBranch(branch);
|
var checkout = new MenuItem();
|
||||||
e.Handled = true;
|
checkout.Header = new Views.NameHighlightedTextBlock("BranchCM.Checkout", branch.Name);
|
||||||
};
|
checkout.Icon = App.CreateMenuIcon("Icons.Check");
|
||||||
submenu.Items.Add(checkout);
|
checkout.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
_repo.CheckoutBranch(branch);
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
submenu.Items.Add(checkout);
|
||||||
|
|
||||||
var merge = new MenuItem();
|
var merge = new MenuItem();
|
||||||
merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", branch.Name, current.Name);
|
merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", branch.Name, current.Name);
|
||||||
merge.Icon = App.CreateMenuIcon("Icons.Merge");
|
merge.Icon = App.CreateMenuIcon("Icons.Merge");
|
||||||
merge.IsEnabled = !merged;
|
merge.IsEnabled = !merged;
|
||||||
merge.Click += (_, e) =>
|
merge.Click += (_, e) =>
|
||||||
{
|
{
|
||||||
if (_repo.CanCreatePopup())
|
if (_repo.CanCreatePopup())
|
||||||
_repo.ShowPopup(new Merge(_repo, branch, current.Name));
|
_repo.ShowPopup(new Merge(_repo, branch, current.Name));
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
};
|
};
|
||||||
submenu.Items.Add(merge);
|
submenu.Items.Add(merge);
|
||||||
|
}
|
||||||
|
|
||||||
var rename = new MenuItem();
|
var rename = new MenuItem();
|
||||||
rename.Header = new Views.NameHighlightedTextBlock("BranchCM.Rename", branch.Name);
|
rename.Header = new Views.NameHighlightedTextBlock("BranchCM.Rename", branch.Name);
|
||||||
|
@ -996,21 +1008,24 @@ namespace SourceGit.ViewModels
|
||||||
submenu.Items.Add(delete);
|
submenu.Items.Add(delete);
|
||||||
submenu.Items.Add(new MenuItem() { Header = "-" });
|
submenu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
|
||||||
var detect = Commands.GitFlow.DetectType(_repo.FullPath, _repo.Branches, branch.Name);
|
if (!_repo.IsBare)
|
||||||
if (detect.IsGitFlowBranch)
|
|
||||||
{
|
{
|
||||||
var finish = new MenuItem();
|
var detect = Commands.GitFlow.DetectType(_repo.FullPath, _repo.Branches, branch.Name);
|
||||||
finish.Header = new Views.NameHighlightedTextBlock("BranchCM.Finish", branch.Name);
|
if (detect.IsGitFlowBranch)
|
||||||
finish.Icon = App.CreateMenuIcon("Icons.GitFlow");
|
|
||||||
finish.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (_repo.CanCreatePopup())
|
var finish = new MenuItem();
|
||||||
_repo.ShowPopup(new GitFlowFinish(_repo, branch, detect.Type, detect.Prefix));
|
finish.Header = new Views.NameHighlightedTextBlock("BranchCM.Finish", branch.Name);
|
||||||
e.Handled = true;
|
finish.Icon = App.CreateMenuIcon("Icons.GitFlow");
|
||||||
};
|
finish.Click += (_, e) =>
|
||||||
submenu.Items.Add(finish);
|
{
|
||||||
submenu.Items.Add(new MenuItem() { Header = "-" });
|
if (_repo.CanCreatePopup())
|
||||||
}
|
_repo.ShowPopup(new GitFlowFinish(_repo, branch, detect.Type, detect.Prefix));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
submenu.Items.Add(finish);
|
||||||
|
submenu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var copy = new MenuItem();
|
var copy = new MenuItem();
|
||||||
copy.Header = App.Text("BranchCM.CopyName");
|
copy.Header = App.Text("BranchCM.CopyName");
|
||||||
|
@ -1104,17 +1119,19 @@ namespace SourceGit.ViewModels
|
||||||
};
|
};
|
||||||
submenu.Items.Add(push);
|
submenu.Items.Add(push);
|
||||||
|
|
||||||
var merge = new MenuItem();
|
if (!_repo.IsBare && !merged)
|
||||||
merge.Header = new Views.NameHighlightedTextBlock("TagCM.Merge", tag.Name, current.Name);
|
|
||||||
merge.Icon = App.CreateMenuIcon("Icons.Merge");
|
|
||||||
merge.IsEnabled = !merged;
|
|
||||||
merge.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (_repo.CanCreatePopup())
|
var merge = new MenuItem();
|
||||||
_repo.ShowPopup(new Merge(_repo, tag, current.Name));
|
merge.Header = new Views.NameHighlightedTextBlock("TagCM.Merge", tag.Name, current.Name);
|
||||||
e.Handled = true;
|
merge.Icon = App.CreateMenuIcon("Icons.Merge");
|
||||||
};
|
merge.Click += (_, e) =>
|
||||||
submenu.Items.Add(merge);
|
{
|
||||||
|
if (_repo.CanCreatePopup())
|
||||||
|
_repo.ShowPopup(new Merge(_repo, tag, current.Name));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
submenu.Items.Add(merge);
|
||||||
|
}
|
||||||
|
|
||||||
var delete = new MenuItem();
|
var delete = new MenuItem();
|
||||||
delete.Header = new Views.NameHighlightedTextBlock("TagCM.Delete", tag.Name);
|
delete.Header = new Views.NameHighlightedTextBlock("TagCM.Delete", tag.Name);
|
||||||
|
|
|
@ -280,19 +280,20 @@ namespace SourceGit.ViewModels
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var gitDir = new Commands.QueryGitDir(node.Id).Result();
|
var isBare = new Commands.IsBareRepository(node.Id).Result();
|
||||||
if (string.IsNullOrEmpty(gitDir))
|
var gitDir = node.Id;
|
||||||
|
if (!isBare)
|
||||||
{
|
{
|
||||||
var ctx = page == null ? ActivePage.Node.Id : page.Node.Id;
|
gitDir = new Commands.QueryGitDir(node.Id).Result();
|
||||||
App.RaiseException(ctx, "Given path is not a valid git repository!");
|
if (string.IsNullOrEmpty(gitDir))
|
||||||
return;
|
{
|
||||||
|
var ctx = page == null ? ActivePage.Node.Id : page.Node.Id;
|
||||||
|
App.RaiseException(ctx, "Given path is not a valid git repository!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var repo = new Repository()
|
var repo = new Repository(isBare, node.Id, gitDir);
|
||||||
{
|
|
||||||
FullPath = node.Id,
|
|
||||||
GitDir = gitDir,
|
|
||||||
};
|
|
||||||
repo.Open();
|
repo.Open();
|
||||||
|
|
||||||
if (page == null)
|
if (page == null)
|
||||||
|
|
|
@ -18,6 +18,11 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
public class Repository : ObservableObject, Models.IRepository
|
public class Repository : ObservableObject, Models.IRepository
|
||||||
{
|
{
|
||||||
|
public bool IsBare
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
public string FullPath
|
public string FullPath
|
||||||
{
|
{
|
||||||
get => _fullpath;
|
get => _fullpath;
|
||||||
|
@ -448,6 +453,13 @@ namespace SourceGit.ViewModels
|
||||||
private set => SetProperty(ref _isAutoFetching, value);
|
private set => SetProperty(ref _isAutoFetching, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Repository(bool isBare, string path, string gitDir)
|
||||||
|
{
|
||||||
|
IsBare = isBare;
|
||||||
|
FullPath = path;
|
||||||
|
GitDir = gitDir;
|
||||||
|
}
|
||||||
|
|
||||||
public void Open()
|
public void Open()
|
||||||
{
|
{
|
||||||
var settingsFile = Path.Combine(_gitDir, "sourcegit.settings");
|
var settingsFile = Path.Combine(_gitDir, "sourcegit.settings");
|
||||||
|
@ -759,6 +771,19 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void MarkTagsDirtyManually()
|
||||||
|
{
|
||||||
|
if (_watcher == null)
|
||||||
|
{
|
||||||
|
Task.Run(RefreshTags);
|
||||||
|
Task.Run(RefreshCommits);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_watcher.MarkTagDirtyManually();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void MarkWorkingCopyDirtyManually()
|
public void MarkWorkingCopyDirtyManually()
|
||||||
{
|
{
|
||||||
if (_watcher == null)
|
if (_watcher == null)
|
||||||
|
@ -995,6 +1020,9 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public void RefreshWorkingCopyChanges()
|
public void RefreshWorkingCopyChanges()
|
||||||
{
|
{
|
||||||
|
if (IsBare)
|
||||||
|
return;
|
||||||
|
|
||||||
var changes = new Commands.QueryLocalChanges(_fullpath, _settings.IncludeUntrackedInLocalChanges).Result();
|
var changes = new Commands.QueryLocalChanges(_fullpath, _settings.IncludeUntrackedInLocalChanges).Result();
|
||||||
if (_workingCopy == null)
|
if (_workingCopy == null)
|
||||||
return;
|
return;
|
||||||
|
@ -1010,6 +1038,9 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public void RefreshStashes()
|
public void RefreshStashes()
|
||||||
{
|
{
|
||||||
|
if (IsBare)
|
||||||
|
return;
|
||||||
|
|
||||||
var stashes = new Commands.QueryStashes(_fullpath).Result();
|
var stashes = new Commands.QueryStashes(_fullpath).Result();
|
||||||
Dispatcher.UIThread.Invoke(() =>
|
Dispatcher.UIThread.Invoke(() =>
|
||||||
{
|
{
|
||||||
|
@ -1044,6 +1075,9 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsBare)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!CanCreatePopup())
|
if (!CanCreatePopup())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1416,73 +1450,72 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
if (branch.IsCurrent)
|
if (branch.IsCurrent)
|
||||||
{
|
{
|
||||||
var discard = new MenuItem();
|
if (!IsBare)
|
||||||
discard.Header = App.Text("BranchCM.DiscardAll");
|
|
||||||
discard.Icon = App.CreateMenuIcon("Icons.Undo");
|
|
||||||
discard.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (CanCreatePopup())
|
var discard = new MenuItem();
|
||||||
ShowPopup(new Discard(this));
|
discard.Header = App.Text("BranchCM.DiscardAll");
|
||||||
e.Handled = true;
|
discard.Icon = App.CreateMenuIcon("Icons.Undo");
|
||||||
};
|
discard.Click += (_, e) =>
|
||||||
|
|
||||||
menu.Items.Add(discard);
|
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(branch.Upstream))
|
|
||||||
{
|
|
||||||
var upstream = branch.Upstream.Substring(13);
|
|
||||||
var fastForward = new MenuItem();
|
|
||||||
fastForward.Header = new Views.NameHighlightedTextBlock("BranchCM.FastForward", upstream);
|
|
||||||
fastForward.Icon = App.CreateMenuIcon("Icons.FastForward");
|
|
||||||
fastForward.IsEnabled = branch.TrackStatus.Ahead.Count == 0;
|
|
||||||
fastForward.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
var b = _branches.Find(x => x.FriendlyName == upstream);
|
|
||||||
if (b == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (CanCreatePopup())
|
if (CanCreatePopup())
|
||||||
ShowAndStartPopup(new Merge(this, b, branch.Name));
|
ShowPopup(new Discard(this));
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
var pull = new MenuItem();
|
menu.Items.Add(discard);
|
||||||
pull.Header = new Views.NameHighlightedTextBlock("BranchCM.Pull", upstream);
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
pull.Icon = App.CreateMenuIcon("Icons.Pull");
|
|
||||||
pull.Click += (_, e) =>
|
|
||||||
{
|
|
||||||
if (CanCreatePopup())
|
|
||||||
ShowPopup(new Pull(this, null));
|
|
||||||
e.Handled = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
menu.Items.Add(fastForward);
|
if (!string.IsNullOrEmpty(branch.Upstream))
|
||||||
menu.Items.Add(pull);
|
{
|
||||||
}
|
var upstream = branch.Upstream.Substring(13);
|
||||||
|
var fastForward = new MenuItem();
|
||||||
|
fastForward.Header = new Views.NameHighlightedTextBlock("BranchCM.FastForward", upstream);
|
||||||
|
fastForward.Icon = App.CreateMenuIcon("Icons.FastForward");
|
||||||
|
fastForward.IsEnabled = branch.TrackStatus.Ahead.Count == 0;
|
||||||
|
fastForward.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
var b = _branches.Find(x => x.FriendlyName == upstream);
|
||||||
|
if (b == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (CanCreatePopup())
|
||||||
|
ShowAndStartPopup(new Merge(this, b, branch.Name));
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var pull = new MenuItem();
|
||||||
|
pull.Header = new Views.NameHighlightedTextBlock("BranchCM.Pull", upstream);
|
||||||
|
pull.Icon = App.CreateMenuIcon("Icons.Pull");
|
||||||
|
pull.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
if (CanCreatePopup())
|
||||||
|
ShowPopup(new Pull(this, null));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
menu.Items.Add(fastForward);
|
||||||
|
menu.Items.Add(pull);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
menu.Items.Add(push);
|
menu.Items.Add(push);
|
||||||
|
|
||||||
var compareWithBranch = CreateMenuItemToCompareBranches(branch);
|
|
||||||
if (compareWithBranch != null)
|
|
||||||
{
|
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
||||||
menu.Items.Add(compareWithBranch);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var checkout = new MenuItem();
|
if (!IsBare)
|
||||||
checkout.Header = new Views.NameHighlightedTextBlock("BranchCM.Checkout", branch.Name);
|
|
||||||
checkout.Icon = App.CreateMenuIcon("Icons.Check");
|
|
||||||
checkout.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
CheckoutBranch(branch);
|
var checkout = new MenuItem();
|
||||||
e.Handled = true;
|
checkout.Header = new Views.NameHighlightedTextBlock("BranchCM.Checkout", branch.Name);
|
||||||
};
|
checkout.Icon = App.CreateMenuIcon("Icons.Check");
|
||||||
menu.Items.Add(checkout);
|
checkout.Click += (_, e) =>
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
{
|
||||||
|
CheckoutBranch(branch);
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(checkout);
|
||||||
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
}
|
||||||
|
|
||||||
var worktree = _worktrees.Find(x => x.Branch == branch.FullName);
|
var worktree = _worktrees.Find(x => x.Branch == branch.FullName);
|
||||||
var upstream = _branches.Find(x => x.FullName == branch.Upstream);
|
var upstream = _branches.Find(x => x.FullName == branch.Upstream);
|
||||||
|
@ -1517,28 +1550,44 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
menu.Items.Add(push);
|
menu.Items.Add(push);
|
||||||
|
|
||||||
var merge = new MenuItem();
|
if (!IsBare)
|
||||||
merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", branch.Name, _currentBranch.Name);
|
|
||||||
merge.Icon = App.CreateMenuIcon("Icons.Merge");
|
|
||||||
merge.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (CanCreatePopup())
|
var merge = new MenuItem();
|
||||||
ShowPopup(new Merge(this, branch, _currentBranch.Name));
|
merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", branch.Name, _currentBranch.Name);
|
||||||
e.Handled = true;
|
merge.Icon = App.CreateMenuIcon("Icons.Merge");
|
||||||
};
|
merge.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
if (CanCreatePopup())
|
||||||
|
ShowPopup(new Merge(this, branch, _currentBranch.Name));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
var rebase = new MenuItem();
|
var rebase = new MenuItem();
|
||||||
rebase.Header = new Views.NameHighlightedTextBlock("BranchCM.Rebase", _currentBranch.Name, branch.Name);
|
rebase.Header = new Views.NameHighlightedTextBlock("BranchCM.Rebase", _currentBranch.Name, branch.Name);
|
||||||
rebase.Icon = App.CreateMenuIcon("Icons.Rebase");
|
rebase.Icon = App.CreateMenuIcon("Icons.Rebase");
|
||||||
rebase.Click += (_, e) =>
|
rebase.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
if (CanCreatePopup())
|
||||||
|
ShowPopup(new Rebase(this, _currentBranch, branch));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
menu.Items.Add(merge);
|
||||||
|
menu.Items.Add(rebase);
|
||||||
|
}
|
||||||
|
|
||||||
|
var compareWithHead = new MenuItem();
|
||||||
|
compareWithHead.Header = App.Text("BranchCM.CompareWithHead");
|
||||||
|
compareWithHead.Icon = App.CreateMenuIcon("Icons.Compare");
|
||||||
|
compareWithHead.Click += (_, _) =>
|
||||||
{
|
{
|
||||||
if (CanCreatePopup())
|
App.OpenDialog(new Views.BranchCompare()
|
||||||
ShowPopup(new Rebase(this, _currentBranch, branch));
|
{
|
||||||
e.Handled = true;
|
DataContext = new BranchCompare(_fullpath, branch, _currentBranch)
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
menu.Items.Add(merge);
|
menu.Items.Add(compareWithHead);
|
||||||
menu.Items.Add(rebase);
|
|
||||||
|
|
||||||
if (_localChangesCount > 0)
|
if (_localChangesCount > 0)
|
||||||
{
|
{
|
||||||
|
@ -1556,35 +1605,28 @@ namespace SourceGit.ViewModels
|
||||||
_histories.DetailContext = new RevisionCompare(_fullpath, target, null);
|
_histories.DetailContext = new RevisionCompare(_fullpath, target, null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
||||||
menu.Items.Add(compareWithWorktree);
|
menu.Items.Add(compareWithWorktree);
|
||||||
}
|
}
|
||||||
|
|
||||||
var compareWithBranch = CreateMenuItemToCompareBranches(branch);
|
|
||||||
if (compareWithBranch != null)
|
|
||||||
{
|
|
||||||
if (_localChangesCount == 0)
|
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
||||||
|
|
||||||
menu.Items.Add(compareWithBranch);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var detect = Commands.GitFlow.DetectType(_fullpath, _branches, branch.Name);
|
if (!IsBare)
|
||||||
if (detect.IsGitFlowBranch)
|
|
||||||
{
|
{
|
||||||
var finish = new MenuItem();
|
var detect = Commands.GitFlow.DetectType(_fullpath, _branches, branch.Name);
|
||||||
finish.Header = new Views.NameHighlightedTextBlock("BranchCM.Finish", branch.Name);
|
if (detect.IsGitFlowBranch)
|
||||||
finish.Icon = App.CreateMenuIcon("Icons.GitFlow");
|
|
||||||
finish.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (CanCreatePopup())
|
var finish = new MenuItem();
|
||||||
ShowPopup(new GitFlowFinish(this, branch, detect.Type, detect.Prefix));
|
finish.Header = new Views.NameHighlightedTextBlock("BranchCM.Finish", branch.Name);
|
||||||
e.Handled = true;
|
finish.Icon = App.CreateMenuIcon("Icons.GitFlow");
|
||||||
};
|
finish.Click += (_, e) =>
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
{
|
||||||
menu.Items.Add(finish);
|
if (CanCreatePopup())
|
||||||
}
|
ShowPopup(new GitFlowFinish(this, branch, detect.Type, detect.Prefix));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
menu.Items.Add(finish);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var rename = new MenuItem();
|
var rename = new MenuItem();
|
||||||
rename.Header = new Views.NameHighlightedTextBlock("BranchCM.Rename", branch.Name);
|
rename.Header = new Views.NameHighlightedTextBlock("BranchCM.Rename", branch.Name);
|
||||||
|
@ -1635,26 +1677,29 @@ namespace SourceGit.ViewModels
|
||||||
menu.Items.Add(createTag);
|
menu.Items.Add(createTag);
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
|
||||||
var remoteBranches = new List<Models.Branch>();
|
if (!IsBare)
|
||||||
foreach (var b in _branches)
|
|
||||||
{
|
{
|
||||||
if (!b.IsLocal)
|
var remoteBranches = new List<Models.Branch>();
|
||||||
remoteBranches.Add(b);
|
foreach (var b in _branches)
|
||||||
}
|
|
||||||
|
|
||||||
if (remoteBranches.Count > 0)
|
|
||||||
{
|
|
||||||
var tracking = new MenuItem();
|
|
||||||
tracking.Header = App.Text("BranchCM.Tracking");
|
|
||||||
tracking.Icon = App.CreateMenuIcon("Icons.Track");
|
|
||||||
tracking.Click += (_, e) =>
|
|
||||||
{
|
{
|
||||||
if (CanCreatePopup())
|
if (!b.IsLocal)
|
||||||
ShowPopup(new SetUpstream(this, branch, remoteBranches));
|
remoteBranches.Add(b);
|
||||||
e.Handled = true;
|
}
|
||||||
};
|
|
||||||
menu.Items.Add(tracking);
|
if (remoteBranches.Count > 0)
|
||||||
}
|
{
|
||||||
|
var tracking = new MenuItem();
|
||||||
|
tracking.Header = App.Text("BranchCM.Tracking");
|
||||||
|
tracking.Icon = App.CreateMenuIcon("Icons.Track");
|
||||||
|
tracking.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
if (CanCreatePopup())
|
||||||
|
ShowPopup(new SetUpstream(this, branch, remoteBranches));
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(tracking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var archive = new MenuItem();
|
var archive = new MenuItem();
|
||||||
archive.Icon = App.CreateMenuIcon("Icons.Archive");
|
archive.Icon = App.CreateMenuIcon("Icons.Archive");
|
||||||
|
@ -1813,7 +1858,18 @@ namespace SourceGit.ViewModels
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasCompare = false;
|
var compareWithHead = new MenuItem();
|
||||||
|
compareWithHead.Header = App.Text("BranchCM.CompareWithHead");
|
||||||
|
compareWithHead.Icon = App.CreateMenuIcon("Icons.Compare");
|
||||||
|
compareWithHead.Click += (_, _) =>
|
||||||
|
{
|
||||||
|
App.OpenDialog(new Views.BranchCompare()
|
||||||
|
{
|
||||||
|
DataContext = new BranchCompare(_fullpath, branch, _currentBranch)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
menu.Items.Add(compareWithHead);
|
||||||
|
|
||||||
if (_localChangesCount > 0)
|
if (_localChangesCount > 0)
|
||||||
{
|
{
|
||||||
var compareWithWorktree = new MenuItem();
|
var compareWithWorktree = new MenuItem();
|
||||||
|
@ -1831,18 +1887,8 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
menu.Items.Add(compareWithWorktree);
|
menu.Items.Add(compareWithWorktree);
|
||||||
hasCompare = true;
|
|
||||||
}
|
}
|
||||||
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
var compareWithBranch = CreateMenuItemToCompareBranches(branch);
|
|
||||||
if (compareWithBranch != null)
|
|
||||||
{
|
|
||||||
menu.Items.Add(compareWithBranch);
|
|
||||||
hasCompare = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasCompare)
|
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
||||||
|
|
||||||
var delete = new MenuItem();
|
var delete = new MenuItem();
|
||||||
delete.Header = new Views.NameHighlightedTextBlock("BranchCM.Delete", name);
|
delete.Header = new Views.NameHighlightedTextBlock("BranchCM.Delete", name);
|
||||||
|
@ -2078,39 +2124,6 @@ namespace SourceGit.ViewModels
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MenuItem CreateMenuItemToCompareBranches(Models.Branch branch)
|
|
||||||
{
|
|
||||||
if (_branches.Count == 1)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var compare = new MenuItem();
|
|
||||||
compare.Header = App.Text("BranchCM.CompareWithBranch");
|
|
||||||
compare.Icon = App.CreateMenuIcon("Icons.Compare");
|
|
||||||
|
|
||||||
foreach (var b in _branches)
|
|
||||||
{
|
|
||||||
if (b.FullName != branch.FullName)
|
|
||||||
{
|
|
||||||
var dup = b;
|
|
||||||
var target = new MenuItem();
|
|
||||||
target.Header = b.FriendlyName;
|
|
||||||
target.Icon = App.CreateMenuIcon(b.IsCurrent ? "Icons.Check" : "Icons.Branch");
|
|
||||||
target.Click += (_, e) =>
|
|
||||||
{
|
|
||||||
App.OpenDialog(new Views.BranchCompare()
|
|
||||||
{
|
|
||||||
DataContext = new BranchCompare(_fullpath, branch, dup)
|
|
||||||
});
|
|
||||||
e.Handled = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
compare.Items.Add(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return compare;
|
|
||||||
}
|
|
||||||
|
|
||||||
private LauncherPage GetOwnerPage()
|
private LauncherPage GetOwnerPage()
|
||||||
{
|
{
|
||||||
var launcher = App.GetLauncer();
|
var launcher = App.GetLauncer();
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace SourceGit.ViewModels
|
||||||
watch.Start();
|
watch.Start();
|
||||||
|
|
||||||
var rootDir = new DirectoryInfo(RootDir);
|
var rootDir = new DirectoryInfo(RootDir);
|
||||||
var founded = new List<string>();
|
var founded = new List<FoundRepository>();
|
||||||
GetUnmanagedRepositories(rootDir, founded, new EnumerationOptions()
|
GetUnmanagedRepositories(rootDir, founded, new EnumerationOptions()
|
||||||
{
|
{
|
||||||
AttributesToSkip = FileAttributes.Hidden | FileAttributes.System,
|
AttributesToSkip = FileAttributes.Hidden | FileAttributes.System,
|
||||||
|
@ -47,16 +47,16 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
foreach (var f in founded)
|
foreach (var f in founded)
|
||||||
{
|
{
|
||||||
var parent = new DirectoryInfo(f).Parent!.FullName.Replace("\\", "/");
|
var parent = new DirectoryInfo(f.Path).Parent!.FullName.Replace("\\", "/");
|
||||||
if (parent.Equals(normalizedRoot, StringComparison.Ordinal))
|
if (parent.Equals(normalizedRoot, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
Preferences.Instance.FindOrAddNodeByRepositoryPath(f, null, false);
|
Preferences.Instance.FindOrAddNodeByRepositoryPath(f.Path, null, false);
|
||||||
}
|
}
|
||||||
else if (parent.StartsWith(normalizedRoot, StringComparison.Ordinal))
|
else if (parent.StartsWith(normalizedRoot, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
var relative = parent.Substring(normalizedRoot.Length).TrimStart('/');
|
var relative = parent.Substring(normalizedRoot.Length).TrimStart('/');
|
||||||
var group = FindOrCreateGroupRecursive(Preferences.Instance.RepositoryNodes, relative);
|
var group = FindOrCreateGroupRecursive(Preferences.Instance.RepositoryNodes, relative);
|
||||||
Preferences.Instance.FindOrAddNodeByRepositoryPath(f, group, false);
|
Preferences.Instance.FindOrAddNodeByRepositoryPath(f.Path, group, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetUnmanagedRepositories(DirectoryInfo dir, List<string> outs, EnumerationOptions opts, int depth = 0)
|
private void GetUnmanagedRepositories(DirectoryInfo dir, List<FoundRepository> outs, EnumerationOptions opts, int depth = 0)
|
||||||
{
|
{
|
||||||
var subdirs = dir.GetDirectories("*", opts);
|
var subdirs = dir.GetDirectories("*", opts);
|
||||||
foreach (var subdir in subdirs)
|
foreach (var subdir in subdirs)
|
||||||
|
@ -111,12 +111,19 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
var normalized = test.StdOut.Trim().Replace("\\", "/");
|
var normalized = test.StdOut.Trim().Replace("\\", "/");
|
||||||
if (!_managed.Contains(normalized))
|
if (!_managed.Contains(normalized))
|
||||||
outs.Add(normalized);
|
outs.Add(new FoundRepository(normalized, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isBare = new Commands.IsBareRepository(subdir.FullName).Result();
|
||||||
|
if (isBare)
|
||||||
|
{
|
||||||
|
outs.Add(new FoundRepository(normalizedSelf, true));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (depth < 5)
|
if (depth < 5)
|
||||||
GetUnmanagedRepositories(subdir, outs, opts, depth + 1);
|
GetUnmanagedRepositories(subdir, outs, opts, depth + 1);
|
||||||
}
|
}
|
||||||
|
@ -161,6 +168,12 @@ namespace SourceGit.ViewModels
|
||||||
return added;
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private record FoundRepository(string path, bool isBare)
|
||||||
|
{
|
||||||
|
public string Path { get; set; } = path;
|
||||||
|
public bool IsBare { get; set; } = isBare;
|
||||||
|
}
|
||||||
|
|
||||||
private HashSet<string> _managed = new HashSet<string>();
|
private HashSet<string> _managed = new HashSet<string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,14 +76,11 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (IncludeUntracked)
|
succ = new Commands.Stash(_repo.FullPath).Push(Message, IncludeUntracked, KeepIndex);
|
||||||
AddUntracked(_changes);
|
|
||||||
succ = StashWithChanges(_changes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddUntracked(_changes);
|
|
||||||
succ = StashWithChanges(_changes);
|
succ = StashWithChanges(_changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,40 +94,6 @@ namespace SourceGit.ViewModels
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddUntracked(List<Models.Change> changes)
|
|
||||||
{
|
|
||||||
var toBeAdded = new List<Models.Change>();
|
|
||||||
foreach (var c in changes)
|
|
||||||
{
|
|
||||||
if (c.WorkTree == Models.ChangeState.Added || c.WorkTree == Models.ChangeState.Untracked)
|
|
||||||
toBeAdded.Add(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toBeAdded.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (Native.OS.GitVersion >= Models.GitVersions.ADD_WITH_PATHSPECFILE)
|
|
||||||
{
|
|
||||||
var paths = new List<string>();
|
|
||||||
foreach (var c in toBeAdded)
|
|
||||||
paths.Add(c.Path);
|
|
||||||
|
|
||||||
var tmpFile = Path.GetTempFileName();
|
|
||||||
File.WriteAllLines(tmpFile, paths);
|
|
||||||
new Commands.Add(_repo.FullPath, tmpFile).Exec();
|
|
||||||
File.Delete(tmpFile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < toBeAdded.Count; i += 10)
|
|
||||||
{
|
|
||||||
var count = Math.Min(10, toBeAdded.Count - i);
|
|
||||||
var step = toBeAdded.GetRange(i, count);
|
|
||||||
new Commands.Add(_repo.FullPath, step).Exec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool StashWithChanges(List<Models.Change> changes)
|
private bool StashWithChanges(List<Models.Change> changes)
|
||||||
{
|
{
|
||||||
if (changes.Count == 0)
|
if (changes.Count == 0)
|
||||||
|
|
|
@ -57,8 +57,25 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
var changes = new Commands.QueryStashChanges(_repo.FullPath, value.SHA).Result();
|
var changes = new Commands.CompareRevisions(_repo.FullPath, $"{value.SHA}^", value.SHA).Result();
|
||||||
Dispatcher.UIThread.Invoke(() => Changes = changes);
|
var untracked = new HashSet<string>();
|
||||||
|
if (value.HasUntracked)
|
||||||
|
{
|
||||||
|
var untrackedChanges = new Commands.CompareRevisions(_repo.FullPath, "4b825dc642cb6eb9a060e54bf8d69288fbee4904", value.Parents[2]).Result();
|
||||||
|
foreach (var c in untrackedChanges)
|
||||||
|
{
|
||||||
|
untracked.Add(c.Path);
|
||||||
|
changes.Add(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changes.Sort((l, r) => Models.NumericSort.Compare(l.Path, r.Path));
|
||||||
|
|
||||||
|
Dispatcher.UIThread.Invoke(() =>
|
||||||
|
{
|
||||||
|
Changes = changes;
|
||||||
|
_untrackedChanges = untracked;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,8 +101,10 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
if (value == null)
|
if (value == null)
|
||||||
DiffContext = null;
|
DiffContext = null;
|
||||||
|
else if (_untrackedChanges.Contains(value.Path))
|
||||||
|
DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption("4b825dc642cb6eb9a060e54bf8d69288fbee4904", _selectedStash.Parents[2], value), _diffContext);
|
||||||
else
|
else
|
||||||
DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption($"{_selectedStash.SHA}^", _selectedStash.SHA, value), _diffContext);
|
DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, value), _diffContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,6 +273,7 @@ namespace SourceGit.ViewModels
|
||||||
private List<Models.Stash> _visibleStashes = new List<Models.Stash>();
|
private List<Models.Stash> _visibleStashes = new List<Models.Stash>();
|
||||||
private string _searchFilter = string.Empty;
|
private string _searchFilter = string.Empty;
|
||||||
private Models.Stash _selectedStash = null;
|
private Models.Stash _selectedStash = null;
|
||||||
|
private HashSet<string> _untrackedChanges = new HashSet<string>();
|
||||||
private List<Models.Change> _changes = null;
|
private List<Models.Change> _changes = null;
|
||||||
private Models.Change _selectedChange = null;
|
private Models.Change _selectedChange = null;
|
||||||
private DiffContext _diffContext = null;
|
private DiffContext _diffContext = null;
|
||||||
|
|
|
@ -83,6 +83,37 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OpenOrInitRepository(string path, RepositoryNode parent, bool bMoveExistedNode)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(path))
|
||||||
|
{
|
||||||
|
if (File.Exists(path))
|
||||||
|
path = Path.GetDirectoryName(path);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var isBare = new Commands.IsBareRepository(path).Result();
|
||||||
|
var repoRoot = path;
|
||||||
|
if (!isBare)
|
||||||
|
{
|
||||||
|
var test = new Commands.QueryRepositoryRootPath(path).ReadToEnd();
|
||||||
|
if (!test.IsSuccess || string.IsNullOrEmpty(test.StdOut))
|
||||||
|
{
|
||||||
|
InitRepository(path, parent, test.StdErr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
repoRoot = test.StdOut.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
var node = Preferences.Instance.FindOrAddNodeByRepositoryPath(repoRoot, parent, bMoveExistedNode);
|
||||||
|
Refresh();
|
||||||
|
|
||||||
|
var launcher = App.GetLauncer();
|
||||||
|
launcher?.OpenRepositoryInTab(node, launcher.ActivePage);
|
||||||
|
}
|
||||||
|
|
||||||
public void InitRepository(string path, RepositoryNode parent, string reason)
|
public void InitRepository(string path, RepositoryNode parent, string reason)
|
||||||
{
|
{
|
||||||
if (!Preferences.Instance.IsGitConfigured())
|
if (!Preferences.Instance.IsGitConfigured())
|
||||||
|
|
|
@ -19,14 +19,14 @@
|
||||||
<v:Avatar Grid.Column="0" Width="64" Height="64" HorizontalAlignment="Right" User="{Binding Author}"/>
|
<v:Avatar Grid.Column="0" Width="64" Height="64" HorizontalAlignment="Right" User="{Binding Author}"/>
|
||||||
<StackPanel Grid.Column="1" Margin="16,0,8,0" Orientation="Vertical">
|
<StackPanel Grid.Column="1" Margin="16,0,8,0" Orientation="Vertical">
|
||||||
<TextBlock Classes="group_header_label" Margin="0" Text="{DynamicResource Text.CommitDetail.Info.Author}"/>
|
<TextBlock Classes="group_header_label" Margin="0" Text="{DynamicResource Text.CommitDetail.Info.Author}"/>
|
||||||
<DockPanel Margin="0,10,0,8" ClipToBounds="True">
|
<Grid Margin="0,10,0,8" ColumnDefinitions="Auto,*" ClipToBounds="True">
|
||||||
<SelectableTextBlock Text="{Binding Author.Name}" Margin="2,0,8,0"/>
|
<v:EnhancedSelectableTextBlock Grid.Column="0" Text="{Binding Author.Name}" Margin="2,0,8,0"/>
|
||||||
<SelectableTextBlock Text="{Binding Author.Email}" ToolTip.Tip="{Binding Author.Email}" Foreground="{DynamicResource Brush.FG2}" TextTrimming="CharacterEllipsis"/>
|
<v:EnhancedSelectableTextBlock Grid.Column="1" Text="{Binding Author.Email}" ToolTip.Tip="{Binding Author.Email}" Foreground="{DynamicResource Brush.FG2}" TextTrimming="CharacterEllipsis"/>
|
||||||
</DockPanel>
|
</Grid>
|
||||||
<SelectableTextBlock Text="{Binding AuthorTimeStr}"
|
<v:EnhancedSelectableTextBlock Text="{Binding AuthorTimeStr}"
|
||||||
Margin="2,0,0,0"
|
Margin="2,0,0,0"
|
||||||
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Decrease}}"
|
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Decrease}}"
|
||||||
Foreground="{DynamicResource Brush.FG2}"/>
|
Foreground="{DynamicResource Brush.FG2}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
@ -35,14 +35,14 @@
|
||||||
<v:Avatar Grid.Column="0" Width="64" Height="64" HorizontalAlignment="Right" User="{Binding Committer}"/>
|
<v:Avatar Grid.Column="0" Width="64" Height="64" HorizontalAlignment="Right" User="{Binding Committer}"/>
|
||||||
<StackPanel Grid.Column="1" Margin="16,0,8,0" Orientation="Vertical">
|
<StackPanel Grid.Column="1" Margin="16,0,8,0" Orientation="Vertical">
|
||||||
<TextBlock Classes="group_header_label" Margin="0" Text="{DynamicResource Text.CommitDetail.Info.Committer}"/>
|
<TextBlock Classes="group_header_label" Margin="0" Text="{DynamicResource Text.CommitDetail.Info.Committer}"/>
|
||||||
<DockPanel Margin="0,10,0,8" ClipToBounds="True">
|
<Grid Margin="0,10,0,8" ColumnDefinitions="Auto,*" ClipToBounds="True">
|
||||||
<SelectableTextBlock Text="{Binding Committer.Name}" Margin="2,0,8,0"/>
|
<v:EnhancedSelectableTextBlock Grid.Column="0" Text="{Binding Committer.Name}" Margin="2,0,8,0"/>
|
||||||
<SelectableTextBlock Text="{Binding Committer.Email}" ToolTip.Tip="{Binding Committer.Email}" Foreground="{DynamicResource Brush.FG2}" TextTrimming="CharacterEllipsis"/>
|
<v:EnhancedSelectableTextBlock Grid.Column="1" Text="{Binding Committer.Email}" ToolTip.Tip="{Binding Committer.Email}" Foreground="{DynamicResource Brush.FG2}" TextTrimming="CharacterEllipsis"/>
|
||||||
</DockPanel>
|
</Grid>
|
||||||
<SelectableTextBlock Text="{Binding CommitterTimeStr}"
|
<v:EnhancedSelectableTextBlock Text="{Binding CommitterTimeStr}"
|
||||||
Margin="2,0,0,0"
|
Margin="2,0,0,0"
|
||||||
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Decrease}}"
|
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Decrease}}"
|
||||||
Foreground="{DynamicResource Brush.FG2}"/>
|
Foreground="{DynamicResource Brush.FG2}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UniformGrid>
|
</UniformGrid>
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="32"/>
|
<RowDefinition Height="32"/>
|
||||||
<RowDefinition Height="32"/>
|
<RowDefinition Height="32"/>
|
||||||
<RowDefinition Height="Auto" MinHeight="32"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="32"/>
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<TextBlock Grid.Row="0" Grid.Column="0"
|
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||||
|
@ -67,27 +67,31 @@
|
||||||
<TextBlock Grid.Row="2" Grid.Column="0"
|
<TextBlock Grid.Row="2" Grid.Column="0"
|
||||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||||
Margin="0,0,8,0"
|
Margin="0,0,8,0"
|
||||||
Text="{DynamicResource Text.CreateBranch.LocalChanges}"/>
|
Text="{DynamicResource Text.CreateBranch.LocalChanges}"
|
||||||
<WrapPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
|
IsVisible="{Binding !IsBareRepository}"/>
|
||||||
<RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.DoNothing}"
|
<Border Grid.Row="2" Grid.Column="1" MinHeight="32" IsVisible="{Binding !IsBareRepository}">
|
||||||
x:Name="RadioDoNothing"
|
<WrapPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||||
GroupName="LocalChanges"
|
<RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.DoNothing}"
|
||||||
Margin="0,0,8,0"
|
x:Name="RadioDoNothing"
|
||||||
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/>
|
GroupName="LocalChanges"
|
||||||
<RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.StashAndReply}"
|
Margin="0,0,8,0"
|
||||||
x:Name="RadioStashAndReply"
|
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/>
|
||||||
GroupName="LocalChanges"
|
<RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.StashAndReply}"
|
||||||
Margin="0,0,8,0"
|
x:Name="RadioStashAndReply"
|
||||||
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/>
|
GroupName="LocalChanges"
|
||||||
<RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.Discard}"
|
Margin="0,0,8,0"
|
||||||
x:Name="RadioDiscard"
|
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/>
|
||||||
GroupName="LocalChanges"
|
<RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.Discard}"
|
||||||
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/>
|
x:Name="RadioDiscard"
|
||||||
</WrapPanel>
|
GroupName="LocalChanges"
|
||||||
|
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/>
|
||||||
|
</WrapPanel>
|
||||||
|
</Border>
|
||||||
|
|
||||||
<CheckBox Grid.Row="3" Grid.Column="1"
|
<CheckBox Grid.Row="3" Grid.Column="1"
|
||||||
Content="{DynamicResource Text.CreateBranch.Checkout}"
|
Content="{DynamicResource Text.CreateBranch.Checkout}"
|
||||||
IsChecked="{Binding CheckoutAfterCreated, Mode=TwoWay}"/>
|
IsChecked="{Binding CheckoutAfterCreated, Mode=TwoWay}"
|
||||||
|
IsVisible="{Binding !IsBareRepository}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
20
src/Views/EnhancedSelectableTextBlock.cs
Normal file
20
src/Views/EnhancedSelectableTextBlock.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace SourceGit.Views
|
||||||
|
{
|
||||||
|
public class EnhancedSelectableTextBlock : SelectableTextBlock
|
||||||
|
{
|
||||||
|
protected override Type StyleKeyOverride => typeof(SelectableTextBlock);
|
||||||
|
|
||||||
|
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||||
|
{
|
||||||
|
base.OnPropertyChanged(change);
|
||||||
|
|
||||||
|
if (change.Property == TextProperty)
|
||||||
|
UpdateLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,7 +45,7 @@
|
||||||
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Increase}}"
|
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Increase}}"
|
||||||
Margin="0,0,0,8"/>
|
Margin="0,0,0,8"/>
|
||||||
|
|
||||||
<Grid RowDefinitions="20,20,20,20,20,20,20" ColumnDefinitions="150,*">
|
<Grid RowDefinitions="20,20,20,20,20,20,20,20" ColumnDefinitions="150,*">
|
||||||
<TextBlock Grid.Row="0" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Shift+P, macOS=⌘+\,}"/>
|
<TextBlock Grid.Row="0" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Shift+P, macOS=⌘+\,}"/>
|
||||||
<TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Global.OpenPreferences}"/>
|
<TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Global.OpenPreferences}"/>
|
||||||
|
|
||||||
|
@ -66,6 +66,9 @@
|
||||||
|
|
||||||
<TextBlock Grid.Row="6" Grid.Column="0" Classes="primary bold" Text="ESC"/>
|
<TextBlock Grid.Row="6" Grid.Column="0" Classes="primary bold" Text="ESC"/>
|
||||||
<TextBlock Grid.Row="6" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Global.CancelPopup}" />
|
<TextBlock Grid.Row="6" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Global.CancelPopup}" />
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="7" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Q, macOS=⌘+Q}"/>
|
||||||
|
<TextBlock Grid.Row="7" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Quit}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<TextBlock Text="{DynamicResource Text.Hotkeys.Repo}"
|
<TextBlock Text="{DynamicResource Text.Hotkeys.Repo}"
|
||||||
|
|
|
@ -62,6 +62,11 @@
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Info}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Info}"/>
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem Header="{DynamicResource Text.Quit}" Command="{x:Static s:App.QuitCommand}" InputGesture="Ctrl+Q">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Quit}"/>
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
</MenuFlyout>
|
</MenuFlyout>
|
||||||
</Button.Flyout>
|
</Button.Flyout>
|
||||||
<Path Width="12" Height="12" Data="{StaticResource Icons.Menu}"/>
|
<Path Width="12" Height="12" Data="{StaticResource Icons.Menu}"/>
|
||||||
|
|
|
@ -146,6 +146,12 @@ namespace SourceGit.Views
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.Key == Key.Q) {
|
||||||
|
App.Quit(0);
|
||||||
|
e.Handled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((OperatingSystem.IsMacOS() && e.KeyModifiers.HasFlag(KeyModifiers.Alt) && e.Key == Key.Right) ||
|
if ((OperatingSystem.IsMacOS() && e.KeyModifiers.HasFlag(KeyModifiers.Alt) && e.Key == Key.Right) ||
|
||||||
(!OperatingSystem.IsMacOS() && !e.KeyModifiers.HasFlag(KeyModifiers.Shift) && e.Key == Key.Tab))
|
(!OperatingSystem.IsMacOS() && !e.KeyModifiers.HasFlag(KeyModifiers.Shift) && e.Key == Key.Tab))
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<!-- Page Switcher for Right Panel -->
|
<!-- Page Switcher for Right Panel -->
|
||||||
<Border Grid.Row="0" Margin="8,0,4,0" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}" CornerRadius="6">
|
<Border Grid.Row="0" Margin="8,0,4,0" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}" CornerRadius="6">
|
||||||
<Border CornerRadius="6" ClipToBounds="True">
|
<Border CornerRadius="6" ClipToBounds="True">
|
||||||
<ListBox Background="Transparent" SelectedIndex="{Binding SelectedViewIndex, Mode=TwoWay}">
|
<ListBox Background="Transparent" SelectedIndex="{Binding SelectedViewIndex, Mode=TwoWay}" SelectionMode="AlwaysSelected">
|
||||||
<ListBox.Styles>
|
<ListBox.Styles>
|
||||||
<Style Selector="Path.icon">
|
<Style Selector="Path.icon">
|
||||||
<Setter Property="Width" Value="12"/>
|
<Setter Property="Width" Value="12"/>
|
||||||
|
@ -128,7 +128,7 @@
|
||||||
</Grid>
|
</Grid>
|
||||||
</ListBoxItem>
|
</ListBoxItem>
|
||||||
|
|
||||||
<ListBoxItem>
|
<ListBoxItem IsVisible="{Binding !IsBare}">
|
||||||
<Grid Classes="view_mode" ColumnDefinitions="Auto,*,Auto">
|
<Grid Classes="view_mode" ColumnDefinitions="Auto,*,Auto">
|
||||||
<Path Grid.Column="0" Classes="icon" Data="{StaticResource Icons.Changes}"/>
|
<Path Grid.Column="0" Classes="icon" Data="{StaticResource Icons.Changes}"/>
|
||||||
<TextBlock Grid.Column="1" Classes="header" Text="{DynamicResource Text.WorkingCopy}"/>
|
<TextBlock Grid.Column="1" Classes="header" Text="{DynamicResource Text.WorkingCopy}"/>
|
||||||
|
@ -143,7 +143,7 @@
|
||||||
</Grid>
|
</Grid>
|
||||||
</ListBoxItem>
|
</ListBoxItem>
|
||||||
|
|
||||||
<ListBoxItem>
|
<ListBoxItem IsVisible="{Binding !IsBare}">
|
||||||
<Grid Classes="view_mode" ColumnDefinitions="Auto,*,Auto">
|
<Grid Classes="view_mode" ColumnDefinitions="Auto,*,Auto">
|
||||||
<Path Grid.Column="0" Classes="icon" Data="{StaticResource Icons.Stashes}"/>
|
<Path Grid.Column="0" Classes="icon" Data="{StaticResource Icons.Stashes}"/>
|
||||||
<TextBlock Grid.Column="1" Classes="header" Text="{DynamicResource Text.Stashes}"/>
|
<TextBlock Grid.Column="1" Classes="header" Text="{DynamicResource Text.Stashes}"/>
|
||||||
|
@ -313,7 +313,7 @@
|
||||||
</ListBox.Styles>
|
</ListBox.Styles>
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
<DataTemplate DataType="m:Submodule">
|
<DataTemplate DataType="m:Submodule">
|
||||||
<Grid ColumnDefinitions="Auto,*,8">
|
<Grid ColumnDefinitions="Auto,*,8,8">
|
||||||
<Path Grid.Column="0" Width="10" Height="10" Margin="8,0" Data="{StaticResource Icons.Submodule}"/>
|
<Path Grid.Column="0" Width="10" Height="10" Margin="8,0" Data="{StaticResource Icons.Submodule}"/>
|
||||||
<TextBlock Grid.Column="1" Text="{Binding Path}" ClipToBounds="True" Classes="primary" TextTrimming="CharacterEllipsis"/>
|
<TextBlock Grid.Column="1" Text="{Binding Path}" ClipToBounds="True" Classes="primary" TextTrimming="CharacterEllipsis"/>
|
||||||
<Path Grid.Column="2"
|
<Path Grid.Column="2"
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Explore}" Margin="0,2,0,0"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Explore}" Margin="0,2,0,0"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button Classes="icon_button" Width="32" Click="OpenWithExternalTools" ToolTip.Tip="{DynamicResource Text.Repository.OpenWithExternalTools}">
|
<Button Classes="icon_button" Width="32" Click="OpenWithExternalTools" IsVisible="{Binding !IsBare}" ToolTip.Tip="{DynamicResource Text.Repository.OpenWithExternalTools}">
|
||||||
<Path Width="13" Height="13" Data="{StaticResource Icons.OpenWith}"/>
|
<Path Width="13" Height="13" Data="{StaticResource Icons.OpenWith}"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Fetch}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Fetch}"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Click="Pull" HotKey="{OnPlatform Ctrl+Shift+Down, macOS=⌘+Shift+Down}">
|
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Click="Pull" IsVisible="{Binding !IsBare}" IsEnabled="{Binding !IsBare}" HotKey="{OnPlatform Ctrl+Shift+Down, macOS=⌘+Shift+Down}">
|
||||||
<ToolTip.Tip>
|
<ToolTip.Tip>
|
||||||
<StackPanel Orientation="Vertical">
|
<StackPanel Orientation="Vertical">
|
||||||
<TextBlock Text="{DynamicResource Text.Pull}"/>
|
<TextBlock Text="{DynamicResource Text.Pull}"/>
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Push}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Push}"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Click="StashAll">
|
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Click="StashAll" IsVisible="{Binding !IsBare}">
|
||||||
<ToolTip.Tip>
|
<ToolTip.Tip>
|
||||||
<StackPanel Orientation="Vertical">
|
<StackPanel Orientation="Vertical">
|
||||||
<TextBlock Text="{DynamicResource Text.Stash}"/>
|
<TextBlock Text="{DynamicResource Text.Stash}"/>
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Stashes.Add}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Stashes.Add}"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Command="{Binding ApplyPatch}" ToolTip.Tip="{DynamicResource Text.Apply}">
|
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Command="{Binding ApplyPatch}" IsVisible="{Binding !IsBare}" ToolTip.Tip="{DynamicResource Text.Apply}">
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Diff}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Diff}"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
@ -88,11 +88,11 @@
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Branch.Add}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Branch.Add}"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button Classes="icon_button" Width="32" Margin="8,0,0,0" Click="OpenGitFlowMenu" ToolTip.Tip="{DynamicResource Text.GitFlow}">
|
<Button Classes="icon_button" Width="32" Margin="8,0,0,0" Click="OpenGitFlowMenu" IsVisible="{Binding !IsBare}" ToolTip.Tip="{DynamicResource Text.GitFlow}">
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.GitFlow}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.GitFlow}"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button Classes="icon_button" Width="32" Margin="8,0,0,0" Click="OpenGitLFSMenu" ToolTip.Tip="{DynamicResource Text.GitLFS}">
|
<Button Classes="icon_button" Width="32" Margin="8,0,0,0" Click="OpenGitLFSMenu" IsVisible="{Binding !IsBare}" ToolTip.Tip="{DynamicResource Text.GitLFS}">
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.LFS}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.LFS}"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,12 @@ namespace SourceGit.Views
|
||||||
var launcher = this.FindAncestorOfType<Launcher>();
|
var launcher = this.FindAncestorOfType<Launcher>();
|
||||||
if (launcher is not null && DataContext is ViewModels.Repository repo)
|
if (launcher is not null && DataContext is ViewModels.Repository repo)
|
||||||
{
|
{
|
||||||
|
if (repo.IsBare)
|
||||||
|
{
|
||||||
|
App.RaiseException(repo.FullPath, "Can't run `git pull` in bare repository!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var startDirectly = launcher.HasKeyModifier(KeyModifiers.Control);
|
var startDirectly = launcher.HasKeyModifier(KeyModifiers.Control);
|
||||||
launcher.ClearKeyModifier();
|
launcher.ClearKeyModifier();
|
||||||
repo.Pull(startDirectly);
|
repo.Pull(startDirectly);
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
@ -197,7 +196,7 @@ namespace SourceGit.Views
|
||||||
{
|
{
|
||||||
foreach (var item in items)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
OpenOrInitRepository(item.Path.LocalPath);
|
ViewModels.Welcome.Instance.OpenOrInitRepository(item.Path.LocalPath, null, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,7 +260,7 @@ namespace SourceGit.Views
|
||||||
{
|
{
|
||||||
foreach (var item in items)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
OpenOrInitRepository(item.Path.LocalPath, to);
|
ViewModels.Welcome.Instance.OpenOrInitRepository(item.Path.LocalPath, to, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,37 +289,6 @@ namespace SourceGit.Views
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenOrInitRepository(string path, ViewModels.RepositoryNode parent = null)
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(path))
|
|
||||||
{
|
|
||||||
if (File.Exists(path))
|
|
||||||
path = Path.GetDirectoryName(path);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var isBare = new Commands.IsBareRepository(path).Result();
|
|
||||||
if (isBare)
|
|
||||||
{
|
|
||||||
App.RaiseException(string.Empty, $"'{path}' is a bare repository, which is not supported by SourceGit!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var test = new Commands.QueryRepositoryRootPath(path).ReadToEnd();
|
|
||||||
if (!test.IsSuccess || string.IsNullOrEmpty(test.StdOut))
|
|
||||||
{
|
|
||||||
ViewModels.Welcome.Instance.InitRepository(path, parent, test.StdErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var node = ViewModels.Preferences.Instance.FindOrAddNodeByRepositoryPath(test.StdOut.Trim(), parent, true);
|
|
||||||
ViewModels.Welcome.Instance.Refresh();
|
|
||||||
|
|
||||||
var launcher = this.FindAncestorOfType<Launcher>()?.DataContext as ViewModels.Launcher;
|
|
||||||
launcher?.OpenRepositoryInTab(node, launcher.ActivePage);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _pressedTreeNode = false;
|
private bool _pressedTreeNode = false;
|
||||||
private Point _pressedTreeNodePosition = new Point();
|
private Point _pressedTreeNodePosition = new Point();
|
||||||
private bool _startDragTreeNode = false;
|
private bool _startDragTreeNode = false;
|
||||||
|
|
|
@ -4,7 +4,6 @@ using System.IO;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using Avalonia.VisualTree;
|
|
||||||
|
|
||||||
namespace SourceGit.Views
|
namespace SourceGit.Views
|
||||||
{
|
{
|
||||||
|
@ -36,7 +35,7 @@ namespace SourceGit.Views
|
||||||
{
|
{
|
||||||
var selected = await topLevel.StorageProvider.OpenFolderPickerAsync(options);
|
var selected = await topLevel.StorageProvider.OpenFolderPickerAsync(options);
|
||||||
if (selected.Count == 1)
|
if (selected.Count == 1)
|
||||||
OpenOrInitRepository(selected[0].Path.LocalPath);
|
ViewModels.Welcome.Instance.OpenOrInitRepository(selected[0].Path.LocalPath, null, false);
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
|
@ -45,30 +44,6 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenOrInitRepository(string path, ViewModels.RepositoryNode parent = null)
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(path))
|
|
||||||
{
|
|
||||||
if (File.Exists(path))
|
|
||||||
path = Path.GetDirectoryName(path);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var test = new Commands.QueryRepositoryRootPath(path).ReadToEnd();
|
|
||||||
if (!test.IsSuccess || string.IsNullOrEmpty(test.StdOut))
|
|
||||||
{
|
|
||||||
ViewModels.Welcome.Instance.InitRepository(path, parent, test.StdErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var node = ViewModels.Preferences.Instance.FindOrAddNodeByRepositoryPath(test.StdOut.Trim(), parent, false);
|
|
||||||
ViewModels.Welcome.Instance.Refresh();
|
|
||||||
|
|
||||||
var launcher = this.FindAncestorOfType<Launcher>()?.DataContext as ViewModels.Launcher;
|
|
||||||
launcher?.OpenRepositoryInTab(node, launcher.ActivePage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue