Skip to content

Feature. Quick View: Show history of file #573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

lolgear
Copy link
Contributor

@lolgear lolgear commented Aug 30, 2019

  • Quick View: menu entry "Show history of file" has been added.
  • Add SearchResultsCommitListView to QuickView. (Delayed)
  • Tests required.
  • Add QuickViewModel.
  • Add QuickView Window. (Delayed)
  • Fix QuickView animations.
  • Fix assert(commit)
  • Set minimum deployment target to macOS 10.11. ( or add backward compatibility for constraints ).

Fixed

Addressed to

Issues

  • Unknown assert(commit) state.
    On old commits Show file history works pretty well.
    On recent commits it fails at assert(commit) for unknown reason.
Example Git SHA Result
Good GitUp bca272f List of commits
Bad GitUp 9128e38 assert(commit)

Discussions
Behavior of commits list.
Current left view on QuickView is CommitListViewController. We should discuss a behavior of this controller.

Should we hide it until person clicks Show file history?
Should we animate its appearance? ( it is hard to do in case of AutoresizingMask and NSLayoutConstraint friendship ).
Should we separate QuickView and HistoryOfFileView?
Should we add HistoryOfFileView on QuickView?
When should we remove HistoryOfFileView?

@lolgear
Copy link
Contributor Author

lolgear commented Sep 9, 2019

It is too slow now. It seems that my approach to gather history commits is incorrect.
I would like to request a code review from @swisspol @lucasderraugh @zwaldowski.

Statistics
I've tested it on my work repository.

> du -h .git
117M	.git

commits: 6011
local branches: 24
remote branches: 17

Benchmarks

Mode Time (ms)
Debug 8580
Profiling 450

Improvements in UI
I would like to change UI by adding GICommitList to QuickView ( as it is done in map view ) to search files paths or to drag them from list in QuickView and to drop them to search files list / commits list.

What do you think?

@lolgear
Copy link
Contributor Author

lolgear commented Sep 14, 2019

Maybe this PR also should contain option from #383

@lolgear
Copy link
Contributor Author

lolgear commented Sep 15, 2019

@lucasderraugh
I suppose that this implementation also should split responsibilities of Document. It should add QuickViewModel with all related ivars from Document.

@lucasderraugh
Copy link
Collaborator

Running this from Xcode at the moment simply aborts in debug:

#2	0x00007fff785df6a6 in abort ()
#3	0x00000001014a5194 in -[XLFacility(Logging) _logMessage:withTag:level:callstack:metadata:] at /Users/lucasderraugh/Developer/GitUp/GitUpKit/Third-Party/XLFacility/XLFacility/Core/XLFacility.m:233
#4	0x00000001014a788d in -[XLFacility(Logging) logMessageWithTag:level:format:] at /Users/lucasderraugh/Developer/GitUp/GitUpKit/Third-Party/XLFacility/XLFacility/Core/XLFacility.m:316
#5	0x0000000101188fd8 in -[GCLiveRepository resumeHistoryUpdates] at /Users/lucasderraugh/Developer/GitUp/GitUpKit/Core/GCLiveRepository.m:383
#6	0x000000010000c88e in -[QuickViewModel exit] at /Users/lucasderraugh/Developer/GitUp/GitUp/Application/QuickViewModel.m:115
#7	0x000000010000b91c in -[QuickViewModel enterWithHistoryCommit:commitList:onResult:] at /Users/lucasderraugh/Developer/GitUp/GitUp/Application/QuickViewModel.m:83
#8	0x0000000100051fc4 in -[Document _enterQuickViewWithHistoryCommit:commitList:] at /Users/lucasderraugh/Developer/GitUp/GitUp/Application/Document.m:935
#9	0x0000000100060948 in -[Document mapViewController:quickViewCommit:] at /Users/lucasderraugh/Developer/GitUp/GitUp/Application/Document.m:1393
#10	0x0000000101420529 in -[GIMapViewController quickViewSelectedCommit:] at /Users/lucasderraugh/Developer/GitUp/GitUpKit/Views/GIMapViewController.m:801
#11	0x00007fff49eca644 in -[NSApplication(NSResponder) sendAction:to:from:] ()
#12	0x00000001014160e0 in -[GIMapViewController keyDown:] at /Users/lucasderraugh/Developer/GitUp/GitUpKit/Views/GIMapViewController.m:556

