Git-tf checkin fails: commit has multiple parents. Using –deep option to create history in TFS
It appears that neither
--shallow seem to work. I am getting an error when attempting to do a
git-tf checkin --deep to a new folder (currently empty) in TFS. I have a git repo with quite a bit of history. I would love to keep/migrate to TFS as part of git-tf.
My understanding is that the
checkin --deep would create an analogous changeset in TFS for each commit. The problem is that any commit in the git repo that appears to have been the result of a merge (and we have many merges in this repo) seems to make the
git-tf command very unhappy and reports the error message I mentioned in the title (with the exception of the [commitid] is replaced with a real commit id (e.g. 9a26d8)).
I’m not sure if I’m totally missing the boat here or what. Is there a reliable way to port a pre-existing git repo with multiple merges commits in history to TFS? I expected this to be a primitive feature/fix. I hope I am missing something. I am very saavy with TFS, but not as seasoned with git so any help is appreciated.
One Solution collect form web for “Git-tf checkin fails: commit has multiple parents. Using –deep option to create history in TFS”
The problem here is that representing a complex merge history in TFS is difficult. Quite simply, git commits can have multiple parents, whereas a TFS changeset can only have one.
Consider the state where my git repository has HEAD at some commit, let’s say
9c42ef.... Now I make a change and commit it, creating a new commit
1f23cd.... Meanwhile, I also take a change from Bob, which was also a commit based on
9c42ef.... His change is commit ID
f41ac3.... If I want to incorporate both changes, I’ll have to do a merge, and let’s say I end up with commit ID
7acdfe.... Now your graph looks like this:
1f23cd / \ 9c42ef 7acdfe (HEAD) \ / f41ac3
This can’t be easily represented in TFS since a single changeset can only have one ancestor (the changeset directly preceding it.) So we need to linearize history. This is why the
--auto-squash options exists on
git-tf checkin (when doing a deep checkin).
--squash option allows you to select which path to follow when working its way through history. For example:
git-tf checkin --deep --squash f41ac3
f41ac3 when walking the graph and you will have three changesets, the contents of
7acdfe. But in a big graph, this is a lot of work to specify each commit to squash. In that case,
--auto-squash will use some magic to determine which path to follow. (It prefers the path with the longest chain of commits so that you get the most history possible and if two segments are of equal length, will use timestamps to determine which path to follow.)
git-tf checkin --deep --auto-squash
You could also rebase such that the commits you were checking in were linear and each had only a single parent.
git-tf developers use each of these strategies depending on the complexity of the tree, masochistic feelings about typing endless strings of SHA1 hashes and the phase of the moon.