I have used Git at my past two companies for version control. It seems from what I've heard that about 90% of companies use Git over other version control systems.

One of the biggest selling points of Git is that it is decentralized, i.e. all repositories are equal; there is no central repository/ source of truth. This was a feature Linus Torvalds championed.

But it seems that every company used Git in a centralized manner, much like one would use SVN or CVS. There is always a central repository on a server (usually on GitHub) that people pull from and push to. I have never seen or heard of (in my admittedly limited experience) people using Git in the truly decentralized manner in which it was intended, i.e. pushing and pulling to other colleagues repositories as they saw fit.

My questions are:

  1. Why don't people use a distributed workflow for Git in practice?
  2. Is the ability to work in a distributed manner even important to modern version control, or does it just sound nice?

Edit

I realized I didn't get across the correct tone in my original question. It sounded like I was asking why anyone would work in a centralized manner when a distributed version control system (DVCS) was so obviously superior. In actuality, what I meant to say was, I don't see any benefits to DVCS at all. Yet I often hear people preaching its superiority, while the real-world seems to agree with my view.

  • 29
    I feel the exact same way, and do not understand this. – Snoop Apr 9 '16 at 15:42
  • 56
    Personally, I just don't know of any use cases for multiple remotes, other than forks for creating PRs to the main remote. The distributed thing is still useful because it means I get a complete history on my machine without having to talk to the network, and I can do some work offline if I really want to, and it's much easier to migrate from one online repo host to another. What exactly do you have in mind when you refer to a "distributed workflow"? – Ixrec Apr 9 '16 at 15:56
  • 42
    I am fairly certain Torvalds intended from the beginning to have one "source of truth" Linux Kernel repository. – Steven Burnap Apr 9 '16 at 16:00
  • 64
    Ultimately, software itself is centralized. Customers don't buy branches or remotes, they buy a final, put-together, built product. There always needs to be some central path forward. – Brandon Apr 9 '16 at 16:19
  • 35
    To me git's "decentralized-ness" is one of the least important features recommending it. The ability to do frequent commits and rollbacks locally, without affecting anyone else, or powerful techniques such as rebasing are where git really shines in my workflow. It's possible (indeed probable) that all these are made possible by being decentralized, but the "D" in DVCS isn't that important by itself to me. – Jay Apr 11 '16 at 0:16

14 Answers 14

up vote 251 down vote accepted

Ahh, but in fact you are using git in a decentralized manner!

Let us compare git's predecessor in mindshare, svn. Subversion had only one "repo", one source of truth. When you did a commit, it was to a single, central repo, to which every other developer was committing as well.

This sort of worked, but it led to numerous problems, the biggest one being the dreaded merge conflict. These turned out to be anywhere from annoying to nightmarish to resolve. And with one source of truth, they had a nasty habit of bringing everyone's work to a screeching halt until they were resolved. Merge conflicts certainly exist with git, but they are not work-stopping events and are much easier and faster to resolve; they generally affect only the developers involved with the conflicting changes, rather than everyone.

Then there is the whole single-point-of-failure, and the attendant problems that brings. If your central svn repo dies somehow, you're all screwed until it can be restored from backup, and if there were no backups, you're all doubly screwed. But if the "central" git repo dies, you can restore from backup, or even from one of the other copies of the repo which are on the CI server, developers' workstations, etc. You can do this precisely because they are distributed, and each developer has a first-class copy of the repo.

On the other hand, since your git repo is a first-class repo in its own right, when you commit, your commits go to your local repo. If you want to share them with others, or to the central source of truth, you must explicitly do this with a push to a remote. Other developers can then pull down those changes when it's convenient for them, rather than having to check svn constantly to see if someone's done something that will screw them up.

