Discussion papers related to the Linux Foundation ELISA project
This document defines the steps necessary to create new content and modify existing content in an ELISA GitHub repository, validate it, submit it for review and accompany it through the review process.
People working in ELISA may come from safety certification, RTOS-based embedded product development, open-source software development, Linux kernel development backgrounds or combinations thereof. Some have extensive experience developing with git, and specifically with GitHub, as well as collaborating with others in such a context (black belts). Others, on the other hand, having only passing or no experience (white belts).
This document aims to define the necessary steps for the black belts while giving additional information to aid understanding those steps for the white belts.
Contribution is possible from Linux-, Mac OS- and Windows-based computers sometimes using the command line (CLI), custom tools, integrated development environments (IDE)s and partially with GitHub’s web-based user interface (UI). GitHub’s documentation often focuses on that web-based UI.
This document focuses on using the CLI, as it is usually the most precise and least ambiguous way to describe an action. Note, however, that tool-supported actions can be less complicated and therefore less error-prone.
For the time being at least, identifying appropriate tools and IDE’s for their platform and mapping their operations to the git actions is left as an exercise for the readers.
NOTE 1: You cannot contribute anonymously to ELISA project repositories. All developers must therefore have a GitHub account before starting.
NOTE 2: You must sign the work that you commit. By signing your work, you document that you are author of the work and have accepted the license conditions documented in the root directory of projectRepo. Developer Certficate of Origin - elinux.org provides a more detailed explanation.
NOTE 3: You will be expected to keep your contribution in sync with the project repository until it has been accepted.
The diagram below illustrates the repository topology underlying the terminology.
You would need write permission to push changes from your localRepo directly to the projectRepo, which is neither advisable not generally permitted. GitHub has devised another approach (refer to About collaborative development models - GitHub Docs. You should therefore use the following procedure:
Create userRepo by forking the projectRepo to your GitHub site. Refer to About Forks - GitHub Docs.
Note: If you activate the issue tracker in the options of userRepo, developers who fork your fork (i.e. to collaborate on intermediate versions before submitting a (final) PR to the project) will be able to create issues in userRepo. Otherwise all issues created on userRepo will be forwarded to the projectRepo repository instead.
If you haven’t already done so, install git on your machine. In corporate environments, the central IT department may have to install it for you. Git is a standard package in many Linux distributions. Otherwise you can install git with the package manager. Windows users can install Git for Windows.
Create a new directory for your development environment and clone userRepo to your machine, thus creating the localRepo.
Refer to the “GitHub.com” tab in
Cloning a repository - GitHub Docs
for a more detailed explanation.
As well as merely copying the code from userRepo, the clone operation also
effectively performs a git init
(docu):
Set your user name and e-mail in your cloned repository. Refer to Set up Git - GitHub Docs for directions.
We recommend that you set the
git pull
docu
command to default to --ff-only
as pull’s default behoviour is to merge from the remote repository’s master branch into the current branch.
Refer to Why you should use git pull -ff-only
for a detailed explanation of why this behaviour is not desirable.
Use the git config
(docu)
command to set the default.
As described in
Set up Git - GitHub Docs,
this command can set values either for the current repository (default, or with the --local
option)
or for all repositories (with the --global
option.
The values are stored in a .git/config file either at the root of localRepo, as mentioned above,
or in your home directory, respectively.
The appropriate command to set the default for all repositories would therefore be:
$ git config --global pull.ff only
Instead of using the git config
command, you can use your favourite text editor
to enter the corresponding entries directly.
Refer to the example conf file contents below for all recommended configuration values.
Optionally, set up a procedure to automatically sign commits.
The currently recommended way is to use a GPG key.
Refer to Signing commits - GitHub Docs.
The traditional method, which is also acceptable, is to sign with your name and e-mail, as set in the git configuration.
This means, however, that each commit must be called with the –signoff (or -s) argument.
git has no configuration parameter for automatic sign-off, but you can set an alias for your commit command.
Again, use the git config
command:
$ git config --global alias.cs commit --signoff
and then substitute cs for the commit command, as in
$ git cs -a -m "commit message"
Assuming you have used localRepo/.git/config for all your configuration, it should contain something like this:
[user]
name = Your Name
email = yourEmail@yourProvider.com
[alias]
cs = commit --signoff
...
[remote "origin"]
url = https://github.com/yourGitHubId/projectRepo.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main
[pull]
ff = only
This section details the actions needed to create content and submit it to the project, which may involve basic git operations. For a summary of the necessary git commands, refer to Using git - GitHub Docs.
For another explanation of what is basically being said here, refer to GitHub flow - GitHub Docs.
You should indicate your intention to work on projectRepo to the project in projectRepo’s issue tracker. This serves two purposes:
Either create an issue for new work or add an entry to an existing issue.
The notification should contain:
Should the local development environment already exist, userRepo and localRepo should contain the latest changes from projectRepo. Perform Steps 1 and 2 described in the Periodically sync with projectRepo section below.
The master branches of userRepo and localRepo should not contain changes from the current work. Instead they should mirror projectRepo in order to update your repositories with the changes that have occurred due to accepted pull requests since you originally created the newFeature branch.. Refer to the next section for instructions on merging those changes into newFeature.
First, ensure that the master branch is kept up to date. You should pull it from userRepo using the –ff-only option (docu).
$ git checkout master
$ git pull origin master --ff-only
Creating a newFeature branch insulates your work from the rest of the project work. Refer to About branches - GitHub for a more detailed explanation.
Although you can create a branch with the
git branch
(docu) command,
the git checkout
(docu) command
can be used to switch to the new branch as well.
$ git checkout -b newFeature
The new branch should be placed on userRepo and the localRepo branch should track it.
$ git push -u origin newFeature
Should the newFeature branch already exist, you need only switch to it using the
git checkout
(docu)
command.
$ git checkout newFeature
There are any number of git operations that may be necessary during a normal write/test development cycle. This section documents only those operations necessary to prepare the developed content for submission. Refer to Everyday git for a short tutorial of useful commands.
Use git status
(docu) to obtain lists of:
Use git add <filelist>
(docu) to track and stage files
Use git commit
(docu) to bundle a set of changed files into an atomic change.
Sign the commit (docu). Refer to the Create and set up localRepo section for information about how to automate signing off commit.
Include a reference the relevant issue in the commit message.
Use the hashtag syntax
#<issue number>
(docu)
This will link the commit to the issue and make it visible in the GitHub interface.
Refer to How to Write a Git Commit Message for good set of tips for writing the commit message.
Use the git push
(docu) command
to update your remote repository.
$ git push origin
You can also configure newFeature to be the default to be pushed to by using:
git push -u origin newFeature
when you first push it, orgit branch --set-upstream newFeature origin/newFeature
if you forgetAs necessary, import the changes from projectRepo that have been merged since the last fork sync. These changes are located on the master branch. This is a two step process as follows.
Your fork of projectRepo can be synchronised in the GitHub browser interface with just one click, provided, of course, that localRepo’s master branch has no conflicts with projectRepo’s master branch. Refer to Syncing a fork from the web UI - GitHub Docs.
Other than the content that you have changed, the content ot the newFeature branch is at the base state. That is, the state it was in as the branch was created or in the state from the last merge from userRepo/master.
To bring updates of all branches in userRepo into your local development environment,
use the
git fetch
(docu)
command.
$ git fetch origin
The fetched changes must still be explicitly merged into the newFeature branch, however.
Since projectMaster contains changes that are not contained in newFeature,
the merge will update the base state of the branch.
Use the
git rebase
(docu)
command.
The fetched changes must still be explicitly merged into the newFeature branch, however.
Since projectMaster contains changes that are not contained in newFeature,
the merge will update the base state of the branch.
Use the
git rebase
(docu)
command to merge.
git rebase origin/master
Should conflicts occur, rebase will interrupt the process and give you a chance to resolve the conflict. After the conflict has been resolved, the merge process can resume. Refer to the rebase documentation for a detailed description of the process and necessary commands.
Now the newFeature branch is based on the most recent master branch and can be merged back into the master branch (of userRepo and projectRepo) without conflicts.
Note 1 This workflow means that the local version of master in localRepo is not updated, but it does have the benefit that the merge operation does not involve checking out master to update it and then merging master into newFeature. This lessens the danger of commiting it instead of newFeature.
Note 2 Pushing the newFeature branch to userRepo will now require the -force switch since rebasing will change the commit history in localRepo. Use
$ git push origin -force
Initially, the validation procedure depends on the type of content being submitted. Code must compile cleanly, pass unit tests and static analyses. Textual submissions should be spell-checked. The validation procedures should be specified by the ELISA working group responsible for projectRepo.
Check that your commits have all been signed off.
Use the git log
(docu)
as follows:
$ git log --show-signature
In any case, the DCO checking configured in GitHub will detect unsigned commits
when you create the PR.
Should it come that far, or if you find unsigned commits with
git log
,
you must rebase back from the first missing commit.
If, for example, there are 10 commits between the unsigned commit
and the last commit (which is at the HEAD),
use the following command:
$ git rebase HEAD~10 --signoff
Note that since this changes the history of localRepo, pushing it to userRepo will overwrite the changelog and thus requires using the –force flag!
The rest of the content of newFeature should brought up to the same state as the current version on projectRepo, if it isn’t already.
How to do this is explained in the Periodically sync with projectRepo section above.
This is explained in the Back up your work on userRepo section above.
Create a cross-fork PR from the newFeature branch on userRepo to the master branch on projectRepo.
This can be done from the GitHub web UI. Refer to Creating a pull request from a fork - GitHub Docs.
GitHub will perform a DCO check and provide instructions about how to remedy failed checks. It provides instructions about how to sign off afterwards. It does not always get it right, though.
Important: Do not continue to push revisions to newFeature on localRepo unless you want the changes included in the PR. The moment you push revisions to localRepo, the PR will be amended automatically.
The maintainer will merge newFeature into master in projectRepo (and delete newFeature from projectRepo?).
Should the maintainer accept other pull requests before yours is accepted, your fork may need to be rebased in order to ensure that it can be merged without conflicts.
This is explained in the Periodically sync with projectRepo section above.