GNU patch and diff

DaEezT

Civ, Pizza, Spam, Repeat
Joined
Sep 22, 2001
Messages
1,087
Location
Munich, Germany
Even though I'm not a mod developer I'd still like to recommend two little programs that might help those who mod and those who want to use those mods:
GNU patch and GNU diff

What would be the advantage of using those tools?
a) It would would be easy to combine multiple mods that modify the same file. patch is able to patch files multiple times and automatically detects collisions. So it would aid those who want to make mod packs that include other people's mods (e.g. Dearmad's mod) and those who want to use multiple mods.

b) It could ease the transition between official game patches in cases where the python files are changed by Firaxis.


Lets have an example with the Simple Game Clock Mod by homegrown (I use the version from November, 10th in this example).
diff -u CvMainInterface.py CvMainInterface_mod.py
--- CvMainInterface.py 2005-10-17 08:47:22.000000000 +0200
+++ CvMainInterface_mod.py 2005-11-05 15:20:18.000000000 +0100
@@ -744,7 +744,7 @@

if (g_iTimeTextCounter >= 30.0): # 15 seconds
g_iTimeTextCounter = 0.0
- self.updateTimeText(false)
+ self.updateTimeText(true)
screen.setLabel( "TimeText", "Background", g_szTimeText, CvUtil.FONT_RIGHT_JUSTIFY, xResolution - 56, 6, -0.3, FontTypes.GAME_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1 )
screen.show( "TimeText" )
elif (g_iTimeTextCounter >= 15.0): # Another 15 Seconds
@@ -1604,7 +1604,7 @@
ePlayer = gc.getGame().getActivePlayer()

if (CyUserProfile().isClockOn() and bUseClockText):
- g_szTimeText = getClockText()
+ g_szTimeText = getClockText() + " " + unicode(CyGameTextMgr().getInterfaceTimeStr(ePlayer))
else:
g_szTimeText = unicode(CyGameTextMgr().getInterfaceTimeStr(ePlayer))
looks scary, eh?
Those lines basically describe the changes that have to be made to the original CvMainInterface.py file to make it into homegrown's file.

now I can do
diff -u CvMainInterface.py CvMainInterface_mod.py > clock.patch
to create a patch file that I can use to add modify my copy of the original file
patch -o CvMainInterface_new.py CvMainInterface.py clock.patch
patching file CvMainInterface.py

the result is a new file that is absolutely identical to the modded file I downloaded.
sha1sum CvMainInterface_mod.py CvMainInterface_new.py
e8d221d8ed36ab25ac7d51dfc38193088e2b21c5 CvMainInterface_mod.py
e8d221d8ed36ab25ac7d51dfc38193088e2b21c5 CvMainInterface_new.py


But what if the original file was modified (e.g. by a patch from Firaxis)? I promised you patch can handle that:
I created a modified file by removing comments from the original file in three places (7 lines total):
diff CvMainInterface.py CvMainInterface_altered.py
1,2d0
< ## Sid Meier's Civilization 4
< ## Copyright Firaxis Games 2005
44,45d41
< # MINIMAP BUTTON POSITIONS
< ######################
611,613d606
< # *********************************************************************************
< # SCORES
< # *********************************************************************************

now I apply the old patch to the altered file
patch -o CvMainInterface_altered_mod.py CvMainInterface_altered.py clock.patch
patching file CvMainInterface_altered.py
Hunk #1 succeeded at 737 (offset -7 lines).
Hunk #2 succeeded at 1597 (offset -7 lines).
patch tells me there is an offset difference of 7 lines, but none of the changes where inside the code blocks that the patch file specified, so the patch process was successful.

now I check the result:
diff CvMainInterface_altered_mod.py CvMainInterface_mod.py 0a1,2
> ## Sid Meier's Civilization 4
> ## Copyright Firaxis Games 2005
41a44,45
> # MINIMAP BUTTON POSITIONS
> ######################
606a611,613
> # *********************************************************************************
> # SCORES
> # *********************************************************************************
and the differences betweend the altered_mod and _mod are the same as the ones between the original and _altered. (OMG WITCHCRAFT!!!!)

patch and diff can be very useful when handling source code files and individual changes to them. Those tools have been used to apply patches to the Linux kernel (and other OS projects) for a long time now and have proven their worth to the open source community, so maybe some of you can make use of them :)

I personaly would like to be able to add another interface mod to the Simple Clock mod without having to merge the files by hand by hand ;)
 
I think this very useful. If say you had a CustomAssets mod which changed the something in one file. Then someone else creates a Mod which changes something else, but uses the same file. With this, you'd be able to easily combine the two mods so you can have both changes at the same time.
 
This will be *very* useful for the XML. Thanks for pointing it out.
 
QiZhe said:
If say you had a CustomAssets mod which changed the something in one file. Then someone else creates a Mod which changes something else, but uses the same file. With this, you'd be able to easily combine the two mods so you can have both changes at the same time.

That was also my understanding of the way civ works. You only have one CustomAssets folder that can only have one CvMainInterface.py at a time. For me, that file only contains homegrown's Clock right now but any other changes to the Main Interface would have to go into the same file and thats when diff and patch come in. :)
 
That's generally a poor way to go about it. Python supports an inheritance model which allows you to subclass the main Civ IV classes. There's no reason to modify any files but the EntryPoint ones. Simply place your class in a separate file, and subclass it from the appropriate EntryPoint file. Then, if someone else wants to use it, it's quite easy to do so.

Bh
 
Back
Top Bottom