The fact that, instead of pushing directly to other developers, you push changes to them indirectly via another remote repo, doesn't matter much. The important part from our perspective is that your local copy of the repo is a repo in its own right. In svn, the central source of truth is enforced by the design of the system. In git, the system doesn't even have this concept; if there is a source of truth, it is decided externally.

  • 12
    SVN merges also only affect the developers involved with conflicting changes. One commit makes it into the repo, no conflicting merge can go into the repo until the conflicts are resolved (you can also commit in parallel to a separate branch/path, but that doesn't actually conflict now does it?) – Ben Voigt Apr 10 '16 at 1:36
  • 27
    I find the main difference, when a central server exists, to be that GIT allows ongoing local versioning while the network is down, and SVN doesn't (some other version control systems are even worse, and stop all work when the network is unreachable, because they don't let you change a file until you check it out). – Ben Voigt Apr 10 '16 at 1:37
  • 17
    @BenVoigt Oh, it's work stopping all right. Remember you have to svn up be up to date with the repo before you can check in. When others continue checking in while you're trying to resolve merge conflicts, and give you another set of merge conflicts... you either put a stop to that or you lose what's left of your sanity. – Michael Hampton Apr 10 '16 at 1:47
  • 20
    No, people can definitely keep committing into the branch you're merging changes from, without interrupting your workflow. – Ben Voigt Apr 10 '16 at 1:49
  • 28
    Ben's right. An SVN repo managed properly, and used by a team that has been properly educated in how to develop software, should effectively never have merge conflicts on trunk. You'll only get them when someone's done something wrong and needs to be fired (:P). inb4 it's easier when you don't have to educate people how to use their tools. Yeah, well, there's a lot more to teach about Git than there is about SVN! – Lightness Races in Orbit Apr 10 '16 at 18:14

When your build server (you are using CI, right?) creates a build, where does it pull from? Sure, an integration build you could argue does not need "one true repo" but surely a distribution build (i.e. what you give to the customer) does.

In other words: fragmentation. If you designate one repo as "the" repo and appoint guardians who vet pull requests, you have an easy way to satisfy the request of "give me a software build" or "I am new to the team, where is the code?"

The strength of DVCS is not so much the peer-to-peer aspect of it, but the fact that it is hierarchical. I modify my workspace, then I commit to local. Once I have a feature complete, I merge my commits and push them to my remote. Then anyone can see my tentative code, provide feedback, etc. before I create a pull request and a project admin merges it into the One True repo.

With traditional CVCS you either commit or you don't. That is fine for some workflows (I use both VCS types for different projects), but falls flat on its face for a public or OSS project. The key is DVCS has multiple steps, which are more work, but provide a better way to integrate code from strangers through a built-in process that allows better visibility into what is being checked in. Using it in a centralized manner means you can still have that gold standard of the current state of the project while also providing a better code sharing mechanism.

  • 2
    Overall good answer, but I'm pretty sure that Git was in widespread use before Continuous Integration was; our team does use CI, by the way, thanks for checking :D. – gardenhead Apr 9 '16 at 22:18
  • 5
    @gardenhead: you missed the point: the same argument holds if one does the integration builds manually. "CI" is just an automatization for a process which is much older that Git. – Doc Brown Apr 9 '16 at 23:48
  • 24
    "anyone can see my tentative code" -- and they can also pull your tentative code, merge it with their tentative code, and run the tests. This is a pain in centralized VCSes, since it requires branches and changes in the One True Copy. Distributed, you just configure extra remotes, then start merging, patching, and cherry-picking. You have tracking of what you've done but nobody else ever has to see what shenanigans you're up to unless you choose to publish them. In general I recommend nobody should declare DVCS pointless until they've actually used SVN for a large project... – Steve Jessop Apr 10 '16 at 0:40
  • 9
    Because there is no "one true build" of the linux kernel. Since everyone builds it themselves, Linus' repo is no more canonical than anyone else's. If you're selling a product that doesn't work so well. – Miles Budnek Apr 10 '16 at 6:25
  • 2
    @Superbest: a lot (if not all) of the design of git was based around Bitkeeper. Git was created after the linux-bitkeeper controversy imploded. – whatsisname Apr 10 '16 at 6:42

I don't know how you define "everyone", but my team has "a central repo on a server" and also from time to time we pull from other colleagues' repos without going via that central repo. When we do this we do still go via a server, because we choose not to email patches about the place, but not via the central repo. This generally happens when a group is collaborating on a particular feature and wants to keep up to date with each other, but as yet has no interest in publishing the feature to everyone. Naturally since we aren't secretive silo-workers those situations don't last long, but DVCS provides the flexibility to do whatever is most convenient. We can publish a feature branch or not according to taste.

