11122
Comment:
|
24344
|
Deletions are marked like this. | Additions are marked like this. |
Line 9: | Line 9: |
The suggested process for people doing significant development to the combinat area of sage is to work in a clone of a clean version of sage (this clone is typically called sage-combinat). The files in this clone are managed with a Mercurial repository using Mercurial queues. The patch files that are created with this process are managed in a secondary Mercurial repository, which is periodically synched with the server at sage.math.washington.edu:2144 . The purpose of this page is to give more detail on how this process works. General concepts are given at the top, and examples of common working situations are given at the bottom. To skip to one of these common examples, click on one of the following links. | The suggested process for people doing significant development to the combinat area of sage is to work in a clone of a clean version of sage (this clone is typically called sage-combinat). The files in this clone are managed with a Mercurial repository using Mercurial queues. The patch files that are created with this process are managed in a secondary Mercurial repository, which is periodically synched with the server at [http://sage.math.washington.edu:2144/] . The purpose of this page is to give more detail on how this process works. General concepts are given at the top, and examples of common working situations are given at the bottom. To skip to one of these common examples, click on one of the following links. TODO: Add links here |
Line 12: | Line 14: |
There are two important sage commands that you must be aware of as part of the development process. The first is related to the fact that editing the sage source-code files will not immediately change the behaviour of sage. In order for your changes to have an effect, you must first run | Note: Throughout this document $SAGE_ROOT is the directory where you have Sage installed. There are two important sage commands that you must be aware of as part of the development process. The first is related to the fact that editing the sage source-code files will not immediately change the behavior of sage. In order for your changes to have an effect, you must first run |
Line 19: | Line 23: |
Line 25: | Line 30: |
The primary Mercurial repository manages all files contained in {{{ $SAGEROOT/devel/sage-combinat/ }}}(including all subdirectories) EXCEPT the directory {{{ $SAGEROOT/devel/sage-combinat/.hg/patches }}}. The files in that directory are managed by the secondary repository which is discussed below. The files in the primary repository are all the files that make sage work, so it is important to manage any changes that are made to these files. That way your changes can easily be undone, shared with other people, etc. | The primary Mercurial repository manages all files contained in {{{ $SAGE_ROOT/devel/sage-combinat/ }}}(including all subdirectories) EXCEPT the directory {{{ $SAGE_ROOT/devel/sage-combinat/.hg/patches }}}. The files in that directory are managed by the secondary repository which is discussed below. The files in the primary repository are all the files that make sage work, so it is important to manage any changes that are made to these files. That way your changes can easily be undone, shared with other people, etc. |
Line 28: | Line 33: |
The primary repository is managed with a Mercurial queue of patches. A patch is information that tells Mercurial how to go back and forth between an "old version" of a collection of files and a "new version" of those files. Changing the collection from the old version to the new is called applying the patch, and the inverse is called unapplying the patch. The information about how to make this transformation is stored in a text file with a {{{.patch}}} extension. For our project, all patch files live in the directory {{{$SAGEROOT/devel/sage-comibinat/.hg/patches}}} . Since these are just text files, they are easy to manually inspect with {{{less}}} or any text editor. Manually editing these files, however, is strongly not recommended. Our project consists of many patches, and these patches are managed with a Mercurial queue. A queue can be thought of as a "stack" of patches. Every change that we make to sage should belong to a patch, and every patch should belong to the queue. If, from any subdirectory of {{{ $SAGEROOT/devel/sage-combinat/}}} (except {{{.hg/patches}}} you type the command {{{ $ hg qseries }}} you will see a list of patches in the queue. These patches are ordered, with the first in the list being the first patch which is applied to the base version of sage. Mercurial stores the series in the text file {{{$SAGEROOT/devel/sage-comibinat/.hg/patches/series}}} . If for some reason you want to change the order in which patches are applied, it is possible to edit this file manually, though this is not generally recommended. (It may be necessary, however, when updating the secondary repository; see below for more details). It is important to realize that not all of the patches in the series are necessarily currently applied. You can see which of these patches are currently applied with the command {{{$ hg qapplied }}}, or just get the name of the last patch applied with the command {{{$ hg top }}}. What makes working with Mercurial queues so nice, is that it makes applying and unapplying patches very, very easy. Specifically, the command {{{$ hg qpop }}} will unapply the patch currently on the top of the stack, and {{{$ hg qpush }}} will apply the next patch in the series that is not currently applied. The variants {{{$ hg qpop -a}}} and {{{$ hg qpush -a}}} will unapply and apply (respectively) all patches in the series. So, for example, if you type {{{$ hg qpop -a}}} all files will revert to their state as of the base version of sage. You can now rebuild and run sage to see sage as ordinary users see it. When you get bored of this and want to go back to the exciting bleeding-edge development version, it's as simple as {{{$ hg qpush -a}}} and {{{$ sage -br}}}. |
The primary repository is managed with a Mercurial queue of patches. A patch is information that tells Mercurial how to go back and forth between an "old version" of a collection of files and a "new version" of those files. Changing the collection from the old version to the new is called applying the patch, and the inverse is called unapplying the patch. The information about how to make this transformation is stored in a text file with a {{{.patch }}} extension. For our project, all patch files live in the directory {{{$SAGE_ROOT/devel/sage-comibinat/.hg/patches }}}. Since these are just text files, they are easy to manually inspect with {{{less}}} or any text editor. Manually editing these files, however, is strongly discouraged. Our project consists of many patches, and these patches are managed with a Mercurial queue. A queue can be thought of as a "stack" of patches. Every change that we make to sage should belong to a patch, and every patch should belong to the queue. If, from any subdirectory of {{{ $SAGE_ROOT/devel/sage-combinat/ }}} (except {{{.hg/patches }}}), you type the command {{{ $ hg qseries }}} you will see a list of patches in the queue. These patches are ordered, with the first in the list being the first patch which is applied to the base version of sage. Mercurial stores the series in the text file {{{$SAGE_ROOT/devel/sage-comibinat/.hg/patches/series }}}. If for some reason you want to change the order in which these patches are applied, it is possible to edit this file manually; this is not generally recommended. (It may be necessary, however, when updating the secondary repository; see below for more details). It is important to realize that not all of the patches in the series are necessarily currently applied. You can see which of the patches are currently applied with the command {{{$ hg qapplied }}}, or just get the name of the last patch applied with the command {{{$ hg top }}}. What makes working with Mercurial queues so nice, is that it makes applying and unapplying patches very, very easy. Specifically, the command {{{$ hg qpop }}} will unapply the patch currently on the top of the stack, and {{{$ hg qpush }}} will apply the next patch in the series that is not currently applied. The variants {{{$ hg qpop -a}}} and {{{$ hg qpush -a}}} will unapply and apply (respectively) all patches in the series. So, for example, if you type {{{$ hg qpop -a}}} all files will revert to their state as of the base version of sage. You can now rebuild and run sage to see sage as ordinary users see it. When you get bored of this and want to go back to the exciting bleeding-edge development version, it's as simple as {{{$ hg qpush -a}}} and {{{$ sage -br }}}. |
Line 37: | Line 42: |
The following is a suggested naming convention: <theme>_<feature/fix>_<trac ref if any>_<rev if any>_<owner or final>.patch Examples: * root_systems_lattices_nt.patch * partitions_fix_3244_mh.patch * crystals_affine_as.patch * free_modules_1_mh.patch * free_modules_2_mh.patch * free_modules_3_final.patch A series of patches like the free_modules one above is intended to be progressively folded together into a single patch free_modules.patch before submission to sage. The name free_modules_3_final is really a message and a promise that the owner of free_modules_3_final won't touch this patch anymore, so it is safe to fold it with the previous one in the series free_modules_2_mh. |
|
Line 40: | Line 64: |
If in your editing process you create or delete files, you must give this information to Mercurial. This is done with the commands {{{$ hg add filename}}} and {{{$ hg remove filename}}}, respectively. Since it is easy to forget your current state of editing, Mercurial provides commands to show you what you have done. The command {{{$ hg status }}} will show you what files you have edited since the last time you did {{{$ hg qrefresh }}}. The command {{{$ hg diff }}} will show you precisely what these changes are. |
It is highly recommended that you only edit your own patches. This is to prevent conflicts that will occur if multiple people simultaneously edit the same patch. Edit other people's patches only with their explicit permission. If in your editing process you create or delete files, you must give this information to Mercurial. This is done with the commands {{{$ hg add filename }}} and {{{$ hg remove filename }}}, respectively. Since it is easy to forget your current state of editing, Mercurial provides commands to show you what you have done. The command {{{$ hg status }}} will show you what files you have edited since the last time you did {{{$ hg qrefresh }}}. The command {{{$ hg diff }}} will show you precisely what these changes are. |
Line 66: | Line 92: |
Line 68: | Line 93: |
At this point, you should understand how to manage your changes to the sage source files using a collection of patch files managed by a Mercurial queue. However |
At this point, you should understand how to manage your changes to the sage source files using a collection of patch files managed by a Mercurial queue. However this is not sufficient for our purposes. How do we share our patches with other developers? If we edit and save an early patch in a way that is not compatible with later patches, how can we recover? These problems are solved with the secondary Mercurial repository. Recall that Mercurial stores all information about the queue (in particular, the individual {{{.patch}}} files and the {{{series}}} file) in the directory {{{$SAGE_ROOT/devel/sage-comibinat/.hg/patches }}}. For the rest of this document, we will refer to this directory as the {{{PATCHES}}} directory. The {{{PATCHES}}} directory is NOT managed by the primary repository because, in a sense, it IS the primary repository. So, we have created a secondary Mercurial repository to manage the files in this directory. The most important point to clarify when working with both the primary and secondary repositories is: When you type a command, how does Mercurial know whether the command should be applied to the primary or secondary repository? The answer is given by the directory from which you type the command. If you are in the {{{PATCHES}}} directory, Mercurial will assume the command applies to the secondary repository; if you are in one of the sage source file directories, Mercurial will assume the command applies to the primary repository. The exception to this rule is the command {{{$ hg qcommit}}} which will be discussed in detail below. Of course, the files in {{{PATCHES/.hg/ }}} are not managed by the secondary repository; they ARE the secondary repository. So, if you so desire, you can go to this directory and create a tertiary Mercurial repository. For the sake of your sanity, this is not recommended. To manage the files in the secondary repository we do not use queues; Mercurial's base functionality is enough. Therefore, it is appropriate to describe at this point how Mercurial manages changes when NOT using queues. |
Line 72: | Line 104: |
=== Mercurial Commands === === Example === {{{ xxx }}} |
In standard Mercurial parlance, the basic unit of change is known as a 'changeset'. A changeset is basically just another name for a patch, although changesets are typically identified by a number and not a descriptive name. If you type the command {{{$ hg log }}} from {{{PATCHES}}} you will see a list of all the changesets applied to the {{{PATCHES}}} directory since it was created. (It is often useful to view the log in a paging program, eg {{{$ hg log | less }}}, since the list of changesets can be quite long. In fact, if you look at the log for the primary repository, you will see every changeset applied to sage since version 1.0.) The most recently applied changeset is known as the {{{tip}}}. The point of the secondary repository is to record changes made to the {{{PATCHES}}} directory, allowing us to revert those changes or merge our changes with those of other developers. Thus, we must periodically report these changes to Mercurial's secondary repository. This can be done in one of two ways: The first is to go to the {{{PATCHES}}} directory and then type {{{$ hg commit}}}. The second, which is completely equivalent, is to type {{{$ hg qcommit}}} from any of the sage source file directories. This command will create changeset (patch file) containing all the differences between the state of the {{{PATCHES}}} directory at the time of the previous {{{commit}}} and the current state of the {{{PATCHES}}} directory. When you run this command, you will be prompted for a message which will show up in the summary line of the log file. You can enter this message directly with the {{{- m}}} option to the {{{commit}}} (or {{{qcommit}}}) command. For example, {{{$ hg qcommit -m "made some changes"}}} . Of course, your message should be much more informative. After having done a commit, the collection of changesets in the secondary repository completely describes the current state of {{{PATCHES}}} directory. The information in the {{{PATCHES}}} directory, in turn, completely describes how to get to the current development version of sage from the base version. Thus, to stay in synch with other combinat developers, it is sufficient to keep our secondary repositories in synch. If you created your sage-combinat branch according to the instruction here, your secondary repository will "know about" our central server: {{{sage.math.washington.edu:2144}}} . Periodically, you will need to push the changes made to your secondary repository to this server, and likewise pull the changes on this server to your own secondary repository. === Pulling changes from the server === Before pulling changes from the server, it is a good idea to save your current working state, by {{{qrefresh}}}ing any patch that you are currently editing, and then {{{qcommit}}}ing all of the changes you have made. Then, from the {{{PATCHES}}} directory you can execute the command {{{$ hg pull }}}. This will examine all changesets in the secondary repository on the server, and will download any changesets that are found which you do not already have locally. One of two things will happen when you run this command. Either no new changesets will be found, or some changesets will be found and downloaded. Mercurial will tell you which of these occurred. In the case that no new changesets are found, there is nothing more to do. If changesets were found, you need to run the command {{{$ hg update }}} to commit and apply them. There are two possible results to this command. The first is that the update will be successful and Mercurial will respond with a line like {{{ 2 files updated, 0 files merged, 1 files removed, 0 files unresolved }}} The other possibility is that there will be a conflict when you try to upgrade. Since we all only edit our own .patch files (unless given explicit permission) the conflict is most likely with the file {{{PATCHES/series }}}. You will need to manually merge the two versions of this file (the version from the server and the version you had locally). Fortunately, the series file is so simple, that this is easy to do. The way to resolve conflicts with this file is to put the entire series file from the server is at beginning of the file, and any new, local, patches at the end. Depending on your system, Mercurial may launch a 'diff' program when you try to {{{upgrade }}} and a conflict is found. You can use this program to make the changes, or just close it and edit the file with your favorite editor. Here is an example. {{{ PATCHES$ cat series A.patch B.patch C.patch PATCHES$ hg pull ** changes found *** PATCHES$ hg upgrade }}} At this point you should see a window pop up with the different versions of the series file. Suppose the version from the server looked like this: {{{ A.patch B.patch D.patch E.patch }}} Then you would want to edit the series file to look like: {{{ A.patch B.patch D.patch E.patch C.patch }}} and then commit this change with the command {{{$ hg commit -m "merge" }}}. Finally you need to update the primary repository by going to a sage source code directory (for example, {{{$SAGE_ROOT/devel/sage-combinat }}} and running {{{$ hg qpop -a}}} followed by {{{$ hg qpush -a }}}. This step also has the possibility of resulting in a conflict: following the example above, your file C.patch could contain some changes which conflict with either D.patch or E.patch. If this is the case, you have two options. The first is to edit C.patch until the conflict goes away. Mercurial will show C.patch at the top of the queue, and you can use the commands from the previous section to edit this patch until the conflict goes away. The second possibility is that you can become convinced that the real problem is an error in either D or E . In this case, you should contact the author of the offending patch, and ask him or her to fix the problem and push the change back to the server. Then you can re-pull, and hopefully this time there will be no conflict. === Pushing Changes To The Server === This step is relatively simple; the hard part is making sure that your changes will apply cleanly on the server. The first step is to create or edit some patch on your local machine. If you want to push this patch to the server so that other developers can work on it, it is not necessary that all doctests pass. However, it should be the case that you can apply this patch and run {{{$ sage -br }}} without errors. The next step is to pull any changes that you might not yet have from the server. This step is described in detail above. If changes were found you should merge, apply all changes to the primary repository, and make sure that everything you expect to work still works (sage -br, doctests, etc). After going through this process you should again try to pull changes from the server. If more changes come down, repeat the process. Eventually, no changes will be found. At this point it is safe to do: {{{PATCHES$ hg push }}}. This should report that your changes were applied successfully to the server. Note: You can always see the state of the server directly in your browser at: [http://sage.math.washington.edu:2144/] . === Resolving Secondary Repository Problems === We've described how the secondary repository keeps track the changes to our {{{PATCHES}}} directory, and how we can synch with central server. Another useful tool to know is the command {{{$ hg strip changeset-number }}}. This command allows you to remove a particular changeset (and all changesets which depend on it) from the secondary repository. (You can not run this command if you have uncommitted changes.) We can use this command to get back to the state of any arbitrary {{{qcommit}}}. For example, if your system is completely fouled up, you can use the following series of commands to force your system to mirror the version currently on the server. Note: If there are any local files which you have changed (and you want to have access to those changes) you should save a copy of them outside of the sage directory structure before starting this process. {{{ cd $SAGE_ROOT/devel/sage-combinat/.hg/patches # Go to the $PATCHES directory hg commit -m "commit uncommitted changes" # Commit uncommitted changes hg strip 0 # Completely clean the $PATCHES directory hg pull # Get the current state from the server hg update # Apply and commit server changesets to secondary repository cd ../.. # Go to a primary repository directory hg qpop -a # Unapply any applied changes hg qpush -a # Apply all the changes from the server }}} |
Line 78: | Line 174: |
In all of the following examples, $SAGE_ROOT is the directory where you have Sage installed. == Create a combinat branch and synch with server == === Example === |
== Create a combinat branch and do initial synch with server == ==== Example ==== |
Line 90: | Line 185: |
== Pull changes from server and merge with local changes == === Example === |
== Pull changes from server == === EXAMPLE === {{{ cd $SAGE_ROOT/devel/sage-combinat hg qrefresh hg qcommit cd .hg/patches hg pull hg upgrade # Resolve conflicts with series file as described above cd ../.. hg qpop -a hg qpush -a sage -b }}} |
Line 94: | Line 202: |
=== Example === == Resolving Conflicts == === Example === |
==== Example ==== {{{ cd $SAGE_ROOT/devel/sage-combinat hg qrefresh hg qpush -a sage -br # Make sure this works sage -t filenames # If you believe your tests should pass, check them. hg qcommit }}} Now pull changes from server as described in the example above. If changes are found, begin this process again. {{{ cd $SAGE_ROOT/devel/sage-combinat/.hg/patches hg push }}} |
Line 98: | Line 218: |
=== Example === | Once you have a patch (or patches) ready for inclusion with Sage, you need to export them for submission. Running "hg export" includes extra information in the patch such as the author of the patch. ==== Example ==== |
Line 106: | Line 228: |
When one runs "sage -upgrade", it will update the repository under $SAGE_ROOT/devel/sage-main and not touch the one under $SAGE_ROOT/deve/sage-combinat. Once an email goes out saying that the patch repository is ready to work with the new version of Sage. === Example === |
When one runs "sage -upgrade", it will update the repository under $SAGE_ROOT/devel/sage-main and not touch the one under $SAGE_ROOT/deve/sage-combinat. Once an email goes out (to sage-combinat-devel) saying that the patch repository is ready to work with the new version of Sage, perform the following steps: ==== Example ==== {{{ cd $SAGE_ROOT/devel/sage-combinat hg qpop -a #Remove all the old patches hg pull ../sage-main #Pull the new version of Sage from your local main repository cd .hg/patches hg pull #Pull the new versions of the patches cd ../../ hg qpush -a #Push on the new patches sage -b #Build the new changes }}} If you haven't upgraded Sage to the latest version, but want to continue development with the new patches, you'll need to run the following commands: |
Line 116: | Line 251: |
hg qselect 3_0_2 #Tell Mercurial that you want the patches that were included in 3.0.2 |
Mercurial Queues and the combinat server
The suggested process for people doing significant development to the combinat area of sage is to work in a clone of a clean version of sage (this clone is typically called sage-combinat). The files in this clone are managed with a Mercurial repository using Mercurial queues. The patch files that are created with this process are managed in a secondary Mercurial repository, which is periodically synched with the server at [http://sage.math.washington.edu:2144/] . The purpose of this page is to give more detail on how this process works. General concepts are given at the top, and examples of common working situations are given at the bottom. To skip to one of these common examples, click on one of the following links.
TODO: Add links here
Important Sage Concepts
Note: Throughout this document $SAGE_ROOT is the directory where you have Sage installed.
There are two important sage commands that you must be aware of as part of the development process. The first is related to the fact that editing the sage source-code files will not immediately change the behavior of sage. In order for your changes to have an effect, you must first run
$ sage -b combinat
which will rebuild combinat branch of sage, using the current source code files. Note that the 'combinat' argument is not necessary if the last time you ran sage you used the combinat branch. Variants of this command are $ sage -br (build and run) which will build sage and then run it, and $ sage -ba (build all) which is necessary if any Cython files have been modified.
The second important sage command to know is
$ sage -t filenames
which will run all the doctests in named files. Note that you should rebuild sage before running $ sage -t .
Managing the Primary Repository
The primary Mercurial repository manages all files contained in $SAGE_ROOT/devel/sage-combinat/ (including all subdirectories) EXCEPT the directory $SAGE_ROOT/devel/sage-combinat/.hg/patches . The files in that directory are managed by the secondary repository which is discussed below. The files in the primary repository are all the files that make sage work, so it is important to manage any changes that are made to these files. That way your changes can easily be undone, shared with other people, etc.
Patch and Queue Concepts
The primary repository is managed with a Mercurial queue of patches. A patch is information that tells Mercurial how to go back and forth between an "old version" of a collection of files and a "new version" of those files. Changing the collection from the old version to the new is called applying the patch, and the inverse is called unapplying the patch. The information about how to make this transformation is stored in a text file with a .patch extension. For our project, all patch files live in the directory $SAGE_ROOT/devel/sage-comibinat/.hg/patches . Since these are just text files, they are easy to manually inspect with less or any text editor. Manually editing these files, however, is strongly discouraged.
Our project consists of many patches, and these patches are managed with a Mercurial queue. A queue can be thought of as a "stack" of patches. Every change that we make to sage should belong to a patch, and every patch should belong to the queue. If, from any subdirectory of $SAGE_ROOT/devel/sage-combinat/ (except .hg/patches ), you type the command $ hg qseries you will see a list of patches in the queue. These patches are ordered, with the first in the list being the first patch which is applied to the base version of sage. Mercurial stores the series in the text file $SAGE_ROOT/devel/sage-comibinat/.hg/patches/series . If for some reason you want to change the order in which these patches are applied, it is possible to edit this file manually; this is not generally recommended. (It may be necessary, however, when updating the secondary repository; see below for more details). It is important to realize that not all of the patches in the series are necessarily currently applied. You can see which of the patches are currently applied with the command $ hg qapplied , or just get the name of the last patch applied with the command $ hg top .
What makes working with Mercurial queues so nice, is that it makes applying and unapplying patches very, very easy. Specifically, the command $ hg qpop will unapply the patch currently on the top of the stack, and $ hg qpush will apply the next patch in the series that is not currently applied. The variants $ hg qpop -a and $ hg qpush -a will unapply and apply (respectively) all patches in the series. So, for example, if you type $ hg qpop -a all files will revert to their state as of the base version of sage. You can now rebuild and run sage to see sage as ordinary users see it. When you get bored of this and want to go back to the exciting bleeding-edge development version, it's as simple as $ hg qpush -a and $ sage -br .
Creating a new patch
This is done with the command $ hg qnew patchname.patch. Generally speaking, you should only create a new patch at the top of the stack, with all previous patches applied. In other words, you should always run $ hg qpush -a before running $ hg qnew . Furthermore, it is a good idea to synch your queue with the server (see below) before starting a new patch. After an $ hg qnew , you will see the new patch as the top patch with $ hg qseries , $ hg qapplied , and $ hg qtop .
The following is a suggested naming convention:
<theme>_<feature/fix>_<trac ref if any>_<rev if any>_<owner or final>.patch
Examples:
- root_systems_lattices_nt.patch
- partitions_fix_3244_mh.patch
- crystals_affine_as.patch
- free_modules_1_mh.patch
- free_modules_2_mh.patch
- free_modules_3_final.patch
A series of patches like the free_modules one above is intended to be progressively folded together into a single patch free_modules.patch before submission to sage. The name free_modules_3_final is really a message and a promise that the owner of free_modules_3_final won't touch this patch anymore, so it is safe to fold it with the previous one in the series free_modules_2_mh.
Editing Patches
The basic idea in editing patches is that you should move the patch you want to edit to the top of the stack (using qpush, qpop, or qnew), edit the files you want to edit, then update the current patch file with the command $ hg qrefresh . If you only want to update your changes to particular files, you can do this with $ hg qrefresh -I filenames . (More options to this command can be found with $ hg help qrefresh .) Once you start editing files, Mercurial will not let you qpush or qpop until you have done a qrefresh. Obviously, you should not edit a patch in the middle of the series if you know there will be conflicts with patches later in the series. However, if you have minor changes that logically belong to a patch in the middle of the stack, it is encouraged to make your edits to that patch, as opposed to creating a new one.
It is highly recommended that you only edit your own patches. This is to prevent conflicts that will occur if multiple people simultaneously edit the same patch. Edit other people's patches only with their explicit permission.
If in your editing process you create or delete files, you must give this information to Mercurial. This is done with the commands $ hg add filename and $ hg remove filename , respectively.
Since it is easy to forget your current state of editing, Mercurial provides commands to show you what you have done. The command $ hg status will show you what files you have edited since the last time you did $ hg qrefresh . The command $ hg diff will show you precisely what these changes are.
If you have made edits since your last qrefresh that you've decided you don't want, you can get rid of them with $ hg revert filenames or hg revert --all . This will take the indicated files back to their state at the time of the last qrefresh. Note that the edits since that time will be completely lost.
You may notice that our instructions to this point only provide a means for having a single saved version of any given patch. It is possible to store information about multiple versions of a single patch file; this is done with the secondary repository which is discussed in more detail below.
Quick Summary of Common Queue Commands
$ hg help -v # List all Mercurial commands (including queue commands) $ hg help command # Provides a brief description and available options for the named command $ hg qseries # Lists all patches in the queue, starting with the first to be applied $ hg qapplied # Lists all patches in the queue which are currently applied $ hg qtop # Displays the most recently applied patch $ hg qpush # Apply the first patch in the series which is not currently applied $ hg pop # Unapply the most recently applied patch $ hg qnew name.patch # Create a new patch on top of the current 'qtop' $ hg add filename # Add a file to the Mercurial repository $ hg remove filename # Remove a file from the Mercurial repository $ hg status # List of files modified since last 'qrefresh' $ hg diff # List of precise changes since last 'qrefresh' $ hg qrefresh # Store recent changes in the current top patch $ hg revert filenames # Lose all changes to filenames since last 'qrefresh' $ hg remove name.patch # Completely remove the named patch from the entire queue. The patch must currently be unapplied
Managing the Secondary Repository
At this point, you should understand how to manage your changes to the sage source files using a collection of patch files managed by a Mercurial queue. However this is not sufficient for our purposes. How do we share our patches with other developers? If we edit and save an early patch in a way that is not compatible with later patches, how can we recover? These problems are solved with the secondary Mercurial repository.
Recall that Mercurial stores all information about the queue (in particular, the individual .patch files and the series file) in the directory $SAGE_ROOT/devel/sage-comibinat/.hg/patches . For the rest of this document, we will refer to this directory as the PATCHES directory. The PATCHES directory is NOT managed by the primary repository because, in a sense, it IS the primary repository. So, we have created a secondary Mercurial repository to manage the files in this directory.
The most important point to clarify when working with both the primary and secondary repositories is: When you type a command, how does Mercurial know whether the command should be applied to the primary or secondary repository? The answer is given by the directory from which you type the command. If you are in the PATCHES directory, Mercurial will assume the command applies to the secondary repository; if you are in one of the sage source file directories, Mercurial will assume the command applies to the primary repository. The exception to this rule is the command $ hg qcommit which will be discussed in detail below.
Of course, the files in PATCHES/.hg/ are not managed by the secondary repository; they ARE the secondary repository. So, if you so desire, you can go to this directory and create a tertiary Mercurial repository. For the sake of your sanity, this is not recommended.
To manage the files in the secondary repository we do not use queues; Mercurial's base functionality is enough. Therefore, it is appropriate to describe at this point how Mercurial manages changes when NOT using queues.
Mercurial Concepts
In standard Mercurial parlance, the basic unit of change is known as a 'changeset'. A changeset is basically just another name for a patch, although changesets are typically identified by a number and not a descriptive name. If you type the command $ hg log from PATCHES you will see a list of all the changesets applied to the PATCHES directory since it was created. (It is often useful to view the log in a paging program, eg $ hg log | less , since the list of changesets can be quite long. In fact, if you look at the log for the primary repository, you will see every changeset applied to sage since version 1.0.) The most recently applied changeset is known as the tip.
The point of the secondary repository is to record changes made to the PATCHES directory, allowing us to revert those changes or merge our changes with those of other developers. Thus, we must periodically report these changes to Mercurial's secondary repository. This can be done in one of two ways: The first is to go to the PATCHES directory and then type $ hg commit. The second, which is completely equivalent, is to type $ hg qcommit from any of the sage source file directories. This command will create changeset (patch file) containing all the differences between the state of the PATCHES directory at the time of the previous commit and the current state of the PATCHES directory. When you run this command, you will be prompted for a message which will show up in the summary line of the log file. You can enter this message directly with the - m option to the commit (or qcommit) command. For example, $ hg qcommit -m "made some changes" . Of course, your message should be much more informative.
After having done a commit, the collection of changesets in the secondary repository completely describes the current state of PATCHES directory. The information in the PATCHES directory, in turn, completely describes how to get to the current development version of sage from the base version. Thus, to stay in synch with other combinat developers, it is sufficient to keep our secondary repositories in synch. If you created your sage-combinat branch according to the instruction here, your secondary repository will "know about" our central server: sage.math.washington.edu:2144 . Periodically, you will need to push the changes made to your secondary repository to this server, and likewise pull the changes on this server to your own secondary repository.
Pulling changes from the server
Before pulling changes from the server, it is a good idea to save your current working state, by qrefreshing any patch that you are currently editing, and then qcommiting all of the changes you have made. Then, from the PATCHES directory you can execute the command $ hg pull . This will examine all changesets in the secondary repository on the server, and will download any changesets that are found which you do not already have locally. One of two things will happen when you run this command. Either no new changesets will be found, or some changesets will be found and downloaded. Mercurial will tell you which of these occurred.
In the case that no new changesets are found, there is nothing more to do. If changesets were found, you need to run the command $ hg update to commit and apply them. There are two possible results to this command. The first is that the update will be successful and Mercurial will respond with a line like
2 files updated, 0 files merged, 1 files removed, 0 files unresolved
The other possibility is that there will be a conflict when you try to upgrade. Since we all only edit our own .patch files (unless given explicit permission) the conflict is most likely with the file PATCHES/series . You will need to manually merge the two versions of this file (the version from the server and the version you had locally). Fortunately, the series file is so simple, that this is easy to do. The way to resolve conflicts with this file is to put the entire series file from the server is at beginning of the file, and any new, local, patches at the end. Depending on your system, Mercurial may launch a 'diff' program when you try to upgrade and a conflict is found. You can use this program to make the changes, or just close it and edit the file with your favorite editor. Here is an example.
PATCHES$ cat series A.patch B.patch C.patch PATCHES$ hg pull ** changes found *** PATCHES$ hg upgrade
At this point you should see a window pop up with the different versions of the series file. Suppose the version from the server looked like this:
A.patch B.patch D.patch E.patch
Then you would want to edit the series file to look like:
A.patch B.patch D.patch E.patch C.patch
and then commit this change with the command $ hg commit -m "merge" .
Finally you need to update the primary repository by going to a sage source code directory (for example, $SAGE_ROOT/devel/sage-combinat and running $ hg qpop -a followed by $ hg qpush -a . This step also has the possibility of resulting in a conflict: following the example above, your file C.patch could contain some changes which conflict with either D.patch or E.patch. If this is the case, you have two options. The first is to edit C.patch until the conflict goes away. Mercurial will show C.patch at the top of the queue, and you can use the commands from the previous section to edit this patch until the conflict goes away. The second possibility is that you can become convinced that the real problem is an error in either D or E . In this case, you should contact the author of the offending patch, and ask him or her to fix the problem and push the change back to the server. Then you can re-pull, and hopefully this time there will be no conflict.
Pushing Changes To The Server
This step is relatively simple; the hard part is making sure that your changes will apply cleanly on the server. The first step is to create or edit some patch on your local machine. If you want to push this patch to the server so that other developers can work on it, it is not necessary that all doctests pass. However, it should be the case that you can apply this patch and run $ sage -br without errors.
The next step is to pull any changes that you might not yet have from the server. This step is described in detail above. If changes were found you should merge, apply all changes to the primary repository, and make sure that everything you expect to work still works (sage -br, doctests, etc). After going through this process you should again try to pull changes from the server. If more changes come down, repeat the process.
Eventually, no changes will be found. At this point it is safe to do: PATCHES$ hg push . This should report that your changes were applied successfully to the server.
Note: You can always see the state of the server directly in your browser at: [http://sage.math.washington.edu:2144/] .
Resolving Secondary Repository Problems
We've described how the secondary repository keeps track the changes to our PATCHES directory, and how we can synch with central server. Another useful tool to know is the command $ hg strip changeset-number . This command allows you to remove a particular changeset (and all changesets which depend on it) from the secondary repository. (You can not run this command if you have uncommitted changes.) We can use this command to get back to the state of any arbitrary qcommit. For example, if your system is completely fouled up, you can use the following series of commands to force your system to mirror the version currently on the server. Note: If there are any local files which you have changed (and you want to have access to those changes) you should save a copy of them outside of the sage directory structure before starting this process.
cd $SAGE_ROOT/devel/sage-combinat/.hg/patches # Go to the $PATCHES directory hg commit -m "commit uncommitted changes" # Commit uncommitted changes hg strip 0 # Completely clean the $PATCHES directory hg pull # Get the current state from the server hg update # Apply and commit server changesets to secondary repository cd ../.. # Go to a primary repository directory hg qpop -a # Unapply any applied changes hg qpush -a # Apply all the changes from the server
Example of common situations
Create a combinat branch and do initial synch with server
Example
sage -clone combinat cd $SAGE_ROOT/devel/sage-combinat/.hg/ hg clone http://sage.math.washington.edu:2144 patches cd ../ hg qpush -a
Pull changes from server
EXAMPLE
cd $SAGE_ROOT/devel/sage-combinat hg qrefresh hg qcommit cd .hg/patches hg pull hg upgrade # Resolve conflicts with series file as described above cd ../.. hg qpop -a hg qpush -a sage -b
Push changes to server
Example
cd $SAGE_ROOT/devel/sage-combinat hg qrefresh hg qpush -a sage -br # Make sure this works sage -t filenames # If you believe your tests should pass, check them. hg qcommit
Now pull changes from server as described in the example above. If changes are found, begin this process again.
cd $SAGE_ROOT/devel/sage-combinat/.hg/patches hg push
Exporting Patches for use with trac
Once you have a patch (or patches) ready for inclusion with Sage, you need to export them for submission. Running "hg export" includes extra information in the patch such as the author of the patch.
Example
cd $SAGE_ROOT/devel/sage-combinat hg export new_feature.patch > /path/to/new_feature_for_trac.patch
You would then upload the file new_feature_for_trac.patch to the appropriate ticket on the Sage Trac server.
Upgrading to new version of sage
When one runs "sage -upgrade", it will update the repository under $SAGE_ROOT/devel/sage-main and not touch the one under $SAGE_ROOT/deve/sage-combinat. Once an email goes out (to sage-combinat-devel) saying that the patch repository is ready to work with the new version of Sage, perform the following steps:
Example
cd $SAGE_ROOT/devel/sage-combinat hg qpop -a #Remove all the old patches hg pull ../sage-main #Pull the new version of Sage from your local main repository cd .hg/patches hg pull #Pull the new versions of the patches cd ../../ hg qpush -a #Push on the new patches sage -b #Build the new changes
If you haven't upgraded Sage to the latest version, but want to continue development with the new patches, you'll need to run the following commands:
cd $SAGE_ROOT/devel/sage-combinat hg qpop -a #Remove all the old patches hg pull ../sage-main #Pull the new version of Sage from the main repository cd .hg/patches hg pull #Pull the new versions of the patches cd ../../ hg qselect 3_0_2 #Tell Mercurial that you want the patches that were included in 3.0.2 hg qpush -a #Push on the new patches sage -b #Build the new changes