git-tfs/git-tfs — pull request #299 by davidalpert (2013-01-27 05:17:47+00:00)
Title: Init branch across rename

makes the behavior of init-branch (& internally create-branch) smarter and able to identify a TFS branch's root commit on the TFS "trunk" across a renamed branch like so:

$/trunk/path/ - a -> b -> c -> d
\
$/branch1/path/ e -> f [renamed]
\
$/branch2/path/ g -> h -> i

where changeset 'e' creates $/branch1/path/ from changeset 'b' on $/trunk/path/, then after changest 'f', changeset 'g' renames $/branch1/path/ to $/branch2/path/ followed by a few more changesets. TFS handles this kind of rename as shown, as a branch of branch2 from branch1 and a simultaneous deletion of branch1.

previously, calling 'git tfs init-branch $/branch2/path/' would fail stating that it's root changeset was 'f' (the changeset of branch2's parent branch from which branch2 was created) and it could not find changeset 'f' in the local git repo unless an explicit call to 'git tfs init-branch $/branch1/path/ (which no longer exists visibly in TFS!) was made first.

in git terms, however, there is no difference between branch1 and branch2; changeset 'f' has a single child and changeset 'g' has a single parent so from git's perspective these are two sequential commits on a single line of history diverging changeset 'b' on 'trunk'/'master'.

now, when calling 'git tfs init-branch $/branch2/path/' we will recognize that changeset 'g' is a TFS rename and follow the original branch to properly (from git's persepective) identify changeset 'b' on $/trunk/path/ as the root commit of $/branch2/path.

the resulting local git repo will then look like this:

a -> b -> c -> d ['tfs/default']
\
e -> f -> g -> h -> i ['tfs/branch2/path']

This may or may not work for every case but works for the case described above.

Tested on VS2010 only.