From a comment on StackOverflow:
Vendoring is the moving of all 3rd party items such as plugins, gems and even rails into the /vendor directory. This is one method for ensuring that all files are deployed to the production server the same as the dev environment.
The activity described above, on its own, is fine. It merely describes the deployment location for various resources in an application.
However, many programmers have begun to commit the result of the above procedure to their own source code repositories.
That is to say, they copy all of the files at some version from one version control repository and paste them into a different version control repository.
You should have flinched reading the previous description. This practice is more vile than extending existing code by duplicating whole functions instead of using inheritance and abstraction, and for the same reasons.
Extracting code from a version control repository to be archived in a compressed file or stored in a particular directory for deployment is not bad.
Extracting code from a version control repository to be re-comitted to a different version control repository is evil.
When you copy code between repositories:
- all history, branch, and tag information is lost
- pulling updates is impossible
- it invites modification, divergence, and unintentional forks
- it wastes space
- it is excruciatingly tedious to discover later which version of the code was the canonical source of the copied version, unless the person doing it went out of their way to document that information
Git's submodule mechanism stores a URL and a commit hash in your repository, which itself is under version control.
(TODO: explain more, examples of work-alikes from different VCSs)
If you can't use git submodules, use a script that deploys your third-party resources at the appropriate time, from a canonical source.
(TODO: describe more, provide examples)
If you have a situation where it seems like "vendoring" is really the best way to deploy your code, contact me, call me an idiot, and describe why. I'm sure there's a better way, and where there's not, it's a bug. I hope to eventually document all such situations to prevent people from falling into this bad habit.
First off, I can confirm that git-submodule is awful to work with. :-)
I've extensively worked with both vendoring and cached repo based build tools like Maven. The OP is clearly frustrated but is also not using best vendoring practices, as pointed out (but that's no excuse for ad-hominem attacks). Still, if I may chip in my 2c this late, I don't think vendoring is an inherently superior method of dependency management.
Vendoring is no more effective for achieving build reproducibility than, say, a repository based system with fixed version numbers such as Maven.
Vendoring is no more effective for building offline than any other build system with a cache. Vendoring is a cache, Maven's ~/.m2/repository is a cache, etc. Being offline only matters when you're changing a dependency, and you're hosed with both methods in that case.
Vendoring is not necessary for diagnosing problems in library code. Any decent IDE will have a debugger that will give you the option of pulling down library source when stepping through.
More subjectively speaking -
It's one.
The back-in-time problem has no reasonable panacea, precisely because of the _ API-OS-toolchain-lib incompatibilities_ mentioned. If some of my team's machines have all moved on to different OS versions or patch levels, 100% old build reproducibility "just working" cannot be guaranteed. Even so, for me personally, this isn't a big or frequent enough problem for me to want to clutter up my repos with vendor code, because the proffered advantages of doing so aren't worth the cost to me.
Every tool and technique has flaws and tradeoffs to make. Including the ones that you and I am familiar and efficient with. This little cognitive bias is worth considering: Golden Hammer.