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

Commit e6f0acf

Browse files
neuroKipshana
authored andcommitted
Initial implementation of discard (git checkout) functionality
1 parent 2be4f51 commit e6f0acf

File tree

7 files changed

+150
-3
lines changed

7 files changed

+150
-3
lines changed

src/GitHub.Api/Git/GitClient.cs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,12 @@ ITask<string> Add(IList<string> files,
6969

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

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

7580
ITask<string> AddAndCommit(IList<string> files, string message, string body,
@@ -365,7 +370,38 @@ public ITask<string> Add(IList<string> files,
365370
return last;
366371
}
367372

368-
public ITask<string> Remove(IList<string> files,
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+
404+
public ITask<string> Remove(IList<string> files,
369405
IOutputProcessor<string> processor = null)
370406
{
371407
Logger.Trace("Remove");

src/GitHub.Api/Git/IRepository.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +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+
ITask CheckoutFiles( List<string> files );
2122

2223
void CheckLogChangedEvent(CacheUpdateEvent gitLogCacheUpdateEvent);
2324
void CheckStatusChangedEvent(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 CheckoutFiles( List<string> files )
116+
{
117+
return repositoryManager.CheckoutFiles( files );
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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public interface IRepositoryManager : IDisposable
3535
ITask CreateBranch(string branch, string baseBranch);
3636
ITask LockFile(string file);
3737
ITask UnlockFile(string file, bool force);
38+
ITask CheckoutFiles(List<string> files);
3839
void UpdateGitLog();
3940
void UpdateGitStatus();
4041
void UpdateGitAheadBehindStatus();
@@ -284,6 +285,14 @@ public void UpdateGitStatus()
284285
}).Start();
285286
}
286287

288+
public ITask CheckoutFiles( List<string> files )
289+
{
290+
var discard = GitClient.Discard(files);
291+
discard.OnStart += t => IsBusy = true;
292+
293+
return discard.Finally(() => IsBusy = false);
294+
}
295+
287296
public void UpdateGitAheadBehindStatus()
288297
{
289298
ConfigBranch? configBranch;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading;
4+
5+
namespace GitHub.Unity
6+
{
7+
class GitCheckoutTask : ProcessTask<string>
8+
{
9+
private const string TaskName = "git checkout";
10+
private readonly string arguments;
11+
12+
public GitCheckoutTask( IEnumerable<string> files, CancellationToken token,
13+
IOutputProcessor<string> processor = null ) : base(token, processor ?? new SimpleOutputProcessor())
14+
{
15+
Guard.ArgumentNotNull( files, "files" );
16+
Name = TaskName;
17+
18+
arguments = "checkout ";
19+
arguments += " -- ";
20+
21+
foreach( var file in files )
22+
{
23+
arguments += " \"" + file.ToNPath().ToString( SlashMode.Forward ) + "\"";
24+
}
25+
}
26+
27+
public GitCheckoutTask( CancellationToken token,
28+
IOutputProcessor<string> processor = null ) : base( token, processor ?? new SimpleOutputProcessor() )
29+
{
30+
arguments = "checkout -- .";
31+
}
32+
33+
public override string ProcessArguments { get { return arguments; } }
34+
public override TaskAffinity Affinity { get { return TaskAffinity.Exclusive; } }
35+
}
36+
}

src/GitHub.Api/GitHub.Api.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
<Compile Include="Application\Organization.cs" />
101101
<Compile Include="Cache\CacheInterfaces.cs" />
102102
<Compile Include="Extensions\ListExtensions.cs" />
103+
<Compile Include="Git\Tasks\GitCheckoutTask.cs" />
103104
<Compile Include="Git\GitAheadBehindStatus.cs" />
104105
<Compile Include="Git\Tasks\GitAheadBehindStatusTask.cs" />
105106
<Compile Include="Git\Tasks\GitLfsVersionTask.cs" />

src/tests/IntegrationTests/Events/RepositoryManagerTests.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,5 +755,64 @@ public async Task ShouldDetectGitFetch()
755755
EndTest(logger);
756756
}
757757
}
758+
759+
760+
761+
[Test]
762+
public async Task ShouldCheckoutFiles()
763+
{
764+
await Initialize( TestRepoMasterCleanSynchronized );
765+
766+
var repositoryManagerListener = Substitute.For<IRepositoryManagerListener>();
767+
repositoryManagerListener.AttachListener( RepositoryManager, repositoryManagerEvents );
768+
769+
var expected = new GitStatus
770+
{
771+
Behind = 1,
772+
LocalBranch = "master",
773+
RemoteBranch = "origin/master",
774+
Entries =
775+
new List<GitStatusEntry> {
776+
new GitStatusEntry("foobar.txt", TestRepoMasterCleanSynchronized.Combine("foobar.txt"),
777+
"foobar.txt", GitFileStatus.None)
778+
}
779+
};
780+
781+
var result = new GitStatus();
782+
Environment.Repository.OnStatusUpdated += status => { result = status; };
783+
784+
var foobarTxt = TestRepoMasterCleanSynchronized.Combine( "foobar.txt" );
785+
foobarTxt.WriteAllText( "foobar" );
786+
787+
await TaskManager.Wait();
788+
RepositoryManager.WaitForEvents();
789+
WaitForNotBusy( repositoryManagerEvents, 1 );
790+
791+
repositoryManagerListener.Received().OnStatusUpdate( Args.GitStatus );
792+
repositoryManagerListener.DidNotReceive().OnActiveBranchChanged( Arg.Any<ConfigBranch?>() );
793+
repositoryManagerListener.DidNotReceive().OnActiveRemoteChanged( Arg.Any<ConfigRemote?>() );
794+
repositoryManagerListener.DidNotReceive().OnLocalBranchListChanged();
795+
repositoryManagerListener.DidNotReceive().OnRemoteBranchListChanged();
796+
repositoryManagerListener.Received().OnIsBusyChanged( Args.Bool );
797+
repositoryManagerListener.DidNotReceive().OnLocksUpdated( Args.EnumerableGitLock );
798+
799+
await RepositoryManager.CheckoutFiles( new List<string>() { "foobar.txt" } )
800+
.StartAsAsync();
801+
802+
await TaskManager.Wait();
803+
RepositoryManager.WaitForEvents();
804+
WaitForNotBusy( repositoryManagerEvents, 1 );
805+
repositoryManagerEvents.OnStatusUpdate.WaitOne( TimeSpan.FromSeconds( 1 ) );
806+
807+
repositoryManagerListener.Received().OnStatusUpdate( Args.GitStatus );
808+
repositoryManagerListener.DidNotReceive().OnActiveBranchChanged( Arg.Any<ConfigBranch?>() );
809+
repositoryManagerListener.DidNotReceive().OnActiveRemoteChanged( Arg.Any<ConfigRemote?>() );
810+
repositoryManagerListener.DidNotReceive().OnLocalBranchListChanged();
811+
repositoryManagerListener.DidNotReceive().OnRemoteBranchListChanged();
812+
repositoryManagerListener.Received().OnIsBusyChanged( Args.Bool );
813+
repositoryManagerListener.DidNotReceive().OnLocksUpdated( Args.EnumerableGitLock );
814+
815+
result.AssertEqual( expected );
816+
}
758817
}
759818
}

0 commit comments

Comments
 (0)