blob: 22d2b000092366aee6f59f8cbef62b2d14393379 [file] [log] [blame] [view]
lowRISC Contributors802543a2019-08-31 12:12:56 +01001# GitHub Notes
2
3The OpenTitan source tree is maintained on GitHub in a [monolithic repository](https://github.com/lowRISC/opentitan) called opentitan.
4
Greg Chadwick567cfd62019-10-31 16:15:33 +00005These notes are for people who intend to contribute back to OpenTitan (based on
6notes taken by a relatively inexperienced git user). If you don't intend to do
7this you can simply clone the main repository, instructions are in [install
8instructions]({{< relref "install_instructions" >}}) and this document can be ignored.There
9is much more to using git, a possible next step is to reference [Resources to
10learn Git](https://try.github.io/).
lowRISC Contributors802543a2019-08-31 12:12:56 +010011
12## Getting a working repository
13
Philipp Wagner14a3fee2019-11-21 10:07:02 +000014To develop in the repository you will need to get a copy on your local
lowRISC Contributors802543a2019-08-31 12:12:56 +010015machine. To allow contributions to be made back to the main repo
16(through a process called a Pull Request) you need to first make your
Philipp Wagner14a3fee2019-11-21 10:07:02 +000017own copy of the repository on GitHub then transfer that to your local
lowRISC Contributors802543a2019-08-31 12:12:56 +010018machine.
19
20You will need to log in to GitHub, go to the [opentitan repository](https://github.com/lowRISC/opentitan) and click on
21"Fork". This will generate a copy in your GitHub area that you can
22use.
23
24Then setup git on your local machine and set some standard parameters
25to ensure your name and email are correctly inserted. These commands
26set them globally for all your use of git on the local machine so you
27may have done this step already, there is no need to repeat it. (See
28below if you want to use a different email address for this repo.)
29
30Check the parameters:
31```console
32$ git config -l
33```
34
35And if they do not exist then set them:
36
37```console
38$ git config --global user.name "My Name"
39$ git config --global user.email "my_name@email.com"
40```
41
42`git` will take care of prompting for your GitHub user name and
43password when it is required, but it can be useful to allow it to
44cache these credentials (set here to an hour using the timeout in
45seconds) so you don't have to enter every time:
46
47```console
48$ git config --global credential.helper 'cache --timeout=3600'
49```
50
Philipp Wagner14a3fee2019-11-21 10:07:02 +000051Now make a local copy of your GitHub copy of the repository and let git know
lowRISC Contributors802543a2019-08-31 12:12:56 +010052that it is derived from the **upstream** lowRISC repo:
53
54```console
Philipp Wagner14a3fee2019-11-21 10:07:02 +000055$ cd <where the repository should go>
lowRISC Contributors802543a2019-08-31 12:12:56 +010056$ git clone https://github.com/$GITHUB_USER/opentitan.git
57$ cd opentitan
58$ git remote add upstream https://github.com/lowRISC/opentitan.git
Philipp Wagner9614a832019-08-31 13:18:08 +010059$ git fetch upstream
lowRISC Contributors802543a2019-08-31 12:12:56 +010060$ git remote -v
61```
62
63The `git remote -v` should give your GitHub copy as **origin** and the
64lowRISC one as **upstream**. Making this link will allow you to keep your
65local and GitHub repos up to date with the lowRISC one.
66
Philipp Wagner14a3fee2019-11-21 10:07:02 +000067If you want a different email address (or name) for the lowRISC repository then
68you can set it locally in the repository (similar to above but without the
lowRISC Contributors802543a2019-08-31 12:12:56 +010069--global flag). This command must be executed from a directory inside
70the local copy of the repo. (There is no need for the first `cd` if
71you are following the previous step.)
72
73
74```console
75$ cd opentitan
76$ git config user.email "my_name@lowrisc.org"
77```
78
79## Working in your local repo
80
Philipp Wagner14a3fee2019-11-21 10:07:02 +000081The repository that you have created locally will initially be on the
Scott Johnsonfe79c4b2020-07-08 10:31:08 -070082`master` branch. In general you should not make changes on this
Philipp Wagner14a3fee2019-11-21 10:07:02 +000083branch, just use it to track your GitHub repository and synchronize with the
Scott Johnsonfe79c4b2020-07-08 10:31:08 -070084main lowRISC repository.
lowRISC Contributors802543a2019-08-31 12:12:56 +010085
86The typical workflow is to make your own branch which it is
87conventional to name based on the change you are making:
88
89```console
90$ git checkout -b forchange
91$ git status
92```
93
94The status will initially indicate there are no changes, but as you
95add, delete or edit files it will let you know the state of things.
96
Philipp Wagner14a3fee2019-11-21 10:07:02 +000097Once you are happy with your changes, commit them to the local repository by adding the files to the changes (if things are clean you can add using `git commit -a -s` instead of a number of `add` commands):
lowRISC Contributors802543a2019-08-31 12:12:56 +010098
99```console
100$ git add...
Alex Bradbury8d5327e2019-11-05 10:50:00 +0000101$ git commit -s
lowRISC Contributors802543a2019-08-31 12:12:56 +0100102```
103
104The commit will make you add a message. The first line of this is a
105short summary of the change. It should be prefixed with a word in
106square brackets indicating the area being changed, typically the IP or
107Tool name. For example:
108
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800109```console
lowRISC Contributors802543a2019-08-31 12:12:56 +0100110[doc/um] Add notes on using GitHub and the repo
111```
112
113After this there should be a blank line and the main description of
114the change. If you are fixing an issue then add a line at the end of
115the message `Fixes #nn` where `nn` is the issue number. This will link
116the fix and close out the issue when it is added to the lowRISC repo.
Eunchan Kimdae614b2019-10-09 10:36:40 -0700117If the change is an attempted fix that has not yet had confirmation from
118verification engineers, it should not close the related issue. In this case,
119write `Related to #nn` in the commit message rather than `Fixes #nn`.
lowRISC Contributors802543a2019-08-31 12:12:56 +0100120
Alex Bradbury8d5327e2019-11-05 10:50:00 +0000121The commit message will end with a "Signed-off-by" line inserted by `git` due to using the `-s` option to `git commit`.
122Adding this line certifies you agree to the statement in [CONTRIBUTING.md](https://github.com/lowRISC/opentitan/blob/master/CONTRIBUTING.md), indicating your contribution is made under our Contributor License Agreement.
123
lowRISC Contributors802543a2019-08-31 12:12:56 +0100124When you have finished everything locally (it is good practice to do a
125status check to ensure things are clean) you can push your branch (eg
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000126forchange) to **your** GitHub repository (the **origin**):
lowRISC Contributors802543a2019-08-31 12:12:56 +0100127
128```console
129$ git status
130$ git push origin forchange
131```
132
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000133Then you need to go to your repository in GitHub and either select branch
lowRISC Contributors802543a2019-08-31 12:12:56 +0100134from the pulldown or often there is a status message that you can
135click on, review the changes and make a Pull Request. You can add
136reviewers and get your change reviewed.
137
138If you need to make changes to satisfy the reviews then you do that in
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000139your local repository on the same branch. You will need to `add` files and
lowRISC Contributors802543a2019-08-31 12:12:56 +0100140commit again. It is normally best to squash your changes into a single
141commit by doing it with `--amend` which will give you a chance to edit
142the message. If you do this you need to force `-f` the push back to
143your repo.
144
145```console
146$ git add...
147$ git commit --amend
148$ git status
149$ git push -f origin forchange
150```
151
Eunchan Kimdae614b2019-10-09 10:36:40 -0700152Once the reviewers are happy you can "Rebase and Merge" the Pull
lowRISC Contributors802543a2019-08-31 12:12:56 +0100153Request on GitHub, delete the branch there (it offers to do this when
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000154you do the merge). You can delete the branch in your local repository with:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100155
156```console
157$ git checkout master
158$ git branch -D forchange
159```
160
Eunchan Kimdae614b2019-10-09 10:36:40 -0700161When a Pull Request contain multiple commits, those commits should be logically
162independent. Interactive rebase can be used to manipulate commits in a pull
163request to achieve that goal. Commonly, it might be used to squash commits that
164fix up issues reported during review back into the relevant commit.
165
166```console
167$ git rebase -i `git merge-base {current_branch} master`
168```
169
170Then, an editor will open. Follow the instructions given there, to reorder and
171combine commits, or to change the commit message. Then update the PR branch in
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000172the GitHub remote repository.
Eunchan Kimdae614b2019-10-09 10:36:40 -0700173
174```console
175$ git push -f origin HEAD
176```
177
Alex Bradbury8d5327e2019-11-05 10:50:00 +0000178## Automatically adding a Signed-off-by line for your commits
179
180One option to avoid having to remember to add `-s` to `git commit` is to configure `git` to append it to your commit messages for you.
181This can be done using an executable hook.
182An appropriate hook can be installed by executing this from the root of your repository checkout:
183
184```console
185$ cat <<"EOF" > .git/hooks/prepare-commit-msg
186#!/bin/sh
187
188# Add a Signed-off-by line to the commit message if not already present.
189git interpret-trailers --if-exists doNothing --trailer \
190 "Signed-off-by: $(git config user.name) <$(git config user.email)>" \
191 --in-place "$1"
192EOF
193$ chmod +x .git/hooks/prepare-commit-msg
194```
195
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000196## Update your repository with changes in the lowRISC repo
lowRISC Contributors802543a2019-08-31 12:12:56 +0100197
198There is a little work to do to keep everything in sync. Normally you
Scott Johnsonfe79c4b2020-07-08 10:31:08 -0700199want to first get your local repository `master` branch up to date with the
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000200lowRISC repository (**upstream**) and then you use that to update your GitHub
lowRISC Contributors802543a2019-08-31 12:12:56 +0100201copy (**origin**).
202
203```console
204$ git checkout master
205$ git pull upstream master
206$ git push origin
207```
208
209If you do this while you have changes on some other branch then before
210a Pull Request will work you need to be sure your branch merges
Scott Johnsonfe79c4b2020-07-08 10:31:08 -0700211cleanly into the new lowRISC repo. Assuming you got the local `master`
lowRISC Contributors802543a2019-08-31 12:12:56 +0100212branch up to date with the procedure above you can now **rebase** your
Scott Johnsonfe79c4b2020-07-08 10:31:08 -0700213changes on the new `master`. Assuming you have your changes on the local
lowRISC Contributors802543a2019-08-31 12:12:56 +0100214branch `forchange`:
215
216```console
217$ git checkout forchange
218$ git rebase master
219```
220
221If you are lucky this will just work, it unwinds your changes, gets
Scott Johnsonfe79c4b2020-07-08 10:31:08 -0700222the updated `master` and replays your changes. If there are conflicts
lowRISC Contributors802543a2019-08-31 12:12:56 +0100223then you need a big pot of coffee and patience (see next section).
224
225Once everything has rebased properly you can do
226
227
228```console
229$ git log
230```
231
232And see that the changes you commited on the branch are at the top of
Scott Johnsonfe79c4b2020-07-08 10:31:08 -0700233the log followed by the latest changes on the `master` branch.
lowRISC Contributors802543a2019-08-31 12:12:56 +0100234
235## Dealing with conflicts after a rebase
236
237If a rebase fails because of conflicts between your changes and the
238code you are rebasing to then git will leave your working directories
239in a bit of a mess and expect you to fix it. Often the conflict is
240simple (eg you and someone else added a new routine at the same place
241in the file) and resolution is simple (have both in the new
242output). Sometimes there is more to untangle if different changes were
243done to the same routine. In either case git has marked that you are
244in a conflict state and work is needed before you can go back to using
245your local git tree as usual.
246
247The git output actually describes what to do (once you are used to how
248to read it). For example:
249
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800250```console
lowRISC Contributors802543a2019-08-31 12:12:56 +0100251$ git rebase master
252First, rewinding head to replay your work on top of it...
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000253Applying: [util][pystyle] Clean Python style in single file tools
lowRISC Contributors802543a2019-08-31 12:12:56 +0100254Using index info to reconstruct a base tree...
255M util/diff_generated_util_output.py
256M util/build_docs.py
257Falling back to patching base and 3-way merge...
258Auto-merging util/build_docs.py
259CONFLICT (content): Merge conflict in util/build_docs.py
260Auto-merging util/diff_generated_util_output.py
261error: Failed to merge in the changes.
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000262Patch failed at 0001 [util][pystyle] Clean Python style in single file tools
lowRISC Contributors802543a2019-08-31 12:12:56 +0100263Use 'git am --show-current-patch' to see the failed patch
264
265Resolve all conflicts manually, mark them as resolved with
266"git add/rm <conflicted_files>", then run "git rebase --continue".
267You can instead skip this commit: run "git rebase --skip".
268To abort and get back to the state before "git rebase", run "git rebase --abort".
269```
270
271The last line of this gives the ultimate out. You can abort the rebase
272and figure some other way to proceed. As it says, this is done with:
273
274```console
275$ git rebase --abort
276```
277
278After executing this command you are back to a clean tree with your
279changes intact, but they are still based on whatever the earlier state
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000280of the repository was. Normally you will have to resolve the conflict
lowRISC Contributors802543a2019-08-31 12:12:56 +0100281sometime, but the escape hatch can be useful if you don't have time
282immediately!
283
284In the normal case, read the output to find the file with the
285problem. In this case `Merge conflict in util/build_docs.py` (The merge
286of `util/diff_generated_util_output.py` was successful even though it
287is mentioned in the middle of what looks like error output.)
288
289If the file is opened with an editor the points at which there are
290conflicts will have diff-style change information embedded in to them. For example:
291
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800292```console
lowRISC Contributors802543a2019-08-31 12:12:56 +0100293<<<<<<< HEAD
294import livereload
295
296import docgen.generate
297=======
298import docgen
299import livereload
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000300>>>>>>> [util][pystyle] Clean Python style in single file tools
lowRISC Contributors802543a2019-08-31 12:12:56 +0100301
302```
303
Scott Johnsonfe79c4b2020-07-08 10:31:08 -0700304In this case, the upstream repository's copy of `util/build_docs.py`
305was modified to import `docgen.generate` rather than just `docgen`.
306Because git couldn't automatically merge that change with the one
307we made, it gave up. The code between `<<<<<<< HEAD` and `=======`
308represents the change in the upstream repository and the code between
309`=======` and `>>>>>>>` represents the change in our copy.
310
311These lines have to be edited to get the correct merged
lowRISC Contributors802543a2019-08-31 12:12:56 +0100312result and the diff markers removed. There may be multiple points in
313the file where fixes are needed. Once all conflicts have been
314addressed the file can be `git add`ed and once all files addressed the
315rebase continued.
316
Scott Johnsonfe79c4b2020-07-08 10:31:08 -0700317
lowRISC Contributors802543a2019-08-31 12:12:56 +0100318After the fix a status report will remind you where you are.
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800319
lowRISC Contributors802543a2019-08-31 12:12:56 +0100320```console
321$ git status
322rebase in progress; onto cb85dc4
323You are currently rebasing branch 'sastyle' on 'cb85dc4'.
324 (all conflicts fixed: run "git rebase --continue")
325
326Changes to be committed:
327 (use "git reset HEAD <file>..." to unstage)
328
329 modified: diff_generated_util_output.py
330 modified: build_docs.py
331
332Changes not staged for commit:
333 (use "git add <file>..." to update what will be committed)
334 (use "git checkout -- <file>..." to discard changes in working directory)
335
336 modified: build_docs.py
337
338```
339
340This gives the same instructions as the original merge failure message
341and gives the comfort that all conflicts were fixed. To finish up you
342need to follow the instructions.
343
344```console
345$ git add build_docs.py
346$ git rebase --continue
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000347Applying: [util][pystyle] Clean Python style in single file tools
lowRISC Contributors802543a2019-08-31 12:12:56 +0100348```
349
350If there were more than one patch outstanding (which isn't usual if
351you use the `commit --amend` flow) then you may get subsequent
352conflicts following the `rebase --continue` as other patches are
353replayed.
354
355You can check the rebase worked as expected by looking at the log to
356see your branch is one commit (or more if there were more) ahead of
Scott Johnsonfe79c4b2020-07-08 10:31:08 -0700357the `master` branch.
lowRISC Contributors802543a2019-08-31 12:12:56 +0100358
359```console
360$ git log
361
362commit dd8721d2b1529c575c4aef988219fbf2ecd3fd1b (HEAD -> sastyle)
363Author: Mark Hayter <mark.hayter@gmail.com>
364Date: Thu Jan 10 09:41:20 2019 +0000
365
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000366 [util][pystyle] Clean Python style in single file tools
lowRISC Contributors802543a2019-08-31 12:12:56 +0100367
368 Result of lintpy.py --fix on the diff and build_docs tools
369
370 Tested with ./diff_generated_util_output.py master
371
372commit cb85dc42199e925ad09c45d33f6483a14764b93e (upstream/master, origin/master, origin/HEAD, master)
373
374```
375
376This shows the new commit (`HEAD` of the branch `sastyle`) and the
377preceding commit is at the `master` branch (and at the same point as
378`master` on both `origin` and `upstream` so everything is in sync at
Scott Johnsonfe79c4b2020-07-08 10:31:08 -0700379`master`).
lowRISC Contributors802543a2019-08-31 12:12:56 +0100380
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000381At this point the conflicts have been cleared and the local repository can
lowRISC Contributors802543a2019-08-31 12:12:56 +0100382be used as expected.
383
384You may find it useful to change the default for the way git reports conflicts in a file. See [Take the pain out of git conflict resolution: use diff3](https://blog.nilbus.com/take-the-pain-out-of-git-conflict-resolution-use-diff3/)
Cindy Chenb52637c2019-10-29 17:12:32 -0700385
386## Downloading a pull request to our local repo
387
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000388With the commands below, you can checkout a pull request from the upstream repository to
Cindy Chenb52637c2019-10-29 17:12:32 -0700389your local repo.
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800390
Cindy Chenb52637c2019-10-29 17:12:32 -0700391```console
392$ git fetch upstream pull/{ID}/head:{BRANCH_NAME}
393$ # e.g. git fetch upstream pull/5/head:docgen_review
394$ git checkout {BRANCH_NAME}
395```
396
397### Applying the pull request to the local commit
398
399In some cases, you might need to apply a pull request on top of your local commits.
400For instance, if one user prepares a verification test case and finds a bug.
401Another user fixed it and created a pull request. The first user needs
402to test if the fix works on the new verification environment.
403
404In this case, it is recommanded to create a new branch on top of the local
405commit and `rebase`, `cherry-pick`, or `merge` the pull request. Assume you have a branch
406name 'br_localfix' which has an update for the verification environment. If the
407other user created a pull request with ID #345, which has a fix for the
408design bug, then you can apply the pull request into new branch
409'br_localandremote' with the following three methods:
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800410
Cindy Chenb52637c2019-10-29 17:12:32 -0700411* The `rebase` method:
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800412
413 ```console
414 $ git checkout -b br_localandremote br_localfix
415 $ git fetch upstream pull/345/head:pr_345
416 $ git rebase pr_345
417 ```
418
Cindy Chenb52637c2019-10-29 17:12:32 -0700419* The `cherry-pick` method:
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800420
421 ```console
422 $ git checkout -b br_localandremote br_localfix
423 $ git fetch upstream pull/345/head:pr_345
424 $ # find the commit ID from pr_345 that you want to merge: b345232342ff
425 $ git cherry-pick b345232342ff
426 ```
Cindy Chenb52637c2019-10-29 17:12:32 -0700427* The `merge` method:
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800428
429 ```console
430 $ git fetch upstream pull/345/head:pr_345
431 $ git checkout -b br_localandremote br_localfix
432 $ git merge pr_345
433 ```
434
Cindy Chenb52637c2019-10-29 17:12:32 -0700435The `rebase` method is more convenient than `cherry-pick` if you have more
436than one commit ID to merge. The `merge` method can only be used for local
437testing as the upstream lowRISC repository does not allow merge commits.
438Sometimes, applying other contributor's pull request can result in conflicts
439if both commits have the same change. In that case, you should resolve the conflicts
440and continue the merge. Section [Dealing with conflicts after a rebase](#dealing-with-conflicts-after-a-rebase)
441has detailed guidance on how to solve conflicts.
442
443## Creating updates on top of a pending pull request
444
445In some cases, you might want to directly change other contributor's pull
446request. The process is quite complicated so please follow the instruction below
447step-by-step with caution:
448
449* Step 1: Checkout the other pull request branch
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800450
451 ```console
452 $ git fetch upstream pull/{ID}/head:{BRANCH_NAME}
453 $ git checkout {BRANCH_NAME}
454 ```
455
Cindy Chenb52637c2019-10-29 17:12:32 -0700456* Step 2: Make necessary changes
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800457
458 ```console
459 $ git add...
Philipp Wagnerff5f23c2019-11-14 13:58:25 +0000460 $ git commit -m "Add CFG examples to UART specification"
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800461 ```
462
Philipp Wagner14a3fee2019-11-21 10:07:02 +0000463* Step 3: Create your GitHub branch for the pull request
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800464
465 ```console
466 $ git push -u origin {BRANCH_NAME}:<remote_branch_name>
467 ```
468
469 You can use any branch name for the pull request.
470 If you want to the created branch name same as local branch name, this can
471 simply be:
472
473 ```console
474 $ git push -u origin HEAD
475 ```
476
Cindy Chenb52637c2019-10-29 17:12:32 -0700477* Step 4: Create a pull request into the other contributor's forked repository
478
Eunchan Kim7b6891a2019-11-06 12:11:52 -0800479 To create a pull request in other's forked repository, you can follow the same method
480 as creating a pull request as section [Working in your local
481 repo](#working-in-your-local-repo) explained in details.
482 Once the other contributor's pull request is merged into the upstream
483 repository, you will need to create a pull request in that upstream repository
484 instead.
Cindy Chenb52637c2019-10-29 17:12:32 -0700485
486These are all the steps needed. Once your pull request is reviewed and merged, you will
487be able to see that the commit is also visible in the original pull request.