This highlights the only thing I don't like about Git. It's an immensely capable tool, but it gives no guidance regarding the right way to do things.
Our own teams have a set of practices which are similar but different from what Linus outlines here. And different projects on my company use different practices from those.
The worst thing is that there's no way of enforcing these workflows or practices other than out-of-band social conventions. And so minor mistakes happen, all the time. Our Git projects are never as pretty as they should be.
In other words, Git provides an awesome set of primitives for source control. I'm not sure what it'd look like, but I'd like to see a product that built on those primitives to enforce a little more order on projects.
> It's an immensely capable tool, but it gives no guidance regarding the right way to do things.
Maybe there isn't a "right way". A workflow that suits a simple desktop application is different from what is used by a kernel or another product that has dozens of targets to worry about. Similarly a web app that gets deployed in a controlled environment will most likely need a different way of working than an end-user application that goes into an app store to be downloaded and ran on a variety of devices.
> Our own teams have a set of practices which are similar but different from what Linus outlines here. And different projects on my company use different practices from those.
The culture around your product is probably very different from the kernel devs' culture so it makes sense for you to have a different model.
> The worst thing is that there's no way of enforcing these workflows or practices other than out-of-band social conventions. And so minor mistakes happen, all the time. Our Git projects are never as pretty as they should be.
Enforcing certain kinds of work flow would mean not allowing something that is currently possible. Crippling one workflow to standardize on another, while there is no clear evidence that one workflow would be the best for everyone.
Everyone has their own ideas on what is a clean history, whether it's a linear or has --no-ff merges for every feature. The most important thing is that it is useful. To me and my team that means that every commit on master should build on every target we have (dozens!) so "git bisect" won't be painful.
> Our own teams have a set of practices which are similar but different from what Linus outlines here. And different projects on my company use different practices from those.
The culture around your product is probably very different from the kernel devs' culture so it makes sense for you to have a different model.
> The worst thing is that there's no way of enforcing these workflows or practices other than out-of-band social conventions. And so minor mistakes happen, all the time. Our Git projects are never as pretty as they should be.
Enforcing certain kinds of work flow would mean not allowing something that is currently possible. Crippling one workflow to standardize on another, while there is no clear evidence that one workflow would be the best for everyone.
I agree 100%. Tools that attempt to defined culture are an enormous pain and often unusable outside the context understood by their creators. Tools that help you reinforce the culture you decide on for your project are wonderful, but they are rarely as un-opinionated as they need to be.
One thing that strikes me about source control culture is that in centralized environments people are very aggressive about installing pre-commit hooks to enforce rules, but I rarely see people using hooks for git, or even including hooks in their project as a suggestion for other developers to use. I wonder why not?
The amount of control you can exercise with hooks as well as the features available in repository management systems like gitolite should be more than adequate to enforce whatever policy you may dream up.
I'm not sure exactly what you think a better tool would look like. By your own admission, there are multiple "right" ways to do branch management, and all of them are supported meaningfully by git. But, more or less by definition, a tool that enforced a "right" way to do things would disallow some of these.
So... I don't understand. Do you want a tool that makes the kernel branching style illegal, or one that breaks your own team's workflow? If you want one that supports both, how is that providing clarity about the "right" way to do things?
It isn't hard to imagine a SCM tool (using GIT internally) that enforces a specific set of curated operations for a particular workflow, that teams could agree to use for a given project. You could have different such tools for different workflows on different projects.
You could even write a meta-tool that allows administrators to define and reify a workflow which would then be enforced for developers on a project.
Isn't that what all large projects are doing internally? Hell, big chunks of the git chrome (things like "git am", "git request-pull", "git send-email") is precisely an attempt to write scripts to automate core parts of the kernel workflow. Github added bits of its own, like "watching" a public repository and providing a core spot for pull requests to land, with discussion and review tools. I don't understand why you're so interested in "enforcement" when projects using these tools seem to be doing just fine.
What you're saying sounds to me a lot like the stuff we heard from Java nerds in the 90's (who certainly didn't invent it, Pascal and PL/1 nuts said much of the same stuff) -- the programming environment should be designed to force the user into a particular style. Our community has, for the most part, rejected that view in favor of dynamic systems with more flexibility. Why should SCM branch management be any different?
I think it's a balance. There is value in having people working on a given project aligned on the same basic workflow. To achieve that for a team that is currently growing or is planning to grow, you have to document what that basic workflow should look like. That "document" can be a set of social mores that are loosely enforced through complaint and argument, or an actual document somewhere, or a tool like your parent is suggesting.
Such a tool, which makes the preferred workflow very easy and excursions outside it achievable but somewhat more difficult seems like a pretty good idea to me, and not at all as stuffy and prohibitive as you seem to fear.
I don't disagree at all. But in reality, those tools exist and are all around us. What would be the value of putting that stuff into git itself? Why is it a shortcoming of git that it hasn't picked one?
You might want to look into writing hooks, perhaps? The company I work at has some simple hooks that require you to have a line stating who code reviewed your commit. Sure, it can be bypassed, but there's social pressure not to do so.
I've written my own hooks to do some automated testing on my changes, too. (I've got one that checks for trailing commas in my Javascript files, for instance.)
gerrit's permission system goes a good ways in the direction you're talking about. (Unfortunately, it's rather baroque and poorly documented.) You can specify who can submit patches, who can approve them, who can merge, whether a repository allows merges at all or requires rebasing or cherry-picking, etc.
That's why I like Mercurial a bit more. It takes a bit more work to shoot yourself in the foot from what I've noticed. They recently added the concept of "phases" so something is in draft state until you push to an external repo. At that point, the phase will change to public and it wont let you rebase it w/o doing a force command. You can also mark a branch as private and it wont accidentally get pushed out which is useful if you are doing some local prototyping.
Unfortunately I haven't done a lot with this project in a few years since github doesn't allow bash post commit hooks; you'd have to run your own git server.
(Edit to add...)
So, I understand your impression that it's impossible to enforce workflow in git, given GitHub doesn't support it, and most users probably don't want to write complex post-commit scripts.
But it is actually possible.
It'd be nice if communities like git-flow/etc. codified their rules into post-commit hooks that you could install, and maybe GitHub could even vet (e.g. that the bash scripts won't nuke their servers), and provide as out-of-the-box/opt-in options in the admin section of their repos. E.g. "Enforce git-flow in my repo".
It's an immensely capable tool, but it gives no guidance regarding the right way to do things.
There is no right way. Think about styling. Is there a right style? No. It is silly to argue over your code's appearance. HOWEVER! As soon as you start collaborating with people and reviewing code, a uniform style is a very nice thing to have.
Teamwork creates the need for shared conventions. And that's where your ability to convince your team members of the value of some standardizations comes into play.
different projects on my company use different practices...
It sounds like your problem is not Git, but lack of organization. I am not sure a more restrictive scm would fix that. You need to find a good way to use Git, and then sell everyone on the benefits of process uniformity.
If there's no right style, then couldn't the SCM just pick one arbitrarily so I don't have to worry about spending time communicating about something irrelevant to getting the product shipped?
> The worst thing is that there's no way of enforcing these workflows or practices other than out-of-band social conventions.
False. It's called the Dictator and Lieutenants workflow. It's costly, but if you're in a position where you don't trust your own developers or your conventions are severe, then it's a price you have to pay.
If you can't afford it, hire trustworthy developers or dial back your conventions.
On a repo I've been maintaining, I'm horribly tempted to revoke almost everyone's commit access, for two reasons: to add a code review step to the process, and to be able to keep the commit history reasonably clean.
It's low-tech, but a human gatekeeper's really your only hope for enforcing whatever conventions your project has.
It makes a lot of sense to require that a commit must go through at least 1-2 human reviewers before getting merged to master. In addition to going through automated builds and tests, if applicable.
You need more than one person who can commit to master and is responsible for the merges, but you most certainly don't need every contributor to have commit access.
- hiring developers that appreciate and obey the conventions, or
- reducing the weight of the conventions.
Simply put, if you have conventions that the developers aren't following, you're organization is dysfunctional in some way. Management should include the team when crafting the conventions, and management should take efforts to give the team time/resources to obey them.
Based on what I've seen from popular open-source Python projects I've used in the past (Fabric, Haystack and basically anything else by daniel lindsley) having a single human gatekeeper is the express lane to hell. If you do that make sure you have at least a few core contribs who can approve commits.
There are an awful lot of maintainers for smaller individual pieces/subsytems of the kernel. Take a look at the MAINTAINERS file to see who is responsible for the smaller chunks:
I've never even looked at any linux source code, but I still know there's too much of it to believe Linus reviews and signs off on every single commit personally.
My main issue with the described github-flow is that they push development branches to the server, and encourage that to be done very often.
And my issue with that is once you push something, it's off-limits to any kind of archaeology in the history. And that's not a "principle" thing. If you push your branch, do some rebasing and push again, you are in a world of hurt.
The operation will very likely fail, and recovery is a serious pain in the butt.
If you don't ever do any sort of archaeology, then that's great and it will work for you. I have had numerous occasions where I've tried some git merge or something and screwed things up. I've fixed it by putting my Indiana Jones hat on and digging in.
Being able to tamper with the history has gotten me out of trouble many times. The only time it has gotten me in to trouble is rewriting history that has been published.
And yet if you _don't_ push it to the server, then nobody else can see it. And don't you want other people to see develop branches to give feedback and even to collaborate on writing?
In practice, what everyone does is they DO rewrite history on those pushed dev branches, and they TRY to avoid the world of hurt by some convention for keeping track of what branches are 'development branches', and knowing that their history can change, and thus not _pulling_ from these branches into anything except a branch that does nothing but track the dev branch. And then using 'rebase' in just the right way on your local copy of that dev branch, when you need to. And then winding up in that world of hurt when something goes wrong.
Contrary to all the git apologists in this thread, i think it is one of the biggest usability problems with git. I'm not familiar enough with the other dcvs to know if they manage to do this better. I do know for all that, branching/merging is still a hell of a lot better than it was with svn.
What I myself tend to do is avoid ever rewriting history, sacrificing 'cleanness' for reliability and safety. Except when I'm working on a dev branch for an open source project where they insist upon it, and then I worry, and mess up a lot, and spend lots of time recovering from my mistakes.
"there's no way of enforcing these workflows or practices other than out-of-band social conventions"
I think this is exactly what Linus intended when he designed Git. He explained in a Google talk the way he controls what is committed to the kernel is by just pulling from people he trusts.
If you try to use git as a centralized version control system you lose control of what gets pushed regardless of how many rules and workflows you setup. Have devs send pull requests instead and don't accept/merge bad commits.
While I personally don't subscribe to the "one true way" philosophy, if you do (absolutely nothing wrong with that), you might be better off with mercurial than git.
It would be handy if there was a option to git-rebase that would print a warning if you were about to rebase a commit by someone other than $(git config user.email)
One could also write a pre-receive hook on their git server that denies force pushing, so it becomes impossible to overwrite published history. Combined with a gatekeeper approach of denying pushes to the master branch to all developers except an assigned reviewer, this helps foster the idea that unstable code should always remain local and not be published.
Our own teams have a set of practices which are similar but different from what Linus outlines here. And different projects on my company use different practices from those.
The worst thing is that there's no way of enforcing these workflows or practices other than out-of-band social conventions. And so minor mistakes happen, all the time. Our Git projects are never as pretty as they should be.
In other words, Git provides an awesome set of primitives for source control. I'm not sure what it'd look like, but I'd like to see a product that built on those primitives to enforce a little more order on projects.