Git: Difference between revisions
No edit summary |
|||
(39 intermediate revisions by 11 users not shown) | |||
Line 1: | Line 1: | ||
= | = Accessing the repository = | ||
The repository can be accessed using ssh (with public key authentication) or https (anonymous read-only or read-write using user/password authentication). The latter is particularly interesting for people behind firewalls, but requires git to be version 1.6.6 or newer (for "Smart HTTP" transfer). The http password can be generated (and regenerated if necessary) at https://review.coreboot.org/settings/#HTTPCredentials. | |||
git clone --recurse-submodules <nowiki>https://review.coreboot.org/coreboot.git</nowiki> | |||
git clone --recurse-submodules <nowiki>ssh://<username>@review.coreboot.org:29418/coreboot</nowiki> | |||
The ssh username has to be configured in the gerrit account settings, too. | |||
Inside the checkout you should install a commit-msg hook that adds a Change-Id into commit messages, which uniquely identifies the logical change in Gerrit even across multiple iterations of the commit. The hook only needs to be installed once per clone, and installation can be done with | |||
- | wget -O .git/hooks/commit-msg <nowiki>https://review.coreboot.org/tools/hooks/commit-msg</nowiki> && \ | ||
chmod +x .git/hooks/commit-msg | |||
Or you can also just run | |||
make gitconfig | |||
== | = Working with Git = | ||
This | Git is a distributed version control system. This means that you can manage commits and branches completely without restriction in your local clone of the coreboot repository. Peter wrote [https://mail.coreboot.org/pipermail/coreboot/2011-June/065422.html a Git introduction] after the switch to Git had been announced on the mailing list. | ||
This section provides some more details on how to format commits so they match our style, which happens all locally on your development machine. For information on how to contribute these changes to the project, see the section below on the code review tool we use, [[Git#Gerrit|Gerrit]]. | |||
== Commit messages == | == Commit messages == | ||
Git does not enforce a commit message style, although perhaps it should. For all aspects of Git to work the best, it's important to follow these simple guidelines for commit messages: | Git does not enforce a commit message style, although perhaps it should. For all aspects of Git to work the best, it's important to follow these simple guidelines for commit messages: | ||
# The first line of the commit message has a short (less than 65 characters, | # The first line of the commit message has a short (less than 65 characters, absolute maximum is 75) summary | ||
# The second line is empty (no whitespace at all) | # The second line is empty (no whitespace at all) | ||
# The third and any number of following lines contain a longer description of the commit as is neccessary, including relevant background information and quite possibly rationale for why the issue was solved in this particular way. These lines should never be longer than 75 characters. | # The third and any number of following lines contain a longer description of the commit as is neccessary, including relevant background information and quite possibly rationale for why the issue was solved in this particular way. These lines should never be longer than 75 characters. | ||
Line 60: | Line 33: | ||
# A Signed-off-by: line according to [[Development_Guidelines#Sign-off_Procedure|the development guidelines]] | # A Signed-off-by: line according to [[Development_Guidelines#Sign-off_Procedure|the development guidelines]] | ||
Please do not create Change-Id: and Signed-off-by: manually because it is boring and error-prone. Instead, please install the commit-msg hook as described [[# | Please do not create Change-Id: and Signed-off-by: manually because it is boring and error-prone. Instead, please install the commit-msg hook as described [[#Accessing_the_repository|above]], and remember to always use '''git commit -s''' to have git add your Signed-off-by: automatically. | ||
Here is an example of a well-formatted commit message: | Here is an example of a well-formatted commit message: | ||
Line 75: | Line 45: | ||
The example is missing a Change-Id: line. This is OK because Joe Hacker has set up the commit-msg hook [[#Authenticated_read/write_access|as mentioned above]], which adds a Change-Id: automatically when the commit message is saved. | The example is missing a Change-Id: line. This is OK because Joe Hacker has set up the commit-msg hook [[#Authenticated_read/write_access|as mentioned above]], which adds a Change-Id: automatically when the commit message is saved. | ||
=== Guidelines on commit message content === | |||
* If anyone involved in coreboot reads your comment in a year, she/he shall still be able to understand what your commit is about, without needing to analyze the code code. | |||
* Double-check that you're really committing what you think you are, e.g. by typing the following in the top-level coreboot directory: | |||
git show | |||
== Pushing changes == | == Pushing changes == | ||
You need to have an authenticated connection to review.coreboot.org setup. With ssh, you always need to authenticate with your username, so you're all set. For http, fetch the [https://review.coreboot.org/settings/#HTTPCredentials http password] and edit (maybe create) a file called .netrc in your home directory ($HOME or ~). In this file, create a line containing | |||
machine review.coreboot.org login <username> password <http password> | |||
Then run the following command once, to tell git that by default you want to submit all commits in the currently checked-out branch for review on gerrit: | Then run the following command once, to tell git that by default you want to submit all commits in the currently checked-out branch for review on gerrit: | ||
git config remote.origin.push HEAD:refs/for/master | git config remote.origin.push HEAD:refs/for/master | ||
After this, the command to push your changes is: | After this, the command to push your changes is: | ||
git push origin | git push origin | ||
If you always push from the same or a few branches the workflow can be simplified further by running once for each branch: | If you always push from the same or a few branches the workflow can be simplified further by running once for each branch: | ||
git config branch.<particularbranchname>.remote origin | git config branch.<particularbranchname>.remote origin | ||
...after which you then push changes with any of the configured branches checked out with a simple: | ...after which you then push changes with any of the configured branches checked out with a simple: | ||
git push | git push | ||
Line 95: | Line 76: | ||
'''NB!''' If you have applied patches from gerrit on a branch and you later push that branch, gerrit will think that you are submitting new versions of the patches that you had applied. This may or may not be what you intend. You can always run | '''NB!''' If you have applied patches from gerrit on a branch and you later push that branch, gerrit will think that you are submitting new versions of the patches that you had applied. This may or may not be what you intend. You can always run | ||
git log origin/master.. | git log origin/master.. | ||
For automating patch submission further (ie. more ways of simplifying the command line), see the last paragraph of | before '''git push''' to verify which commits you are about to send for review. | ||
For automating patch submission further (ie. more ways of simplifying the command line), see the last paragraph of [https://review.coreboot.org/Documentation/user-upload.html#push_create this gerrit documentation]. | |||
== Pushing Private Commits == | |||
Sometimes changes are just not ready yet for public consumption. For this purpose, gerrit allows pushing private changes that are only visible to people added as reviewers: | |||
git push origin HEAD:refs/for/master%private | |||
However note that one benefit of open source development is the wide range of possible reviewers inside and outside organizations, so consider if this is really necessary. | |||
A better alternative is to mark commits as Work In Progress: | |||
git push origin HEAD:refs/for/master%wip | |||
That way they're visible to everybody but it's clear that they're not yet ready and can't be submitted without you (the owner) removing the WIP flag. | |||
== Pushing to Topics == | |||
git push origin HEAD:refs/for/master/i915-kernel-x60 | |||
will push to the i915-kernel-x60 topic. | |||
== Evolving patches == | |||
Often it might happen that the patch you sent for approval is not good enough from the first attempt. Gerrit and git make it easy to track patch evolution during the review process until patches meet our quality standards and are ready for approval. | |||
You can easily modify a patch sent to gerrit by you or even by someone else. Just apply it locally using one of the possible ways to do it, make a new local commit that fixes the issues reported by the reviewers, then rebase the change by preserving the same Change-ID. We recommend you to use the git rebase command in interactive mode, | |||
git rebase -i master | |||
then commit and push the updated patch. | |||
Alternatively, you may amend your local commit and push the updated patch to gerrit: | |||
git add <path/to/updated/files> | |||
git commit --amend | |||
then push the updated patch. | |||
== Further Git reading == | == Further Git reading == | ||
There are tons of git tutorials out there. Take a look at http://git-scm.com/ | There are tons of git tutorials out there. Take a look at some of these documents: | ||
* http://git-scm.com/ | |||
* http://www.kernel.org/pub/software/scm/git/docs/v1.7.5.4/gittutorial.html | |||
* http://git.or.cz/course/svn.html | |||
* and in particular the [http://progit.org/ Pro Git book] | |||
Please also feel free to ask Git questions in the [[IRC|coreboot IRC channel]] or on the [[Mailinglist|mailing list]]. | |||
= Browsing the sources = | |||
See https://review.coreboot.org/cgit/coreboot.git | |||
= Gerrit = | |||
We use Gerrit on https://review.coreboot.org/ for code review. | |||
== Register with gerrit == | |||
For authenticated access (to submit patches) you'll need a gerrit account which you can register at https://review.coreboot.org/. | |||
You also need to add your ssh key(s) (used for authenticating your connections to the repo) and your email address(es) (used to match up Signed-off-by: statements) to your gerrit user data at https://review.coreboot.org/#settings. | |||
=== OpenID and OAuth2 === | |||
Gerrit uses OpenID and OAuth2 for authentication. Besides many large web services that provide OpenID identity services (eg. Yahoo), you can run your own, if you want. We support OAuth2 for Google and GitHub accounts. | |||
= | Once you have an account, you can link additional identity providers on https://review.coreboot.org/#/settings/web-identities ("Link Another Identity"). Any of these accounts can then be used to access your account. If you simply login with each of the identities, different accounts on gerrit are created, which is probably not the intention. | ||
Note that gerrit is a bit picky about the OpenID format. Always provide a full URL, including protocol (http:// or https:// prefix). Unfortunately the error messages are non-intuitive. | |||
== Gerrit workflow == | |||
Gerrit interprets each Git commit as an individual change. Changes are autobuilt by [http://qa.coreboot.org/ Jenkins], and can be reviewed by developers. Once a change has gotten a positive review and has no build issues, it is applied to the master branch. Thus, no developer directly pushes to master. | |||
Reviews grant points on a scale from -2 to 2. The meaning is: | |||
* -2: Do not merge (blocks gerrit from merging) | |||
* -1: I'd prefer you don't merge it | |||
* 0: neutral | |||
* +1: Looks good, but I won't make the last call on it | |||
* +2: Looks good, go ahead and merge (gerrit provides a "submit" function to developers once it has a +2 vote) | |||
-2 is only available to core developers since it has veto power. Contributors with more activity than a one-off commit can request (eg. on IRC) to be added to the Reviewers group which has extended permissions (eg giving +2) over the default access level. | |||
=== Gerrit and CLI === | |||
Reviews normally happens through the website. | |||
Since gerrit exposes an interface through its ssh daemon, it's also possible to do reviews from CLI or mail. Unfortunately there doesn't seem to be any standing tradition on how to build a workflow around these parts, so we'll document our best practices here once they settled. You can find the official Gerrit documentation about its CLI tools [https://review.coreboot.org/Documentation/cmd-index.html here]. | |||
=== Gerrit and Email === | |||
Gerrit has no email integration. We extended it to send a couple of notifications to the coreboot-gerrit mailing list. | |||
=== Translating Gerrit Change-Ids using the CLI === | |||
To map Gerrit Change-Ids to git commit ids, this git alias may help: | |||
$ # setup (only needed once) | |||
$ git config --global alias.gerrit-id '!f() { git log |egrep "^(commit | *Change-Id:)" |grep -B1 $1 |head -1 |sed "s,^commit ,,"; }; f' | |||
$ # use: | |||
$ git gerrit-id Ifeb277 | |||
a3ea1e45902b64b45e141ebae2f59b94e745d187 |
Latest revision as of 07:23, 25 May 2018
Accessing the repository
The repository can be accessed using ssh (with public key authentication) or https (anonymous read-only or read-write using user/password authentication). The latter is particularly interesting for people behind firewalls, but requires git to be version 1.6.6 or newer (for "Smart HTTP" transfer). The http password can be generated (and regenerated if necessary) at https://review.coreboot.org/settings/#HTTPCredentials.
git clone --recurse-submodules https://review.coreboot.org/coreboot.git
git clone --recurse-submodules ssh://<username>@review.coreboot.org:29418/coreboot
The ssh username has to be configured in the gerrit account settings, too.
Inside the checkout you should install a commit-msg hook that adds a Change-Id into commit messages, which uniquely identifies the logical change in Gerrit even across multiple iterations of the commit. The hook only needs to be installed once per clone, and installation can be done with
wget -O .git/hooks/commit-msg https://review.coreboot.org/tools/hooks/commit-msg && \ chmod +x .git/hooks/commit-msg
Or you can also just run
make gitconfig
Working with Git
Git is a distributed version control system. This means that you can manage commits and branches completely without restriction in your local clone of the coreboot repository. Peter wrote a Git introduction after the switch to Git had been announced on the mailing list.
This section provides some more details on how to format commits so they match our style, which happens all locally on your development machine. For information on how to contribute these changes to the project, see the section below on the code review tool we use, Gerrit.
Commit messages
Git does not enforce a commit message style, although perhaps it should. For all aspects of Git to work the best, it's important to follow these simple guidelines for commit messages:
- The first line of the commit message has a short (less than 65 characters, absolute maximum is 75) summary
- The second line is empty (no whitespace at all)
- The third and any number of following lines contain a longer description of the commit as is neccessary, including relevant background information and quite possibly rationale for why the issue was solved in this particular way. These lines should never be longer than 75 characters.
- The next line is empty (no whitespace at all)
- A Change-Id: line to let gerrit track this logical change
- A Signed-off-by: line according to the development guidelines
Please do not create Change-Id: and Signed-off-by: manually because it is boring and error-prone. Instead, please install the commit-msg hook as described above, and remember to always use git commit -s to have git add your Signed-off-by: automatically.
Here is an example of a well-formatted commit message:
examplecomponent: Refactor duplicated setup into a function Setting up the demo device correctly requires the exact same register values to be written into each of the PCI device functions. Moving the writes into a function allows also otherexamplecomponent to use them. Signed-off-by: Joe Hacker <joe@hacker.email>
The example is missing a Change-Id: line. This is OK because Joe Hacker has set up the commit-msg hook as mentioned above, which adds a Change-Id: automatically when the commit message is saved.
Guidelines on commit message content
- If anyone involved in coreboot reads your comment in a year, she/he shall still be able to understand what your commit is about, without needing to analyze the code code.
- Double-check that you're really committing what you think you are, e.g. by typing the following in the top-level coreboot directory:
git show
Pushing changes
You need to have an authenticated connection to review.coreboot.org setup. With ssh, you always need to authenticate with your username, so you're all set. For http, fetch the http password and edit (maybe create) a file called .netrc in your home directory ($HOME or ~). In this file, create a line containing
machine review.coreboot.org login <username> password <http password>
Then run the following command once, to tell git that by default you want to submit all commits in the currently checked-out branch for review on gerrit:
git config remote.origin.push HEAD:refs/for/master
After this, the command to push your changes is:
git push origin
If you always push from the same or a few branches the workflow can be simplified further by running once for each branch:
git config branch.<particularbranchname>.remote origin
...after which you then push changes with any of the configured branches checked out with a simple:
git push
Pushing several commits not yet in the coreboot repository at once will create one review request on gerrit per commit.
NB! If you have applied patches from gerrit on a branch and you later push that branch, gerrit will think that you are submitting new versions of the patches that you had applied. This may or may not be what you intend. You can always run
git log origin/master..
before git push to verify which commits you are about to send for review.
For automating patch submission further (ie. more ways of simplifying the command line), see the last paragraph of this gerrit documentation.
Pushing Private Commits
Sometimes changes are just not ready yet for public consumption. For this purpose, gerrit allows pushing private changes that are only visible to people added as reviewers:
git push origin HEAD:refs/for/master%private
However note that one benefit of open source development is the wide range of possible reviewers inside and outside organizations, so consider if this is really necessary.
A better alternative is to mark commits as Work In Progress:
git push origin HEAD:refs/for/master%wip
That way they're visible to everybody but it's clear that they're not yet ready and can't be submitted without you (the owner) removing the WIP flag.
Pushing to Topics
git push origin HEAD:refs/for/master/i915-kernel-x60
will push to the i915-kernel-x60 topic.
Evolving patches
Often it might happen that the patch you sent for approval is not good enough from the first attempt. Gerrit and git make it easy to track patch evolution during the review process until patches meet our quality standards and are ready for approval.
You can easily modify a patch sent to gerrit by you or even by someone else. Just apply it locally using one of the possible ways to do it, make a new local commit that fixes the issues reported by the reviewers, then rebase the change by preserving the same Change-ID. We recommend you to use the git rebase command in interactive mode,
git rebase -i master
then commit and push the updated patch.
Alternatively, you may amend your local commit and push the updated patch to gerrit:
git add <path/to/updated/files> git commit --amend
then push the updated patch.
Further Git reading
There are tons of git tutorials out there. Take a look at some of these documents:
- http://git-scm.com/
- http://www.kernel.org/pub/software/scm/git/docs/v1.7.5.4/gittutorial.html
- http://git.or.cz/course/svn.html
- and in particular the Pro Git book
Please also feel free to ask Git questions in the coreboot IRC channel or on the mailing list.
Browsing the sources
See https://review.coreboot.org/cgit/coreboot.git
Gerrit
We use Gerrit on https://review.coreboot.org/ for code review.
Register with gerrit
For authenticated access (to submit patches) you'll need a gerrit account which you can register at https://review.coreboot.org/. You also need to add your ssh key(s) (used for authenticating your connections to the repo) and your email address(es) (used to match up Signed-off-by: statements) to your gerrit user data at https://review.coreboot.org/#settings.
OpenID and OAuth2
Gerrit uses OpenID and OAuth2 for authentication. Besides many large web services that provide OpenID identity services (eg. Yahoo), you can run your own, if you want. We support OAuth2 for Google and GitHub accounts.
Once you have an account, you can link additional identity providers on https://review.coreboot.org/#/settings/web-identities ("Link Another Identity"). Any of these accounts can then be used to access your account. If you simply login with each of the identities, different accounts on gerrit are created, which is probably not the intention.
Note that gerrit is a bit picky about the OpenID format. Always provide a full URL, including protocol (http:// or https:// prefix). Unfortunately the error messages are non-intuitive.
Gerrit workflow
Gerrit interprets each Git commit as an individual change. Changes are autobuilt by Jenkins, and can be reviewed by developers. Once a change has gotten a positive review and has no build issues, it is applied to the master branch. Thus, no developer directly pushes to master.
Reviews grant points on a scale from -2 to 2. The meaning is:
- -2: Do not merge (blocks gerrit from merging)
- -1: I'd prefer you don't merge it
- 0: neutral
- +1: Looks good, but I won't make the last call on it
- +2: Looks good, go ahead and merge (gerrit provides a "submit" function to developers once it has a +2 vote)
-2 is only available to core developers since it has veto power. Contributors with more activity than a one-off commit can request (eg. on IRC) to be added to the Reviewers group which has extended permissions (eg giving +2) over the default access level.
Gerrit and CLI
Reviews normally happens through the website.
Since gerrit exposes an interface through its ssh daemon, it's also possible to do reviews from CLI or mail. Unfortunately there doesn't seem to be any standing tradition on how to build a workflow around these parts, so we'll document our best practices here once they settled. You can find the official Gerrit documentation about its CLI tools here.
Gerrit and Email
Gerrit has no email integration. We extended it to send a couple of notifications to the coreboot-gerrit mailing list.
Translating Gerrit Change-Ids using the CLI
To map Gerrit Change-Ids to git commit ids, this git alias may help:
$ # setup (only needed once) $ git config --global alias.gerrit-id '!f() { git log |egrep "^(commit | *Change-Id:)" |grep -B1 $1 |head -1 |sed "s,^commit ,,"; }; f' $ # use: $ git gerrit-id Ifeb277 a3ea1e45902b64b45e141ebae2f59b94e745d187