24
votes

Context

A GitHub Enterprise installation used for development. Every developer has his own public repo, and the organization has the authorative repo. Pull requests are used for code reviews, and we loosely follow nvie's git flow branching model.

A TFS installation used for issue tracking and deployment (the release branch). We mirror the release branch into a TFS repo.

Work Items

Now the hard part is: How do we associate git commits (that may originally be done on the public branches of the developers) with TF work items?

What I did

I've looked at the following projects for help:

I've read references to associating commits with work item in both Git-TF projects, but I am unsure what tool to use, and how to go about it exactly.

I would be fine if I had to run a script on the release branch commits to extract work item references from the commit message and associate them with changesets sent to TFS. However, a solution that allows the association in metadata (instead of commit messages) would be preferred.

What are my options to associate work items in TFS with git commits?

4

4 Answers

26
votes

If you use # in your git commit message as in git commit -m'fixes #123' TFS will automatically add the commit as a linked item in workitem specified.

19
votes

With git-tfs, you can associate workitems in a commit message using metadatas (and even force commit policy!).

They are automaticaly associated when the commit are done in the TFS server ( if you use the rcheckin command )

And there is even a git-note created on the git commit to have the title of the workitem and a link toward the workitem!

But to use rcheckin in a synchronisation process between git and TFS, you should before (abolutely) understand how it works!

When you rcheckin git commits in TFS, git-tfs, for each commit create the corresponding changeset in tfs and fetch the content of this changeset to recreate a git commit. So, even if it's (nearly) invisible for you in a normal worklow, you have the git commits after the rcheckin that are not the same than the original ones (there is a modification of the history!).

That could be a big problem if this git reporitory is supposted to be the central repository because every commiters will have to do a rebase. Otherwise, it shouldn't be a problem because it's completly transparent, except in special cases but easily solvable.

Not a perfect solution...

6
votes

Without having much information about those Git-TFS tools, note that you can add at any time metadata to a commit (without changing the history / SHA1 of the repo) by adding notes.

See git notes (or Git Tip of the Week: Git Notes).

By adding that information in a dedicated "note namespace", you can quickly store / retrieve an information like a Work Item reference from the note associated to a Git commit.

3
votes

You should be able to do it in the ms git tf:

git tf checkin --associate=27631,27637

Help says:

usage: git-tf checkin [--help] [--quiet|-q|--verbose] [--message|-m=<msg>] [--metadata|--no-metadata] [--renamemode=<all|justFiles|none>] [--deep|--shallow] [--squash=<commit id>|--autosquash]
[--resolve=<workitem id>] [--associate=<workitem id>] [--mentions] [--no-lock] [--preview|-p] [--bypass|--gated|-g=<definition>] [--keep-author|--ignore-author] [--user-map=[<file path>]]

Arguments:
    --help                Displays usage information
    --quiet, -q, --verbose
                          Determines the output detail level
    --message, -m=<msg>   Use the given <msg> as the changeset comment
    --metadata, --no-metadata
                          Determine whether to include git commit meta data in the changeset comment when checking in deep. If omitted, value provided during configure is used.
    --renamemode=<all|justFiles|none>
                          The rename mode to use when pending changes. Specify either "all", "justFiles" or "none" (default: justFiles)
    --deep, --shallow Creates a "deep" check-in, checking in a TFS changeset for each git commit since the latest TFS changeset(requires linear history or "--squash" or "--autosquash"), or
                          "shallow", checking in a single changeset for all commits.If omitted, the depth value provided during clone or configure is used.
    --squash=< commit id>, --autosquash
                          Specifies how check in should operate in the deep mode if one commit has more than one parent
    --resolve=< workitem id>
                          ID of the TFS work item to resolve during check-in
    --associate=< workitem id>
                          ID of the TFS work item to associate during check-in
    --mentions Add references in the commit comments for any work items linked to the corresponding changeset.
    --no-lock             Does not take a lock on the server path before committing (dangerous)
    --preview, -p Displays a preview of the commits that will be checked in TFS
    --bypass, --gated, -g=<definition>
                          Bypass gated check-in or specify a gated build<definition> to use
    --keep-author Use the commit author as the changeset owner when checking in deep.The commit author should be known to TFS either by his name or e-mail address.To use this option you should
                 be either a TFS project administrator or have the "Check in other users' changes" permission.
    --ignore-author Use the current authenticated user as the changeset owner.
    --user-map=[< file path >]
                          Specifies an absolute or relative path to a file providing mapping between Git repository commit authors and TFS user identities. (default: ./USERMAP) To generate a template
                          mapping file, run the checkin command in preview mode with the --keep-author and --deep options specified.

Creates a check-in of the changes in the current master branch head, provided it is parented off a commit converted from a TFS changeset.