@lucasderraugh
Copy link
Collaborator

Not sure what I'm expected to be seeing here, but everything I look at just seems to be empty space on the left.
Screen Shot 2019-09-18 at 10 14 52 AM

@lolgear
Copy link
Contributor Author

lolgear commented Sep 18, 2019

@lucasderraugh If latest commit fixed abort() you mentioned above, please, look at assert(commit) message.

For example, if you take commit at master branch bca272fc9c81a2f3c5f4c21e65b9d309ddfef7d7 and look at Debug.xcconfig, it works pretty well.
But sometimes it fails on assert(commit);

@lucasderraugh
Copy link
Collaborator

lucasderraugh commented Sep 18, 2019

Your latest commit fixed the assertion, but I just don't see anything other than empty space. Every commit in the map view looks like the image I posted above when I hit the spacebar to go into one.

@lolgear
Copy link
Contributor Author

lolgear commented Sep 18, 2019

@lucasderraugh
Sure. Click on gear button near file path and choose "Show file history".

@lucasderraugh
Copy link
Collaborator

Ok, well now I'm just hitting the assert(commit) you mentioned. Can we please reserve PRs for mostly working implementations, it's a lot of work to go back and forth on PRs when I assume they're done and in a state almost ready to be merged. If you want to discuss beforehand, let's try to leave that to issues.

@lolgear
Copy link
Contributor Author

lolgear commented Sep 18, 2019

@lucasderraugh
Hm.. Ok.
But this assert(commit) is coming from GitUpKit <-> libgit2 where I don't have enough expertise.
Some old commits ( example above ) work perfectly with this feature.

@lucasderraugh
Copy link
Collaborator

lucasderraugh commented Sep 18, 2019

Ok, just please state all the issues up front so I’m not debugging for myself. We can work through these but I have to know what doesn’t work beforehand.

@lucasderraugh
Copy link
Collaborator

lucasderraugh commented Sep 18, 2019

If I go to bca272f and use the file history on Debug.xcconfig, it would appear that it picks up commits that don't affect Debug.xcconfig. It picks up ccd76bb as a commit that changed that file, but it doesn't appear in the diff. I will finally have some time to myself this coming weekend, so I'll try and help debug what we can do here.

Some side notes:

  • I don't like the fact that it shows all the changes in the previous commits (files that aren't the one I'm looking up history for).
  • The left view (initially empty) shouldn't be visible until I go into the "Show file history..." mode.
  • Perhaps we should consider it a different view altogether. Then we could make a view that simply has the history on left and file contents on the right.

@lolgear
Copy link
Contributor Author

lolgear commented Sep 18, 2019

@lucasderraugh
By extending QuickView we can easily bring this functionality to user.
By adding new view (FileHistoryView or HistoryOfFileView) we simplify interface for user, but not user's workflow. He still needs to open some view with file path.

@lucasderraugh
Copy link
Collaborator

I don’t want a new window, just a different view perhaps. Though this can get confusing with having 2 layers deep of 1Up.

@lolgear
Copy link
Contributor Author

lolgear commented Sep 21, 2019

@lucasderraugh Could we also move to NSLayoutConstraints instead of plain views and Autoresizing masks?

@lolgear
Copy link
Contributor Author

lolgear commented Sep 22, 2019

@lucasderraugh Check it.
I hope it is done. I suppose, that commit = NULL; is typo. Not sure yet.

@lolgear
Copy link
Contributor Author

lolgear commented Sep 22, 2019

@lucasderraugh Fixed finally, I hope...
Could you have a look?

@lolgear
Copy link
Contributor Author

lolgear commented Sep 23, 2019

