How to block TFS check-ins that contain a specific keyword? - tfs

I want to create a TFS policy that blocks a changeset from being checked in if a certain keyword is found in the diff.
This will allow me to make local changes for testing ideas without worrying that these changes will be mistakanly checked in, as long as I add something like //nocommit in the code.
How can this be done?

There is no out-of-box check-in policy to achieve your requirement, you have to customize your own check-in policy and use command tf diff itemspec /noprompt to compare files.
As a suggestion, you could consider using Git version control, create a branch from master and work on the branch. When you are ready to merge your code to master, create a pull request to review the code. In order to protect master, you could set branch policy on master. After you set up a branch policy, you cannot directly push changes to the branch. Changes to the branch are only made through pull requests.

Related

Github PR Checks Without Disallowing Pushing

Please read carefully as I believe my use case is unique and I have tried searching a lot on how to do this, but I am still unsure.
Generally, I am trying to set up a repo for a group of developers to work on and have it contain CI checks and require reviewers. However, I have run into some issues with how Github enforces branch protection. On top of that, I cannot use Actions as we are using a self-hosted Enterprise Github through an organization.
My desires:
Use Jenkins (which is already set up and building) builds as checks for PRs. If the checks don't pass, you cannot click merge on the PR.
Allow pushing to a branch that I have a PR up for so the author can push changes based on PR comments.
Require two approvals from maintainers. You cannot click merge without these.
It seems I could protect a master branch for example. However, I would like to enforce the PR checks whenever a person chooses to make a PR. For example, from one dev branch into another dev branch.
Use case:
An author sets up a PR for merging a branch some-work into dev. Jenkins builds the HEAD of the branch some-work to evaluate the checks. I would like to enforce this PR to have two approvals from maintainers. So, those reviewers make some comments and request some changes. The author makes those changes and pushes a new commit to the some-work branch. Jenkins runs on the new HEAD to reevaluate the checks. Then, if-and-only-if the two reviewers approve and the checks pass can the merge button be clicked.
What I have tried:
Using Github branch protections: the required approvals and the required status checks. However, this prevents any pushing or force pushing to the branch being developed on. I could just apply these protections to master, but I also want these checks part of any PR (even dev2->dev1, for example).
Github actions, but these are not available in the self-hosted enterprise Github I have to use.
What I understand:
I understand that I can protect master, for example, in this manner with the native Github branch protection. However, if I want master to be something that always works, it is understandable that developers would break up a feature into multiple branches. They would also want their follow developers to review it when merging it from their branch to an intermediate (non-master) branch. Then the actual branch being merged into master consists of code written by many developers.
Thank you all in advance for your time and help. :)
Using Github branch protections: the required approvals and the required status checks.
However, this prevents any pushing or force pushing to the branch being developed on
But... that issue (not being able to push a protected branch) could be part of a possible solution.
I would make jenkins create/reset a PR branch based on a push on a topic branch (like some-work-pr, based on some-work)
some-work is not protected, and can receive commits at any time
some-work-pr is created by Jenkins protected, and cannot be modified: compilation/test/review/approval happens here.
PR would only be done from xxx-pr branches (protected PR branches created/managed by Jenkins), while other topic branches continue to evolve.
You can only enforce these policies with branch protections, so if you want to enable required CI checks before merging a PR for all branches, then you need to protect all branches (e.g., with the pattern **). In that case, you'll need to have developers use a forking model for your repositories so that they can push code to their forks and then merge in the changes via pull requests only.
Note that if you adopt an approach where projects are implemented as a set of small, incremental changes that are merged frequently and use feature flags to control whether the code is enabled, then as a practical matter developers will only merge into the main branch and you can get away with only protecting the main branch.

Branches Ahead/Behind based only on Code Changes

For our projects have Integration and Master branch. For deployment we cut a RC branch off Integration. Once deploy is complete we create Pull request for RC to Master.
However, now Master shows as 1 ahead because it has a commit that does not exist in Integration. I considered to create Pull request RC to Integration as well, but TFS does not allow it since there are no changes.
Is there a way to avoid this situation with Master? Can behind/ahead only check the code changes and not commits? To fix this I now have to create Pull Master to Integration, and that is a pain for all the projects we do.
Afraid not able to avoid this situation. It's also not possible to make behind/ahead only check the code changes and not commits. Since you are using Pull Request (which execute git merge --no-ff).
To be honest, it's not necessary to resolve Integration branch behind/ahead master.
you can have two mostly independent branches without any problems. The important measure of differences between branches is given by git diff. If this reports no differences, then it's Ok.
You could also take a look at this similar question: VSTS Git: Is it necesary to resolve dev branch behind/ahead master and if so how?
If you insist on avoid the ahead on Master, you may have to create Pull Master to Integration as you have pointed out in the question.

How to combine work from more than one developer before checking into TFS?

