-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Faster multiple file staging #629
Faster multiple file staging #629
Conversation
Absolutely wonderful! I’m out for Christmas but I will gladly review this when I’m back on the 27th. 🍻 |
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.
Looks pretty good to me. A few points to address but overall I'm excited about this 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.
Oops, meant to request 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.
Looks good! I'll give it a spin for performance soon and then merge it in.
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.
Sorry, just one last thing to fix. I think we need to be freeing that malloced region before this function returns and it doesn't have to be + 1
count worth of space.
The selectedFiles array would always be empty because the `else` should've been outside the `if (submodule)`
I've pushed the requested change and fixed a bug in the code that calls |
The speed boost is fantastic. Thanks for this! |
@lapfelix I ended up reverting this change unfortunately. There are some major issues with discarding selected files that need resolution. |
Oh no! Do you have any steps to reproduce the issue? |
Okay I see the linked issue |
Ya, my repro steps were just selecting a few files and hitting the delete key to discard. I had cases where it would not notify about the change, but I also noticed that sometimes it would discard things I didn't select, so it had to be reverted for that reason. |
|
||
NSError* error; | ||
if (![self discardAllChangesForFiles:selectedFiles resetIndex:NO error:&error]) { | ||
[self.repository notifyWorkingDirectoryChanged]; |
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 believe this was the issue around why it didn't notify when discarding files. This code would only notify on failures basically. The other issue where it would discard things I didn't select was the most concerning however and I'm not sure what the cause of that was.
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.
Ugh yeah the notifyWorkingDirectoryChanged
and makeFirstResponder
lines definitely shouldn't be in that if
.
I'll review the rest of the code and see if I can reproduce that otgher issue where more things were discarded than necessary.
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 really can't reproduce the other issue (with these lines placed at the right place). I wonder if it might be related to your other issue where the wrong files were discarded though. I'll revert my fix and see if I can make it happen like this.
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.
Okaaaaayyyy I've reproduced it. It's bad.
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.
Looks like the issue is in the call to the libgit2 function git_checkout_index
. Right before it's called, the repo is fine (the right files have been deleted) but it seems like it resets too many files.
Ya, perhaps it’s a bug on their end? We’ll have to update libgit at some point. |
@lucasderraugh Hmmmm I have a fix which is to remove the GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH option in |
@lucasderraugh I've opened a PR with the changes I'm testing: #639 |
Definitely want to know what that flag does. Thanks for looking into it though! |
One thing we could do to work around this apparent (?) bug is remove the flag and escape the paths we pass in so file names aren't recognized as match patterns. I've tried it and it works. I'll try it with filenames that might get recognized as match patterns before committing this change. |
I'll have to look up what this match pattern stuff means 😊. One other concern I have that I'd like to test out is what happens on failure? Previously just 1 file was skipped over, but in this case does every file fail to get merged? I'm thinking of the discard case where perhaps you have submodules and you try to discard them and a few other files but one thing fails so the entire discard fails. |
@lucasderraugh Submodules are still handled individually so if there's an error discarding a submodule, it will happen before we batch-process the files so we keep the same behaviour in this specific file. It will abort once it hits an error discarding a submodule. When discarding changes in multiple files (deleting them then doing a checkout), if there's an error when deleting the file (not sure how often this happens, but it could), it will stop deleting files and will abort, present an error and stay where it was (which means the files that were already successfully deleted will stay deleted). So in that case, we won't do the checkout for these already deleted files. If it successfully deletes the files and then fails when doing the batch-checkout, I'm not sure what will happen. I guess it will fail for all of them, yes. I haven't encountered that yet. |
* Improve performance when staging/unstaging multiple files at once * Optimize multiple files discarding * Run ClangFormat * Changes following PR feedback * Fix bug caused by bad merge and add comments The selectedFiles array would always be empty because the `else` should've been outside the `if (submodule)` * Correctly allocate and free multiple path strings
Staging/unstaging/discarding multiple files takes a long time. Seems to be O(N) where N is multiplied by 1-2 seconds, depending on the repo.
I fixed it by only calling
-[GCRepository writeRepositoryIndex:error:]
once when doing staging/discarding operations on multiple files by adding methods for these operations that take multiple files instead of one.I tested the changes in a big repository (with thousands of commits, ~50 branches and ~20-30 total submodules) and the time it takes to stage/unstage 19 files went from ~25.5 seconds to ~2.5 seconds. The more files are modified, the bigger the performance increase is.
I AGREE TO THE GITUP CONTRIBUTOR LICENSE AGREEMENT