Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit 89fbd02

Browse files
Merge branch 'master' into niceio-latest
2 parents 4604ace + 01d142b commit 89fbd02

File tree

15 files changed

+362
-96
lines changed

15 files changed

+362
-96
lines changed

docs/process/roadmap.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# The roadmap
2+
3+
## The road to 1.0
4+
5+
### 1.0-RC ETA
6+
7+
March 2018
8+
9+
### 1.0 ETA
10+
11+
May 2018
12+
13+
### Feature list
14+
15+
- Windows and Mac support
16+
- Unity 5.4 and above
17+
- Initialize new repository in existing project
18+
- Configure yaml merge tool
19+
- Configure project serialization for source control
20+
- Configure git and lfs
21+
- Publish to GitHub
22+
- Authentication
23+
- Login with user/password and 2FA if needed
24+
- Invoked when doing git operations
25+
- https support
26+
- Local repository management
27+
- List changed files
28+
- Commit selectively
29+
- Discard file changes
30+
- Repository history and network operations
31+
- List of commits
32+
- Individual commit detail
33+
- Revert commit
34+
- List of local branches
35+
- List of remote branches
36+
- Create branch
37+
- Delete branch
38+
- Fetch
39+
- Push
40+
- Pull
41+
- File locking
42+
- Lock and unlock files
43+
- Visual locking indicators in file UIs
44+
- List locked files
45+
- Notification when file is locked by someone else
46+
- Git management
47+
- User and email configuration
48+
- Git remote configuration
49+
- Git installation path configuration
50+
- Misc
51+
- Notification of new releases

src/GitHub.Api/Application/ApplicationManagerBase.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ public void Run(bool firstRun)
7272
}
7373
});
7474

75-
var applicationDataPath = Environment.GetSpecialFolder(System.Environment.SpecialFolder.LocalApplicationData).ToNPath();
76-
var installDetails = new GitInstallDetails(applicationDataPath, true);
75+
var installDetails = new GitInstallDetails(Environment.UserCachePath, true);
7776
var gitInstaller = new GitInstaller(Environment, CancellationToken, installDetails);
7877

7978
// if successful, continue with environment initialization, otherwise try to find an existing git installation
@@ -128,7 +127,7 @@ public void RestartRepository()
128127
{
129128
if (Environment.RepositoryPath != null)
130129
{
131-
repositoryManager = Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, Environment.RepositoryPath);
130+
repositoryManager = Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, ProcessManager, Environment.FileSystem, Environment.RepositoryPath);
132131
repositoryManager.Initialize();
133132
Environment.Repository.Initialize(repositoryManager);
134133
repositoryManager.Start();

