-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Refactor repository models (repository refactor part 1) #2008
Conversation
Refactor the constructor that took IGitService into LocalRepositoryModel where it was used.
Move GenerateUrl from LocalRepositoryModel to LinkCommandBase.
Codecov Report
@@ Coverage Diff @@
## master #2008 +/- ##
==========================================
- Coverage 40.67% 39.36% -1.31%
==========================================
Files 377 410 +33
Lines 16333 17572 +1239
Branches 2253 2422 +169
==========================================
+ Hits 6643 6918 +275
- Misses 9150 10117 +967
+ Partials 540 537 -3
|
Move LocalRepositoryModel construction tests to new home.
This property wasn't being used.
We Now only need the CreateLocalRepositoryModel(localPath) overload.
Previously the current branch was being read when CurrentBranch was fetched. This changes it to be read when the LocalRepositoryModel is created.
Remove redundant code and usings.
| /// <summary> | ||
| /// Gets the repository clone URL. | ||
| /// </summary> | ||
| public UriString CloneUrl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Future: should these properties be raising change notifications? If so, should other properties also be raising them (CurrentBranch for example).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should aim to get rid of the Refresh command so this model would be immutable after creation.
| /// <summary> | ||
| /// Gets an icon for the repository that displays its private and fork state. | ||
| /// </summary> | ||
| public Octicon Icon |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Future: move this out of the model: it's a view model-level reponsibility that only really applies to the repository list in Team Explorer.
src/GitHub.TeamFoundation.14/Services/LocalRepositoryModelFactory.cs
Outdated
Show resolved
Hide resolved
| { | ||
| var repo = ServiceProvider.TryGetService<IGitService>().GetRepository(path); | ||
| return new LocalRepositoryModel(repo.Info.WorkingDirectory.TrimEnd('\\'), GitService.GitServiceHelper); | ||
| return GitService.GitServiceHelper.CreateLocalRepositoryModel(repo.Info.WorkingDirectory.TrimEnd('\\')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is TrimEnd needed here? If so, should that logic be put into CreateLocalRepositoryModel?
Previously CurrentBranch was created as the property was read. We now need a way to refresh it.
jcansdale
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this logic be part of RepositoryViewModel?
jcansdale
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this logic be part of RepositoryViewModel?
jcansdale
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this logic be part of RepositoryViewModel?
It appears VSGitExt.ActiveRepositoriesChanged is fired before the local repository has actually changed its branch. This means we can't read the branch information immediately!
jcansdale
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments about removing CurrentBranch.
| Name = name, | ||
| Icon = Octicon.repo | ||
| }; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is currently being refreshed before the branch has actually changed. :-(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is now a CreateCurrentBranchModel command instead of the CurrentBranch property. We'll still need to be careful about calling it too soon.
Remove the ILocalRepositoryModel.CurrentBranch property and explicitly call IGitService.CreateCurrentBranchModel instead. Fix all the broken tests.
Convert GetPullRequestForCurrentBranch to return (string owner, int number). This allows the tuple to be compared directly.
We can now use GitService as a LocalRepositoryMode factory.
3abf4d6 to
db41ef9
Compare
Be explicit about what it does.
grokys
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! a couple of nits and questions but going to approve anyway.
| /// Creates a new branch model for the current branch. | ||
| /// </summary> | ||
| /// <param name="model">The <see cref="ILocalRepositoryModel" /> to create a current branch model for.</param> | ||
| /// <returns>A new branch model.</returns> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might be less verbose if it were simply called GetBranch: I'd tend to think of it more as a method to get the state of an ILocalRepositoryModel than a factory method. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could change it to GetBranch(string name = "HEAD"). Do you think that would make sense? Otherwise we'd probably need to qualify it with GetHeadBranch or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think that would make sense.
| else if (newRepositoryPath != null) | ||
| { | ||
| log.Debug("Fire StatusChanged event when PullRequest changes for ActiveRepository"); | ||
| log.Debug("Fire StatusChanged event when on a repository and anything changes"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reads a bit yoda-y ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if that's a feature? 😉
I'll change it to:
"Fire StatusChanged event if anything about an active repository has changed"
| log.Debug("Fire StatusChanged event when BranchName changes for ActiveRepository"); | ||
| StatusChanged?.Invoke(this, EventArgs.Empty); | ||
| } | ||
| else if (newHeadSha != headSha) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So StatusChanged is no longer firing when HEAD changes? Is this because it wasn't working before anyway? (i.e. it was firing before the actual change)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now either a repository change event will be fired when we set ActiveRepository or a StatusChanged will be fired if we think anything about the active repository might have changed (including when the HEAD changed).
This is actually similar to what was happening before because newPullRequest != pullRequest was always returning true (the tuple comparison issue).
I have changed it so that if we're not on a repository, no StatusChanged event will fire.
|
Merged as part of #2028. |

This is the first iteration of refactoring
LocalRepositoryModelandGitService(see #2007).I've focused on moving the code to where is should be, with as few functional changes as possible. There is more to do, but I think this makes sense as a chunk.
ILocalRepositoryModel.CurrentBranchproperty withIGitService.CreateCurrentBranchModel(model)methodLocalRepositoryModeltoGitService.CreateLocalRepositoryModelLocalRepositoryModel.GenerateUrltoLinkCommandBaseLocalReposotoryModel.RefreshtoGitService.RefreshCloneUrl(this will be removed in Remove repository responsibilities from TeamExplorerServiceHolder (repository refactor part 2) #2025)LocalRepositoryModelFactory(we can useGitServiceinstead)LocalRepositoryModel.HeadShapropertyThe most significant functional change was to replace the
LocalRepositoryModel.CurrentBranchproperty with aGitService.CreateCurrentBranchModel(repositoryModel)method.This was necessary because the
IGitExt.ActiveRepositoriesproperty changed event fires before the current branch is actually changed. If we populateLocalRepositoryModel.CurrentBranchwhen the model is created,CurrentBranchends up with information about the previous branch.By deferring creation of the current branch model, we can populate it when the branch has actually changed and only create the branch model when it's actually required (the property change event can fire a lot).
Bugs to fix
The
ActiveRepositoriesChangedevent fires before the branch has changed on the local repositoryVisualStudio/src/GitHub.Exports/Services/GitService.cs
Line 52 in 47430fd
Tuples aren't comparable so this was always coming back
falseVisualStudio/src/GitHub.App/Services/TeamExplorerContext.cs
Line 146 in 47430fd
Still to do
Now the junk has been removed from
LocalReposotoryModel, we can decide how we want the models to look!ITeamExploerContextinstead ofITeamExplorerServiceHolder(done in Remove repository responsibilities from TeamExplorerServiceHolder (repository refactor part 2) #2025)BranchModelto make it an actual modelRemoteRepositoryModel.OwnerAccountto be aActorModelinstead of anIAccount(@grokys)Octiconfrom the model Refactor repository models (repository refactor part 1) #2008 (comment)BranchModelis being passed a repository constructed from a URL rather then a local pathVisualStudio/src/GitHub.Exports/Models/BranchModel.cs
Line 36 in e3f8114
LocalRepositoryModel.GetHashCodeandEqualsshould use consistent comparisonsVisualStudio/src/GitHub.Exports/Models/LocalRepositoryModel.cs
Line 36 in e3f8114
VisualStudio/src/GitHub.Exports/Models/LocalRepositoryModel.cs
Line 55 in e3f8114
OrdinalIgnoreCaseorInvariantCultureIgnoreCasemaybe?