-
Notifications
You must be signed in to change notification settings - Fork 12
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
Handle checking out a branch when that branch is already checked out #34
Comments
For extra helpful output with (Solution 1), it could be nice (but not essential) to output a WARNING message if (after fetching from the given remote, but before doing the checkout) we detect that:
(1) could be determined by scraping the output of (2) could be determined by checking the output of In the case of (2a), we could suggest doing:
In the case of (2b), we could suggest doing:
(However, I'm also fine waiting to add this extra outputs until we see that this actually bites someone in practice.) |
For the record, I am in favor of working in real local branches when a branch is specified in the externals configuration file.
Some notes / questions: Something easy to parse to check for tracking branches:
Do we ever want to attempt a merge? Is there any harm in running:
|
Thanks for your thoughts @gold2718 What's tricky here is that (1) Different people could have different expectations regarding the final state following running (2) Different people could have different expectations regarding what (if anything) is done to any local branches. @bandre-ucar has convinced me that it's probably best if we stick to the simplest, most consistent rules possible: This will help avoid surprises. Along those lines, I like @bandre-ucar 's simple-to-remember rule: When you run I would add a corollary of this rule: If two people run For this reason, I don't like the idea of just checking out an existing branch, which may be ahead of or behind the branch on the remote. I also don't like the idea of having This leaves the question of whether to create a tracking branch. Given all of my other arguments in this comment, I'd say no: Given my argument that we should never update local branches, the problem comes down to what happens when you rerun
Given my above arguments, the result of (3) should be that you're in detached head state, with a warning message issued. This state makes sense if you manually created the given tracking branch (presumably because you wanted to do some work on it). But for someone who didn't create the branch themselves, the warning message and resulting state will likely be confusing. For this reason, I'd vote for maintaining the current behavior of not creating tracking branches for you. That is, any time you run All that said: I'm open to being convinced that some other behavior would be better. |
Isn't that what documentation is for?
It seems to me that the simplest, most consistent action is the no-branch (detached head) action. Did I understand correctly? Is the simplest really best? What about the desired workflows? Maybe I'm misunderstanding you but it seems that according to your rules, if you:
then you are back where you were after step 1. Did I get that right? Would that not be surprising to users? Under your proposed rules, how do I create a branch or fork of a repo with some of the tags replaced with branches? Do I have to manually create local branches every time I clone the repo? |
@gold2718 I'll be honest, I'm struggling here myself. I was probably wrong to say "simplest", but I'll stand by "most consistent" as a goal, and I've been struggling to see how we can remain consistent if we sometimes create a local branch for people. Regarding this:
Sorry, I wasn't clear in my recent, long comment. I still stand by my initial request in this issue:
Regarding this:
I think you mean (for example) that you're creating a branch of CESM where (e.g.) CLM and MOSART point to branches. In this case, under my suggestions: You can clone the repo and use it (create a case, etc.) without creating local branches. But if you want to do further development (e.g., of CLM) in that new clone, then yes: you would need to manually create a local CLM branch. I think the critical questions to answer are these. I'm giving my thoughts, but I'm not claiming that my thoughts are the only ones that matter :-)
(2) seems like the critical piece here for allowing
I'd be okay with this solution as long as that last (aborting) piece is in place. I could even be convinced that it's better than my original suggestions. @gold2718 and @bandre-ucar what do you think about this? |
Short summary of my last post: I'd be fine with having A couple more thoughts:
|
Reviving an old discussion because some of my thoughts on #56 seem better suited in this ticket... reading through this thread, I agree with @billsacks that
It seems like there are several scenarios where the User requests a branch rather than a tag User creates local copy of branch and then reruns User creates a new branch locally but branch does not exist on remote User creates So of @gold2718 suggestions:
I agree with (1) and (2b). For (2a), the logic I would expect is
As a user, I would not expect this tool to change the state of the checkout if the local tracking branch is currently checked out or if I am already at a detached head with the sha of the remote branch. Note that if the local tracking branch is checked out at the correct sha but the working copy is not clean this should still trigger an abort -- it keeps with the stated goal of identical .cfg files producing identical results barring errors. If a user runs
|
Talking with @billsacks I realized that my previous comment is somewhat unclear and also very git-centric; to clarify, here is the decision tree I think
And most of the git concepts can be applied to svn as well
|
For the record: I'm happy with @mnlevy1981 's latest comment. The one thing I'm a little uncomfortable with is that it does NOT cleanly support the workflow of: You have a branch of cesm which has a |
I have one question about @mnlevy1981's decision tree.
I think my |
@gold2718 asked
If you are asking for specific git commands, then I don't know the answer. If you're asking a conceptual question, then I'll give you three scenarios based on the assumption that the cfg file looks like
Note that we've already checked that if
If we are in case (3) but the user has a branch
I'm not sure what you mean... if |
@mnlevy1981, thanks for the explanation. I did not follow your original logic correctly. |
Yeah, I was trying to present how I thought the code should handle branches (with no urgency; this issue seems to be low priority at the moment and I'm not trying to imply that should change). So I don't think you need a new issue for your edge case, this is probably the best place for that discussion. |
- Talk about this in the context of CTSM rather than CESM - Cut documentation on modifying a component, because we currently don't have a great workflow for doing this with components in git (due to ESMCI/manage_externals#34)
@ekluzek points out this is important for FATES. We should discuss a reasonable timeline for implementing it. |
In talking with @bandre-ucar he pointed out some things to consider in implementing the solution proposed in #34 (comment)
For the record, I'm still okay (I think) with @mnlevy1981 's proposed solution, but I'd like to think through @bandre-ucar 's points a little more. |
- Talk about this in the context of CTSM rather than CESM - Cut documentation on modifying a component, because we currently don't have a great workflow for doing this with components in git (due to ESMCI/manage_externals#34)
I imagine that some of the needs here can be implemented by modifying |
@johnpaulalex @jedwards4b @mnlevy1981 and I met to revive this issue. My understanding of the decisions is:
I think the rules we have specified result in behavior where, after running manage_externals, either (1) your locally-checked-out sha matches the head of the remote branch, or (2) an error was issued. I like that. (This seems consistent with the suggestions in #34 (comment) and #34 (comment)). In #34 (comment), @mnlevy1981 suggested that, if you are starting in detached head state at the correct sha, then you should end in detached head state, rather than checking out a local branch and getting it set to the correct sha in this case. I don't have strong feelings one way or the other on this point. But that logic of remaining in detached head state in this situation would support the scenario where the user isn't ready to push their local changes to the remote, yet wants manage_externals to help them track the remote. I'm not sure how often this will come up in practice. If we wanted to follow this, I think we'd end up with the rules:
|
Thanks Bill, this all seems right to me. I'll wait for Jim and Michael to chime in before looking into implementation. As for that final note about detached head, I'm a bit nervous because it means the same config lands you in two different end states depending on your start state. What if we instead have a --detached_head flag to unconditionally cause that end state? (aka reproduce the current behavior of the script, iiuc) And without the flag, we point you to the local branch w/o detached head. No strong feelings here either. |
Since detached head is the current behavior I think it might be better to add a flag for the branch w/o detached head --no-detached-head. |
@johnpaulalex - Good point that it might be confusing if the end state – at least in terms of whether you are in detached head state or on a branch – would depend on the starting state. I'm fine dropping the idea on those grounds. I think we should focus on specifying good default behavior for now, and we can come back to possible flags later. @jedwards4b - I wasn't clear whether your suggestion refers just to this case (where you are starting with a detached head) or more generally. My feeling is that this use of branches in manage_externals is relatively non-standard, so it's probably okay to introduce a behavior change. I'm fine with your suggestion of |
(Trying to swap this back into my head) To sum up, we currently do a git checkout $remote/$branch, and in some circumstances we want to do just a plain 'git checkout $branch' , yes? Where 'circumstances' are defined above - you don't have a conflicting local branch with the same name, and you're only fast-forwarding, at least. If that sounds right, I can start trying to code it up. |
@johnpaulalex thanks a lot. Yes, I agree with that high-order description, though I'll add that in what is probably the most common case - where someone is already on the correct branch and wants to stay on that branch - the new implementation will result in a no-op (though doing a git checkout $branch when you are already on $branch probably won't hurt). |
If I have (for example) a CESM repository that points to a git repo for CLM, and do the following:
From components/clm:
git checkout -b mybranch
Make some changes in components/clm
From components/clm:
git push -u origin mybranch
Change CESM.cfg to point to mybranch (modifying the repo_url and setting the branch appropriately)
Run checkout_externals
then I end up in detached head state in components/clm.
In fact, any time you run checkout_externals pointing to a branch, you'll end up in detached head state - though @bandre-ucar has convinced me that this is okay (and probably preferable) in the case where you weren't already on the given branch.
However, in this relatively common case where you're already on the given branch, I'd like to end up in a state where I'm still on that branch. There are issues with what to do if the branch on the remote is ahead or behind the local branch. But for starters, I think it would be very helpful to have the following special-purpose logic:
(Solution 1) If the cfg file specifies a branch, and (after fetching from the remote) the sha of the remote branch matches the currently-checked-out sha, then do nothing. (Can this be done by comparing
git rev-parse HEAD
withgit rev-parse remotename/branchname
?)I also like @bandre-ucar 's idea:
(Solution 2) If you give repo_url as "." for a git repository, then all operations will be done on local tags and branches.
However, I think that even if we have (Solution 2), I'd still like to have (Solution 1), because this will facilitate doing cross-component development on multiple machines.
The text was updated successfully, but these errors were encountered: