source.rst 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. .. _source:
  2. Source Code
  3. ===========
  4. The GeoServer source code is located on GitHub at https://github.com/geoserver/geoserver.
  5. To clone the repository::
  6. % git clone git://github.com/geoserver/geoserver.git geoserver
  7. To list available branches in the repository::
  8. % git branch
  9. 2.15.x
  10. 2.16.x
  11. * main
  12. To switch to the 2.16.x branch above::
  13. % git checkout 2.16.x
  14. Git
  15. ---
  16. Git is a distributed version control system with a steep learning curve.
  17. Luckily there is lots of great documentation around. Before continuing developers should take the
  18. time to educate themselves about git. The following are good references:
  19. * `The Git Book <http://git-scm.com/book/>`__
  20. * `A nice introduction <http://www.sbf5.com/~cduan/technical/git/>`__
  21. * `Git Pull Requests <https://help.github.com/en/articles/about-pull-requests>`__
  22. .. _gitconfig:
  23. Git client configuration
  24. ------------------------
  25. To review global settings:
  26. .. code-block:: bash
  27. $ git config --global --get-regexp core.*
  28. On Linux and Windows machines:
  29. ::
  30. core.autocrlf input
  31. core.safecrlf true
  32. On macOS using decomposed unicode paths, and a default APFS case-insensitive file system:
  33. ::
  34. core.autocrlf input
  35. core.safecrlf true
  36. core.ignorecase false
  37. core.precomposeunicode true
  38. We recommend making these changes to ``--global`` (or ``--system``) as they reflect the operating system and file system on your local machine.
  39. Some useful reading on this subject:
  40. * `git config <https://git-scm.com/docs/git-config>`__ (git)
  41. Line endings
  42. ^^^^^^^^^^^^
  43. When a repository is shared across different platforms it is necessary to have a
  44. strategy in place for dealing with file line endings. In general git is pretty good about
  45. dealing this without explicit configuration but to be safe developers should set the
  46. ``core.autocrlf`` setting to "input":
  47. .. code-block:: bash
  48. $ git config --global core.autocrlf input
  49. The value "input" respects the line ending form as present in the git repository.
  50. .. note::
  51. It is also a good idea, especially for Windows users, to set the ``core.safecrlf``
  52. option to "true":
  53. .. code-block:: bash
  54. $ git config --global core.safecrlf true
  55. This will prevent commits that may potentially modify file line endings.
  56. Some useful reading on this subject:
  57. * `Configuring Git to handle line endings <https://help.github.com/articles/dealing-with-line-endings>`__ (GitHub)
  58. * `What's the best CRLF (carriage return, line feed) handling strategy with Git? <http://stackoverflow.com/questions/170961/whats-the-best-crlf-handling-strategy-with-git>`__ (Stack Overflow)
  59. * `Mind the end of the End of Your Line <https://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/>`__ (Tim Clem)
  60. File paths
  61. ^^^^^^^^^^
  62. For those working on non case-sensitive, please keep in mind that our repository is case-sensitive:
  63. .. code-block:: bash
  64. $ git config --global core.ignorecase false
  65. Take extra care when adding files to prevent problems for others. To correct a file added with the wrong case:
  66. .. code-block:: bash
  67. $ git mv --cached HttpHandler.java HTTPHandler.java
  68. .. note::
  69. File paths can use two different representations of select unicode characters:
  70. +-------------------------+---------------+--------------------------+
  71. | Representation | Example | Operating System Default |
  72. +=========================+===============+==========================+
  73. | Precomposed form | ``Ü`` | Linux, Windows |
  74. +-------------------------+---------------+--------------------------+
  75. | Decomposed form | ``U`` + ``¨`` | macOS |
  76. +-------------------------+---------------+--------------------------+
  77. Files committed in decomposed form show up as untracked (even with no modification made).
  78. .. code-block:: bash
  79. $ git status
  80. ::
  81. Untracked files:
  82. (use "git add <file>..." to include in what will be committed)
  83. ...
  84. "Entit\303\251G\303\251n\303\251rique/"
  85. GeoServer requires macOS users to use the following setting:
  86. .. code-block:: bash
  87. $ git config --global core.precomposeunicode true
  88. This setting converts paths to precomposed form when adding files to the repository.
  89. To fix a file added in decomposed form it must be removed:
  90. .. code-block:: bash
  91. git config --global core.precomposeunicode false
  92. mv EntitéGénérique /tmp/EntitéGénérique
  93. git rm EntitéGénérique
  94. git commit -m "Remove EntitéGénérique with decomposed filename"
  95. And then added:
  96. .. code-block:: bash
  97. git config --global core.precomposeunicode true
  98. mv /tmp/EntitéGénérique EntitéGénérique
  99. git add EntitéGénérique
  100. git commit -m "Restore EntitéGénérique with precomposed filename"
  101. Some useful reading on this subject:
  102. * `Untracked filenames with unicode names <https://www.git-tower.com/help/mac/faq-and-tips/faq/unicode-filenames>`__
  103. Committing
  104. ----------
  105. In order to commit the following steps must be taken:
  106. #. Configure your git client for cross platform projects. See :ref:`notes <gitconfig>` below.
  107. #. Register for commit access as described :ref:`here <comitting>`.
  108. #. Fork the canonical GeoServer repository into your github account.
  109. #. Clone the forked repository to create a local repository
  110. #. Create a remote reference to the canonical repository using a non-read only URL (``git@github.com:geoserver/geoserver.git``).
  111. .. note::
  112. The next section describes how the git repositories are distributed for the project and
  113. how to manage local repository remote references.
  114. Repository distribution
  115. -----------------------
  116. Git is a distributed versioning system which means there is strictly no notion of a single
  117. central repository, but many distributed ones. For GeoServer these are:
  118. * The **canonical** repository located on GitHub that serves as the official authoritative
  119. copy of the source code for project
  120. * Developers' **forked** repositories on GitHub. These repositories
  121. generally contain everything in the canonical repository, as well any feature or
  122. topic branches a developer is working on and wishes to back up or share.
  123. * Developers' **local** repositories on their own systems. This is where development work is actually done.
  124. Even though there are numerous copies of the repository they can all interoperate because
  125. they share a common history. This is the magic of git!
  126. In order to interoperate with other repositories hosted on GitHub,
  127. a local repository must contain *remote references* to them.
  128. A local repository typically contains the following remote references:
  129. * A remote called **origin** that points to the developers' forked GitHub repository.
  130. * A remote called **upstream** that points to the canonical GitHub repository.
  131. * Optionally, some remotes that point to other developers' forked repositories on GitHub.
  132. To set up a local repository in this manner:
  133. #. Clone your fork of the canonical repository (where "bob" is replaced with your GitHub account name)::
  134. % git clone git@github.com:bob/geoserver.git geoserver
  135. % cd geoserver
  136. #. Create the ``upstream`` remote pointing to the canonical repository::
  137. % git remote add upstream git@github.com:geoserver/geoserver.git
  138. Or if your account does not have push access to the canonical repository use the read-only url::
  139. % git remote add upstream git://github.com/geoserver/geoserver.git
  140. #. Optionally, create remotes pointing to other developer's forks. These remotes are typically
  141. read-only::
  142. % git remote add aaime git://github.com/aaime/geoserver.git
  143. % git remote add jdeolive git://github.com/jdeolive/geoserver.git
  144. Repository structure
  145. --------------------
  146. A git repository contains a number of branches. These branches fall into three categories:
  147. #. **Primary** branches that correspond to major versions of the software
  148. #. **Release** branches that are used to manage releases of the primary branches
  149. #. **Feature** or topic branches that developers do development on
  150. Primary branches
  151. ^^^^^^^^^^^^^^^^
  152. Primary branches are present in all repositories and correspond to the main release streams of the
  153. project. These branches consist of:
  154. * The **main** branch that is the current unstable development version of the project
  155. * The current **stable** branch that is the current stable development version of the project
  156. * The branches for previous stable versions
  157. For example at present these branches are:
  158. * **main** - The 2.17.x release stream, where unstable development such as major new features take place
  159. * **2.16.x** - The 2.16.x release stream, where stable development such as bug fixing and stable features take place
  160. * **2.15.x** - The 2.15.x release stream, which is at end-of-life and has no active development
  161. Release tags
  162. ^^^^^^^^^^^^
  163. Release tags are used to mark releases from the stable or maintenance branches. These can be used to create a release branch if an emergency patch needs to be made:
  164. * 2.15-M0
  165. * 2.15-RC
  166. * 2.15.0
  167. * 2.15.1
  168. Release tags are only used during a versioned release of the software. At any given time a release branch
  169. corresponds to the exact state of the last release from that branch. During release these branches are tagged.
  170. Release branches are also present in all repositories.
  171. Feature branches
  172. ^^^^^^^^^^^^^^^^
  173. Feature branches are what developers use for day-to-day development. This can include small-scale bug fixes or
  174. major new features. Feature branches serve as a staging area for work that allows a developer to freely commit to
  175. them without affecting the primary branches. For this reason feature branches generally only live
  176. in a developer's local repository, and possibly their remote forked repository. Feature branches are never pushed
  177. up into the canonical repository.
  178. When a developer feels a particular feature is complete enough the feature branch is merged into a primary branch,
  179. usually ``main``. If the work is suitable for the current stable branch the changeset can be ported back to the
  180. stable branch as well. This is explained in greater detail in the :ref:`source_workflow` section.
  181. Codebase structure
  182. ------------------
  183. Each branch has the following structure::
  184. build/
  185. doc/
  186. src/
  187. data/
  188. * ``build`` - release and continuous integration scripts
  189. * ``doc`` - sources for the user and developer guides
  190. * ``src`` - java sources for GeoServer itself
  191. * ``data`` - a variety of GeoServer data directories / configurations
  192. .. _source_workflow:
  193. Development workflow
  194. --------------------
  195. This section contains examples of workflows a developer will typically use on a daily basis.
  196. To follow these examples it is crucial to understand the phases that a changeset goes though in the git
  197. workflow. The lifecycle of a single changeset is:
  198. #. The change is made in a developer's local repository.
  199. #. The change is **staged** for commit.
  200. #. The staged change is **committed**.
  201. #. The committed changed is **pushed** up to a remote repository
  202. There are many variations on this general workflow.
  203. For instance, it is common to make many local commits and then push them all up in batch to a remote repository.
  204. Also, for brevity multiple local commits may be *squashed* into a single final commit.
  205. Updating from canonical
  206. ^^^^^^^^^^^^^^^^^^^^^^^
  207. Generally developers always work on a recent version of the official source code. The following example
  208. shows how to pull down the latest changes for the main development branch from the canonical repository::
  209. % git checkout main
  210. % git pull upstream main
  211. Similarly for the stable branch::
  212. % git checkout 2.2.x
  213. % git pull upstream 2.2.x
  214. Making local changes
  215. ^^^^^^^^^^^^^^^^^^^^
  216. As mentioned above, git has a two-phase workflow in which changes are first staged and then committed
  217. locally. For example, to change, stage and commit a single file::
  218. % git checkout main
  219. # do some work on file x
  220. % git add x
  221. % git commit -m "commit message" x
  222. Again there are many
  223. variations but generally the staging process involves using ``git add`` to stage files that have been added
  224. or modified, and ``git rm`` to stage files that have been deleted. ``git mv`` is used to move files and
  225. stage the changes in one step.
  226. At any time you can run ``git status`` to check what files have been changed in the working area
  227. and what has been staged for commit. It also shows the current branch, which is useful when
  228. switching frequently between branches.
  229. Pushing changes to canonical
  230. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  231. Once a developer has made some local commits they generally will want to push them up to a remote repository.
  232. For the primary branches these commits should always be pushed up to the canonical repository. If they are for
  233. some reason not suitable to be pushed to the canonical repository then the work should not be done on a primary
  234. branch, but on a feature branch.
  235. For example, to push a local bug fix up to the canonical ``main`` branch::
  236. % git checkout main
  237. # make a change
  238. % git add/rm/mv ...
  239. % git commit -m "making change x"
  240. % git pull upstream main
  241. % git push upstream main
  242. The example shows the practice of first pulling from canonical before pushing to it. Developers should **always** do
  243. this. In fact, if there are commits in canonical that have not been pulled down, by default git will not allow
  244. you to push the change until you have pulled those commits.
  245. .. note::
  246. A **merge commit** may occur when one branch is merged with another.
  247. A merge commit occurs when two branches are merged and the merge is not a "fast-forward" merge.
  248. This happens when the target branch has changed since the commits were created.
  249. Fast-forward merges are worth `reading about <http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging>`_.
  250. An easy way to avoid merge commits is to do a "rebase" when pulling down changes::
  251. % git pull --rebase upstream main
  252. The rebase makes local changes appear in git history after the changes that are pulled down.
  253. This allows the following merge to be fast-forward. This is not a required practice since merge commits are fairly harmless,
  254. but they should be avoided where possible since they clutter up the commit history and make the git log harder to read.
  255. Working with feature branches
  256. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  257. As mentioned before, it is always a good idea to work on a feature branch rather than directly on a primary branch.
  258. A classic problem every developer who has used a version control system has run into is when they have
  259. worked on a feature locally and made a ton of changes, but then need to switch context to work on some other feature or
  260. bug fix. The developer tries to make the fix in the midst of the other changes
  261. and ends up committing a file that should not have been changed.
  262. Feature branches are the remedy for this problem.
  263. To create a new feature branch off the main branch::
  264. % git checkout -b my_feature main
  265. % # make some changes
  266. % git add/rm, etc...
  267. % git commit -m "first part of my_feature"
  268. Rinse, wash, repeat. The nice about thing about using a feature branch is that it is easy to switch context
  269. to work on something else. Just ``git checkout`` whatever other branch you need to work on,
  270. and then return to the feature branch when ready.
  271. .. note::
  272. When a branch is checked out, all the files in the working area are modified to reflect
  273. the current state of the branch. When using development tools which cache the state of the
  274. project (such as Eclipse) it may be necessary to refresh their state to match the file system.
  275. If the branch is very different it may even be necessary to perform a rebuild so that
  276. build artifacts match the modified source code.
  277. Merging feature branches
  278. ^^^^^^^^^^^^^^^^^^^^^^^^
  279. Once a developer is done with a feature branch it must be merged into one of the primary branches and pushed up
  280. to the canonical repository. The way to do this is with the ``git merge`` command::
  281. % git checkout main
  282. % git merge my_feature
  283. It's as easy as that. After the feature branch has been merged into the primary branch push it up as described before::
  284. % git pull --rebase upstream main
  285. % git push upstream main
  286. Porting changes between primary branches
  287. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  288. Often a single change (such as a bug fix) has to be committed to multiple branches. Unfortunately primary
  289. branches **cannot** be merged with the ``git merge`` command. Instead we use ``git cherry-pick``.
  290. As an example consider making a change to main::
  291. % git checkout main
  292. % # make the change
  293. % git add/rm/etc...
  294. % git commit -m "fixing bug GEOS-XYZ"
  295. % git pull --rebase upstream main
  296. % git push upstream main
  297. We want to backport the bug fix to the stable branch as well. To do so we have to note the commit
  298. id of the change we just made on main. The ``git log`` command will provide this. Let's assume the commit
  299. id is "123". Backporting to the stable branch then becomes::
  300. % git checkout 2.2.x
  301. % git cherry-pick 123
  302. % git pull --rebase upstream 2.2.x
  303. % git push upstream 2.2.x
  304. Cleaning up feature branches
  305. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  306. Consider the following situation. A developer has been working on a feature branch and has gone back
  307. and forth to and from it making commits here and there. The result is that the feature branch has accumulated
  308. a number of commits on it. But all the commits are related, and what we want is really just one commit.
  309. This is easy with git and you have two options:
  310. #. Do an **interactive rebase** on the feature branch
  311. #. Do a **merge with squash**
  312. Interactive rebase
  313. ~~~~~~~~~~~~~~~~~~
  314. Rebasing allows us to rewrite the commits on a branch, deleting commits we don't want, or merging commits that should
  315. really be done. You can read more about interactive rebasing `here <http://git-scm.com/book/en/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages>`_.
  316. .. warning::
  317. Much care should be taken with rebasing. You should **never** rebase commits that are public (that is, commits that have
  318. been copied outside your local repository). Rebasing public commits changes branch history and results in the inability to merge
  319. with other repositories.
  320. The following example shows an interactive rebase on a feature branch::
  321. % git checkout my_feature
  322. % git log
  323. The git log shows the current commit on the branch is commit "123".
  324. We make some changes and commit the result::
  325. % git commit "fixing bug x" # results in commit 456
  326. We realize we forgot to stage a change before committing, so we add the file and commit::
  327. % git commit -m "oops, forgot to commit that file" # results in commit 678
  328. Then we notice a small mistake, so we fix and commit again::
  329. % git commit -m "darn, made a typo" # results in commit #910
  330. At this point we have three commits when what we really want is one. So we rebase,
  331. specifying the revision immediately prior to the first commit::
  332. % git rebase -i 123
  333. This invokes an editor that allows indicating which commits should be combined.
  334. Git then *squashes* the commits into an equivalent single commit.
  335. After this we can merge the cleaned-up feature branch into main as usual::
  336. % git checkout main
  337. % git merge my_feature
  338. Again, be sure to read up on this feature before attempting to use it. And again, **never rebase a public commit**.
  339. Merge with squash
  340. ~~~~~~~~~~~~~~~~~
  341. The ``git merge`` command takes an option ``--squash`` that performs the merge
  342. against the working area but does not commit the result to the target branch.
  343. This squashes all the commits from the feature branch into a single changeset that
  344. is staged and ready to be committed::
  345. % git checkout main
  346. % git merge --squash my_feature
  347. % git commit -m "implemented feature x"
  348. More useful reading
  349. -------------------
  350. The content in this section is not intended to be a comprehensive introduction to git. There are many things not covered
  351. that are invaluable to day-to-day work with git. Some more useful info:
  352. * `10 useful git commands <http://webdeveloperplus.com/general/10-useful-advanced-git-commands/>`_
  353. * `Git stashing <http://git-scm.com/book/en/Git-Tools-Stashing>`_
  354. * `GeoTools git primer <http://docs.geotools.org/latest/developer/procedures/git.html>`_