One-to-one mapping of git commits to TFS changesets using git-tfs rcheckin

The Context

  • We have a git repository with a release branch.
  • We have a TFS repo (currently empty).

My task is to mirror the release branch of the git repo into TFS so that every commit in git maps to a changeset in TFS. All the developers only commit to git and (lets assume) are unaware of TFS.

Reading the documentation for rcheckin and the answer to this related issue makes me believe that rcheckin is capable of doing that.

  • What is the reason for “Procfile declares types -> (none)” in Heroku?
  • How to add already cloned projects as submodules?
  • Teamcity - Create git tag after successful build
  • git plugin for Jenkins fails to clone a repo from local machine. Error code 128
  • Removing Hunk Interactively with git add --patch
  • Track a new remote branch created on GitHub
  • The Problem

    All the commits in git are squashed into a single changeset.

    Reproduction sequence:

    git tfs clone http://tfs:8080 $/tfsrepo
    cd tfsrepo
    git remote add github git@github.com:REPO/Repo.git
    git fetch github
    git merge github/release
    git tfs rcheckin
    

    This results in a single checkin into TFS that contains all the commits.

    Other attempts at solving the problem

    • After clone, merge the first commit from the source (git) repo, rcheckin to create a shared base

      • This worked, but subsequent git pull github release followed by git-tfs rcheckin led to commit squashing again.
    • For the first few commits in the origin repo, I merged them one-by-one into the git-tfs shared repo and rcheckin’d after each.

      • This kind of worked, as for every commit, there was one changeset in TFS. However, the original commit message second underneath a “merged c02436de4f..” message.
      • It is not realistic to do for every changeset, even with scripting.
      • As pointed out by patthoyts, this would make me the commiter for that change as far as TFS is concerned.

    My question

    What do I have to do to keep TFS up-to-date with the release branch from the git-repo so that every commit in git has a corresponding TFS changeset?

    Additional info

    I do have administrative control of both repos, and I would be able to rebase the git repo if necessary, with all the consequences this implies. I just don’t want to lose the history we already created.

  • Git makes all checked out files' end of line CRLF
  • How to update git version from GitHub Desktop on Windows
  • Git: says origin already exists on “NEW” (init) repository, using shell but installed github for windows
  • Adding all “error_log” files to .gitignore
  • Alias git stash poop to pop?
  • Should foo.xcodeproj/xcuserdata be ignored in git repo?
  • 2 Solutions collect form web for “One-to-one mapping of git commits to TFS changesets using git-tfs rcheckin”

    I think what you’re seeing is git-tfs using only commits along the shortest path between HEAD and tfs/default. TFS’s history is a list of changes, while git’s is a graph, and you’re hitting the impedance mismatch between the two. To get a picture of what git-tfs is seeing, try git log --graph --oneline --decorate HEAD tfs/default before you use rcheckin.

    If you want the 1:1::commit:changeset thing, try this:

    git tfs clone http://tfs:8080 $/tfsrepo
    cd tfsrepo
    git remote add github git@github.com:REPO/Repo.git
    git fetch github
    git tfs rcheckin github/release
    

    Another approach is to use cherry-pick or rebase.

    git tfs clone http://tfs:8080 $/tfsrepo
    cd tfsrepo
    git remote add github git@github.com:REPO/Repo.git
    git fetch github
    git checkout -b about-to-be-rewritten-twice github/release
    git rebase tfs/default
    git tfs rcheckin
    

    Check out the rebase docs for more examples of things rebase can do.

    And don’t git push github about-to-be-rewritten-twice:release.

    I don’t think this is going to come out well. If you do fix making the commits, each one will have the timestamp and user id of the moment you comitted to TFS. You can’t preserve the original author or time when comitting these to TFS. You might be better off waiting as Microsoft have announced TFS will in future support Git. So before too long anyone needing to use tfs can upgrade their tools and access your real git repository.

    I suspect your merge made a merge commit and that is causing the squash. You might try resetting the git-tfs branch to your git master and then pushing the commits. We use git-tfs the other way around where the shared repository is TFS and we all use git with git tfs to make commits. If I create a branch and add a few commits then git tfs rcheckin does not squash these into one but makes a series matching what I have in my local git. I did find that using ‘stage’ and then unstaging in tfs to make a commit squashed everything into one. You didn’t say why you have to mirror to TFS but I suggest you try and point them at the recent microsoft announcements and tell them git is the future! Even with TFS. 🙂

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