forked from gdevic/GitForce
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathClassStatus.cs
168 lines (153 loc) · 5.29 KB
/
ClassStatus.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace GitForce
{
/// <summary>
/// Class containing status of the files in a git repository.
/// </summary>
public class ClassStatus
{
/// <summary>
/// Reference to class repo that this Status class wraps
/// </summary>
public ClassRepo Repo;
/// <summary>
/// Lookup dictionary to get the status code string (length of 2) from a file path relative to the root.
/// </summary>
private readonly Dictionary<string, string> XY = new Dictionary<string, string>();
/// <summary>
/// Supplemental file name addressed by the primary file name, both relative to the root.
/// This is used to store the original file name of a renamed and copied files (codes 'R' and 'C')
/// </summary>
private readonly Dictionary<string, string> AltFile = new Dictionary<string, string>();
/// <summary>
/// Class constructor
/// </summary>
public ClassStatus(ClassRepo repo)
{
Repo = repo;
}
/// <summary>
/// Constructor used only once at FormMain init to register
/// the repo status refresh before any other refresh in the chain.
/// </summary>
public ClassStatus()
{
App.Refresh += Refresh;
}
/// <summary>
/// Global status refresh function.
/// Refresh status of the current repo.
/// </summary>
public static void Refresh()
{
ClassRepo repo = App.Repos.Current;
if(repo!=null)
{
repo.Status = new ClassStatus(repo);
repo.Status.Status();
}
}
/// <summary>
/// Reload status fields in the context of a status class
/// </summary>
private void Status()
{
XY.Clear();
AltFile.Clear();
ExecResult result = Repo.Run("status --porcelain -uall -z");
if (!result.Success()) return;
string[] response = result.stdout
.Replace('/', Path.DirectorySeparatorChar) // Correct the path slash on Windows
.Split(("\0")
.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < response.Length; i++)
{
string s = response[i].Substring(3);
string code = response[i].Substring(0, 2);
XY[s] = code;
if ("RC".Contains(response[i][0]))
{
i++;
AltFile[s] = response[i];
}
}
}
/// <summary>
/// Returns a list of files stored in a class
/// </summary>
public List<string> GetFiles()
{
return XY.Keys.ToList();
}
/// <summary>
/// Return true if a given file is part of the git file status database
/// </summary>
public bool IsMarked(string path)
{
return XY.ContainsKey(path);
}
/// <summary>
/// Returns the git status "X" key code for a file
/// </summary>
public char Xcode(string file)
{
return XY.ContainsKey(file) ? XY[file][0] : ' ';
}
/// <summary>
/// Returns the git status "Y" key code for a file
/// </summary>
public char Ycode(string file)
{
return XY.ContainsKey(file) ? XY[file][1] : ' ';
}
/// <summary>
/// Returns the alternate file name associated with the given file
/// </summary>
public string GetAltFile(string key)
{
return AltFile.ContainsKey(key) ? AltFile[key] : string.Empty;
}
/// <summary>
/// Display the info from the given tree node on the main application status pane.
/// </summary>
public void ShowTreeInfo(TreeNode tn)
{
// Translation of git status codes into useful human readable strings
Dictionary<char, string> desc = new Dictionary<char, string> {
{ ' ', "OK" },
{ 'M', "Modified" },
{ 'A', "Added" },
{ 'D', "Deleted" },
{ 'R', "Renamed" },
{ 'C', "Copied" },
{ 'U', "Unmerged" },
{ '?', "Untracked" } };
string status = "";
if (tn != null)
{
string name = tn.Tag.ToString();
#if DEBUG
status = String.Format("{0} Tag:'{1}': ", tn.Tag.GetType(), name);
#endif
if (IsMarked(name))
{
char xcode = Xcode(name);
char ycode = Ycode(name);
string x = "", y = "";
if (ycode != ' ')
y = desc[ycode];
if (xcode != ' ' && xcode != '?')
x = ((ycode!=' ')? ", " : "") + desc[xcode] + " in index";
status += name + ((x.Length>0 || y.Length>0) ? " ... <" + y + x + ">" : "");
}
}
App.MainForm.SetStatusText(status);
}
}
}