Branches Ahead/Behind based only on Code Changes - tfs

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.

Related

Should I test master branch before put into production?

I'm working with git flow and a doubt arouse about the master branch. I have development and user acceptance working on develop branch and when I finish the test, I merge the develop with master branch and put into production. My question is if something goes wrong after this merge with master branch, I will not have tested it. What should I do to have the master branch tested? How to ensure that the master is not broken? Is there any pattern?
tl;dr: No, you already tested it.
Details:
In a properly implemented Git-Flow strategy, anything you merge into master should be fully ahead of master 1, so you would never need to test what you'll get after merging into master, as it will be the identical state before and after the merge. (And presumably you have fully tested the branch before merging into master!) The reason this is true is that when hotfix branches are merged into master, they should be immediately merged back down into develop too (or into a release branch if one currently exists). This means there should never be any code that is only on master and not yet in the branch you're about to merge into master. As documented by Git Flow regarding completing hotfix branches:
When finished, the bugfix needs to be merged back into master, but also needs to be merged back into develop, in order to safeguard that the bugfix is included in the next release as well. This is completely similar to how release branches are finished.
And also,
The one exception to the rule here is that, when a release branch currently exists, the hotfix changes need to be merged into that release branch, instead of develop.
Side Note: You mentioned that you are merging develop directly into master, and you can do that if it's working for you, but I just want to point out that typically in Git Flow you use a release branch instead. Doing so enables simultaneous development on develop while you are hardening a release as it awaits deployment. Here's a question that discusses this, and my answer there provides some tips for how to avoid creating release branches in Git Flow, if you normally don't need them.
1 In Git we oftentimes say that one branch is "fully ahead" of another branch when the first branch can reach the tip commit of the second branch. For example, develop is ahead of master if the tip commit of master is in the history of the develop branch. In this case however what we actually mean is that all commits with state changes in master are present on develop, and this distinction exists only because of the --no-ff requirement when merging into master, so it's possible that master might have some merge commits that don't yet exist on develop. Those merge commits do not contain any new state though, so we can say from a practical point of view that develop is fully ahead of master.
From a purity standpoint, my personal preference is to always have every commit on master be present in develop or release before merging into master, so that we can say "fully ahead" and mean it from a commit ID standpoint as well. To achieve this, you can slightly tweak the documented Git Flow by, instead of merging release and hotfix branches back to develop after merging into master, merge master back down into develop. This achieves the identical state but also achieves the "fully ahead" meaning that we like to see in Git. It also means anytime you merge anything into master, you could do a fast forward merge, but we choose to use --no-ff instead to maintain a historical record of when the merge occurred, and exactly what was merged. Using this tweak, the fact that you could have done a fast-forward merge is the proof you need that you don't have re-test master after the merge.
If the master branch changed since you forked the develop branch, you certainly could break master after merging develop (especially if you had to sift through merge conflicts), even if develop was working fine on its own. The way to make sure that master isn't broken after merging is to have good unit tests for master to make sure no existing functionality is broken, and then add and run additional unit tests for develop which test the new feature works after its merged.

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.

Can an old branch be remerged?

I finished working on a local branch1 and merged it to master.
Now I would like to work on another feature for my application and so I will create a second local branch2, finish to add the feature and merge to master also branch2. This can go on for as long as I need to implement my application with features and until my application is completed.
Suppose now that after all these implementations I would like to make some improvement or change on the topic that was the job of branch1, say the static pages about, help and contact. Is it possible to checkout to and reuse branch1 for these changes or that branch cannot be used anymore and should rather be deleated?
After a while there might be a considerable pileup of old topic branches that I initially may have wanted to keep for these purposes. However these old branches are all outdated, no more a complete reproduction of the master branch as they were when created: is this a prerequisite in order to merge with success?
The branching/merging strategy is yours to decide but you seem to describe a feature-based workflow.
In that case, after you have merged your feature branch branch1 to master, the content/history of this feature is contained in the master branch thanks to the merge. branch1 becomes useless and even obsolete with time so you can safely remove it so that old feature branches don't accumulate in your repository.
If you then look at the improvements you want to add to the functionality introduced by branch1, you can see those improvements as a new feature and therefore create a new feature branch from master to perform those improvements.
How you should organize your workflow is rather subjective and the best strategy often depends on how the project is organized in terms on contributors and how you deploy your changes.
You can use these old branches, but ... you should merge new changes from master before (So you can avoid big merging problems in future). When you need to reincarnate old branch do:
git checkout very-old-branch
git pull ./ master
# do some changes into very-old-branch
git add .
git commit -m 'changes in the very old branch'
# need to merge very old branch with new changes into master again
git checkout master
git pull ./ very-old-branch
git push origin master
But it would be better not to be necromancer and to just create new branch and make changes in it:)
You should take a look on gitflow.
Its a very known workflow for doing such kind of development as you are asking
The full workflow will look like this. In your case you refer to the feature branches (purple ones).
The relevant article is here:
http://nvie.com/posts/a-successful-git-branching-model/
As you can see you keep working on new features all the time and once you done with them you simply merge them back to dev (in your case can be master)

Phabricator pull/merge request

Is it possible to do pull request in bitbucket style in Phabricator?
Eg. to branch off of some existing branch and then to create pull (merge) request to merge new branch back?
I see that Phabricator differential tool only allows to submit some manually entered diff to some branch. Is it the only way?
You can mix git and arc together, but it does go against how arc diff is meant to be used.
You could leverage audit instead, although I haven't gone into any details about that below (nor have I used audit, yet).
Below, I've tried to explain our new workflow, coming from git-flow to an adapted version using git and arc diff.
Background
Before we started using Phabricator we used Gitlab and created merge requests. These would get reviewed by another developer. We use JIRA and our workflow incorporates a review required stage which has several checks before progressing into testing.
At this point, we've pushed the branch to the remote, requested a review and awaiting testing to occur (we have a mix of both manual and automated testing).
Once the review has been accepted and tests have passed, the feature branch is merged into origin/develop.
New workflow
Our new workflow removes the need to create the merge request within Gitlab, especially for reviewing.
My team still uses a workflow that incorporates git-flow, however, we've introduced the arc diff command. This creates the diff within Phabricator. The developer pushes his branch to the remote, but doesn't raise a merge request.
We run the following commands when creating a diff (merge into origin/develop)
git checkout -b feature/foo
git add <files>
git commit -m "A useful commit message"
git push origin feature/foo
arc diff origin/develop # this creates the diff within diffusion
Once the review has been accepted, we don't merge (or arc land) the branch, we await all testing to take place. This allows us to update the diff should testing fail and the developer who reviews can easily see which commits need reviewing.
Once testing has passed we can simply merge, either using gitlab merge request or the command line. We usually run arc close-revision <revision-id> to close the revision within Phabricator itself.
Additional notes
I believe the philosophy of arc diff is that you don't push your local branch. Instead you create a diff which diffusion displays. This is classed as a pre-push workflow.
Phabricator also has a post-push workflow which incorporates audit. You can simply mark commits ready for audit by amending your commit messages.
No, see https://secure.phabricator.com/T5000 to track this feature request.
Differential's primary input should be Arcanist, the Phabricator command line tool. It wraps git and provides lint, unit, and other precommit checks that help reduce time spent reviewing code. For example, it can emit patches and amend code before submission for review.
https://secure.phabricator.com/book/phabricator/article/arcanist/

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