I have never worked for FB, so I don't know how internally FB handles this. But my understanding is, FB uses Hg for its main repository. However, FB has developed open source projects which most of them are published on Github, so for those development teams they work with Git. The question is, how do they reconcile some dev teams are context switching between hg and git? How common is that?
Personally, I would allow one DVCS only, so my internal development platform doesn't have to support both Git and Hg (who knows, maybe FB also have teams using SVN for good reasons).
People at Facebook who use both internal repos and external ones (like me) need to know both hg and git. It's not too hard; the two provide similar functionality and many of our hg extensions (https://bitbucket.org/facebook/hg-experimental) make hg more git-like in some ways.
Most of our open source projects also use an in-house tool "fbshipit" https://github.com/facebook/fbshipit to automatically export internal commits to open source so if you make changes that happen to touch an open source project but it's not your primary focus then you can work entirely in the internal (hg) repo and your changes get copied out automatically.
Do you go through a process to clean those commits for open source?
It sounds really interesting - I assume the tool is mostly just for marshalling commits (or parts of commits?) that touch external projects, but I would also assume that someone then needs to do the work to get those changes into a publishable state. Organising commits into a consistent set of changes, meaningful commit messages for the target project, removing any vestiges of internal content.
Is there a team who manage all of those aspects, or is it down to the individual developers liaising with the open source projects?
We don't. We err on the side of moving faster here and asking people not to put internal-only info in commit messages that might be exported. We don't reorganize commits since it's usually more valuable to export them as they were developed/committed internally. No one looks at every commit before they get published to our GitHub repos though, other than the regular code review that happens on every internal commit.
What happens in the case of a series of commits that belong together? Is there a way of making sure they are applied to the project correctly (say in a branch or something)?
I guess the point is moot if internally you are more-or-less working on the full tree of the external project. In that case, the commits would already be organised however they needed to be.
The alternative would be that the external project is mixed in with an internal one, and you make commits against both in the same tree. Lots of potential edge cases around refactored commits etc, and I would guess the tool assumes you follow a certain set of workflow guidelines (like not force pushing a new set of commits) so those edge cases may not be that important.
External projects that use fbshipit each live in a subdirectory of an internal project. We don't use branches or merge commits, and commits are exported in order.
Do third party changes get brought into the external project, and how do they get brought back into the internal project?
For example, would a third party contributor need to rebase their work when pushing in order to make history linear? Do you ever get situations where different internal projects are trying to use fbshipit on the same external project, at the same time?
> Do third party changes get brought into the external project, and how do they get brought back into the internal project?
There's a feature of fbshipit called "importit" that allows for importing an external pull request from GitHub and reversing the path mapping in order to create an internal commit. That's how we land all changes on projects that use fbshipit. The internal repo is the source of truth and an employee always needs to land that commit internally, then it gets synced back out automatically and the PR closed.
> For example, would a third party contributor need to rebase their work when pushing in order to make history linear?
We typically end up squashing each PR into one commit.
> Do you ever get situations where different internal projects are trying to use fbshipit on the same external project, at the same time?
Each external project lives in only one internal repo and that is the source of truth. Occasionally we have scripts to automatically copy files between internal repos when pieces need to be shared but we try to avoid it. We prefer merging repos together and making larger single repos. Most of our developers work in one of two large repos – one for all our web products, and one for all our backend services and mobile apps.
Also facebook is a big company, and like all bigger companies many people in it prefer different stuff.