src/GitHub.Api/Git/GitClient.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ ITask<string> Add(IList<string> files,
6969

7070
ITask<string> AddAll(IOutputProcessor<string> processor = null);
7171

72+
ITask<string> Discard(IList<string> files,
73+
IOutputProcessor<string> processor = null);
74+
75+
ITask<string> DiscardAll(IOutputProcessor<string> processor = null);
76+
7277
ITask<string> Remove(IList<string> files,
7378
IOutputProcessor<string> processor = null);
7479

@@ -365,6 +370,37 @@ public ITask<string> Add(IList<string> files,
365370
return last;
366371
}
367372

373+
public ITask<string> Discard( IList<string> files,
374+
IOutputProcessor<string> processor = null)
375+
{
376+
Logger.Trace("Checkout Files");
377+
378+
GitCheckoutTask last = null;
379+
foreach (var batch in files.Spool(5000))
380+
{
381+
var current = new GitCheckoutTask(batch, cancellationToken, processor).Configure(processManager);
382+
if (last == null)
383+
{
384+
last = current;
385+
}
386+
else
387+
{
388+
last.Then(current);
389+
last = current;
390+
}
391+
}
392+
393+
return last;
394+
}
395+
396+
public ITask<string> DiscardAll(IOutputProcessor<string> processor = null)
397+
{
398+
Logger.Trace("Checkout all files");
399+
400+
return new GitCheckoutTask(cancellationToken, processor)
401+
.Configure(processManager);
402+
}
403+
368404
public ITask<string> Remove(IList<string> files,
369405
IOutputProcessor<string> processor = null)
370406
{

src/GitHub.Api/Git/IRepository.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
namespace GitHub.Unity
55
{
66
/// <summary>
7-
/// Represents a repository, either local or retreived via the GitHub API.
7+
/// Represents a repository, either local or retrieved via the GitHub API.
88
/// </summary>
99
public interface IRepository : IEquatable<IRepository>
1010
{
@@ -18,7 +18,7 @@ public interface IRepository : IEquatable<IRepository>
1818
ITask Revert(string changeset);
1919
ITask RequestLock(string file);
2020
ITask ReleaseLock(string file, bool force);
21-
21+
ITask DiscardChanges(GitStatusEntry[] discardEntries);
2222
void CheckLogChangedEvent(CacheUpdateEvent gitLogCacheUpdateEvent);
2323
void CheckStatusChangedEvent(CacheUpdateEvent cacheUpdateEvent);
2424
void CheckStatusEntriesChangedEvent(CacheUpdateEvent cacheUpdateEvent);

src/GitHub.Api/Git/Repository.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ public ITask ReleaseLock(string file, bool force)
112112
return repositoryManager.UnlockFile(file, force);
113113
}
114114

115+
public ITask DiscardChanges(GitStatusEntry[] gitStatusEntry)
116+
{
117+
return repositoryManager.DiscardChanges(gitStatusEntry);
118+
}
119+
115120
public void CheckLogChangedEvent(CacheUpdateEvent cacheUpdateEvent)
116121
{
117122
var managedCache = cacheContainer.GitLogCache;
@@ -834,4 +839,4 @@ public string UpdatedTimeString
834839
private set { updatedTimeString = value; }
835840
}
836841
}
837-
}
842+
}

src/GitHub.Api/Git/RepositoryManager.cs

Lines changed: 93 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public interface IRepositoryManager : IDisposable
1717
event Action<List<GitLogEntry>> GitLogUpdated;
1818
event Action<Dictionary<string, ConfigBranch>> LocalBranchesUpdated;
1919
event Action<Dictionary<string, ConfigRemote>, Dictionary<string, Dictionary<string, ConfigBranch>>> RemoteBranchesUpdated;
20+
event Action<GitAheadBehindStatus> GitAheadBehindStatusUpdated;
2021

2122
void Initialize();
2223
void Start();
@@ -35,6 +36,7 @@ public interface IRepositoryManager : IDisposable
3536
ITask CreateBranch(string branch, string baseBranch);
3637
ITask LockFile(string file);
3738
ITask UnlockFile(string file, bool force);
39+
ITask DiscardChanges(GitStatusEntry[] gitStatusEntries);
3840
void UpdateGitLog();
3941
void UpdateGitStatus();
4042
void UpdateGitAheadBehindStatus();
@@ -44,7 +46,6 @@ public interface IRepositoryManager : IDisposable
4446
IGitConfig Config { get; }
4547
IGitClient GitClient { get; }
4648
bool IsBusy { get; }
47-
event Action<GitAheadBehindStatus> GitAheadBehindStatusUpdated;
4849
}
4950

