-
Notifications
You must be signed in to change notification settings - Fork 899
Update working directory on Checkout #233
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
Conversation
I like it. 😸 Have you thought about progress reporting? Libgit2 is moving to just callbacks for this; how do you envision the user passing in a delegate? (Obviously you wouldn't be able to write this until that PR is merged, but it bears thinking about.) I ask because I've heard some good arguments against optional method parameters. What do you think about the proposal over on #223 for exposing operations with lots of optional parameters as separate classes? |
Assert.False(repo.Index.RetrieveStatus().IsDirty); | ||
|
||
Branch test = repo.Checkout(tagName); | ||
Assert.False(repo.Info.IsHeadDetached); |
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.
Hmmm. Something may be fishy here. Checking a tag out should detach the HEAD.
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.
Thanks - fixed this test.
@jamill Thanks a lot for contributing this. This is very promising!
Have you tried the following?:
|
I have - However, unsetting this flag also results in files that exist in the current branch but that are not present in the checkout target not being removed. That is, if a.txt exist in branchA but not in branchB, then a.txt will not get removed when switching from branchA to branchB if this flag is not set. |
@ben @nulltoken Thanks for the review!
Yes. I wouldn't expect it to be very disruptive to the current API. I was thinking that I would add another parameter for the delegate. I think it also wouldn't be too bad to not use optional parameters here, and just have a single overload: Branch.cs:
Repository.cs:
In this case, CheckoutOptions is always a required parameter, but I don't think it adds to much complexity to the simple case (i.e. passing CheckoutOptions.None)... |
Dammit You're right! This would require a ton of failing test to be built, but I think I might solve this with a diff involving the old Tree, the Index (updated from the target Tree) and the workdir. @arrbee Have you got some code up you sleeve or can I give a try at this one? |
@nulltoken Interesting. This does seem like a design flaw in the checkout code. Simply doing a I don't have any code sitting around -- if you want to look at it, that sounds great! I'm guessing you'll need to rearrange things so that both |
@arrbee Indeed, I was under the impression that this would require some interesting refactoring ;-) |
👍 if you make that |
One weird thing is that this is not the same callback as the I have updated the PR and moved the Checkout tests into their own fixture. |
I have updated the PR to react to the newly exposed callbacks for checkout. Here is output from an example program calling checkout on a repository cloned from http://github.com/libgit2/TestGitRepository (from checkout master from first-merge):
With the following Checkout progress handler:
@ben are the duplicate 7/7 steps expected? the path string in this case in |
@jamill It's a small fencepost bug in libgit2. The initial |
hmm.. not sure about the build errors:
and:
I do not see them locally, and this is not really a code path that I modified. Maybe an interaction with a transient network connection issue during fetch that is not handled appropriately (guessing)? |
@jamill I just also hit the same error through the TeamCity CI server against 46548c5 (cf. log)
|
I would have to investigate this some more... I suspect we are hitting some other intermittent error, and then when LibGit2Sharp calls to get the last error, the error has been cleared (or not set?)... @nulltoken : I know there are some changes going on in libgit2 regarding checkout flags (libgit2/libgit2#1016). As it appears that the main change(s) will be the flags that are exposed (and we might have to switch which checkout_* method is called), what are your thoughts on bringing in this PR sooner? As I don't believe the basic flow of the checkout would change, and there are other PR's that are waiting on this on (#223), would it be reasonable to go ahead and bring this in? Unless there are other outstanding issues to address with this PR... |
@jamill Dammit! I was under the impression that you were waiting after the checkout fix. Sorry for this. I've slightly rewritten the history (cf. https://github.com/nulltoken/libgit2sharp/commits/checkout_workdir_rebased) to get rid of the review commits and get a coherent commit timeline. The I haven't had the time to perform a full review yet. I'll tackle this within the following hours. |
Not a problem - I was waiting to complete the Fetch update more than anything. Incorporating this PR would be helpful for me, as long as it makes sense (with the understanding that there will be reaction to updates in libgit2). If this is a burden on you, we can wait, but I wanted to at least get your thoughts on this.
👍 |
@jamill This looks pretty nice and ready tio be merged. One last nitpick: could you please make sure that we do not assert that an untracked file is being overwritten in the tests? This way, we'll avoid having passing tests today that will fail when libgit2/libgit2#1016 land. |
@nulltoken Thank you for the review! There are not currently any tests that assert that untracked files are being overwritten. All of the tests either deal with:
I did update one test ( |
Perfect! 👍
I'd only squash jamill/libgit2sharp@63fbb4c into jamill/libgit2sharp@c3d5d1d |
I hit an issue with the checkout tests when run against the 64-bit version and the 3.5 CLR that I am working on tracking down. |
Fixed the issue with the tests failing with the 64-bit 2.0 xunit test runner. The issue was with the checkout progress callback containing a custom marshaler - it appears that this causes some issues. I think I have seen similar issues discussed here in the past. The fix is to have the callback method take a pointer to the string, and then manually marshal the string. |
Awesome job, and .... merged in 💖 |
This is an initial implementation of updating the working directory as part of Checkout (using
git_checkout_head
)I am labeling this as a work in progress because I do not include any progress reporting (until the progress callbacks are in libgit2 and make it to LibGit2Sharp).
As there is not support for merge in libgit2, I only allow checking out the working directory if there are no changes in the current branch (staged, unstages, or untracked) by default. I do support taking a
Force
option, but it behaves slightly differently fromgit checkout -f
on the command line (see below).CheckoutOptions
I expose a bit flag enum
CheckoutOptions
on theCheckout()
API. Currently, this only exposes a single flag (Force
) - but once more checkout behavior is supported in libgit2 we can add extra flags here (Merge
,AutoMerge
, etc). One thing I am not sure of is how closely this particular API should match options exposed on the Git command line vs the flexibility exposed by libgit2.As it is,
CheckoutOptions.Force
does not completly mimicgit checkout -f branch
, asgit_checkout_head
currently resets the whole working directory, whilegit checkout -f
leaves untracked files. There is a small discussion on libgit2 checkout options at libgit2/libgit2#986Any feedback is appreciated. I will close Issue #227, and continue the discussion on this thread.