But 90%+ of the time, sure, we go via the central repo. When I don't care about any particular change or particular colleague's work it's more convenient, and it scales better, to pull "all my colleagues' changes that have been vetted in the central repo", rather than separately pulling changes from each of N colleagues. DVCS isn't trying to prevent "pull from main repo" being the most common workflow, it's trying to prevent it being the only available workflow.

"Distributed" means that all repos are technically equivalent as far as the git software is concerned, but it doesn't follow that they all have equal significance as far as developers and our workflows are concerned. When we release to clients or to production servers, the repo we use to do that has a different significance from a repo used only by one developer on their laptop.

If "truly decentralized" means "there are no special repos" then I don't think that's what Linus means to champion, given that in point of fact he does maintain special repos that are more important in the grand scheme of things, than is some random clone of Linux that I made yesterday and plan to use only to develop some little patch and then delete it once he's accepted the patch. git doesn't privilege his repo over mine, but Linus does privilege it. His "is the current state of Linux", mine isn't. So naturally changes tend to go through Linus. The strength of DVCS over centralized VCS isn't that there must not be a de facto centre, it's that changes don't have to go through any centre because (conflicts permitting) anyone can merge anything.

DVCS systems are also forced, because they are decentralized, to provide certain convenient features based around the fact that you necessarily must have a complete history (i.e. a repo) locally in order to do anything. But if you think about it there's no fundamental reason why you couldn't configure a centralized VCS with a local cache that keeps the whole history for read-only operations permitted to be out of date (I think Perforce has an option for this mode, but I've never used Perforce). Or in principle you could configure git with your .git/ directory on a remote-mounted filesystem in order to emulate the "feature" of SVN that it doesn't work when you don't have a network connection. In effect, DVCS forces the plumbing to be more robust than you can get away with in a centralized VCS. This is a (very welcome) side effect and helped motivate DVCS design, but this distribution of responsibility at the technical level isn't the same as fully decentralizing all human responsibility.

  • 7
    They're technically equivalent, not socially equivalent. – curiousdannii Apr 11 '16 at 4:23
  • 3
    Emailing patches is fairly painless, just in case anyone is considering it, just use git format-patch and then git send-email. Did that when I didn't want to fiddle around with Github's access controls and it was very straightforward, everyone has email after all. – Rudolf Olah Apr 11 '16 at 18:06
  • 1
    "necessarily must have a complete history [...] locally in order to do anything" -- not true; modern DSCMs support partial repos ("shallow checkouts" in bzr terms, "shallow clones" in git terms). – Charles Duffy Apr 13 '16 at 2:28

The interesting thing about the nature of DVCS, is if other people are using it in a distributed manner, you likely wouldn't know it unless they are interacting directly with you. The only thing you can say definitively is that you and your direct teammates don't use git this way. This doesn't require a company-wide policy. So I will ask you, why don't you use git in a decentralized manner?

To address your edit, perhaps you need some experience working with an actual centralized version control to appreciate the differences, because although they may seem subtle, they are pervasive. These are all things my team actually does at work that we couldn't do when when we had centralized VCS:

  • Have a very small list of core developers with commit access to the "central" repo for each microservice. Everyone else can work out of forks and submit via pull requests.
  • Can commit much more frequently, usually several times per hour versus once or twice per day.
  • Can create branches for any reason to coordinate temporarily with coworkers, and push to it and pull from it several times per day, then squash it when ready to share with a larger group. Do you have any idea how hard it is to get permission to create a temporary branch for something like this in a traditional CVCS?

At the risk of sounding old for saying it, you really don't know how easy you have it.

  • 1
    The question how hard it is to create a branch in a traditional CVCS is entirely down to policy: I happen to work with an upstream SVN repo (naturally via a git-svn clone!), and I have every right to create any branches I want to, even though it's quite a large project. I'm just not allowed to touch a number of designated integration branches, let alone the trunk, without talking to my superiors first. Other companies may have other policies which may be more restrictive, but they certainly don't have to be. – cmaster Apr 10 '16 at 7:06
  • 7
    You're right, I don't know how easy I have it. I wish I had been around in the days of SVN dominance to appreciate how far we've come. As a very young software developer, I find this same pattern repeating quite often: the more experienced devs telling me that the old way of doing something was bad, and this new way / technology is much easier. But I just have to take their word for it; I can never truly appreciate the advantages. I've always found this dissonance difficult to overcome. – gardenhead Apr 10 '16 at 16:31
  • 1
    @gardenhead you can always create your own SVN repo and try to break it ;) (and notice how much harder it is than creating a git repo and cloning it...) - One other major feature I've noticed (at least in corporate environments especially) is that file sharing is either a bit awkward, or it's done in such a way that horks up repositories (because virus scanner locks on a network drive, for instance). – Wayne Werner Apr 11 '16 at 0:51
  • 4
    @gardenhead: well, consider yourself lucky that you're not stuck in a legacy project, with old software developers who are telling you the old way of doing things is just fine... sometimes you can't help but feel they are just glad they don't need to learn any new technologies! – leftaroundabout Apr 11 '16 at 15:25
  • 1
    @gardenhead apparently projects are being released at a pretty insane rate. The ability to continue learning is necessary if you want to be able to find an awesome job. – Wayne Werner Apr 12 '16 at 12:45

