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

Commit 5506401

Browse files
Merge branch 'fixes/update-after-push' into enhancements/branches-view-rollup
2 parents 83ddb4b + 2ff8713 commit 5506401

File tree

17 files changed

+300
-46
lines changed

17 files changed

+300
-46
lines changed

src/GitHub.Api/Cache/CacheInterfaces.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ public interface IGitUserCache : IManagedCache
5555

5656
public interface IGitStatusCache : IManagedCache
5757
{
58-
GitStatus GitStatus { get; set; }
58+
int Ahead { get; set; }
59+
int Behind { get; set; }
60+
List<GitStatusEntry> Entries { get; set; }
5961
}
6062

6163
public interface ILocalConfigBranchDictionary : IDictionary<string, ConfigBranch>

src/GitHub.Api/Extensions/GitStatusExtensions.cs

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
3+
namespace GitHub.Unity
4+
{
5+
[Serializable]
6+
public struct GitAheadBehindStatus
7+
{
8+
public static GitAheadBehindStatus Default = new GitAheadBehindStatus();
9+
10+
public int ahead;
11+
public int behind;
12+
13+
public GitAheadBehindStatus(int ahead, int behind)
14+
{
15+
this.ahead = ahead;
16+
this.behind = behind;
17+
}
18+
19+
public int Ahead => ahead;
20+
21+
public int Behind => behind;
22+
}
23+
}

src/GitHub.Api/Git/GitClient.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ public interface IGitClient
1515

1616
ITask LfsInstall(IOutputProcessor<string> processor = null);
1717

18+
ITask<GitAheadBehindStatus> AheadBehindStatus(string gitRef, string otherRef,
19+
IOutputProcessor<GitAheadBehindStatus> processor = null);
20+
1821
ITask<GitStatus> Status(IOutputProcessor<GitStatus> processor = null);
1922

2023
ITask<string> GetConfig(string key, GitConfigSource configSource,
@@ -219,6 +222,14 @@ public ITask<GitStatus> Status(IOutputProcessor<GitStatus> processor = null)
219222
.Configure(processManager);
220223
}
221224

225+
public ITask<GitAheadBehindStatus> AheadBehindStatus(string gitRef, string otherRef, IOutputProcessor<GitAheadBehindStatus> processor = null)
226+
{
227+
Logger.Trace("AheadBehindStatus");
228+
229+
return new GitAheadBehindStatusTask(gitRef, otherRef, cancellationToken, processor)
230+
.Configure(processManager);
231+
}
232+
222233
public ITask<List<GitLogEntry>> Log(BaseOutputListProcessor<GitLogEntry> processor = null)
223234
{
224235
Logger.Trace("Log");

src/GitHub.Api/Git/IRepository.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ public interface IRepository : IEquatable<IRepository>
5757
/// Gets the current branch of the repository.
5858
/// </summary>
5959
GitBranch? CurrentBranch { get; }
60-
GitStatus CurrentStatus { get; }
60+
int CurrentAhead { get; }
61+
int CurrentBehind { get; }
62+
List<GitStatusEntry> CurrentChanges { get; }
6163
GitRemote[] Remotes { get; }
6264
GitBranch[] LocalBranches { get; }
6365
GitBranch[] RemoteBranches { get; }

src/GitHub.Api/Git/Repository.cs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public void Initialize(IRepositoryManager initRepositoryManager)
4949
repositoryManager = initRepositoryManager;
5050
repositoryManager.CurrentBranchUpdated += RepositoryManagerOnCurrentBranchUpdated;
5151
repositoryManager.GitStatusUpdated += RepositoryManagerOnGitStatusUpdated;
52+
repositoryManager.GitAheadBehindStatusUpdated += RepositoryManagerOnGitAheadBehindStatusUpdated;
5253
repositoryManager.GitLogUpdated += RepositoryManagerOnGitLogUpdated;
5354
repositoryManager.GitLocksUpdated += RepositoryManagerOnGitLocksUpdated;
5455
repositoryManager.LocalBranchesUpdated += RepositoryManagerOnLocalBranchesUpdated;
@@ -373,7 +374,17 @@ private void RepositoryManagerOnCurrentBranchUpdated(ConfigBranch? branch, Confi
373374
private void RepositoryManagerOnGitStatusUpdated(GitStatus gitStatus)
374375
{
375376
new ActionTask(CancellationToken.None, () => {
376-
CurrentStatus = gitStatus;
377+
CurrentChanges = gitStatus.Entries;
378+
CurrentAhead = gitStatus.Ahead;
379+
CurrentBehind = gitStatus.Behind;
380+
}) { Affinity = TaskAffinity.UI }.Start();
381+
}
382+
383+
private void RepositoryManagerOnGitAheadBehindStatusUpdated(GitAheadBehindStatus aheadBehindStatus)
384+
{
385+
new ActionTask(CancellationToken.None, () => {
386+
CurrentAhead = aheadBehindStatus.Ahead;
387+
CurrentBehind = aheadBehindStatus.Behind;
377388
}) { Affinity = TaskAffinity.UI }.Start();
378389
}
379390

@@ -486,10 +497,22 @@ private ConfigRemote? CurrentConfigRemote
486497
set { cacheContainer.BranchCache.CurrentConfigRemote = value; }
487498
}
488499

489-
public GitStatus CurrentStatus
500+
public int CurrentAhead
501+
{
502+
get { return cacheContainer.GitStatusCache.Ahead; }
503+
private set { cacheContainer.GitStatusCache.Ahead = value; }
504+
}
505+
506+
public int CurrentBehind
507+
{
508+
get { return cacheContainer.GitStatusCache.Behind; }
509+
private set { cacheContainer.GitStatusCache.Behind = value; }
510+
}
511+
512+
public List<GitStatusEntry> CurrentChanges
490513
{
491-
get { return cacheContainer.GitStatusCache.GitStatus; }
492-
private set { cacheContainer.GitStatusCache.GitStatus = value; }
514+
get { return cacheContainer.GitStatusCache.Entries; }
515+
private set { cacheContainer.GitStatusCache.Entries = value; }
493516
}
494517

495518
public GitBranch? CurrentBranch

src/GitHub.Api/Git/RepositoryManager.cs

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ public interface IRepositoryManager : IDisposable
3535
ITask UnlockFile(string file, bool force);
3636
void UpdateGitLog();
3737
void UpdateGitStatus();
38+
void UpdateGitAheadBehindStatus();
3839
void UpdateLocks();
3940
int WaitForEvents();
4041

4142
IGitConfig Config { get; }
4243
IGitClient GitClient { get; }
4344
bool IsBusy { get; }
45+
event Action<GitAheadBehindStatus> GitAheadBehindStatusUpdated;
4446
}
4547