@lucasderraugh
Also, in current implementation, there is no need to keep QuickViewController in _ivar in Document. Everything is incapsulated in QuickViewModel. Maybe it is better to create controller each time user press space?
It will eliminate errors such as improper commits retains. (Which I've caught earlier).

I suggest to add method to ViewController -immerseViewController:(ViewController *) inView:(View *)view which will add controller as child and set all constraints to edges of parent view.

@lolgear
Copy link
Contributor Author

lolgear commented Oct 5, 2019

@lucasderraugh
Could you check latest commits?

@lucasderraugh
Copy link
Collaborator

What's the current status of this PR? Were all the apparent issues addressed?

@lolgear
Copy link
Contributor Author

lolgear commented Dec 29, 2019 via email

@lolgear
Copy link
Contributor Author

lolgear commented Jan 7, 2020

@lucasderraugh
Oh, I just have fixed annoying issue with ignored commits.
As a roadmap for this issue I would like to rewrite if pyramid in lookup history as state machine later (after merging).

@lolgear
Copy link
Contributor Author

lolgear commented Jan 16, 2020

Ready?

@lolgear lolgear requested a review from lucasderraugh January 16, 2020 14:52
@lolgear
Copy link
Contributor Author

lolgear commented Feb 7, 2020

@lucasderraugh Go-go-go!

Copy link
Collaborator

@lucasderraugh lucasderraugh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Things to address. Also, we would need some way of hiding the history after it's been shown.

@@ -338,7 +338,9 @@ - (void)windowControllerDidLoadNib:(NSWindowController*)windowController {
_searchResultsViewController.emptyLabel = NSLocalizedString(@"No Results", nil);
[_searchControllerView replaceWithView:_searchResultsViewController.view];

_quickViewController = [[GIQuickViewController alloc] initWithRepository:_repository];
_quickViewModel = [[QuickViewModel new] configuredWithRepository:_repository];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this an alloc init. I don't want new in this codebase lol. Make the initializer take the repository and don't have a separate config method.

Comment on lines 1456 to 1471
// static GICommitListViewController *theViewController = nil;
// if (theViewController != nil) {
// [_windowController.contentViewController dismissViewController:theViewController];
// }
// GICommitListViewController *viewController = [[GICommitListViewController alloc] init];
// viewController.results = commitsList;
// viewController.selectedCommit = commitsList.firstObject;
// theViewController = viewController;
// _searchResultsViewController.results = commitsList;
// _searchResultsViewController.selectedResult = commitsList.firstObject;
//
// if (_searchView.superview == nil) {
// [self _addSideView:_searchView withIdentifier:kSideViewIdentifier_Search completion:NULL];
// }
// [_mainWindow makeFirstResponder:theViewController.preferredFirstResponder];
// [_windowController.contentViewController presentViewControllerAsSheet:theViewController];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

???

@@ -16,7 +16,18 @@
#import "GIViewController.h"

@class GCHistoryCommit;
@class GCCommit;
@protocol GIQuickViewController__Delegate__Intentions
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use underscores. End with "Delegate" if that's what it is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lucasderraugh

GIQuickViewControllerIntentionsDelegate
or
GIQuickViewControllerDelegate
?

Comment on lines 267 to 269
@dynamic commit;
@dynamic delegate;
@dynamic list;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aren't dynamic...you are implementing the setters but not the getters and they will crash upon access. Implement the getters if it's going to be a property. Otherwise implement them as methods with setters only. What would happen if you called the getter?

if (paths.count == 0) {
return @[];
}
// GCHistory *history = [self.repository loadHistoryUsingSorting:kGCHistorySorting_ReverseChronological error:error];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove?

[commits addObject:newCommit];
[newCommit release];
commit = NULL;
// commit = NULL; // well, if we are here, we should terminate for-loop (count = git_commit_parentcount(commit))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't leave commented out code. It should either be there with some action to take in the future or it shouldn't. There's no way to take further action on this.

Comment on lines 1254 to 1258
// if (0 && (status == GIT_OK)) {
// printf("here: %s\n", git_commit_summary(commit));
// git_commit_free(commit);
// continue;
// }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Comment on lines 104 to 106
- (instancetype)followRenames:(BOOL)followRenames;
- (instancetype)includeMerges:(BOOL)includeMerges;
- (instancetype)shouldIteroverWhenObjectNotFoundInTreeEntryByPath:(BOOL)shouldIteroverWhenObjectNotFoundInTreeEntryByPath;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aren't initializers...you can't treat them as such. They need to follow init conventions if they're to initialize an object.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lucasderraugh
Do you really want all of them in one initializer? I remember the longest initializer ever in, well, 100 words?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They don't need to be 1, but they need to follow standard Obj-C conventions of instance type instance methods that initialize objects need to start with init and they need to call super init. Otherwise you never initialized the object.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+alloc return instancetype. If you invoke any property, say, [[UIViewController alloc] view], you will catch crash or even undefined behavior.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that. My point is that generally speaking in Obj-C we don't return instancetype unless we're creating a new instance. Here, you aren't doing that. You're mutating the existing instance and then returning it, which is very unexpected. I can't think of anything in Foundation or AppKit that would work this way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lucasderraugh Yes, we could use struct with flags, it is more appropriate for ObjC since it doesn't have convenient alternatives ( no, NS_OPTIONS are not convenient ). But should we?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lucasderraugh Or we could add NSCopying and create new objects in these methods.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please delete these.

cleanup:
git_revwalk_free(walker);
free(fileName);
return [commits autorelease];
}

- (NSArray*)lookupCommitsForFile:(NSString*)path followRenames:(BOOL)follow error:(NSError**)error {
return [self lookupCommitsForFile:path options:[[GCRepositoryHistoryFileOptions new] followRenames:follow] error:error];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, alloc] initWith...]

}