I think you're question comes from an (understandable) always connected mindset. i.e. The central 'truth' ci server is always (or near always) available. While this is true in most environments, I have worked in at least one which was far from this.

A Military Simulation project my team worked on several years ago. All the code (We're talking a >US$1b codebase) had to (by law/international agreement, men in dark suits come if you don't) be on machines physically isolated from any Internet connection. This meant the usual situation of we each had 2 PCs, one for writing/running/testing the code, the other to Google things, check E-mail and such. And there was a local network within the team of these machines, obviously not in any way connected to the Internet.

The "central source of truth" was a machine on an army base, in an all-cinderblock underground windowless room (reinforced building, yada-yada). That machine also had no Internet connection.

Periodically, it would be someone's job to transport (physically) a drive with the git repo (containing all our code changes) to the army base - which was several hundred kilometers away, so, you can imagine.


Moreover, in very large systems where you have lots of teams. They will generally each have their own "central" repo, which then goes back to the actual (god tier) "central" central repo. I know of at least 1 other contractor who did the same hard-drive git repo dash with their code too.

Also, if you consider something on the scale of the Linux kernel... Developers don't just send a pull request to Linus himself. It's essentially a hierarchy of repo's - each of which was/is "central" to someone/some team.

The disconnected nature of git means that it can be used in environments where connected model source-control tools (i.e. SVN, for one) couldn't be used - or couldn't be used as easily.

  • 3
    I'm a member of the Mile High (Software) Club - I've committed code at 35,000 feet. Sure, planes have Wifi now, but that wasn't always the case. And it's nice to know that at least if we crash there's a possibility that my team will get my code intact. – Wayne Werner Apr 11 '16 at 0:56
  • @WayneWerner that's true. I had been thinking about providing some more generic situations where it wasn't possible to be (near-)always connected. E.g. on a plane, boat out at sea, space station, remote places in Africa, etc. – Tersosauros Apr 11 '16 at 3:50

Ultimately, you are building a product. This product represents your code at a single point in time. Given that, your code must coalesce somewhere. The natural point is a ci server or central server from which the product is built, and it makes sense that this central point is a git repository.

The distributed aspect of a DVCS shows up in open source development all the time, in the form of forking. For example, some of the projects I contribute to were abandoned by the original author and now have a bunch of forks where the maintainers sometimes pull specific features from one another. Even in general, OSS projects take outside contributions via pull request, rather than by granting random people push access to the ground-truth repo.

This isn't a very common use case when building a concrete product with a specific official release, but in the F/OSS world it's the norm, not the exception.

  • 4
    That is the right answer, also from a historical point of view. The Linux kernel has had multiple source repositories for a long time (called "trees" by the developers, such as "Linus' tree" or "Andrew's tree"). Linux wanted something to support that type of distributed development when he developed git. – sleske Apr 10 '16 at 7:30
  • @Luaan After thinking about this for a while, I realized you're right. I've changed the wording a bit - does this capture the distinction a bit better? – fluffy Apr 11 '16 at 23:34
  • @fluffy Sounds good to me ;) – Luaan Apr 12 '16 at 8:04

Why does everyone use git in a centralized manner?

We've never met, how comes that you say everyone? ;)

Secondly, there are more other features that you find in Git but not in CVS or SVN. Maybe it's just you assuming that this must be the only feature for everyone.

Sure many people may use it centralized like CVS or SVN. But don't forget the other feature that inherently comes with a ditributed VCS: all copies are more or less "complete" (all branches and the full history is available) and all branches can be checked out without connecting to a server.

