David Turner <novalis@xxxxxxxxxxx> writes: > If I do "git checkout -b fleem", with no additional flags, why does it > need to rewrite the index? Or even read the index? The "reading" part can be explained easily. It needs to show the list of dirty paths, which involves reading the index, refreshing them in-core to cull the timestamp-only changes out of the report. Once in-core index is refreshed, it is a waste not to write them out if it can, so it is not surprising if it writes, too. The real reason is a lot more involved. "git checkout -b new" is different from "git update-ref refs/heads/new HEAD" (i.e. create a new branch at the same commit) followed by "git symbolic-ref HEAD refs/heads/new" (i.e. point the HEAD at it). If it were, I fully agree with you that it shouldn't need to touch either index or working tree at all. It is "git branch new" followed by "git checkout new", and the latter step does the full two-tree "read-tree" between the same two commits. I personally very much prefer "Switching between the same two commits? That should be a no-op by definition.", but we cannot blindly that naive optimization, as it would break some use cases (which I personally do not care too much about ;-). For example, extra working tree files outside the "sparse" area are removed when sparse-checkout is in use while switching from the current branch to the new and identical branch. I do not personally agree with the behaviour, but that has been what the users accept; there may be other funnies like that.