xref: /petsc/doc/developers/contributing/developingmr.md (revision 3f02e49b19195914bf17f317a25cb39636853415)
1(ch_developingmr)=
2
3# Developing a Merge Request
4
5(sec_integration_branches)=
6
7## Select the integration branch
8
9**Integration branches** are permanent branches in a repository that developers can contribute to. PETSc has two integration branches: `release`
10and `main`. **Feature branches** are temporary branches created by developers to add or change a feature. A new feature branch is the basis for each
11merge request.
12
13(sec_release_branch)=
14
15### `release`
16
17The `release` branch contains the latest PETSc release including bug-fixes.
18
19Bug-fixes, along with most documentation fixes, should start from `release`.
20
21```console
22$ git fetch
23$ git checkout -b yourname/fix-component-name origin/release
24```
25
26Bug-fix updates, about every month, (e.g. 3.17.1) are tagged on `release` (e.g. v3.17.1).
27
28(sec_main_branch)=
29
30### `main`
31
32The `main` branch contains everything in the release branch as well as new features that have passed all testing
33and will be in the next release (e.g. version 3.18). Users developing software based
34on recently-added features in PETSc should follow `main`.
35
36New features should start from `main`.
37
38```console
39$ git fetch
40$ git checkout -b yourname/fix-component-name origin/main
41```
42
43(sec_developing_a_new_feature)=
44
45## Start a new feature branch
46
47- Determine the appropriate integration_branch to start from, `main` or `release` (for documentation and bug fixes only).
48
49- Create and switch to a new feature branch:
50
51  ```console
52  $ git fetch
53  $ git checkout -b <loginname>/<affected-package>-<short-description> origin/main  # or origin/release
54  ```
55
56  For example, Barry’s new feature branch on removing CPP in `snes/` will
57  use
58
59  ```console
60  $ git checkout -b barry/snes-removecpp origin/main
61  ```
62
63  Use all lowercase and no additional underscores in the branch name.
64
65## Develop your code
66
67- Write code and tests.
68
69- For any new features or API changes you introduced add information on them to `doc/changes/dev.rst`.
70
71- Inspect changes and stage code using standard Git commands, e.g.
72
73  ```console
74  $ git status
75  $ git add file1 file2
76  $ git commit
77  ```
78
79- Commit code with good commit message, for example
80
81  ```console
82  $ git commit
83  ```
84
85  ```none
86  ComponentName: one-line explanation of commit
87
88  After a blank line, write a more detailed explanation of the commit. Many tools do not auto-wrap this part, so wrap paragraph text at a reasonable length. Commit messages are meant for other people to read, possibly months or years later, so describe the rationale for the change in a manner that will make sense later, and which will be provide helpful search terms.
89
90  Use the imperative, e.g. "Fix bug", not "Fixed bug".
91
92  If any interfaces have changed, the commit should fix occurrences in PETSc itself and the message should state its impact on users.
93
94  We have defined several standard commit message tags you should use; this makes it easy to search for specific types of contributions. Multiple tags may be used in the same commit message.
95
96  /spend 1h or 30m
97
98  If other people contributed significantly to a commit, perhaps by reporting bugs or by writing an initial version of the patch, acknowledge them using tags at the end of the commit message.
99
100  Reported-by: Helpful User <helpful@example.com>
101  Based-on-patch-by: Original Idea <original@example.com>
102  Thanks-to: Incremental Improver <improver@example.com>
103
104  If work is done for a particular well defined funding source or project you should label the commit with one or more of the tags
105
106  Funded-by: My funding source
107  Project: My project name
108  ```
109
110- Push the feature branch to the remote repository as desired:
111
112  ```console
113  % git push -u origin barry/snes-removecpp
114  ```
115
116## Test your branch
117
118- Include {doc}`tests </developers/testing>` which cover any changes to the source code.
119
120- {any}`Run the full test suite <sec_runningtests>` on your machine.
121
122  ```console
123  $ make alltests TIMEOUT=600
124  ```
125
126- Run the source checkers on your machine.
127
128  ```console
129  $ make checkbadSource
130  $ make clangformat
131  $ make lint
132  ```
133
134(sec_clean_commit_history)=
135
136## Maintain a clean commit history
137
138If your contribution can be logically decomposed into 2 or more
139separate contributions, submit them in sequence with different
140branches and merge requests instead of all at once.
141
142Often a branch's commit history does not present a logical series of changes.
143Extra commits from bug-fixes or tiny improvements may accumulate. One commit may contain multiple orthogonal changes.
144The order of changes may be incorrect. Branches without a clean commit history will often break `git bisect`.
145Ideally, each commit in an MR will pass the PETSc CI testing, while presenting a small-as-possible set of very closely related changes.
146
147Use different commits for:
148
149- fixing formatting and spelling mistakes,
150- fixing a bug,
151- adding a new feature,
152- adding another new feature.
153
154Rewriting history can be done in [several ways](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History); the easiest is often with the interactive `rebase` command, which allows one to combine ("squash"), rearrange, and edit commits.
155
156It is better to clean up your commits regularly than to wait until you have a large number of them.
157
158For example, if you have made three commits and the most recent two are fixes for the first, you could use
159
160```console
161$ git rebase -i HEAD~3
162```
163
164If the branch has already been pushed, the rewritten branch is not compatible with the remote copy of the branch. You must force push your changes with
165
166```console
167$ git push -f origin branch-name
168```
169
170to update the remote branch with your copy. This must be done with extreme care and only if you know someone else has not changed the remote copy of the branch,
171otherwise you will lose those changes. Never do a `git pull` immediately after you rebase since that will merge the old branch (from GitLab) into your local one and create a mess [^block-ugly-pull-merge].
172
173You can use `git log` to see the recent changes to your branch and help determine what commits should be rearranged, combined, or split.
174You may also find it helpful to use an additional tool such as
175[git-gui](https://git-scm.com/docs/git-gui/), [lazygit](https://github.com/jesseduffield/lazygit), or [various GUI tools](https://git-scm.com/downloads/guis).
176
177(sec_rebasing)=
178
179## Rebase your branch against the integration branch
180
181You may also need to occasionally [rebase](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) your branch onto to the latest version of your {any}`integration branch <sec_integration_branches>` [^rebase-not-merge-upstream], if the integration branch has had relevant changes since you started working on your feature branch.
182
183```console
184$ git fetch origin                              # assume origin --> PETSc upstream
185$ git checkout myname/component-feature
186$ git branch myname/component-feature-backup-1  # optional
187$ git rebase origin/main                        # or origin/release
188```
189
190Note that this type of rebasing is different than the `rebase -i` process for organizing your commits in a coherent manner.
191
192```{rubric} Footnotes
193```
194
195[^rebase-not-merge-upstream]: Rebasing is generally preferable to [merging an upstream branch](http://yarchive.net/comp/linux/git_merges_from_upstream.html).
196
197[^block-ugly-pull-merge]: You may wish to [make it impossible to perform these usually-undesired "non fast-forward" merges when pulling](https://git-scm.com/docs/git-config#Documentation/git-config.txt-pullff), with `git config --global pull.ff only`.
198