I my opinion this is another feature that should not be forgotten.

While you're not able to do this with out of box CVS and SVN, Git can be used centralized like the former ones without any problems.

So I'm able to commit my changes, maybe squash work-in-progress commits together, then fetch and rebase my work onto the main development branch.

Other features that come out of box with Git:

  • cryptographically sign commits
  • rebasing (reorder and squash commits; edit commits, not only the message)
  • cherry picking
  • bisecting the history
  • local branches and stashing changes (called "shelving" in Wikipedia)

Also see these three tables in Wikipedia - Comparison of version control software:

So again, maybe the decentralized manner isn't that only feature that make people use it.

  1. Why don't people use a distributed workflow for Git in practice?

Anyone contributing to or hosting a bigger project on Bitbucked, GitHub etc. will excactly do that. The maintainers keep the "main" repository, a contributor clones, commits and then sends a pull request.

In companies, even with small projects or teams, a distributed workflow is an option when they either outsource modules and don't want externals to modify the sacred development branch(es) without having their changes reviewed before.

  1. Is the ability work in a distributed manner even important to modern version control, ...

As always: it depends on the requirements.

Use a decentralized VCS if any point applies:

  • want to commit or navigate the history offline (i.e. finishing the submodule in the mountain cabin during vacation)
  • provide central repos but want to keep "the true" repository apart to review changes (i.e. for big projects or distributed teams)
  • want to provide (a copy of) the whole history and branches occasionally while preventing direct access to the central repo (similar to the second one)
  • want to version something without having to store that remotely or setting up a dedicated repository (especially with Git a mere git init . whould be enough to be ready to version something)

There are some more but four should be enough.

... or does it just sound nice?

Of course it sounds nice - for beginners.

  • Didn't SVN gain svn init at some point? – immibis Apr 12 '16 at 4:11

Flexibility is a curse as well as a blessing. And as Git is extremely flexible, it's almost always far too flexible for the typical situation. Specifically, most Git projects aren't Linux.

As a result, the smart choice is to remove some of that theoretical flexibility when implementing Git. In theory repositories can form any graph, in practice the usual choice is a tree. We can see the clear benefits using graph theory: in a tree of repositories, any two repositories share exactly one ancestor. In a random graph, the idea of an ancestor doesn't even exist!

Your git client however almost certainly defaults to the "single ancestor" model. And graphs in which nodes have a single ancestor (except for a root node) are exactly trees. So your git client itself defaults to the tree model, and therefore centralized repositories.

  • 1
    I agree that the flexibility of Git needs to be toned down for most use cases. At my last job, we didn't have guidelines on how to use git, and there were constant conflicts and breakage due to this. At my new company, we use the Git Flow model, and it makes development much more streamlined and stress-free. – gardenhead Apr 11 '16 at 14:53
  • 1
    It's not "theoretical flexibility" to allow non-trees. Restrict yourself to "trees only" and you will never be able to merge in your changes, thus rendering your entire VCS somewhat pointless. – Wildcard Apr 11 '16 at 15:44
  • 2
    @Wildcard: Merging is no problem at all with trees, why would that be the case? You can't merge between random nodes, of course, just between parent/child. – MSalters Apr 12 '16 at 7:00
  • 1
    I wasn't clear enough, evidently. I was referring to a tree of commits, not a filesystem tree. By definition, a merge commit has more than one parent, and your history graph is therefore no longer a tree, but instead is a DAG. – Wildcard Apr 12 '16 at 19:02
  • 2
    @Wildcard: MSalters said that repositories are usually connected as trees, not that commits are. He's saying that repos usually have only one "upstream" remote that they push to (or issue pull requests to). I don't have any statistics on whether that's true or not, but it's a completely separate claim from anything to do with how many parents a merge commit has. – Steve Jessop Apr 14 '16 at 11:04

Business logic rewards a centralized server. For nearly all realistic business scenarios, a centralized server is a fundamental feature of the workflow.

Just because you have the capacity to do DVCS doesn't mean your primary work flow has to be DVCS. When I use git at work, we use it in a centralized manner, except for those strange odd cases where the distributed bit was essential to keeping things moving along.

The distributed side of things is complicated. Typically you want to keep things smooth and easy. However, by using git you ensure that you have access to the distributed side to deal with the gnarly situations that may arise down the road.

