One well-known branching strategy is called Git Flow. The main branch always reflects the current production state. There is a second long-running branch, typically called develop. All feature branches start from here and will be merged into develop.
Git Flow is the most widely known branching strategy that takes a multi-branch approach to manage the source code. This approach consists of two main branches that live throughout the development lifecycle.
Once you've completed work on your branch, it is time to merge it into the main branch. Merging takes your branch changes and implements them into the main branch. Depending on the commit history, Git performs merges two ways: fast-forward and three-way merge.
The most troubling feature new developers to DVCS need to realize is about the publication process:
From that, you can respect a few rules to make your questions easier:
Now:
Workflows / branching models:
each workflow is there to support a release management process, and that is tailored for each project.
What I can add to the workflow you mention is: each developer should not create a feature branch, only a "current dev" branch, because the truth is: the developer often doesn't know what exactly his/her branch will produce: one feature, several (because it ended up being too complex a feature), none (because not ready in time for release), another feature (because the original one had "morphed"),...
Only an "integrator" should established official feature branches on a "central" repo, which can then be fetched by developers to rebase/merge the part of their work that fits that feature.
Merging vs rebasing (tangled vs sequential history):
I like my answer you mention ("Workflow description for git usage for in-house development")
I am looking for a natural workflow:
for fixes, it can help associating each fix with a ticket from a bug tracking, which helps the developer remember where (i.e. on which branch, i.e. a dedicated branch "for fixes") he/she should commit such modifications.
Then hooks can help protect a central repo against pushes from non-validated bug-fixes or from branches from which one shouldn't push. (no specific solution here, all this need to be adapted to your environment)
How to avoid creating merge conflicts (due to cherry-pick)?
As stated by Jakub Narębski in his answer, cherry-picking should be reserved for rare situations where it is required.
If your setup involves a lot of cherry-picking (i.e. "it is not rare"), then something is off.
Would applying the same commit in revert (how to do this?)
git revert
should take care of that, but that is not ideal.
How to decompose into topical branches?
As long as a branch as not yet been pushed everywhere, a developer should reorganize its history of commits (once he/she finally see the development takes a more definitive and stable shape) into:
Proper procedures like code review and graduating ?
Integration branches (in a dedicated integration) repo can help the developer to:
I think, and I might be wrong, that one of the things that's most misunderstood about git is its distributed nature. This makes it very different to say subversion in the ways you can work although you can mimick SVN behaviour should you want. The problem is pretty much any workflow will do, which is great but also misleading.
If I have my understanding of kernel development (I'll focus on that) right, everyone has their own git repository for developing the kernel. There is one repository, linux-2.6.git, looked after by Torvalds, that acts as the release repository. People clone from here if they wish to start developing a feature against the "release" branch.
Other repositories do some development. The idea is to clone from linux-2.6, branch out as many times as you like until such a point as you've got a working "new" feature. Then, when this is ready, you may make it available to someone considered trusted, who will pull this branch from your repository into theirs and merge it into the mainstream. In the linux kernel this happens on several levels (trusted lieutenants) until it reaches linux-2.6.git at which point it becomes "the kernel".
Now here's where it gets confusing. Branch names don't need to be consistent across repositories at all. So I can git pull origin master:vanilla-code
and get a branch from the origin
's master in a branch in my repository called vanilla-code
. Providing I know what's going on, it really doesn't matter - it is distributed in the sense that all repositories are peers to each other and not just shared across several computers like SVN.
So, with all of this in mind:
head
. Releases could be tags or branches and hotfixes are probably branches in themselves. In fact, I'd probably do releases as branches so you can keep patching them.origin
you should, in your repository, probably make another branch and merge the latest master
into yourbranch
so that someone else can pull your changes with as little effort as possible. There is very rarely a need to truly rebase, in my experience.git add .
and then git commit
.I hope that helps. I realise VonC as just posted a very similar explanation... I can't type fast enough!
Edit some further thoughts on how to use git in a commercial setting, as this seems relevant to the OP from the comments:
product.git
, is accessible by a number of senior programmers / technical people responsible for actually looking after the product itself. They are analogous to the role of maintainers in OSS.So what happens? Well, everyone pulls at the start of each day from the "upstream" source i.e. the release repository (which will also probably contain the latest material from the previous days development). Everyone does this, directly. This will go on a branch in their repository, probably called "master" or maybe if you're me called "latest". The programmer will then do some work. This work might be something they're not sure about, so they make a branch, do the work. If it doesn't work, they can delete the branch and go back. If it does, they will have to merge into the main branch they're currently working on. We'll say this is a UI programmer working on latest-ui
so he does git checkout latest-ui
followed by git merge abc-ui-mywhizzynewfeature
. He then tells his technical lead (the UI lead) hey, I've completed such a task, pull from me. So the UI lead does git pull user-repo lastest-ui:lastest-ui-suchafeature-abc
. The UI lead then looks at it on that branch and says, actually, that's very good, I'll merge it into ui-latest
. He might then tell everyone below him to pull from him on their ui-latest
branches or whatever name they've given them, and so the feature gets explored by the devs. If the team is happy, the UI lead might ask the testing lead to pull from him and merge the changes. This propagates out to everyone (downstream of the change) who tests it and submits bug reports etc. Finally, if the feature passes testing etc, one of the top technical leads might merge it into the current working copy of the program, at which point all the changes are then propagated back down. And so on.
It's not a "traditional" way of working and is designed to be "peer driven" rather than "hierarchical" like SVN/CVS. In essence, everyone has commit access, but only locally. It is access to the repository and which repository you designate as the release repo that allows you to use hierarchy.
A model that I've used with good results is the following:
A "blessed" repo everybody pushes and pulls to/from, basically a client-server topology.
There's no master branch so no developer can push any code into "mainline".
All developments happen on topic branches. We namespaced names to easily detect who is responsible for it: jn/newFeature or jn/issue-1234
There is also a near 1-to-1 mapping between branches and kanban/scrum cards on the whiteboard.
To release a branch it is pushed to the blessed repo and the kanban-card is moved to ready for review.
Then, if the branch is accepted by the review, it is a candidate for a release.
A release happens when a set of accepted branches are merged together and tagged with a version number.
By pushing the new tag to the blessed repo there is a new possible base for new features.
To avoid merge conflicts developers are kindly requested to update (merge) their unreleased branches to the latest release tag.
Personally, I try and keep only release-ready code in the master branch.
When I work on a new feature or bugfix I do that in a branch. I also unit-test in the branch. If everything works out OK, only then do I merge/rebase back into master.
I try and use common branch naming conventions as well, such as:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With