forked from gdevic/GitForce
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ClassRepos.cs
189 lines (166 loc) · 6.22 KB
/
ClassRepos.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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace GitForce
{
/// <summary>
/// Class containing a set of repos that the program knows about.
/// Also contains a pointer to the current, active repo.
/// </summary>
public class ClassRepos
{
/// <summary>
/// Contains a list of repos in this workspace
/// </summary>
public List<ClassRepo> Repos = new List<ClassRepo>();
/// <summary>
/// Pointer to the default repo to switch to upon start
/// </summary>
public ClassRepo Default { get; set; }
/// <summary>
/// Pointer to the currently active repo
/// </summary>
public ClassRepo Current { get; private set; }
/// <summary>
/// ToString override returns the number of repos.
/// </summary>
public override string ToString()
{
return Repos.Count.ToString();
}
/// <summary>
/// Load a set of repositories from a file.
/// Returns true if load succeeded.
/// </summary>
public bool Load(string fileName)
{
bool ret = false;
Repos = new List<ClassRepo>();
// Wrap the opening of a repository database with an outer handler
try
{
using (FileStream file = new FileStream(fileName, FileMode.Open))
{
try
{
BinaryFormatter rd = new BinaryFormatter();
Repos = (List<ClassRepo>)rd.Deserialize(file);
string defaultRepo = (string)rd.Deserialize(file);
// WAR: Mono 2.6.7 does not support serialization of a HashSet.
foreach (var classRepo in Repos)
classRepo.ExpansionReset(null);
// Upon load, set the current based on the default repo
Default = Repos.Find(r => r.Root == defaultRepo);
SetCurrent(Default);
// TODO: Commenting out since it takes long time when loading many repos, and it seems not needed
//App.Repos.Refresh();
ret = true;
}
catch (Exception ex)
{
throw new ClassException(ex.Message);
}
}
}
catch (Exception ex)
{
App.PrintLogMessage(ex.Message);
}
return ret;
}
/// <summary>
/// Saves the current set of repositories to a file.
/// Returns true if save succeeded.
/// </summary>
public bool Save(string fileName)
{
bool ret = false;
try
{
using (FileStream file = new FileStream(fileName, FileMode.Create))
{
try
{
BinaryFormatter wr = new BinaryFormatter();
wr.Serialize(file, Repos);
wr.Serialize(file, Default == null ? "" : Default.Root);
ret = true;
}
catch (Exception ex)
{
throw new ClassException(ex.Message);
}
}
}
catch (Exception ex)
{
App.PrintLogMessage(ex.Message);
}
return ret;
}
/// <summary>
/// Loads username/email for all repos in this workspace.
/// Removes repos that are not valid.
/// </summary>
public void Refresh()
{
// Get the user name and email for each repo adding invalid ones to the list
List<ClassRepo> invalidRepos = Repos.Where(r => r.Init() == false).ToList();
// Remove all invalid repos from the workspace
foreach (var r in invalidRepos)
{
App.PrintStatusMessage("Removing invalid repo " + r);
Delete(r);
}
}
/// <summary>
/// Add a new repository with the root at the given path. Create a directory if it does not exist.
/// This function throws exceptions!
/// </summary>
/// <param name="root">The root path of a new repository</param>
/// <returns>Newly created repository class or null if a repo already exists at that root directory</returns>
public ClassRepo Add(string root)
{
// Detect a repository with the same root path
if (Repos.Exists(r => r.Root == root))
throw new ClassException("Repository with the same name already exists!");
Directory.CreateDirectory(root);
ClassRepo repo = new ClassRepo(root);
if (!repo.Init())
throw new ClassException("Unable to initialize git repository!");
Repos.Add(repo);
App.PrintStatusMessage("Adding repo " + repo);
// If this is a very first repo, set it as default and current
if (Repos.Count == 1)
Current = Default = repo;
return repo;
}
/// <summary>
/// Delete a repository given by its class variable
/// </summary>
public void Delete(ClassRepo repo)
{
Repos.Remove(repo);
// If the current has been deleted, find a new current
if (repo == Current)
SetCurrent(Repos.Count > 0 ? Repos[0] : null);
// Reset the default if that one has been deleted
if (repo == Default)
Default = Current;
}
/// <summary>
/// Set the new current repo.
/// Given repo can be null.
/// </summary>
public void SetCurrent(ClassRepo repo)
{
Current = repo;
if (Current != null)
Current.Remotes.Refresh(Current); // Refresh the list of remote repos
}
}
}