4648
interface IRepositoryPathConfiguration
@@ -101,6 +103,7 @@ class RepositoryManager : IRepositoryManager
101103
public event Action<ConfigBranch?, ConfigRemote?> CurrentBranchUpdated;
102104
public event Action<bool> IsBusyChanged;
103105
public event Action<GitStatus> GitStatusUpdated;
106+
public event Action<GitAheadBehindStatus> GitAheadBehindStatusUpdated;
104107
public event Action<List<GitLock>> GitLocksUpdated;
105108
public event Action<List<GitLogEntry>> GitLogUpdated;
106109
public event Action<Dictionary<string, ConfigBranch>> LocalBranchesUpdated;
@@ -281,6 +284,33 @@ public void UpdateGitStatus()
281284
}).Start();
282285
}
283286

287+
public void UpdateGitAheadBehindStatus()
288+
{
289+
ConfigBranch? configBranch;
290+
ConfigRemote? configRemote;
291+
GetCurrentBranchAndRemote(out configBranch, out configRemote);
292+
293+
if (configBranch.HasValue && configBranch.Value.Remote.HasValue)
294+
{
295+
var name = configBranch.Value.Name;
296+
var trackingName = configBranch.Value.IsTracking ? configBranch.Value.Remote.Value.Name + "/" + name : "[None]";
297+
298+
var task = GitClient.AheadBehindStatus(name, trackingName);
299+
task = HookupHandlers(task, true, false);
300+
task.Then((success, status) =>
301+
{
302+
if (success)
303+
{
304+
GitAheadBehindStatusUpdated?.Invoke(status);
305+
}
306+
}).Start();
307+
}
308+
else
309+
{
310+
GitAheadBehindStatusUpdated?.Invoke(GitAheadBehindStatus.Default);
311+
}
312+
}
313+
284314
public void UpdateLocks()
285315
{
286316
var task = GitClient.ListLocks(false);
@@ -345,16 +375,33 @@ private void SetupWatcher()
345375

346376
private void UpdateHead()
347377
{
348-
var head = repositoryPaths.DotGitHead.ReadAllLines().FirstOrDefault();
349-
Logger.Trace("UpdateHead: {0}", head ?? "[NULL]");
350-
UpdateCurrentBranchAndRemote(head);
378+
Logger.Trace("UpdateHead");
379+
UpdateCurrentBranchAndRemote();
351380
UpdateGitLog();
352381
}
353382

354-
private void UpdateCurrentBranchAndRemote(string head)
383+
private string GetCurrentHead()
384+
{
385+
return repositoryPaths.DotGitHead.ReadAllLines().FirstOrDefault();
386+
}
387+
388+
private void UpdateCurrentBranchAndRemote()
389+
{
390+
ConfigBranch? branch;
391+
ConfigRemote? remote;
392+
GetCurrentBranchAndRemote(out branch, out remote);
393+
394+
Logger.Trace("CurrentBranch: {0}", branch.HasValue ? branch.Value.ToString() : "[NULL]");
395+
Logger.Trace("CurrentRemote: {0}", remote.HasValue ? remote.Value.ToString() : "[NULL]");
396+
CurrentBranchUpdated?.Invoke(branch, remote);
397+
}
398+
399+
private void GetCurrentBranchAndRemote(out ConfigBranch? branch, out ConfigRemote? remote)
355400
{
356-
ConfigBranch? branch = null;
401+
branch = null;
402+
remote = null;
357403

404+
var head = GetCurrentHead();
358405
if (head.StartsWith("ref:"))
359406
{
360407
var branchName = head.Substring(head.IndexOf("refs/heads/") + "refs/heads/".Length);
@@ -367,7 +414,6 @@ private void UpdateCurrentBranchAndRemote(string head)
367414
}
368415

369416
var defaultRemote = "origin";
370-
ConfigRemote? remote = null;
371417

372418
if (branch.HasValue && branch.Value.IsTracking)
373419
{
@@ -387,10 +433,6 @@ private void UpdateCurrentBranchAndRemote(string head)
387433
remote = configRemotes.FirstOrDefault();
388434
}
389435
}
390-
391-
Logger.Trace("CurrentBranch: {0}", branch.HasValue ? branch.Value.ToString() : "[NULL]");
392-
Logger.Trace("CurrentRemote: {0}", remote.HasValue ? remote.Value.ToString() : "[NULL]");
393-
CurrentBranchUpdated?.Invoke(branch, remote);
394436
}
395437

