[[PageOutline]] = Creating Patches = Have you changed !InVesalius and would like to share the improvements? Great! We'd love to see them. However, some people are not used to the process to send patches and sometimes make it more complicated than it really is. In order to make things easier, here are some instructions for sending your patch. '''Note:''' It is necessary to be logged in to have full access to Trac. [wiki:InVesalius/Register]! == What is a patch? == A patch is a file which lists the changes you've done to the original !InVesalius source code, using a format that can be applied using [http://www.gnu.org/software/patch/ GNU patch]. It is similar to the file bellow: {{{ Index: invesalius.py =================================================================== --- invesalius.py (revision 1573) +++ invesalius.py (working copy) @@ -20,11 +20,10 @@ import multiprocessing from optparse import OptionParser import os -import sys +from session import Session import gui.language_dialog as lang_dlg import i18n -from session import Session import utils }}} This format is called unified diff. Find how to create it bellow. == Begining == First you'll need a copy of !InVesalius source-code, so you can apply and test your changes. Use [http://subversion.tigris.org/ Subversion] so you can keep the source-code updated and generate unified diff file. Downlod !InVesalius source-code: {{{ svn co --username YourName@Email.com http://svn.softwarepublico.gov.br/svn/invesalius/invesalius3/trunk invesalius3 }}} Where '''YourName@Email.com''' is your email account. == Making changes == Go on and make changes to !InVesalius source-code. Please, do small changes per time. Don't forget to test the rest of the software, to see if other tools are still working. '''Notes:''' Configure your editor to use spacings and not tabs (4 spacings) and try to keep !InVesalius style. == Adding new files == Have you created new modules and files? If you have only modified existing files, jump this step. Otherwise, if you created new files, don't forget to tell Subversion that you want to add them: {{{ svn add invesalius/data/viewer_panoramic.py }}} == Creating patch == Run: {{{ svn diff > bug_fix.patch }}} This will save your changes into "bug_fix.patch". Give an adequate name, according to the changes you've made. Note that `svn diff` will make an unified diff. If for some reason you'd rather use `diff` tool to create a patch, please, use `diff -u`, otherwise the patch won't be an unified one. == Sharing your patch == If there is a ticket related to the changes you've made, please, attach your patch to the ticket. Otherwise, please, [http://svn.softwarepublico.gov.br/trac/invesalius/newticket create a new ticket]. Don't forget to comment briefly your changes. You can add "[PATCH]" in the begin of sumary ("Breve Resumo"), so !InVesalius core developers know a patch was provided. == Telling community about your patch == Use the forum: http://svn.softwarepublico.gov.br/trac/invesalius/wiki/InVesalius/Forum] Sample message: {{{ Subject: [PATCH] Window/Level bug Guys, Please, have a look into my patch for the bug #145: http://svn.softwarepublico.gov.br/trac/invesalius/ticket/145 Thanks Name }}} == General orientations == * '''Use Trac:''' Please, don't send patches to the personal email of a developer. Use Trac and communicate in hte forum. We'll let you know if your patch was aproved. * '''Describe changes:''' Please, fill the comment filed of Trac and describe your patch as brief as possible. Don't forget that it is not easy to understand a patch only reading source-code. Explaining it will make us analyze and aprove it more quickly. * '''Let us know your name:''' Considering the presented above, we'd also like to give you credits for your patch (if it is not something too trivial we won't comment in our changelog), but we need to know your name in order to do these. Please, tell us your name. == What is a good patch? == Ok, you've writte a patch, attached it to a ticket... And... "ok, I've contributed to InVesalius"?! To write a patch it is not a guarantee it will be applied to !InVesalius repository. The patch has to be approved by an !InVesalius core developer, with commit permission, that will have to keep this change for a long time. Therefore, a patch has to be convincing in several aspects: * Atomic patch (see bellow) * Easy to read * dont' try to cheat enhacements, just adding blank lines or random style changes; * don't do several non-correlated changes -- if you need to rearrange something before making the change, do it in a different patch; * follow !InVesalius style. * Easy to mantain * comment source code that needs commenting - not more, nor less; * add, whenever possible, unit tests; * be sure that the change won't make other parts of !InVesalius stop working. * and, sure, the quality of the source-code, the importance of the bug fix or the new feature added are extremelly important conditions. It might be hard to get it all right at the first time, and probably the core team will ask you to improve your patch. Be prepared to take into consideration the feedback and do several iterations with your patch, if necessary. === Why atomic patches === 1. The probability of a patch being accepted is the product of the probability of each individual new feature be accepted. This shows why it is a good idea to send one feature per time; 2. The probability of having a bug in a patch is the sum of each individual new feature havin ga bug. So, we want each feature per patch, so we can make regressions to check errors; 3. The difficult of reviewing a patch increases lineary with the number of supported features. This means we don't want to review a patch including more than one feature. == Applying a patch == Go to the directory where the patch was created (using cd). Probably this will be invesalius folder. If it is related to !InVesalius root directory, run: {{{ patch -p0 < bug_fix.patch }}} Otherwise, if the patch was created from another project tool, apply the patch without -p option. For this, change your current directory using cd and type: {{{ patch < bug_fix.patch }}} Patch will automatically check the file format. You can also use the command line options -u to indicate it is a unified patch and -b to create a backup copy of the file before changing it. It is pretty easy to revert changes... == Reverting patches == You can revert a patch after testing it, or if you want to check if a certain patch caused some problem. You can also want to revert an applied patch in order to test a newer version of the same patch. In order to revert it, use the -R commnad line argument: {{{ patch -p0 -R < bug_fix.patch }}} If you have applied multiple patches, or want ot revert changes from !InVesalius source-code, another useful command is: {{{ svn -q diff | patch -p0 -R }}} This way you create a diff of all changes and revert it, leavin a clear copy at . If you've managed to revert everything, you'll se a list of the main files which were changed. If there is no change to revert, than you'll see a message similar to 'only garbage was found in the patch'. You can also revert changes using: {{{ svn revert --recursive . }}} == Thank you for reading this! We're waiting yout patches == '''Note:''' The material above was based on similar docs made by other free software communities, as: Drupal, Mercurial, Trac and wxWidgets.