A significant part of my job, unfortunately, is helping people fix their workspaces when Perforce (p4) goes bad, or creating guardrails and wrappers to stop Perforce doing bad things.

In fairness, p4 predates most of the VCSes we consider "modern", so I empathize with a lot of the underlying architecture decisions. However, it has and continues to utterly fail at improving at a reasonable pace.

For example:

  - p4 tracks file metadata of client workspaces on the server (sync'ed locally, opened for edit, file revision, etc) and uses this as the basis to avoid doing unneeded work.  If this becomes desync'ed, a reconcile or force sync must be used.  A reconcile can take hours, potentially days; it tries do detect file moves by default, so likely at least O(c^n) for some c>1. I have never personally seen a default reconcile operation _complete_ over any modestly large game code base, and in practice, people accumulate a litany of workarounds and scripts to fix this for themselves.

  - Scripting p4 is a nightmare. Documentation is poor, schemas do not exist, and all the language-specific libraries are just thin wrappers over its C++ API.

  - By default, p4 "helps" you with text files by "correcting" line endings on sync or even converting between encodings. This works until you have a mixed-OS environment, and discover a part of the pipechain that _must_ have a certain style.  There are various levers to pull to make this better, but I've yet to find something fool proof.

  - By default, p4 keeps flies read-only, only unlocking them when explicitly marked as being edited.  This means, to avoid having to do this manually, every tool you use needs to be p4-aware.  Or, you can turn this off, and choose to contend reconcile instead. (See above)

  - Branching a modest game project, with, say, Unreal source code, can take hours.  And this is the quick version where you ask the server to simply create new metadata, with no file transfer to a client.

  - p4 is licensed by the user-account. Every user entity in p4 not intended exclusively for performing backups and maintenance operations counts toward this, including users required to integrate with other services.  Plus, often times, these integration users must have admin access to be useful. The security posture is horrific.

> Scripting p4 is a nightmare

This is why I wish more command line tools were split into a library that does most of the work and a cli module for purely user interaction. Parsing stdout seems so unnecessary and could be avoided if a program could simply import a library.

There are various language specific wrappers for the API - the Python one is good, and now there is a Go one too.

> p4 predates most of the VCSes we consider "modern"

p4 also significantly predates VCSes we consider obsolete. p4 is almost a decade older than SVN.

20yrs ago, for me migrating off p4 onto svn was such a relief and feeling really "freeing" in a way I haven't felt often.

A quick reply;

> p4 tracks file metadata of client workspaces on the server

Honestly, using P4 necessitates a plugin for $EDITOR of choice. The jetbrains IDEs do full on integration, but I managed a decade with an addon that just ran "p4 add/edit" on any save.

> Scripting p4 is a nightmare

Agreed, but so is git, or plastic. My experience has been using the CLI with -Ztag is the way.

> By default, p4 "helps" you with text files by "correcting" line endings on sync or even converting between encodings

This is a nightmare, and definitely one of P4's worst traits. Everywhere I've worked we have a presubmit trigger, to catch this.

> By default, p4 keeps flies read-only, only unlocking them when explicitly marked as being edited.

See point 1, but honestly you go very very far with just p4 edit a whole folder.

> Branching a modest game project, with, say, Unreal source code, can take hours. And this is the quick version where you ask the server to simply create new metadata, with no file transfer to a client.

A new stream including submission at my current job is about 20 minutes. Even at $BIG_CORP with 800 people working on a project, a branch didn't take hours. (Assumning by branch you mean streams. If it's a branch I have no idea, we don't use them)

> p4 is licensed by the user-account

P4's licensing is predatory. It's very much "talk to us", but you'll find out that "talk to us" pricing is exactly the same for absolutely everyone. If you're really lucky, and get someone who is feeling generous, they might give you 1-2 extra automation seats. Given P4's security model is so old, I don't hate shared credentials for this. A bit like IAM roles, nobody should really have access to the credentials even if they were scoped appropriately.

I've been using p4 daily for about 21 years at various game studios (with a small break of around 5 years in the middle, where I used it only sporadically) and I think I can count the number of times I've used "reconcile offline work" on one hand. I think the only time my workspace has gotten into some kind of corrupted state was because of a crash that left it half-synced. If that ever happens I usually just blow it away and force sync the entire repo again rather than use reconcile (because it's so slow).

I’ll add some more

- The P4 cpp api was apparently designed before any modern Cpp std lib was available. And is at best archaic, and stringly to use.

- P4 encoding support is pain in the ass to configure. And ensist on adding or removing bom to files.

Modern cpp is a bit of an oxymoron

Reconciling is my least favourite part. It always feels like everyone’s checkout is a unique blend of local files and permissions you have to fix up now and then. It can be hard to keep track of how much one’s deviated.

I can understand how git isn’t always appropriate for less technical workflows and large file sizes, but p4 pain is its own character.

I've had the misfortune of scripting an UE build with perfoce as the VCS, it truly is abysmal.