396438
private void WatcherOnRemoteBranchesChanged()
@@ -409,6 +451,7 @@ private void WatcherOnRepositoryCommitted()
409451
{
410452
Logger.Trace("WatcherOnRepositoryCommitted");
411453
UpdateGitLog();
454+
UpdateGitAheadBehindStatus();
412455
}
413456

414457
private void WatcherOnRepositoryChanged()
@@ -507,6 +550,8 @@ private void UpdateRemoteBranches()
507550

508551
Logger.Trace("OnRemoteBranchListUpdated {0} remotes", remotes.Count);
509552
RemoteBranchesUpdated?.Invoke(remotes, remoteBranches);
553+
554+
UpdateGitAheadBehindStatus();
510555
}
511556

512557
private bool disposed;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Threading;
2+
3+
namespace GitHub.Unity
4+
{
5+
class GitAheadBehindStatusTask : ProcessTask<GitAheadBehindStatus>
6+
{
7+
private const string TaskName = "git rev-list";
8+
private readonly string arguments;
9+
10+
public GitAheadBehindStatusTask(string gitRef, string otherRef,
11+
CancellationToken token, IOutputProcessor<GitAheadBehindStatus> processor = null)
12+
: base(token, processor ?? new GitAheadBehindStatusOutputProcessor())
13+
{
14+
Name = TaskName;
15+
arguments = $"rev-list --left-right --count {gitRef}...{otherRef}";
16+
}
17+
18+
public override string ProcessArguments => arguments;
19+
public override TaskAffinity Affinity { get { return TaskAffinity.Exclusive; } }
20+
}
21+
}

src/GitHub.Api/GitHub.Api.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@
104104
<Compile Include="Cache\CacheInterfaces.cs" />
105105
<Compile Include="Extensions\ListExtensions.cs" />
106106
<Compile Include="Git\ManagedCacheExtensions.cs" />
107+
<Compile Include="Git\GitAheadBehindStatus.cs" />
108+
<Compile Include="Git\Tasks\GitAheadBehindStatusTask.cs" />
107109
<Compile Include="Git\Tasks\GitLfsVersionTask.cs" />
108110
<Compile Include="Git\Tasks\GitVersionTask.cs" />
109111
<Compile Include="Git\ValidateGitInstallResult.cs" />
@@ -115,6 +117,7 @@
115117
<Compile Include="Application\ApplicationManagerBase.cs" />
116118
<Compile Include="Helpers\Constants.cs" />
117119
<Compile Include="Helpers\Validation.cs" />
120+
<Compile Include="OutputProcessors\GitAheadBehindStatusOutputProcessor.cs" />
118121
<Compile Include="OutputProcessors\LfsVersionOutputProcessor.cs" />
119122
<Compile Include="OutputProcessors\VersionOutputProcessor.cs" />
120123
<Compile Include="Helpers\TaskHelpers.cs" />
@@ -149,7 +152,6 @@
149152
<Compile Include="Metrics\UsageModel.cs" />
150153
<Compile Include="Metrics\UsageTracker.cs" />
151154
<Compile Include="Git\Tasks\GitLfsInstallTask.cs" />
152-
<Compile Include="Extensions\GitStatusExtensions.cs" />
153155
<Compile Include="Git\Tasks\GitRemoteChangeTask.cs" />
154156
<Compile Include="Git\Tasks\GitRemoveFromIndexTask.cs" />
155157
<Compile Include="Threading\IMainThreadSynchronizationContext.cs" />
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace GitHub.Unity
2+
{
3+
class GitAheadBehindStatusOutputProcessor : BaseOutputProcessor<GitAheadBehindStatus>
4+
{
5+
public override void LineReceived(string line)
6+
{
7+
if (line == null)
8+
{
9+
return;
10+
}
11+
12+
var proc = new LineParser(line);
13+
14+
var ahead = int.Parse(proc.ReadUntilWhitespace());
15+
var behind = int.Parse(proc.ReadToEnd());
16+
17+
RaiseOnEntry(new GitAheadBehindStatus(ahead, behind));
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)