#pragma mark - Initialization
- (instancetype)initWithFollowRenames:(BOOL)followRenames includeMerges:(BOOL)includeMerges shouldIteroverWhenObjectNotFoundInTreeEntryByPath:(BOOL)shouldIteroverWhenObjectNotFoundInTreeEntryByPath {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Iterover isn't a word.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GIT_ITEROVER

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldStopWhenObjectNotFoundInTreeEntryByPath

?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guess it's fine then.

@lolgear
Copy link
Contributor Author

lolgear commented Feb 17, 2020

@lucasderraugh Go-go-go? ( No, objective-c, but go! ) :)

@lolgear
Copy link
Contributor Author

lolgear commented May 16, 2021

I did it!
Carefully rebase all commits onto old master and then merge current master.

@lucasderraugh
Copy link
Collaborator

Just FYI, I still intend to get this PR into next release. Going to give feedback on your other PRs first.

@lolgear lolgear changed the title [Feature] Quick View: Show history of file Feature. Quick View: Show history of file Oct 13, 2021
@YarikArsenkinDrest
Copy link

Will we get this PR in the next release as well? 😍

@lucasderraugh
Copy link
Collaborator

lucasderraugh commented May 25, 2022

@lolgear I'm hitting a crash (abort statement) reliably when simply holding the down arrow key when I have the history view open. My repro commit is opening commit a502be4, then getting history on Document.m and start from the top item in the list selected and hold the down arrow.

It's the same one I hit in my comment back here Sep 18, 2019

GitUp-2022-05-24-213724.ips.zip

Copy link
Collaborator

@lucasderraugh lucasderraugh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to address abort case being hit before we can merge into production.

@lolgear
Copy link
Contributor Author

lolgear commented May 25, 2022

@lucasderraugh
Let's merge PR with libgit2 1.3.0 before this PR.
I would like to know if this case appears in libgit2 1.3.0.

@lolgear
Copy link
Contributor Author

lolgear commented May 26, 2022

@lucasderraugh
I checked this case.
It exists in "Debug Configuration" in master branch also. So, maybe it is incorrect algorithm on our side OR a bug in old libgit2.

@lucasderraugh
Copy link
Collaborator

How are you reproducing the issue in master?

@lolgear
Copy link
Contributor Author

lolgear commented Aug 21, 2022

How are you reproducing the issue in master?

Run debug build.
This issue is related to Debug assert that is disabled in Release build.

@lucasderraugh
Copy link
Collaborator

I don't hit the same assert that I hit when running the history though.

@lolgear
Copy link
Contributor Author

lolgear commented Aug 21, 2022

@lucasderraugh
Let's try to adjust this PR to latest master first.
I checked it before merging new version of libgit2 into master.

@lolgear lolgear force-pushed the quick_view_show_history_of_file branch from a502be4 to 26ce6ff Compare August 21, 2022 22:01
…n added.

