To Junio in particular: See the very bottom of this email. On Mon, Mar 1, 2010 at 04:50, Markus Elfring <Markus.Elfring@xxxxxx> wrote: >> - The branch you happen to have checked out was 'next', but the solution >> is a bugfix, and should go to 'maint'. >> >> Now, at this point, you want to checkout 'maint' without losing your local >> change. The paths you touched with your quick fix are often not different >> between the two branches, and "checkout maint" will checkout the branch >> while keeping your local changes intact. > > Does the wording in the manual fit to the mentioned software development practice? > > "When <paths> are not given, this command switches branches by updating the > index, working tree, and HEAD to reflect the specified branch." > > I see a need for further clarifications of the involved details. Junio pointed out that the documentation is currently lacking: [Unfortunately,] I don't see anything that states clearly that "checkout" is designed to carry your local changes across in any documentation (I gave a cursory look to the user manual, tutorial and checkout manual page). Probably "git checkout --help" needs a "Switching branches" section, just like the planned enhancement for "Detached HEAD" section. In other words, the documentation NEEDS to be updated to include the explanation and rationale that Junio also supplied: Checking out another branch (branch switching) is designed to carry your local modification across with you. This is to allow you to start working on something, realize that your changes are better suited for another branch, and at that point after the fact "git checkout" that other branch, while keeping what you have done so far. If the original branch you started your work from and the branch you are checking out have different contents in files you have changed (aka "your changes conflict at the paths level"), without -m option, "git checkout" refuses to check out the other branch, because it will need a three-way merge to carry your changes forward, and you might not be prepared to resolve conflicts resulting from such a merge. In practice, however, your changes often don't conflict with the changes between the branches at the paths level, and "git checkout" lets you carry your local changes across just fine. I'd say this is the majority of the case especially for experienced git users, as they tend to commit in smaller and more logical units than those from other SCM background. and Junio expanded on this later: It is important to understand that a local change does not belong to your current branch (it does not belong to _any_ branch). It belongs to you, and you can take it around while switching between branches. And that is a big time-saving feature. This lets you work like this: - You are reading a mailing list message that asks for help, and you know the solution---you can give the help real quick. - You hack in whatever branch that happen to be checked out. The change is perfect, it works. - The branch you happen to have checked out was 'next', but the solution is a bugfix, and should go to 'maint'. Now, at this point, you want to checkout 'maint' without losing your local change. The paths you touched with your quick fix are often not different between the two branches, and "checkout maint" will checkout the branch while keeping your local changes intact. All that is left for you to do is to run another round of test to make sure that your fix didn't depend on anything not in 'maint' and commit the change with appropriate log message, and then you can go back to whatever you were doing with "checkout next". When the change involves paths that were touched between 'maint' and 'next', of course you won't be able to switch without merging the local change to the difference between 'next' and 'maint'. There are a few workflows to deal with such a case, and the easiest is "checkout -m", if you are confident that you can resolve it. In a case where "checkout -m" would result in a conflict too big to resolve, the original fix you made would not be applicable to 'maint' (iow, you should have solved it differently starting from 'maint'), and you may end up doing "reset --hard" and start from scratch, but that is a rare worst case. I said it is rare, because you would notice, while doing the "quick fix" based on 'next' codebase, that the code you are touching have changed since 'maint' and won't be applicable to its final destination (by that time you know you are "fixing"), and you won't waste too much time continuing to work in a checkout of 'next'. I think it would be a great contribution if you could clean up Junio's explanation and submit a patch that includes it in the documentation for "git checkout". > - Would it be useful if it will become configurable if the corresponding > contents will also be automatically restored by a checkout? >From what you've said, I think you essentially want to implement "git checkout" with something like the following (this hack is **not** meant as a solution; it is only meant to illustrate what I think is Markus Elfring's desire): # Utility: get_stash_id() { local branch=$(git rev-parse --symbolic-full-name HEAD) [ $branch = HEAD ] && return 1 # don't stash for detached HEAD echo -n "$branch" | md5sum | awk -F" " '{print $1}' } # New implementation: checkout() { # Stash local modifications (including index modifications) if # necessary, using an easily identifiable message known as the # 'stash id': local stash_id stash_id=$(get_stash_id) && git stash save -q "$stash_id" || # Save local modifications git reset --hard HEAD # Throw away changes on detached HEAD # Do the checkout that was requested: git checkout "$@" # Unstash previously stashed local modifications (including # index modifications) if they were automatically stashed # before (the lookup is done with the relevant 'stash id'): stash_id=$(get_stash_id) && stash_id=$(git stash list | awk -F': ' "/$stash_id/ {print \$1}") && [ -n "$stash_id" ] && git stash pop --index "$stash_id" } Sincerely, Michael Witten -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html