Git-tf checkin fails: commit has multiple parents. Using –deep option to create history in TFS

It appears that neither --deep or --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)).

  • Move the most recent commit(s) to a new branch with Git
  • Proper git workflow scheme with multiple developers working on same task
  • Trying to use Git with Android Studio
  • Creating a branch with TortoiseSVN without /trunk structure
  • Merge and delete branch in one step/command
  • Why do I need the “master” in git merge origin/master?
  • 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.

  • How to work on two major versions using the GitFlow model
  • Default remote for git fetch
  • Git push hangs when pushing to Github?
  • Git: get number of changed lines per day
  • How can you unstash changes using EGit?
  • How does git deal with binary files?
  • 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:

            /        \
    9c42ef             7acdfe (HEAD)
            \        /

    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 --squash and --auto-squash options exists on git-tf checkin (when doing a deep checkin).

    The --squash option allows you to select which path to follow when working its way through history. For example:

    git-tf checkin --deep --squash f41ac3

    Will omit f41ac3 when walking the graph and you will have three changesets, the contents of 9c42ef, 1f23cd and 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.

    The 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.

    Git Baby is a git and github fan, let's start git clone.