When you modify this repository, please follow these rules.

1. Every commit pushed to the repository needs to compile, including changes to Projects, Tools, and Tests.  If you push five commits at once, all five must compile.
  * Many of us do full compiles of the entire repository, including the automatic testing suite.  If anything does not compile, these things fail.
  * Commits that do not compile forever cause problems when trying to binary search bugs in the repository.
  * Note that it is inevitable that minor compiler errors will happen.  This is especially true since we are using different compilers, different versions of compilers, and different operating systems.  If you encounter one, just fix it and push the fix for others.
  * If you make a change that breaks someone else's code (changing the name of a function, the number or order of the arguments, etc), please propagate the change into their code, too.  If you do not know how to do this, please communicate with the author of that code (if they are still around).

2. Do not check in files that are automatically generated.  This includes anything generated by your compiler or build system (executables, executable wrappers, libraries (*.so, *.dll), and object files (*.o), .sconsign.dblite).  If you are using Mac, please be careful not to check in OS-generated directories (such as .DS_Store or __MACOSX).
  * Use .gitignore to "hide" these files from git.  This will prevent you from accidentally checking these files in, and it prevent git from bugging you about them.
  * Automatically generated tend to change whenever the source changes, which generally results in a new version of these files being checked in when the source is changed.
  * Automatically generated files tend to be much larger than their source file.  (More on the problems caused by large files later.)
  * Automatically generated files cause major merge headaches.  Note that everyone that compiles your code also regenerates the output files, and those will probably not be identical to yours (different compilers or versions of the compiler, different environment variables, etc.)  If two people are working at the same time, the first one to do a push sends their version of the generated file to the repository.  The second person must then do a pull, which causes a merge conflict (both people modified the generated file, even if they aren't working on the same project or the same source files).  These merge conflicts are very confusing to understand and resolve.

3. Do not check in binary files or large files.
  * These files tend to be large.
  * git is not able to compact binary files well (it can compress them, but it cannot store diffs when they change).
  * Large files (especially when especially large or modified frequently) cause a lot of repository bloat.  Remember that everyone who does a "git clone" must fetch a copy of the entire repository to their computer, including not only these large files, but also all previous versions of those large files.  And then they must store the entire repo forever.  Note that deleting the file does not fix the problem - once a large file is added to the repository, it is stuck there forever.

4. Merge commits are not allowed.  The repository will reject your changes if you try.
  * Use "git pull --rebase" instead of "git pull".  Note that you can make this the default: "git config --global pull.rebase true"
  * If you already have a merge, you can use rebase to eliminate it.
  * Originally, merges were allowed.  In practice, they caused more problems than they solved.
  * Merges tended to result in a very spaghetti-like history that was hard to understand (you can still see them in the early history).
  * Merges were a major source of bugs.  Complex merges were often done incorrectly, resulting in bugs.
  * Merge commits contain a mixture of the changes made by two independent sets of changes, and understanding these merges often requires understanding both sets of changes.
  * When a merge is done incorrectly, bisecting the bug leads back to the merge.  If doing the merge in the first place was hard, debugging the merge later is even harder.
  * Note that rebase also leads to merge problems.  Unlike merge, however, the history of what went wrong is lost.  This is why some prefer merges.  On the other hand, when tracking down such a bug, you are led to a regular commit.  This commit will typically be simpler and involve only one set of changes.  This makes the problem easier to identify.
  * If you end up needing to do a complex rebase, a useful piece of advice is to remember the original commit (copy its hash or make a local banch to keep track of it).  If you mess up the rebase, you can also "undo it" by "git reset --hard <hash-or-branch>".  Once you have checked that your rebased code still works correctly, you can delete the local branch.  Note that the branch approach is safer, since git sometimes does garbage collection.

5. Certain characters are not allowed in source files (*.h, *.cpp).  The repository will reject your changes if you try.
  * tab characters.
    - Use 4 spaces instead of a tab.  All modern text editors used for writing code can do this.
    - Tab characters tend to be visualized as different numbers of characters in different programs, and code files tended to be a complex mixture of tabs and spaces.  What looks like it is indented correctly for one person is often unreadable for another.  Tabs also complicate parsing tasks.
    - Sometimes text editors change existing spacing from spaces to tabs or back, often only for a subset of lines, even when those lines were not otherwise modified.  The changes are invisible unless you diff your changes before committing them, and the extra whitespace changes make it harder to look over changes later.
  * carriage return (\r).  Use only a newline character (\n).
    - This is the default on POSIX systems (Linux, Mac).  On Windows, the default is carriage return + newline (\r\n).  Note that Visual studio can be told to do this automatically, as can other editors like Notepad++.
    - Allowing both POSIX newlines and DOS newlines turns out to cause problems.  In the past, Visual Studio was very bad about automatically replacing all newlines with DOS newlines.  The result was that *every* line in the file got changed, since every line contains a newline.  That made it hard to tell what was actually changed in the file.  This also prevents git from properly storing diffs of the file.  Although text editors have generally learned to check for the end of line style when they read the file and then write the file out the same way when saving, this is not always the case.
  * "strange" characters.
    - Rule of thumb: if the character is not used by the C++ language, it should not be in the source file.
    - This includes in comments.
    - Non-ASCII characters are not allowed (including accent characters and characters from other languages)
    - These characters sometimes find their way into source files when copying from non-text sources like PDF files or word documents.  This is a problem since some non-ASCII characters look like ASCII characters (especially - and ") but do not behave like them.
    - Compilers and other tools sometimes don't like non-ASCII characters.
  * Note that these limitations do not apply to other types of files (such as *.txt).
  * If your push is rejected, you should see a message telling you why.  If this happens simply fix the problem (e.g., replace tabs with spaces) and try again.

6. Push and pull frequently.
  * The longer you wait to do a pull, the more like you are to get conflicts.  And those conflicts are going to be harder to resolve.
  * Code that is not pushed is not accessible to others that are working with you on your project.
  * If you do not pull, you do not benefit from bug fixes or compile fixes.

7. Some types of files belong in this repository.  Others don't.
  * If it is C++ and used for your project, it probably belongs here someplace.
  * Some types of scripts are useful to include here.  For example, it is quite helpful to write scripts to run final examples for papers.  It may also be appropriate to check in postprocessing scripts (for example, to generate figure plots from the log file, but not the figures themselves).  These should be inside the project subdirectory used for the paper.
  * Papers belong in the Papers repository, not here.  Notes about the paper, derivations, etc. also belong in the Papers repository, as do figures and illustrations.
  * The output of programs does not belong in the repository.  You should save the final simulation results for your paper, but it should be placed in a dedicated directory somewhere where it can be found later if needed.  This is data is often needed during paper revisions.
  * Models, geometry files, texture maps, etc. do not belong in this repository.  Note that you should have a Public_Data directory, which contains common geometry files.  Although these files are placed within the PhysBAM directory structure, they are not part of the repository and should not be checked in.
  * Code that is specific to your project should be in a subdirectory of Projects.  Code that may potentially be useful beyond your project should be placed in Public_Library.

8. PhysBAM is a living library.  It changes quite a bit.
  * A library that does not change cannot improve.
  * If you find a mistake, fix it.  If you found what you think is a mistake but are not sure, ask someone.
  * If someone makes a change that breaks your code, let them know.  (Unless it is something very minor, in which case you might as well just fix it.)
  * Code that is unmaintainable tends to rot rather quickly.  Don't write code under the assumption that once it has been debugged it will never need to be visited again.  The library evolves.  Compilers change.  Eventually, someone will need to update your code.

9. Remember that we all share this library.
  * You contribute to it while you are here.
  * You benefit from the code that others have written.
  * Others will benefit from the code that you have written.
  * You can take a copy of the code with you when you leave.
    - The library is open source.  See the PHYSBAM_COPYRIGHT.txt file for the software license.
    - When you contribute to this repository, you do so under that license.
  * Remember that others may use your code, especially if it lives in Public_Library.
    - Avoid leaving broken routines lying around.  You may know the routine does not work, but others won't know this.  If the routine name sounds like it does what they need, they may try to use it.  And it could take them quite a while to figure out that it does not work, especially if the routine actually almost does.
    - If reasonable, implement all of the code paths, not just the bare minimum needed for your immediate project.  This allows the routine to be reused later.  The next person who finds the routine useful may need code paths you have not implement.
    - If a code path cannot be implemented or would be too difficult or time-intensive to implement, it is okay not to.  But don't let the routine fail silently.  Consider using a PHYSBAM_ASSERT or PHYSBAM_FATAL_ERROR to check for code paths that have not been implemented.  This way, if someone else uses the code and tries to use functionality that has not been implemented, they will discover this immediately.