5051
interface IRepositoryPathConfiguration
@@ -96,7 +97,10 @@ class RepositoryManager : IRepositoryManager
9697
{
9798
private readonly IGitConfig config;
9899
private readonly IGitClient gitClient;
100+
private readonly IProcessManager processManager;
99101
private readonly IRepositoryPathConfiguration repositoryPaths;
102+
private readonly IFileSystem fileSystem;
103+
private readonly CancellationToken token;
100104
private readonly IRepositoryWatcher watcher;
101105

102106
private bool isBusy;
@@ -112,18 +116,24 @@ class RepositoryManager : IRepositoryManager
112116

113117
public RepositoryManager(IGitConfig gitConfig,
114118
IRepositoryWatcher repositoryWatcher, IGitClient gitClient,
119+
IProcessManager processManager,
120+
IFileSystem fileSystem,
121+
CancellationToken token,
115122
IRepositoryPathConfiguration repositoryPaths)
116123
{
117124
this.repositoryPaths = repositoryPaths;
125+
this.fileSystem = fileSystem;
126+
this.token = token;
118127
this.gitClient = gitClient;
128+
this.processManager = processManager;
119129
this.watcher = repositoryWatcher;
120130
this.config = gitConfig;
121131

122132
SetupWatcher();
123133
}
124134

125-
public static RepositoryManager CreateInstance(IPlatform platform, ITaskManager taskManager,
126-
IGitClient gitClient, NPath repositoryRoot)
135+
public static RepositoryManager CreateInstance(IPlatform platform, ITaskManager taskManager, IGitClient gitClient,
136+
IProcessManager processManager, IFileSystem fileSystem, NPath repositoryRoot)
127137
{
128138
var repositoryPathConfiguration = new RepositoryPathConfiguration(repositoryRoot);
129139
string filePath = repositoryPathConfiguration.DotGitConfig;
@@ -132,7 +142,8 @@ public static RepositoryManager CreateInstance(IPlatform platform, ITaskManager
132142
var repositoryWatcher = new RepositoryWatcher(platform, repositoryPathConfiguration, taskManager.Token);
133143

134144
return new RepositoryManager(gitConfig, repositoryWatcher,
135-
gitClient, repositoryPathConfiguration);
145+
gitClient, processManager, fileSystem,
146+
taskManager.Token, repositoryPathConfiguration);
136147
}
137148

138149
public void Initialize()
@@ -211,15 +222,13 @@ public ITask Revert(string changeset)
211222
public ITask RemoteAdd(string remote, string url)
212223
{
213224
var task = GitClient.RemoteAdd(remote, url);
214-
task = HookupHandlers(task, true, false);
215-
return task;
225+
return HookupHandlers(task, true, false);
216226
}
217227

218228
public ITask RemoteRemove(string remote)
219229
{
220230
var task = GitClient.RemoteRemove(remote);
221-
task = HookupHandlers(task, true, false);
222-
return task;
231+
return HookupHandlers(task, true, false);
223232
}
224233

225234
public ITask RemoteChange(string remote, string url)
@@ -260,28 +269,75 @@ public ITask UnlockFile(string file, bool force)
260269

261270
public void UpdateGitLog()
262271
{
263-
var task = GitClient.Log();
264-
task = HookupHandlers(task, false, false);
265-
task.Then((success, logEntries) =>
266-
{
267-
if (success)
272+
var task = GitClient
273+
.Log()
274+
.Then((success, logEntries) =>
268275
{
269-
GitLogUpdated?.Invoke(logEntries);
270-
}
271-
}).Start();
276+
if (success)
277+
{
278+
GitLogUpdated?.Invoke(logEntries);
279+
}
280+
});
281+
task = HookupHandlers(task, false, false);
282+
task.Start();
272283
}
273284

