Skip to content

Commit 3e441e2

Browse files
Feature: Added Git Integration to the status bar (#12020)
1 parent 8ad02d7 commit 3e441e2

13 files changed

+313
-44
lines changed

NOTICE.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,3 +704,33 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
704704
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
705705
SOFTWARE.
706706
```
707+
708+
## libgit2sharp
709+
710+
**Source**: [https://github.com/libgit2/libgit2sharp](https://github.com/libgit2/libgit2sharp)
711+
712+
### License
713+
714+
```
715+
MIT License
716+
717+
Copyright (c) LibGit2Sharp contributors
718+
719+
Permission is hereby granted, free of charge, to any person obtaining a copy
720+
of this software and associated documentation files (the "Software"), to deal
721+
in the Software without restriction, including without limitation the rights
722+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
723+
copies of the Software, and to permit persons to whom the Software is
724+
furnished to do so, subject to the following conditions:
725+
726+
The above copyright notice and this permission notice shall be included in
727+
all copies or substantial portions of the Software.
728+
729+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
730+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
731+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
732+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
733+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
734+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
735+
THE SOFTWARE.
736+
```

src/Files.App/Files.App.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.1.0" />
7676
<PackageReference Include="FluentFTP" Version="43.0.1" />
7777
<PackageReference Include="ini-parser-netstandard" Version="2.5.2" />
78+
<PackageReference Include="LibGit2Sharp" Version="0.26.2" />
7879
<PackageReference Include="Microsoft.AppCenter.Analytics" Version="5.0.1" />
7980
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="5.0.1" />
8081
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="7.0.5" />

src/Files.App/Helpers/DynamicDialogFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,4 @@ public static DynamicDialog GetFor_CredentialEntryDialog(string path)
223223
return dialog;
224224
}
225225
}
226-
}
226+
}

src/Files.App/Helpers/GitHelpers.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using LibGit2Sharp;
2+
using System;
3+
using Files.App.Filesystem.StorageItems;
4+
5+
namespace Files.App.Helpers
6+
{
7+
public static class GitHelpers
8+
{
9+
public static string? GetGitRepositoryPath(string? path, string root)
10+
{
11+
if (root.EndsWith('\\'))
12+
root = root.Substring(0, root.Length - 1);
13+
14+
if (
15+
string.IsNullOrWhiteSpace(path) ||
16+
path.Equals(root, StringComparison.OrdinalIgnoreCase) ||
17+
path.Equals("Home", StringComparison.OrdinalIgnoreCase) ||
18+
ShellStorageFolder.IsShellPath(path)
19+
)
20+
return null;
21+
22+
return Repository.IsValid(path)
23+
? path
24+
: GetGitRepositoryPath(PathNormalization.GetParentDir(path), root);
25+
}
26+
}
27+
}

src/Files.App/Strings/en-US/Resources.resw

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3154,6 +3154,9 @@
31543154
<data name="CloseTab" xml:space="preserve">
31553155
<value>Closes current tab</value>
31563156
</data>
3157+
<data name="Branch" xml:space="preserve">
3158+
<value>Branch: {0}</value>
3159+
</data>
31573160
<data name="Redo" xml:space="preserve">
31583161
<value>Redo</value>
31593162
</data>
@@ -3196,4 +3199,4 @@
31963199
<data name="RedoDescription" xml:space="preserve">
31973200
<value>Redo the last file operation</value>
31983201
</data>
3199-
</root>
3202+
</root>

src/Files.App/UserControls/StatusBarControl.xaml

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,60 @@
22
x:Class="Files.App.UserControls.StatusBarControl"
33
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
44
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:converters="using:Files.App.Converters"
56
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
67
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
78
d:DesignHeight="32"
89
d:DesignWidth="400"
910
mc:Ignorable="d">
1011

11-
<StackPanel
12-
Height="32"
13-
Padding="8,0"
14-
HorizontalAlignment="Stretch"
15-
VerticalAlignment="Stretch"
16-
Orientation="Horizontal"
17-
Spacing="8">
12+
<UserControl.Resources>
13+
<converters:NullToTrueConverter x:Key="NullToFalseConverter" Inverse="True" />
14+
</UserControl.Resources>
1815

19-
<TextBlock
20-
x:Name="DirectoryItemCount"
21-
VerticalAlignment="Center"
22-
x:Load="{x:Bind ShowInfoText, Mode=OneWay}"
23-
Text="{x:Bind DirectoryPropertiesViewModel.DirectoryItemCount, Mode=OneWay}" />
16+
<Grid Padding="8,0" ColumnSpacing="8">
17+
<Grid.ColumnDefinitions>
18+
<ColumnDefinition />
19+
<ColumnDefinition Width="Auto" />
20+
</Grid.ColumnDefinitions>
21+
<StackPanel
22+
Grid.Column="0"
23+
Height="32"
24+
HorizontalAlignment="Stretch"
25+
VerticalAlignment="Stretch"
26+
Orientation="Horizontal"
27+
Spacing="8">
2428

25-
<TextBlock
26-
x:Name="SelectedItemsCountString"
27-
VerticalAlignment="Center"
28-
x:Load="{x:Bind ShowInfoText, Mode=OneWay}"
29-
Text="{x:Bind SelectedItemsPropertiesViewModel.SelectedItemsCountString, Mode=OneWay}"
30-
Visibility="{x:Bind SelectedItemsPropertiesViewModel.IsItemSelected, Mode=OneWay}" />
29+
<TextBlock
30+
x:Name="DirectoryItemCount"
31+
VerticalAlignment="Center"
32+
x:Load="{x:Bind ShowInfoText, Mode=OneWay}"
33+
Text="{x:Bind DirectoryPropertiesViewModel.DirectoryItemCount, Mode=OneWay}" />
34+
35+
<TextBlock
36+
x:Name="SelectedItemsCountString"
37+
VerticalAlignment="Center"
38+
x:Load="{x:Bind ShowInfoText, Mode=OneWay}"
39+
Text="{x:Bind SelectedItemsPropertiesViewModel.SelectedItemsCountString, Mode=OneWay}"
40+
Visibility="{x:Bind SelectedItemsPropertiesViewModel.IsItemSelected, Mode=OneWay}" />
41+
42+
<TextBlock
43+
x:Name="ItemSize"
44+
VerticalAlignment="Center"
45+
x:Load="{x:Bind ShowInfoText, Mode=OneWay}"
46+
Text="{x:Bind SelectedItemsPropertiesViewModel.ItemSize, Mode=OneWay}"
47+
Visibility="{x:Bind SelectedItemsPropertiesViewModel.ItemSizeVisibility, Mode=OneWay}" />
48+
</StackPanel>
3149

32-
<TextBlock
33-
x:Name="ItemSize"
50+
<StackPanel
51+
Grid.Column="1"
3452
VerticalAlignment="Center"
35-
x:Load="{x:Bind ShowInfoText, Mode=OneWay}"
36-
Text="{x:Bind SelectedItemsPropertiesViewModel.ItemSize, Mode=OneWay}"
37-
Visibility="{x:Bind SelectedItemsPropertiesViewModel.ItemSizeVisibility, Mode=OneWay}" />
38-
</StackPanel>
39-
</UserControl>
53+
Orientation="Horizontal"
54+
Spacing="8">
55+
<TextBlock
56+
x:Name="GitBranch"
57+
x:Load="{x:Bind DirectoryPropertiesViewModel.GitBranchDisplayName, Mode=OneWay, Converter={StaticResource NullToFalseConverter}}"
58+
Text="{x:Bind DirectoryPropertiesViewModel.GitBranchDisplayName, Mode=OneWay}" />
59+
</StackPanel>
60+
</Grid>
61+
</UserControl>

src/Files.App/UserControls/StatusBarControl.xaml.cs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
using Files.App.ViewModels;
22
using Microsoft.UI.Xaml;
33
using Microsoft.UI.Xaml.Controls;
4-
using System.ComponentModel;
5-
using System.Runtime.CompilerServices;
64

75
namespace Files.App.UserControls
86
{
9-
public sealed partial class StatusBarControl : UserControl, INotifyPropertyChanged
7+
public sealed partial class StatusBarControl : UserControl
108
{
119
public DirectoryPropertiesViewModel DirectoryPropertiesViewModel
1210
{
@@ -41,12 +39,5 @@ public StatusBarControl()
4139
{
4240
InitializeComponent();
4341
}
44-
45-
public event PropertyChangedEventHandler PropertyChanged;
46-
47-
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
48-
{
49-
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
50-
}
5142
}
52-
}
43+
}

src/Files.App/ViewModels/CurrentInstanceViewModel.cs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
using CommunityToolkit.Mvvm.ComponentModel;
2+
using Files.App.Extensions;
23
using Files.Shared.Enums;
4+
using LibGit2Sharp;
5+
using System.Linq;
36

47
namespace Files.App.ViewModels
58
{
69
public class CurrentInstanceViewModel : ObservableObject
710
{
8-
// TODO:
9-
// In the future, we should consolidate these public variables into
10-
// a single enum property providing simplified customization of the
11-
// values being manipulated inside the setter blocks
11+
// TODO:
12+
// In the future, we should consolidate these public variables into
13+
// a single enum property providing simplified customization of the
14+
// values being manipulated inside the setter blocks
1215

1316
public FolderSettingsViewModel FolderSettings { get; }
1417

@@ -186,5 +189,41 @@ public bool CanTagFilesInPage
186189
{
187190
get => !isPageTypeRecycleBin && !isPageTypeFtp && !isPageTypeZipFolder;
188191
}
192+
193+
public bool IsGitRepository => !string.IsNullOrWhiteSpace(gitRepositoryPath);
194+
195+
private string? gitRepositoryPath;
196+
public string? GitRepositoryPath
197+
{
198+
get => gitRepositoryPath;
199+
set
200+
{
201+
if (SetProperty(ref gitRepositoryPath, value))
202+
{
203+
OnPropertyChanged(nameof(IsGitRepository));
204+
OnPropertyChanged(nameof(GitBranchName));
205+
}
206+
}
207+
}
208+
209+
public string GitBranchName
210+
{
211+
get
212+
{
213+
if (IsGitRepository)
214+
{
215+
using var repository = new Repository(gitRepositoryPath);
216+
return repository.Branches.First(branch =>
217+
branch.IsCurrentRepositoryHead).FriendlyName;
218+
}
219+
220+
return string.Empty;
221+
}
222+
}
223+
224+
public void UpdateCurrentBranchName()
225+
{
226+
OnPropertyChanged(nameof(GitBranchName));
227+
}
189228
}
190229
}

src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,12 @@ public string DirectoryItemCount
1010
get => directoryItemCount;
1111
set => SetProperty(ref directoryItemCount, value);
1212
}
13+
14+
private string? gitBranchDisplayName;
15+
public string? GitBranchDisplayName
16+
{
17+
get => gitBranchDisplayName;
18+
set => SetProperty(ref gitBranchDisplayName, value);
19+
}
1320
}
1421
}

0 commit comments

Comments
 (0)