For a coworker to pull from a git repo on my machine means I need to have a git daemon running at root level as a background task. I am very leery of daemons running on my own computer, or on my company-provided laptop. The easiest solution is "NO"! For a coworker to pull from a git repo on my machine also means my internet address needs to be fixed. I travel, I work from home, and I occasionally work from my office.

On the other hand, VPNing to the corporate site and pushing an branch to the central repo takes less than a minute. I don't even need to VPN in if I'm in the office. My coworkers can easily pull from that branch.

On the third hand, my local git repo is a full-featured repository. I can commit new work, create a new branch for experimental work, and revert work when I make a mess of things, even when I'm working in an airplane flying at 30,000 feet over the middle of nowhere. Try doing that with a centralized version control system.

  • " I am very leery of daemons running on my own computer, or on my company-provided laptop." -- because aside from anything else, running a service on my laptop means that the service is unavailable when I close the lid! DynDNS might help with multiple locations (to an extent, you can still be trapped behind a NAT), but it doesn't help with powering down your network card... – Steve Jessop Apr 14 '16 at 11:10
  • There are plenty of ways of making a git repo visible without running any special daemon; it can be accessed via pretty much any file share (smb, sshfs, etc.), and can even be made available as a plain ol' HTTP store as well. – fluffy Apr 14 '16 at 19:51

Complexity:

With a central repository, a typical work flow might be

branch off from the central master branch
change the code
test
possibly go back to changing the code
commit
merge any new changes from the central master branch
test
possibly go back to changing the code
merge changes into the central master branch and push

The complexity with respect to the number of developers in O(1).

If instead each developer has their own master branch it becomes, for developer 0:

branch off from master branch 0
merge from master branch 1
...
merge from master branch N-1
change the code
test
possibly go back to changing the code
commit
merge any changes from master branch 0
merge any changes from master branch 1
...
merge any changes from master branch N-1
test
possibly go back to changing the code
merge changes into master branch 0

The peer-to-peer approach is O(N).

Consistency:

Now consider if there is a merge conflict between Alice's master branch and Bob's master branch. Each of the N developers could resolve the conflict differently. Result: chaos. There are ways of achieving eventual consistency, but until that happens, all sorts of developer time can be wasted.

  • If you are going to down vote, could you please leave a comment on why? – Theodore Norvell Apr 14 '16 at 16:02
  • Not that I mind the downvotes. I just want to know if the answer is wrong in some way. – Theodore Norvell Apr 14 '16 at 20:03

Simple:

Companies are centralized organizations, with centralized workflow.

Every programmer has a boss and he has his boss, etc up to CTO. CTO is the ultimate source of technical truth. Whatever tool company uses, it must reflect this chain of command. A company is like an army - you can't let privates outvote a general.

GIT offers features that are useful to the companies (eg. pull requests for code review) and that alone makes them switch to GIT. The decentralized part is simply a feature they don't need - so they ignore it.

To answer your question: The distributed part is indeed superior in distributed environment, eg open-source. Results vary depending on who's talking. Linus Torvalds is not exactly your cubicle rat, that's why different features of GIT are important to him than to your github-centric company.

Maybe it is because he payroll processing is centralized, so we have to keep a central person happy if we wish to get paid.

Maybe it is because we are creating one product, so we need a master copy of the software for the customers.

Maybe it is because it is a lot easier for a programmer to go to one place to get everyone’s changes, rather than having to connect to lots of different machines.

Maybe it is because the bug database is centralized, and must be kept in sync with the code.

Being centralized is great, until there is a problem…..

Git being a distributed system allows a new centre to be created at low cost from any up-to-date repository (just expose the repository to the network). Git also allows an out of date backup to be updated from the repositories on developer machines, so making it easier to recover the centre.

Being able to do merge etc on a local copy of a repository when the network is down is great, but does not need a distributed system; it just needs a system that keeps a local copy of all the data. Likewise with checking in code with flying etc.

At the end of the day there is little cost for being distributed and some benefits. Most of the cost of being distributed is in area that are needed if you want great tracking of branches etc. If you were to design a system for usage in most companies you would not design it to be distributed, as centralized control of the source code is clearly the primary “use case”.

protected by gnat Apr 10 '16 at 15:54

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.