Imagine the following imaginary scenario:
One day you’ve been assigned to a new project.
It turn out you should modify an ancient system.
How ancient? The code is on a production machine you should ssh to, and it was written before source control was invented. How do I know that? because it does not use source control. It’s just developers writing shell scripts and python files and if you’re lucky they copy a backup just before they did it to a
If you’re unlucky, there is no documentation and you don’t have a clue or context why and when it was written other than its linux file metadata.
So you’re this smart-ass developer saying “we must have git for this” and they just yell at you: “we want the flexibility of editing those files just where they are executed”.
Here is my advice if you encounter such case: use 2-Way-SyncⓇ*.
Let me explain how it works, but first what it allows. It allows you to put all those files to a git repository, and edit the files either with Pull-Requests and Code-Review and all those clean-code-best-known-methods. Or just manually edit them with vim on the production machine at your own risk. But if you know how to exit from vim there is no risk.
The idea is to use an intermediate repository that will sync from/to both. Let’s call them the following repositories: P[roduction], G[it server] and I[ntermediate repo].
The sync works as follows:
- Commit all un-committed changes on P.
- Rebase changes from P to I.
- Rebase changes from G to I.
- Push changes from I to G.
- Push changes from I to P.
- Repeat this process as often as possible. We use jenkins job that runs every minute.
There is still a small chance for conflicts that will fail this, but it will happen only on a conflict that cannot automatically be resolved. I guess only if the same file was edited on both git and production at the same time. Luckily we didn’t encounter that yet.
Here are the actual commands to execute (from I server):
See also the initial setup in the comments of the script above.
The main caveat is that you can’t push directly to master branch on production (unlike git server) so an “upload” branch is used in-between.
Hope that you’ll never need that, but in case you do, that it will be clear enough and useful.
*It’s actually not a registered trademark, I got help from the smart people at stack-overflow.