274285
public void UpdateGitStatus()
275286
{
276-
var task = GitClient.Status();
287+
var task = GitClient
288+
.Status()
289+
.Then((success, status) =>
290+
{
291+
if (success)
292+
{
293+
GitStatusUpdated?.Invoke(status);
294+
}
295+
});
277296
task = HookupHandlers(task, true, false);
278-
task.Then((success, status) =>
279-
{
280-
if (success)
297+
task.Start();
298+
}
299+
300+
public ITask DiscardChanges(GitStatusEntry[] gitStatusEntries)
301+
{
302+
Guard.ArgumentNotNullOrEmpty(gitStatusEntries, "gitStatusEntries");
303+
304+
ActionTask<GitStatusEntry[]> task = null;
305+
task = new ActionTask<GitStatusEntry[]>(token, (_, entries) =>
281306
{
282-
GitStatusUpdated?.Invoke(status);
307+
var itemsToDelete = new List<string>();
308+
var itemsToRevert = new List<string>();
309+
310+
foreach (var gitStatusEntry in gitStatusEntries)
311+
{
312+
if (gitStatusEntry.status == GitFileStatus.Added || gitStatusEntry.status == GitFileStatus.Untracked)
313+
{
314+
itemsToDelete.Add(gitStatusEntry.path);
315+
}
316+
else
317+
{
318+
itemsToRevert.Add(gitStatusEntry.path);
319+
}
320+
}
321+
322+
if (itemsToDelete.Any())
323+
{
324+
foreach (var itemToDelete in itemsToDelete)
325+
{
326+
fileSystem.FileDelete(itemToDelete);
327+
}
328+
}
329+
330+
ITask<string> gitDiscardTask = null;
331+
if (itemsToRevert.Any())
332+
{
333+
gitDiscardTask = GitClient.Discard(itemsToRevert);
334+
task.Then(gitDiscardTask);
335+
}
283336
}
284-
}).Start();
337+
, () => gitStatusEntries);
338+
339+
340+
return HookupHandlers(task, true, true);
285341
}
286342

287343
public void UpdateGitAheadBehindStatus()
@@ -295,15 +351,17 @@ public void UpdateGitAheadBehindStatus()
295351
var name = configBranch.Value.Name;
296352
var trackingName = configBranch.Value.IsTracking ? configBranch.Value.Remote.Value.Name + "/" + name : "[None]";
297353

298-
var task = GitClient.AheadBehindStatus(name, trackingName);
299-
task = HookupHandlers(task, true, false);
300-
task.Then((success, status) =>
301-
{
302-
if (success)
354+
var task = GitClient
355+
.AheadBehindStatus(name, trackingName)
356+
.Then((success, status) =>
303357
{
304-
GitAheadBehindStatusUpdated?.Invoke(status);
305-
}
306-
}).Start();
358+
if (success)
359+
{
360+
GitAheadBehindStatusUpdated?.Invoke(status);
361+
}
362+
});
363+
task = HookupHandlers(task, true, false);
364+
task.Start();
307365
}
308366
else
309367
{
@@ -324,9 +382,9 @@ public void UpdateLocks()
324382
}).Start();
325383
}
326384

327-
private ITask<T> HookupHandlers<T>(ITask<T> task, bool isExclusive, bool filesystemChangesExpected)
385+
private ITask HookupHandlers(ITask task, bool isExclusive, bool filesystemChangesExpected)
328386
{
329-
return new ActionTask(TaskManager.Instance.Token, () => {
387+
return new ActionTask(token, () => {
330388
if (isExclusive)
331389
{
332390
Logger.Trace("Starting Operation - Setting Busy Flag");
@@ -340,7 +398,7 @@ private ITask<T> HookupHandlers<T>(ITask<T> task, bool isExclusive, bool filesys
340398
}
341399
})
342400
.Then(task)
343-
.Finally((success, exception, result) => {
401+
.Finally((success, exception) => {
344402
if (filesystemChangesExpected)
345403
{
346404
Logger.Trace("Ended Operation - Enable Watcher");
@@ -353,12 +411,10 @@ private ITask<T> HookupHandlers<T>(ITask<T> task, bool isExclusive, bool filesys
353411
IsBusy = false;
354412
}
355413

356-
if (success)
414+
if (!success)
357415
{
358-
return result;
416+
throw exception;
359417
}
360-
361-
throw exception;
362418
});
363419
}
364420

0 commit comments

Comments
 (0)