My team's policy is to not check in broken code into TFS. But what if two team members are working on the same file and each member's work represents a partial solution ? One members changes won't work without the other.
How is the best way to combine the code and still follow policy of not checking in broken code ?
Both developers could create a shelveset of their changes once their own coding is complete. Once it's time to merge their code, you have 1 developer unshelve the other developer's shelveset into their own workspace. Doing this will also trigger the Merge Tool in case there are any merge conflicts that can't be automatically resolved. This should allow the developer to combine work with the other without checking in broken code.
Note that both developers should make a shevleset of their own work before unshelving the other's, in case the unshelve of the other developers work goes terribly wrong in the merge and they need to revert their own work to the un-merged state.
Here's some documentation on creating and unshelving shelvesets
Consider allowing broken code on branches. The team members could commit code to branches and merge those branches together before merging into master. Your primary or master branch should require a passing build before a pull request can be merged in.
Look at the feature branch model: https://learn.microsoft.com/en-us/vsts/git/concepts/git-branching-guidance. This does not depend on Git but it is convenient as branching is cheap.
Both developers work on the feature branch which is allowed to be broken. When they are finished they issue a pull request to the master branch. The merge is only allowed if all tests pass to make sure the master branch stays healthy.

Discard unwanted change set

I am looking for a way to discard some unwanted change sets using TFS. I have looked into this site and many other and know that we need to use
tf merge /version:C137~C137 branch1 branch2 /recursive
However, I store all my source code in TFS DEV environment, I normally check out the code from DEV to my machine, work on it then check it back in DEV, roll back, fix it then check it back in. This process create many different change sets that hang around and needed to be cleaned up. So when I use TF merge command which branch I have to specify DEV and ????.
Thanks for your help
The merge command applies changes from one branch into another. /discard option means does not perform the merge operation, but updates the merge history to track that the merge occurred. This discards a changeset from being used for a particular merge.
But according to your description, you don't use branches or merge. What you want is delete/destroy changesets. Unfortunately, you can't delete changesets in TFS by default, if you delete changesets, the version control may be defeated.
You can always work with the latest version, when you want to work on a specific version, you can use TF rollback command. This command does not remove the changesets from an item's version history. Instead, this command creates in your workspace a set of pending changes that negate the effects of the changesets that you specify.

Limitations to consider when using git with TFS via git-tf or git-tfs?

What will I actually miss if basing my source code handling on TFS (to get all the integration and reporting etc) but use git-tf or git-tfs locally?
Will I then be able to use the complete git functionally to branch and merge locally just as if used a git based central repository, or will there be a different workflow and limitations to consider?
We use feature and release development branches a lot and like to keep doing so, how does actually the TFS server handle this when pushing these locally using git-tf etc?
Actually, git-tfs is more advanced than git-tf. I highly advice to use it instead of git-tf (for the moment).
With git-tf, you should clone each branch as a repository (and be unable to cherrypick, merge...) while in the last version of git-tfs you can do it and keep your workflow.
See https://stackoverflow.com/a/13710811/3619
If you know git there is not problem to use git-tfs!
The documentation : https://github.com/git-tfs/git-tfs/blob/master/doc/
just know that if you use :
git tfs checkintool
or :
git tfs checkin
it will create a merge commit
and if you use :
git tfs rcheckin
it will commit each local commit in tfs and fetch and rebase automaticaly on these commits...
But read the wiki documentation, it's clear enough ;)
edit:
Contrary to what #gbjbaanb said, there is a lot of advantages of using git-tfs instead of plain TFS (if you know how to use git...). ALL what you could do with git locally works and is still an advantage (light branching, rebase, local commits, reworking commits, knowing exactly which version is checkouted, fetching and seeing changes WITHOUT merging them with your current workspace, better history,...).
Now with git-tfs, you could even create more easily than with TFS a TFS branch (you just have to create it before doing a commit in it, or rebase onto after creating it if you began your work in a git branch before... ).
The only thing that is not better than TFS, for the moment, is merging 2 TFS branches that is not supported. You should either do a merge with TFS if you want to see the merge in your history (what we generally want) or merge with git and checkin in tfs (and you won't see the merge changeset :( ).
A pull request[1] to resolve all this (and permit to manage merge commit a LOT easier than with TFS) already done and waiting for merge in the trunc (I have just to refactor Unit test and the feature be reviewed).
[1] https://github.com/git-tfs/git-tfs/pull/363
If you use git-tf (the MS version) firstly you will have to understand the commands you use will be different - they stuck an additional "tf" in every command. (eg git tf push)
The second is that branching will not work like git - I found (and this could be due to security setups and suchlike, even though I can create branches locally and on the server) that whilst you can branch your local git setup, you cannot push a new branch back to the server - you have to merge it onto an "offical" branch first.
If using TFS, I wouldn't bother trying to use any of the bridges (though svn-tfs bridge is very close due to the nature of TFS being close to SVN). I'd use the native client. I wouldn't choose TFS first though, but if that was what I had to use - the Team Explorer Everywhere client would be my choice.

Resources