kit: view controllers quick view contextual menu entry show file history has been added.

application: document quick view delegate has been adopted.

kit: quick view delegate protocol has been changed to match history commits.

application: document delegate for quick view has been set.

application: document show selected commits list in search view has been mocked up.

kit: views quick view commits list has been added.

application: document quick view with commits list have has been added.

application: quick view model has been introduced.

application: quick view model paging and moving have been fixed.

application: document quick view model has been adopted.

application: quick view model cleanup on reentering enter state.

kit: quick view controller first attempt to show git history of file has been completed.

application: document updating toolbar on reentering enter state of quick view has been added.

application: quick view model selected commit setter has been added.

project: quick view model has been added on application level.

application: document toolbar sync in quick view has been fixed.

kit: quick view controller delegate has been extended by did select commit method.

application: quick view model guards against history updates suspended semaphore has been added.

kit: views quick view animation has been added.

kit: history lookup commits for file for loop null guard has been added.

kit: views quick view cleanup.

kit: components commit list view controller storage modifiers has been changed.

kit: history lookup commits for file retain commit has been added.

kit: views quick view cleanup.

kit: quick view controller set commit equality guards have been added.

kit: repository history file options have been added.

kit: repository history file options have been updated.

kit: repository history lookup commits for file parent and child trees have been swapped.

kit: views quick view controller with commits list left view layout backward compatibility has been added.

kit: cleanup.

application: cleanup.

kit: quick view controller possible fix for corrupted layout.

kit: quick view set commit guards have been changed.

kit: quick view hide file history variant has been added.

document: quick view controller delegate protocol has been updated.

kit: quick view layout constraints have been possibly fixed.

kit: extensions nsview embedding has been added.

kit: quick view layout has been changed to constraints.

kit: quick view controller has been fixed.

kit: xibs quick view controller has been fixed.

kit: extensions view embedding has been cleaned up.

kit: core gchistory file options have been cleaned up.

kit: quick view controller with commits list has been extracted.

kit: public headers have been updated.
@lolgear lolgear force-pushed the quick_view_show_history_of_file branch from 26ce6ff to 6d73e98 Compare August 21, 2022 22:17
@lolgear
Copy link
Contributor Author

lolgear commented Aug 21, 2022

Very good, I finally rebased branch onto current master.
Now we can check if it works.

@lolgear
Copy link
Contributor Author

lolgear commented Sep 25, 2022

@lucasderraugh
Can you check it?

@hovsater
Copy link

Would love to get this in. 🙏 @lolgear have been maintaining this pull request since 2019. @lucasderraugh have you had a chance to look at this yet? 🙂

@lucasderraugh
Copy link
Collaborator

Just pushed 1.3.3 to the continuous release channel. Please verify if the assertion is still hit, as this is the reason it was never merged originally.

If you believe the assert isn't hit anymore, then please let me know and I'll check the latest, but I don't have time to debug every commit change.

@soberman
Copy link

I would absolutely love to have this merged 😍

@NikKovIos
Copy link
Contributor

Should we hide it until person clicks Show file history? - hell yes!

@lolgear
Copy link
Contributor Author

lolgear commented Sep 11, 2023

Another year without this feature...

@lucasderraugh
Copy link
Collaborator

As I said in my previous comment, if the assert is no longer hit then please let me know so I should go through and check it again. But the last changes we made I spend a solid week fixing the fallout and there is still some unresolved.

I take seriously that I don't want to create regressions in this app as many have come to rely on it (including myself) and frankly it's not my job to make any PR that comes my way shippable.

@NikKovIos
Copy link
Contributor

@lucasderraugh what do you think about making unit tests in order to now regress the app?

@lucasderraugh
Copy link
Collaborator

We have unit tests, just didn't cover all the cases (and I resolved many issues to get the existing ones passing). When I resolve the new hit issues I intend to make tests around that.

@lolgear
Copy link
Contributor Author

lolgear commented Nov 10, 2023

4 years and going...

@lucasderraugh
Copy link
Collaborator

Did you fix the assert (I ask for the 3rd time) @lolgear

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

6 participants