Sergio Callegari <scallegari@xxxxxxxxxxxxxx> writes: > Junio C Hamano <junkio <at> cox.net> writes: > >> >> Answering that is part of "let's see who are motivated enough" >> area . Are you? > > Touché! :-) Having said that... If we allowed a commit to be created in such a case, your next commit will have B as the parent, with the tree state you wanted to have in X. The graph becomes like this: x---x---B / \ ---o---A X (New HEAD) The commit essentially reverts what happened in 'x' and 'B', which is quite bad. What you want to happen in this case is to make a graph like this: x---x---B branch tip / ---o---A-------X (your work is still based on A) and then perhaps merge B's work, after making sure B is a fast-forward of A and doing other sanity checks: x---x---B / \ ---o---A-------X---M the final branch tip I did not code the patch to detach the HEAD at the same time, because I was not convinced that "What you want to happen" part is the *only* sane resolution of the situation. Depending on who created the chain that leads to B, I suspect the desired outcome to resolve this situation would be different. If it was yourself working in another repository (either working in a separate repository on the same machine, and then pushed to update the branch tip from there, or working in a separate working tree that shares the .git/refs with this repository created with Julian Phillips's workdir script to directly update the branch tip), then you might want to rebase the branch tip on top of your commit 'X', resulting in a picture like this instead: x'--x'--B' branch tip / ---o---A-------X (your work is still based on A) Both of these workflows would require you to detach your HEAD to A. But it is conceivable that you might want to do an equivalent of "switching branches while merging the local changes" (aka "git checkout -m other-branch") without making a commit, to result in: x---x---B.......X' (your work is now based on B) / tip ---o---A This is especially true when the chain leading to B is somebody else's work, which potentially is already published elsewhere. You do not want to rebase that (although it is perfectly fine to merge with it, so the solution I suggested in the original message is Ok). The difference in the end result is your commit will come after B, not before it, and in this case you do not need to detach the HEAD. For this, you would need to perform the same operation as "# Match the index to the working tree, and do a three-way" part of git-checkout.sh: git update-index --refresh >/dev/null new=`git rev-parse --verify HEAD` ;# updated head at B old=`git update-index --get-base` ;# base of the working tree at A # prepare $work tree that represents what you would have # committed if you did "git commit -a" git diff-files --name-only | git update-index --remove --stdin && work=`git write-tree` && git read-tree --reset -u $new || exit # Three-way merge to transplant A..X change on top of B eval GITHEAD_$new='${new_name:-${branch:-$new}}' && eval GITHEAD_$work=local && export GITHEAD_$new GITHEAD_$work && git merge-recursive $old -- $new $work # Do not register the cleanly merged paths in the index yet. # this is not a real merge before committing, but just carrying # the working tree changes along. unmerged=`git ls-files -u` git read-tree --reset $new ;# index has B's tree now case "$unmerged" in '') ;; *) # ... except we carry the conflicted paths along ( z40=0000000000000000000000000000000000000000 echo "$unmerged" | sed -e 's/^[0-7]* [0-9a-f]* /'"0 $z40 /" echo "$unmerged" ) | git update-index --index-info ;; esac Where you should detach your head to (if you choose to do so) is already recorded in the index and "git update-index --get-base" would give that to you if you need it, but once we detach the HEAD, we would not know on which branch we were, and we need to keep that information while detaching the HEAD. If there is a sane resolution that does not require detaching the HEAD (such as the above example), there is no point to do so, so I left that policy decision to later steps. - 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