Please follow these guidelines when submitting changes to WinMerge sources as patches.
Do not waste yours and our time by submitting large feature patches before you have made sure the feature is a desired addition to WinMerge. Communicate with our developers, either in bug/feature request(rfe) items or preferably in the Developers-forum or Developers- mailing list.
Post development intentions:
Before you start developing, make sure to capture a snapshot of your starting sources (presumably a pristine copy of sources from subversion, or of a source zip from a distribution).
DO NOT submit a patch against a year-old version. The latest experimental/beta version is at most a few weeks old. Stable releases should only get bug fixes. And even then the bugfix is usually first applied to development versions. So there should be no reason to submit a patch against an old version.
Review the sections on Coding conventions and Doxygen comments
Develop your new version.
Post your changes as a patch, to the SourceForge patch list. Try to give an informative patch title of course. Post to any relevant SourceForge bugs or RFEs, giving the patch number and title.
If the bug/rfe item is already assigned to you (or you submitted it), you can also attach patch into that item. Remember to add a comment so others notice the new attachment.
The active developers have often been posting entire original and modified files rather than traditional diffs, because obviously all developers have access to WinMerge to compare original and modified files, and this may be viewed as an infinite line context diff :)
HINT: If you have archive support installed in WinMerge you can do a folder
compare of your original and changed source trees. And then select
Zip - Differences
from context menu and WinMerge creates a zip-file for you. Ready to be posted!
Wait for reactions from other developers (and sometimes active users).
Usually this means one of the active developers approves your patch before you commit.
After a reasonable amount of time has passed, and one of active developers has approved the patch, apply the patch to Subversion. (Or ask a project member to do so, if you don't have developer access to the project.)
What is a reasonable amount of time? That is somewhat subjective, and we need to rely on your expertise as the patch developer, but let us suggest waiting a few days for minor patches, and at least a week for major patches.
Add a note in
Src/Changes.txt telling what files you committed,
and what bug/RFE/patch you solved. This is very important so everybody else
has a chance to figure out who did what and when.
Src/Changes.txt was split from
2.4.0 release. So
Src/readme.txt contains older changelog entries. Also, many
subfolders have their own
Changes.txt -file. If the file exists in the folder, it must be
used instead of "global"
It is reasonable to post small snippets of code showing small changes directly in the text in bug postings, or patch postings. For example, see PATCH [ 824987 ] "Change binary-file detection (look only for zeros)", which gives the change directly in the text.
Note, however, that sourceforge trackers currently ignore tabs, so if you can convert tabs to spaces in your posting, it helps greatly.
Bugfixes may be treated less formally, especially for simple ones, or for fixes to code you know well -- eg, you caused the bug yourself with a recent patch :)
Consider still posting something to the tracker lists, even if it is simply a summary in English. If the fix is something like "misspelled variable name foo as fooz in many places", it is quite understandable that you prefer to just fix the instances rather than doing a full patch for it.
Please conform to the prevalent coding conventions. There are quite a number of files which originated elsewhere, and have their own coding conventions; please conform to the local one, in whichever files you are at work.
WinMerge itself uses Microsoft MFC style coding.
Crystal Text Editor (
WinMerge/editlib/*) and diffutils code (
util.c) use traditional Unix style coding.
analyze.c should be in this format, but we have made a mess of it :(
We have adopted doxygen style as our desired commenting style for functions, classes, files, and so forth, in WinMerge code (this applies only to native WinMerge code, not imported files).
DiffThread.cppare fully doxygen commented (TODO: it would be better to give a class example, if anyone knows a fully doxygen commented class).
We have adopted the convention of using Revision ID lines near the top of our source files (following the doxygen file header comments). Merely add these two lines to any new file you add to the repository, and SVN will modify the Id line by appending revision and date information at checkout:
// Revision ID line follows -- this is updated by SVN // $Id$
We are trying to keep a consistent numbering scheme on our file releases, so everybody can figure out what we have released by just looking at the release number. Unfortunately the original 4-number version numbering didn't work as well as we thought and caused a lot of confusion. So WinMerge 2.13.x and later use new 3-number version numbers:
2.14.2 | | | | | | | | | | | `--------- Denotes a beta release, an experimental release | | or a minor bug fix of a major release. | | For experimental and stable releases this number increases by | | one. For beta releases we may increase few numbers more. | `----------- Denotes a major release. | even numbers means "stable". | odd numbers means "unstable". `------------- Denotes a major release with major changes.
In this case:
And if we decide to rewrite most of the code, the next major release will have the number 3.0.0. This is something big like cross-platform support, 3-way merge etc.
WinMerge 2.12.x and earlier releases used a four-number version numbers:
220.127.116.11 | | | | | | | `------- This number increases for each experimental, | | | and it is reset after each beta or major release. | | `--------- Denotes a beta release, an experimental release | | or a minor bug fix of a major release. | | even numbers means "stable" (i.e. a beta). | | odd numbers means "unstable" (i.e. an experimental). | `----------- Denotes a major release. | even numbers means "stable". | odd numbers means "unstable". `------------- Denotes a major release with major changes.
On SourceForge there is some space to enter Release Notes and Change Notes. For experimental releases make sure to put in a note telling people that this is indeed experimental, so they should not expect everything to work perfectly. For beta builds we paste in all the changes since the last beta release, so that people can see exactly what changed. For major releases, we paste in the list of changes since the last major release, and this list can become very long.
We are using InnoSetup to make the installer for WinMerge. See readme-developers-InnoSetup.html for more information. Also zip-packages for releases are provided, zip up these files:
unregister.batto register/unregister it.
filters/directory (remember template file!)
plugins/dlls/directory. Create a
MergePlugins/directory and copy the plugins to it
*.langfiles (currently we have 21 languages, counting both Chinese versions)
Please remember to put the version number into both executables. You may use any of the following three methods at least.
Merge.rcin the copy using the MSVC6 resource editor, and compiling that (many releases have been made in this manual, low-tech fashion).
Whatever method you use, please double-check the executable version numbers before uploading and releasing them.
Since WinMerge 2.4 we have translations for Shell Extension and must also version it
carefully. If we don't update version number, installer won't install updated version.
There are no scripts or other tools to update version number, it must be done by hand
ShellExtension.rc file (make sure you update all four numbers!). Version numbers
follow the rule:
18.104.22.168 | | | | | | | `------- Not used - 0 (or your own build version?) | | `--------- Translation updates or other minor changes increase this by one | `----------- New features, bug fixes and other changes affecting to behavior | increase this number by one `------------- Denotes a major release with major changes.
Filenames in file releases follow this standard:
That is, dots are used only inside the version number and before the final extension.
When we make a release we always put a note in
Src/Changes.txt in SVN.
It is recommended to create a tag to the repository when making a stable- or beta- releases. Although with subversion we have kind of tags for every commit (revision numbers) it is still a lot easier to handle and remember them with human-readable names (R2_6_0) than with revision numbers (revision 3637 (not a real revision number!)). Experimental or other testing releases don't need tags since they are not intended for wide use and are usually just one-time snapshots.
The tag should follow the same numbering scheme as used above, with the dots replaced by underscores
and prefixed with an
R, so the example experimental above would have a tag named
the next beta would be named
R2_1_4, and the next major release would be named
WinMergeU.exe are always compiled with the english resources.
Custom languages are in per-language PO files in
Languages subfolder of WinMerge folder.
Language may be changed dynamically through the menu.
WinMerge localization is achieved by loading translated strings from per-language PO files. There is only one rc
file in the project
Merge.rc, which is used to generate POT (PO template) file. Per-language PO files
are updated (after
Merge.rc changes) from generated POT file. All PO files are in same
Unlike with 2.6.x versions of WinMerge, there is no anymore need to compile language files. The same PO files are used for translation and in runtime to load translated strings. This helps translating WinMerge a lot.
If you have done changes to the
Merge.rc file you must call
to create the latest version from the file
English.pot and update the language PO files from this PO template.
And for strings, who should not appear in the PO files just add a line in the
Besides the resources files you could also translate things like the installer (the ISL files are just INI files) and the readme files.
The code must use resource strings for all messages, or displayed text (column title ...).
Strings ID: when applying a patch, you may define new strings (with as ID the first free ID). But probably you wrote your patch from an old version, and someone may have already inserted a patch for this ID. You need to adapt the ID in resource.h to avoid overlapping ID.
Strings order: that is really annoying with MSVC. It is important to keep the order of strings unchanged,
because merging rc files with WinMerge is then a lot easier. Strings are grouped in block according to their ID masked by
So there are at most 16 strings in a block, but maybe less. MSVC reorders strings between and inside blocks, but never reorders blocks
(when a new blocks is created, MSVC always put it at the last position).
Typical method to merge strings in a
Merge.rc from a patch with a
Merge.rc in SVN :
resource.hfor ID, and
Note: Blocks are not really ordered (there order comes from history), it is not a problem as MSVC never reorders blocks after creation. If you use another tool to change resources, please make sure that the blocks order is unchanged.
Logs are a good tool for tracing errors. But logs must be first written. Its always a good habit to write error message to logfile also.
Simplest way to write errormessage to log is using
void LogErrorString(LPCTSTR sz) defined in
way is to directly use
gLog which is global instance of
CLogFile. Log is written to users temporary directory (
$temp) with name
Log writing is controlled by registry value:
Possible values are:
WinMerge sets executable path (
WinMerge.exe) which shellextension starts every
time when options-dialog is closed. This can cause problems when testing
several versions of WinMerge. There is registry value to overwrite path to
It does not exist by default, so create
PriExecutable as string value and type
WinMerge.exe you mainly use as its value. If this value exists
ShellExtension does not care about another path value.