01 September 2018 | 4 min read

Patching file with diff and patch

How to do file patch without VCS?

There is a way but it quite complicated and people tend to do mistake when handling lot of files / directory but sometimes developer don’t have connection to VCS and we don’t have any option.. ;d

I face difficult situation during previous project to deploy changes on AIX machine when unlucky we don’t have VPN access to our CVS. I learn something and let me show you the harder way to manage you source code.

#Patching Hello World

For example, I have nodeJS codes and we need to do some changes on hello.js (our target) and I don’t want to lose the current codes we have right now, so we create a backup called as hello.js.BEFORE_CHANGES

$ cp hello.js hello.js.BEFORE_CHANGES

Let me show to you what inside our current code:

const express = require('express')
const app = express()
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(3000, () => console.log('Example app listening on port 3000!'))

Now lets do some changes on hello.js, I change port number and response data

const express = require('express')
const app = express()
app.get('/', (req, res) => res.send('Hello Dunia Yang Zalim!'))
app.listen(1337, () => console.log('Example app listening on port 1337!'))

So this is our current changes

--- hello.js.BEFORE_CHANGES	2018-09-01 10:18:05.403580392 +0800
+++ hello.js	2018-09-01 10:24:13.492668930 +0800
@@ -1,4 +1,4 @@
 const express = require('express')
 const app = express()
-app.get('/', (req, res) => res.send('Hello World!'))
-app.listen(3000, () => console.log('Example app listening on port 3000!'))
\ No newline at end of file
+app.get('/', (req, res) => res.send('Hello Dunia Yang Zalim!'))
+app.listen(1337, () => console.log('Example app listening on port 1337!'))
\ No newline at end of file

Now we need to create a copies of thus changes to new file. We should call it as hello.js.MODIFIED and put hello.js.BEFORE_CHANGES back as hello.js

$ mv hello.js hello.js.MODIFIED
$ cp hello.js.BEFORE_CHANGES hello.js

We going to create a patch file by stdout to new file, I called as hello.js.PATCH

$ diff -u hello.js hello.js.MODIFIED > hello.js.PATCH

So this is our current changes

--- hello.js	2018-09-01 10:18:05.403580392 +0800
+++ hello.js.MODIFIED	2018-09-01 10:24:13.492668930 +0800
@@ -1,4 +1,4 @@
 const express = require('express')
 const app = express()
-app.get('/', (req, res) => res.send('Hello World!'))
-app.listen(3000, () => console.log('Example app listening on port 3000!'))
\ No newline at end of file
+app.get('/', (req, res) => res.send('Hello Dunia Yang Zalim!'))
+app.listen(1337, () => console.log('Example app listening on port 1337!'))
\ No newline at end of file

Now we are going to send this so called PATCHES to our friends and start patching as deployemt on his system via patch and we can simulate the patching process with --dry-run args.

$ patch -b --dry-run -p0 < hello.js.PATCH

At this stage the patch has not been applied. We just simulated the application (with the –dry-run option), to see if we are going to find any problems with it. Remove --dry-run args to deploy the patches but keep -b args

$ patch -b -p0 < hello.js.PATCH
patching file hello.js

If you get message like below, than you got problem to patch file:

Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED -- saving rejects to file *.rej

Thank to -b arg, it will auto create .orig and .rej as backup and for inspection. Try to check if the target file are same as *.BEFORE_CHANGES

Otherwise, you patch should be worked fine.

#What you think?

It look easier? Imagine you have tonnes of files and you do silly mistake or you comrade do code changes without telling you. It gonna be disaster!

Robbi Nespu | AIX, Bash, Code, Fedora, Linux, VCS


Discussion and feedback