├── .gitignore ├── GitInfoExplorerExtension ├── key.snk ├── Images │ └── Git.png ├── GitInfoExplorerExtension.csproj.user ├── Program.cs ├── packages.config ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── GitInfoContextMenu.cs └── GitInfoExplorerExtension.csproj ├── README.md ├── ExplorerExtension.sln └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | /packages/ 4 | /.idea/ 5 | /.vs/ 6 | -------------------------------------------------------------------------------- /GitInfoExplorerExtension/key.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedoc/GitInfoExplorerExtension/HEAD/GitInfoExplorerExtension/key.snk -------------------------------------------------------------------------------- /GitInfoExplorerExtension/Images/Git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedoc/GitInfoExplorerExtension/HEAD/GitInfoExplorerExtension/Images/Git.png -------------------------------------------------------------------------------- /GitInfoExplorerExtension/GitInfoExplorerExtension.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ProjectFiles 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GitInfoExplorerExtension 2 | 在资源管理器中,利用右键上下文菜单展示git信息 3 | 4 | 5 | Q:TortoiseGit在属性界面中增加了Git栏展示Git信息,为什么不用这个? 6 | A:简单说,为了这么一个小功能,太重了。其次,懒人不想多次点击。 7 | 8 | Q:为什么是在右键菜单中? 9 | A:最开始想加到任务管理器的Title中,(如[RepoZ](https://github.com/awaescher/RepoZ)),或者也可以直接鼠标指向时显示提示信息,取决于个人。同时当不在一个Git目录下时,不会出现此菜单项,避免干扰。 10 | -------------------------------------------------------------------------------- /GitInfoExplorerExtension/Program.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace GitInfoExplorerExtension 4 | { 5 | internal class Program 6 | { 7 | public static void Main(string[] args) 8 | { 9 | var result= GitInfoContextMenu.IsGitDirectory(@"E:\RNSS\dashboard\entrypoint.sh"); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /GitInfoExplorerExtension/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /GitInfoExplorerExtension/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("GitInfoExplorerExtension")] 6 | [assembly: AssemblyDescription("")] 7 | [assembly: AssemblyConfiguration("")] 8 | [assembly: AssemblyCompany("")] 9 | [assembly: AssemblyProduct("GitInfoExplorerExtension")] 10 | [assembly: AssemblyCopyright("Copyright © pedoc 2019")] 11 | [assembly: AssemblyTrademark("")] 12 | [assembly: AssemblyCulture("")] 13 | 14 | [assembly: ComVisible(false)] 15 | 16 | [assembly: Guid("2B87A3A8-93AD-454E-AD0C-C4BD98E068D0")] 17 | 18 | [assembly: AssemblyVersion("1.0.0.0")] 19 | [assembly: AssemblyFileVersion("1.0.0.0")] 20 | -------------------------------------------------------------------------------- /ExplorerExtension.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitInfoExplorerExtension", "GitInfoExplorerExtension\GitInfoExplorerExtension.csproj", "{1104D7B6-9986-45D6-B750-693004A94CD9}" 4 | EndProject 5 | Global 6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 7 | Debug|Any CPU = Debug|Any CPU 8 | Release|Any CPU = Release|Any CPU 9 | EndGlobalSection 10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 11 | {1104D7B6-9986-45D6-B750-693004A94CD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 12 | {1104D7B6-9986-45D6-B750-693004A94CD9}.Debug|Any CPU.Build.0 = Debug|Any CPU 13 | {1104D7B6-9986-45D6-B750-693004A94CD9}.Release|Any CPU.ActiveCfg = Release|Any CPU 14 | {1104D7B6-9986-45D6-B750-693004A94CD9}.Release|Any CPU.Build.0 = Release|Any CPU 15 | EndGlobalSection 16 | EndGlobal 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 pedoc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /GitInfoExplorerExtension/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace GitInfoExplorerExtension.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GitInfoExplorerExtension.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 重写当前线程的 CurrentUICulture 属性 51 | /// 重写当前线程的 CurrentUICulture 属性。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 65 | /// 66 | internal static System.Drawing.Bitmap Git { 67 | get { 68 | object obj = ResourceManager.GetObject("Git", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /GitInfoExplorerExtension/GitInfoContextMenu.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Runtime.InteropServices; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | using LibGit2Sharp; 10 | using SharpShell.Attributes; 11 | using SharpShell.SharpContextMenu; 12 | 13 | namespace GitInfoExplorerExtension 14 | { 15 | [ComVisible(true)] 16 | [COMServerAssociation(AssociationType.AllFiles)] 17 | [COMServerAssociation(AssociationType.Directory)] 18 | public class GitInfoContextMenu : SharpContextMenu 19 | { 20 | private const string GitDirectoryName = ".git"; 21 | private const string GitInfoMenuName = "GitInfo"; 22 | 23 | private ContextMenuStrip _menu = new ContextMenuStrip(); 24 | 25 | protected override bool CanShowMenu() 26 | { 27 | if (SelectedItemPaths.Count() == 1 && IsGitDirectory(SelectedItemPaths.First()))//选中一个目录时构建菜单并显示 28 | { 29 | this.UpdateMenu(); 30 | return true; 31 | } 32 | else 33 | { 34 | return false; 35 | } 36 | } 37 | 38 | private static void Log(string msg) => Debug.WriteLine(msg); 39 | 40 | public static bool IsGitDirectory(string path) 41 | { 42 | if (string.IsNullOrEmpty(path)) return false; 43 | if (!IsDirectory(path)) path = Path.GetDirectoryName(path); 44 | if (string.IsNullOrEmpty(path)) return false; 45 | return !string.IsNullOrEmpty(GetGitDirectory(path)); 46 | } 47 | 48 | private static string GetGitDirectory(string path) 49 | { 50 | if (!IsDirectory(path)) path = Path.GetDirectoryName(path); 51 | if (string.IsNullOrEmpty(path)) return String.Empty; 52 | var directoryInfo = new DirectoryInfo(path); 53 | if (directoryInfo.GetDirectories(GitDirectoryName, SearchOption.TopDirectoryOnly).Length == 1) return directoryInfo.FullName; 54 | return GetGitDirectory(directoryInfo.Parent?.FullName); 55 | } 56 | 57 | protected override ContextMenuStrip CreateMenu() 58 | { 59 | BuildGitInfoContextMenus(); 60 | return _menu; 61 | } 62 | 63 | private void UpdateMenu() 64 | { 65 | _menu.Dispose(); 66 | _menu = CreateMenu(); 67 | } 68 | 69 | private static bool IsDirectory(string path) 70 | { 71 | if (string.IsNullOrEmpty(path)) return false; 72 | var attr = File.GetAttributes(path); 73 | return attr.HasFlag(FileAttributes.Directory); 74 | } 75 | 76 | protected void BuildGitInfoContextMenus() 77 | { 78 | _menu.Items.Clear(); 79 | var gitDir = GetGitDirectory(SelectedItemPaths.First()); 80 | if (string.IsNullOrEmpty(gitDir) || !Directory.Exists(gitDir)) return; 81 | var repo = new Repository(gitDir); 82 | 83 | var lastCommit = repo.Head.Tip; 84 | var mainMenu = new ToolStripMenuItem 85 | { 86 | Text = GitInfoMenuName, 87 | Image = Properties.Resources.Git 88 | }; 89 | mainMenu.DropDownItems.Add(new ToolStripMenuItem { Text = $@"Branch Name: {repo.Head.FriendlyName} <->{repo.Head.TrackedBranch?.FriendlyName}" }); 90 | mainMenu.DropDownItems.Add(new ToolStripMenuItem { Text = @"Branches Count: " + repo.Branches.Count().ToString() }); 91 | mainMenu.DropDownItems.Add(new ToolStripMenuItem { Text = @"Tags Count: " + repo.Tags.Count().ToString() }); 92 | mainMenu.DropDownItems.Add(new ToolStripSeparator()); 93 | mainMenu.DropDownItems.Add(new ToolStripMenuItem { Text = $@"Last Commit : {lastCommit.Message} {lastCommit.Author} {lastCommit.Author.When.ToString()}" }); 94 | _menu.Items.Clear(); 95 | _menu.Items.Add(mainMenu); 96 | repo.Dispose(); 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /GitInfoExplorerExtension/GitInfoExplorerExtension.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {1104D7B6-9986-45D6-B750-693004A94CD9} 9 | Library 10 | Properties 11 | GitInfoExplorerExtension 12 | GitInfoExplorerExtension 13 | v4.6 14 | 512 15 | 16 | 17 | 18 | 19 | 20 | 21 | AnyCPU 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | false 30 | 31 | 32 | AnyCPU 33 | pdbonly 34 | true 35 | bin\Release\ 36 | TRACE 37 | prompt 38 | 4 39 | false 40 | 41 | 42 | 43 | 44 | 45 | true 46 | 47 | 48 | key.snk 49 | 50 | 51 | 52 | ..\packages\SharpShellTools.2.2.0.0\lib\Apex.WinForms.dll 53 | 54 | 55 | ..\packages\LibGit2Sharp.0.26.1\lib\net46\LibGit2Sharp.dll 56 | 57 | 58 | ..\packages\SharpShellTools.2.2.0.0\lib\ServerManager.exe 59 | 60 | 61 | ..\packages\SharpShellTools.2.2.0.0\lib\srm.exe 62 | True 63 | 64 | 65 | ..\packages\SharpShellTools.2.2.0.0\lib\SharpShell.dll 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | True 80 | True 81 | Resources.resx 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | ResXFileCodeGenerator 91 | Resources.Designer.cs 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 102 | 103 | 104 | 105 | 112 | -------------------------------------------------------------------------------- /GitInfoExplorerExtension/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\images\git.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | --------------------------------------------------------------------------------