Commit 1f146986 authored by rameshthoomu's avatar rameshthoomu
Browse files

[FAB-2977] convert v0.6 .md to .rst



This patch provides broken v0.6 documentation build.
This patch coverts v0.6 .md files to .rst to support Sphinx theme.

Fix broken links.
Reformat home page
Trim down TOC
Fix Starter Kit
Fix abstract animation
Update curl commands
Update FAQ formatting

Change-Id: Ib89069915d743a66bc62c5b2e414624b9b3d3319
Signed-off-by: default avatarrameshthoomu <rameshbabu.thoomu@gmail.com>
Signed-off-by: default avatarNick Gaski <ngaski@us.ibm.com>
parent 21c64b48
......@@ -27,3 +27,4 @@ go-carpet-coverage*
# make node-sdk copied files
sdk/node/lib/protos/*
report.xml
build/
# Attributes usage
## Overview
The Attributes feature allows chaincode to make use of extended data in a transaction certificate. These attributes are certified by the Attributes Certificate Authority (ACA) so the chaincode can trust in the authenticity of the attributes' values.
To view complete documentation about attributes design please read ['Attributes support'](../tech/attributes.md).
## Use case: Authorizable counter
A common use case for the Attributes feature is Attributes Based Access Control (ABAC) which allows specific permissions to be granted to a chaincode invoker based on attribute values carried in the invoker's certificate.
['Authorizable counter'](../../examples/chaincode/go/authorizable_counter/authorizable_counter.go) is a simple example of ABAC, in this case only invokers whose "position" attribute has the value 'Software Engineer' will be able to increment the counter. On the other hand any invoker will be able to read the counter value.
In order to implement this example we used ['VerifyAttribyte' ](https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim#ChaincodeStub.VerifyAttribute) function to check the attribute value from the chaincode code.
```
isOk, _ := stub.VerifyAttribute("position", []byte("Software Engineer")) // Here the ABAC API is called to verify the attribute, just if the value is verified the counter will be incremented.
if isOk {
// Increment counter code
}
```
The same behavior can be achieved by making use of ['Attribute support'](https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim/crypto/attr) API, in this case an attribute handler must be instantiated.
```
attributesHandler, _ := attr.NewAttributesHandlerImpl(stub)
isOk, _ := attributesHandler.VerifyAttribute("position", []byte("Software Engineer"))
if isOk {
// Increment counter code
}
```
If attributes are accessed more than once, using `attributeHandler` is more efficient since the handler makes use of a cache to store values and keys.
In order to get the attribute value, in place of just verifying it, the following code can be used:
```
attributesHandler, _ := attr.NewAttributesHandlerImpl(stub)
value, _ := attributesHandler.GetValue("position")
```
## Enabling attributes
To make use of this feature the following property has to be set in the membersrvc.yaml file:
- aca.enabled = true
Another way is using environment variables:
```
MEMBERSRVC_CA_ACA_ENABLED=true ./membersrvc
```
## Enabling attributes encryption*
In order to make use of attributes encryption the following property has to be set in the membersrvc.yaml file:
- tca.attribute-encryption.enabled = true
Or using environment variables:
```
MEMBERSRVC_CA_ACA_ENABLED=true MEMBERSRVC_CA_TCA_ATTRIBUTE-ENCRYPTION_ENABLED=true ./membersrvc
```
### Deploy API making use of attributes
#### CLI
```
$ ./peer chaincode deploy --help
Deploy the specified chaincode to the network.
Usage:
peer chaincode deploy [flags]
Global Flags:
-a, --attributes="[]": User attributes for the chaincode in JSON format
-c, --ctor="{}": Constructor message for the chaincode in JSON format
-l, --lang="golang": Language the chaincode is written in
--logging-level="": Default logging level and overrides, see core.yaml for full syntax
-n, --name="": Name of the chaincode returned by the deploy transaction
-p, --path="": Path to chaincode
--test.coverprofile="coverage.cov": Done
-t, --tid="": Name of a custom ID generation algorithm (hashing and decoding) e.g. sha256base64
-u, --username="": Username for chaincode operations when security is enabled
-v, --version[=false]: Display current version of fabric peer server
```
To deploy a chaincode with attributes "company" and "position" it should be written in the following way:
```
./peer chaincode deploy -u userName -n mycc -c '{"Function":"init", "Args": []}' -a '["position", "company"]'
```
#### REST
```
POST host:port/chaincode
{
"jsonrpc": "2.0",
"method": "deploy",
"params": {
"type": 1,
"chaincodeID":{
"name": "mycc"
},
"ctorMsg": {
"function":"init",
"args":[]
}
"attributes": ["position", "company"]
},
"id": 1
}
```
### Invoke API making use of attributes
#### CLI
```
$ ./peer chaincode invoke --help
Invoke the specified chaincode.
Usage:
peer chaincode invoke [flags]
Global Flags:
-a, --attributes="[]": User attributes for the chaincode in JSON format
-c, --ctor="{}": Constructor message for the chaincode in JSON format
-l, --lang="golang": Language the chaincode is written in
--logging-level="": Default logging level and overrides, see core.yaml for full syntax
-n, --name="": Name of the chaincode returned by the deploy transaction
-p, --path="": Path to chaincode
--test.coverprofile="coverage.cov": Done
-t, --tid="": Name of a custom ID generation algorithm (hashing and decoding) e.g. sha256base64
-u, --username="": Username for chaincode operations when security is enabled
-v, --version[=false]: Display current version of fabric peer server
```
To invoke "autorizable counter" with attributes "company" and "position" it should be written as follows:
```
./peer chaincode invoke -u userName -n mycc -c '{"Function":"increment", "Args": []}' -a '["position", "company"]'
```
#### REST
```
POST host:port/chaincode
{
"jsonrpc": "2.0",
"method": "invoke",
"params": {
"type": 1,
"chaincodeID":{
"name": "mycc"
},
"ctorMsg": {
"function":"increment",
"args":[]
}
"attributes": ["position", "company"]
},
"id": 1
}
```
### Query API making use of attributes
#### CLI
```
$ ./peer chaincode query --help
Query using the specified chaincode.
Usage:
peer chaincode query [flags]
Flags:
-x, --hex[=false]: If true, output the query value byte array in hexadecimal. Incompatible with --raw
-r, --raw[=false]: If true, output the query value as raw bytes, otherwise format as a printable string
Global Flags:
-a, --attributes="[]": User attributes for the chaincode in JSON format
-c, --ctor="{}": Constructor message for the chaincode in JSON format
-l, --lang="golang": Language the chaincode is written in
--logging-level="": Default logging level and overrides, see core.yaml for full syntax
-n, --name="": Name of the chaincode returned by the deploy transaction
-p, --path="": Path to chaincode
--test.coverprofile="coverage.cov": Done
-t, --tid="": Name of a custom ID generation algorithm (hashing and decoding) e.g. sha256base64
-u, --username="": Username for chaincode operations when security is enabled
-v, --version[=false]: Display current version of fabric peer server
```
To query "autorizable counter" with attributes "company" and "position" it should be written in this way:
```
./peer chaincode query -u userName -n mycc -c '{"Function":"read", "Args": []}' -a '["position", "company"]'
```
#### REST
```
POST host:port/chaincode
{
"jsonrpc": "2.0",
"method": "query",
"params": {
"type": 1,
"chaincodeID":{
"name": "mycc"
},
"ctorMsg": {
"function":"read",
"args":[]
}
"attributes": ["position", "company"]
},
"id": 1
}
```
* Attributes encryption is not yet available.
# Chaincode APIs
When the `Init`, `Invoke` or `Query` function of a chaincode is called, the fabric passes the `stub *shim.ChaincodeStub` parameter. This `stub` can be used to call APIs to access to the ledger services, transaction context, or to invoke other chaincodes.
The current APIs are defined in the [shim package](https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim), generated by `godoc`. However, it includes functions from [chaincode.pb.go](https://github.com/hyperledger/fabric/blob/master/core/chaincode/shim/chaincode.pb.go) such as `func (*Column) XXX_OneofFuncs` that are not intended as public API. The best is to look at the function definitions in [chaincode.go](https://github.com/hyperledger/fabric/blob/master/core/chaincode/shim/chaincode.go) and [chaincode samples](https://github.com/hyperledger/fabric/tree/master/examples/chaincode) for usage.
This diff is collapsed.
# Certificate Authority API
Each of the CA services is split into two [GRPC](http://www.grpc.io) interfaces, namely a public one (indicated by a _P_ suffix) and an administrator one (indicated by an _A_ suffix).
## Enrollment Certificate Authority
The administrator interface of the ECA provides the following functions:
service ECAA { // admin
rpc RegisterUser(RegisterUserReq) returns (Token);
rpc ReadUserSet(ReadUserSetReq) returns (UserSet);
rpc RevokeCertificate(ECertRevokeReq) returns (CAStatus); // not yet implemented
rpc PublishCRL(ECertCRLReq) returns (CAStatus); // not yet implemented
}
The `RegisterUser` function allows you to register a new user by specifiying their name and roles in the `RegisterUserReq` structure. If the user has not been registered before, the ECA registers the new user and returns a unique one-time password, which can be used by the user to request their enrollment certificate pair via the public interface of the ECA. Otherwise an error is returned.
The `ReadUserSet` function allows only auditors to retrieve the list of users registered with the blockchain.
The public interface of the ECA provides the following functions:
service ECAP { // public
rpc ReadCACertificate(Empty) returns (Cert);
rpc CreateCertificatePair(ECertCreateReq) returns (ECertCreateResp);
rpc ReadCertificatePair(ECertReadReq) returns (CertPair);
rpc ReadCertificateByHash(Hash) returns (Cert);
rpc RevokeCertificatePair(ECertRevokeReq) returns (CAStatus); // not yet implemented
}
The `ReadCACertificate` function returns the certificate of the ECA itself.
The `CreateCertificatePair` function allows a user to create and read their enrollment certificate pair. For this, the user has to do two successive invocations of this function. Firstly, both the signature and encryption public keys have to be handed to the ECA together with the one-time password previously returned by the `RegisterUser` function invocation. The request has to be signed by the user's private signature key to demonstrate that the user is in possession of the private signature key. The ECA in return gives the user a challenge encrypted with the user's public encryption key. The user has to decrypt the challenge, thereby demonstrating that they are in possession of the private encryption key, and then re-issue the certificate creation request - this time with the decrypted challenge instead of the one-time password passed in the invocation. If the challenge has been decrypted correctly, the ECA issues and returns the enrollment certificate pair for the user.
The `ReadCertificatePair` function allows any user of the blockchain to read the certificate pair of any other user of the blockchain.
The `ReadCertificatePairByHash` function allows any user of the blockchain to read a certificate from the ECA matching a given hash.
## Transaction Certificate Authority
The administrator interface of the TCA provides the following functions:
service TCAA { // admin
rpc RevokeCertificate(TCertRevokeReq) returns (CAStatus); // not yet implemented
rpc RevokeCertificateSet(TCertRevokeSetReq) returns (CAStatus); // not yet implemented
rpc PublishCRL(TCertCRLReq) returns (CAStatus); // not yet implemented
}
The public interface of the TCA provides the following functions:
service TCAP { // public
rpc ReadCACertificate(Empty) returns (Cert);
rpc CreateCertificate(TCertCreateReq) returns (TCertCreateResp);
rpc CreateCertificateSet(TCertCreateSetReq) returns (TCertCreateSetResp);
rpc RevokeCertificate(TCertRevokeReq) returns (CAStatus); // not yet implemented
rpc RevokeCertificateSet(TCertRevokeSetReq) returns (CAStatus); // not yet implemented
}
The `ReadCACertificate` function returns the certificate of the TCA itself.
The `CreateCertificate` function allows a user to create and retrieve a new transaction certificate.
The `CreateCertificateSet` function allows a user to create and retrieve a set of transaction certificates in a single call.
## TLS Certificate Authority
The administrator interface of the TLSCA provides the following functions:
service TLSCAA { // admin
rpc RevokeCertificate(TLSCertRevokeReq) returns (CAStatus); not yet implemented
}
The public interface of the TLSCA provides the following functions:
service TLSCAP { // public
rpc ReadCACertificate(Empty) returns (Cert);
rpc CreateCertificate(TLSCertCreateReq) returns (TLSCertCreateResp);
rpc ReadCertificate(TLSCertReadReq) returns (Cert);
rpc RevokeCertificate(TLSCertRevokeReq) returns (CAStatus); // not yet implemented
}
The `ReadCACertificate` function returns the certificate of the TLSCA itself.
The `CreateCertificate` function allows a user to create and retrieve a new TLS certificate.
The `ReadCertificate` function allows a user to retrieve a previously created TLS certificate.
# Contributions Welcome!
We welcome contributions to the Hyperledger Project in many forms, and
there's always plenty to do!
First things first, please review the Hyperledger Project's [Code of
Conduct](https://github.com/hyperledger/hyperledger/wiki/Hyperledger-Project-Code-of-Conduct)
before participating. It is important that we keep things civil.
## Getting a Linux Foundation account
In order to participate in the development of the Hyperledger Fabric project,
you will need an [LF account](Gerrit/lf-account.md). You will need to use
your LF ID to grant you access to all the Hyperledger community tools, including
[Gerrit](https://gerrit.hyperledger.org) and [Jira](https://jira.hyperledger.org).
### Setting up your SSH key
For Gerrit, you will want to register your public SSH key. Login to
[Gerrit](https://gerrit.hyperledger.org)
with your LF account, and click on your name in the upper right-hand corner
and then click 'Settings'. In the left-hand margin, you should see a link for
'SSH Public Keys'. Copy-n-paste your [public SSH key](https://help.github.com/articles/generating-an-ssh-key/)
into the window and press 'Add'.
## Getting help
If you are looking for something to work on, or need some expert assistance in
debugging a problem or working out a fix to an issue, our
[community](https://www.hyperledger.org/community) is always eager to help. We
hang out on [Slack](https://hyperledgerproject.slack.com/), IRC (#hyperledger on
freenode.net) and the [mailing lists](http://lists.hyperledger.org/). Most of us
don't bite ;-) and will be glad to help.
## Requirements and Use Cases
We have a [Requirements
WG](https://github.com/hyperledger/hyperledger/wiki/Requirements-WG) that is
documenting use cases and from those use cases deriving requirements. If you are
interested in contributing to this effort, please feel free to join the
discussion in
[slack](https://hyperledgerproject.slack.com/messages/requirements/).
## Reporting bugs
If you are a user and you find a bug, please submit an
[issue](https://github.com/hyperledger/fabric/issues). Please try to provide
sufficient information for someone else to reproduce the issue. One of the
project's maintainers should respond to your issue within 24 hours. If not,
please bump the issue and request that it be reviewed.
## Fixing issues and working stories
Review the [issues list](https://github.com/hyperledger/fabric/issues) and find
something that interests you. You could also check the ["help
wanted"](https://github.com/hyperledger/fabric/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)
and ["good first
bug"](https://github.com/hyperledger/fabric/issues?q=is%3Aissue+is%3Aopen+label%3Agood-first-bug)
lists. It is wise to start with something relatively straight forward and
achievable. Usually there will be a comment in the issue that indicates whether
someone has already self-assigned the issue. If no one has already taken it,
then add a comment assigning the issue to yourself, eg.: `I'll work on this
issue.`. Please be considerate and rescind the offer in comments if you cannot
finish in a reasonable time, or add a comment saying that you are still actively
working the issue if you need a little more time.
## Working with a local clone and Gerrit
We are using [Gerrit](https://gerrit.hyperledger.org/r/#/admin/projects/fabric)
to manage code contributions. If you are unfamiliar, please review [this
document](Gerrit/gerrit.md) before proceeding.
After you have familiarized yourself with `Gerrit`, and maybe played around with
the `lf-sandbox` project, you should be ready to set up your local [development
environment](dev-setup/devenv.md). We use a Vagrant-based approach to
development that simplifies things greatly.
## Coding guidelines
Be sure to check out the language-specific [style
guides](Style-guides/go-style.md) before making any changes. This will ensure a
smoother review.
### Becoming a maintainer
This project is managed under open governance model as described in our
[charter](https://www.hyperledger.org/about/charter). Projects or sub-projects
will be lead by a set of maintainers. New projects can designate an initial set
of maintainers that will be approved by the Technical Steering Committee when
the project is first approved. The project's maintainers will, from
time-to-time, consider adding or removing a maintainer. An existing maintainer
will post a patchset to the [MAINTAINERS.md](MAINTAINERS.md) file. If a
majority of the maintainers concur in the comments, the pull request is then
merged and the individual becomes a (or is removed as a) maintainer. Note that
removing a maintainer should not be taken lightly, but occasionally, people do
move on - hence the bar should be some period of inactivity, an explicit
resignation, some infraction of the code of conduct or consistently
demonstrating poor judgement.
## Legal stuff
**Note:** Each source file must include a license header for the Apache Software
License 2.0. A template of that header can be found [here](https://github.com/hyperledger/fabric/blob/master/docs/dev-setup/headers.txt).
We have tried to make it as easy as possible to make contributions. This
applies to how we handle the legal aspects of contribution. We use the same
approach&mdash;the [Developer's Certificate of Origin 1.1 (DCO)](docs/biz/DCO1.1.txt)&mdash;that
the Linux&reg; Kernel [community](http://elinux.org/Developer_Certificate_Of_Origin) uses to manage code contributions.
We simply ask that when submitting a patch for review, the developer must include
a sign-off statement in the commit message.
Here is an example Signed-off-by line, which indicates that the submitter
accepts the DCO:
```
Signed-off-by: John Doe <john.doe@hisdomain.com>
```
You can include this automatically when you commit a change to your local git
repository using `git commit -s`.
## Chaincode (Smart Contracts and Digital Assets)
&nbsp;
##### Does the fabric implementation support smart contract logic?
Yes. Chaincode is the fabric’s interpretation of the smart contract method/algorithm, with additional features.
A chaincode is programmatic code deployed on the network, where it is executed and validated by chain validators together during the consensus process. Developers can use chaincodes to develop business contracts, asset definitions, and collectively-managed decentralized applications.
&nbsp;
##### How do I create a business contract using the fabric?
There are generally two ways to develop business contracts: the first way is to code individual contracts into standalone instances of chaincode; the second way, and probably the more efficient way, is to use chaincode to create decentralized applications that manage the life cycle of one or multiple types of business contracts, and let end users instantiate instances of contracts within these applications.
&nbsp;
##### How do I create assets using the fabric?
Users can use chaincode (for business rules) and membership service (for digital tokens) to design assets, as well as the logic that manages them.
There are two popular approaches to defining assets in most blockchain solutions: the stateless UTXO model, where account balances are encoded into past transaction records; and the account model, where account balances are kept in state storage space on the ledger.
Each approach carries its own benefits and drawbacks. This blockchain fabric does not advocate either one over the other. Instead, one of our first requirements was to ensure that both approaches can be easily implemented with tools available in the fabric.
&nbsp;
##### Which languages are supported for writing chaincode?
Chaincode can be written in any programming language and executed in containers inside the fabric context layer. We are also looking into developing a templating language (such as Apache Velocity) that can either get compiled into chaincode or have its interpreter embedded into a chaincode container.
The fabric's first fully supported chaincode language is Golang, and support for JavaScript and Java is planned for 2016. Support for additional languages and the development of a fabric-specific templating language have been discussed, and more details will be released in the near future.
&nbsp;
##### Does the fabric have native currency?
No. However, if you really need a native currency for your chain network, you can develop your own native currency with chaincode. One common attribute of native currency is that some amount will get transacted (the chaincode defining that currency will get called) every time a transaction is processed on its chain.
## Confidentiality
&nbsp;
##### How is the confidentiality of transactions and business logic achieved?
The security module works in conjunction with the membership service module to provide access control service to any data recorded and business logic deployed on a chain network.
When a code is deployed on a chain network, whether it is used to define a business contract or an asset, its creator can put access control on it so that only transactions issued by authorized entities will be processed and validated by chain validators.
Raw transaction records are permanently stored in the ledger. While the contents of non-confidential transactions are open to all participants, the contents of confidential transactions are encrypted with secret keys known only to their originators, validators, and authorized auditors. Only holders of the secret keys can interpret transaction contents.
&nbsp;
##### What if none of the stakeholders of a business contract are validators?
In some business scenarios, full confidentiality of contract logic may be required – such that only contract counterparties and auditors can access and interpret their chaincode. Under these scenarios, counter parties would need to spin off a new child chain with only themselves as validators.
## Consensus Algorithm
&nbsp;
##### Which Consensus Algorithm is used in the fabric?
The fabric is built on a pluggable architecture such that developers can configure their deployment with the consensus module that best suits their needs. The initial release package will offer three consensus implementations for users to select from: 1) No-op (consensus ignored); and 2) Batch PBFT.
## Identity Management (Membership Service)
&nbsp;
##### What is unique about the fabric's Membership Service module?
One of the things that makes the Membership Service module stand out from the pack is our implementation of the latest advances in cryptography.
In addition to ensuring private, auditable transactions, our Membership Service module introduces the concept of enrollment and transaction certificates. This innovation ensures that only verified owners can create asset tokens, allowing an infinite number of transaction certificates to be issued through parent enrollment certificates while guaranteeing the private keys of asset tokens can be regenerated if lost.
Issuers also have the ability revoke transaction certificates or designate them to expire within a certain timeframe, allowing greater control over the asset tokens they have issued.
Like most other modules on the fabric, you can always replace the default module with another membership service option should the need arise.
&nbsp;
##### Does its Membership Service make the fabric a centralized solution?
No. The only role of the Membership Service module is to issue digital certificates to validated entities that want to participate in the network. It does not execute transactions nor is it aware of how or when these certificates are used in any particular network.
However, because certificates are the way networks regulate and manage their users, the module serves a central regulatory and organizational role.
## Usage
&nbsp;
#####What are the expected performance figures for the fabric?
The performance of any chain network depends on several factors: proximity of the validating nodes, number of validators, encryption method, transaction message size, security level set, business logic running, and the consensus algorithm deployed, among others.
The current performance goal for the fabric is to achieve 100,000 transactions per second in a standard production environment of about 15 validating nodes running in close proximity. The team is committed to continuously improving the performance and the scalability of the system.
&nbsp;
##### Do I have to own a validating node to transact on a chain network?
No. You can still transact on a chain network by owning a non-validating node (NV-node).
Although transactions initiated by NV-nodes will eventually be forwarded to their validating peers for consensus processing, NV-nodes establish their own connections to the membership service module and can therefore package transactions independently. This allows NV-node owners to independently register and manage certificates, a powerful feature that empowers NV-node owners to create custom-built applications for their clients while managing their client certificates.
In addition, NV-nodes retain full copies of the ledger, enabling local queries of the ledger data.
&nbsp;
##### What does the error string "state may be inconsistent, cannot query" as a query result mean?
Sometimes, a validating peer will be out of sync with the rest of the network. Although determining this condition is not always possible, validating peers make a best effort determination to detect it, and internally mark themselves as out of date.
When under this condition, rather than reply with out of date or potentially incorrect data, the peer will reply to chaincode queries with the error string "state may be inconsistent, cannot query".
In the future, more sophisticated reporting mechanisms may be introduced such as returning the stale value and a flag that the value is stale.
# Gerrit Recommended Practices
This document presents some best practices to help you use Gerrit more
effectively. The intent is to show how content can be submitted easily. Use the
recommended practices to reduce your troubleshooting time and improve
participation in the community.
## Browsing the Git Tree
Visit [Gerrit](https://gerrit.hyperledger.org/r/#/admin/projects/fabric) then
select `Projects --> List --> SELECT-PROJECT --> Branches`. Select the branch
that interests you, click on `gitweb` located on the right-hand side. Now,
`gitweb` loads your selection on the Git web interface and redirects
appropriately.
## Watching a Project
Visit [Gerrit](https://gerrit.hyperledger.org/r/#/admin/projects/fabric), then
select `Settings`, located on the top right corner. Select `Watched Projects`
and then add any projects that interest you.
## Commit Messages
Gerrit follows the Git commit message format. Ensure the headers are at the
bottom and don't contain blank lines between one another. The following example
shows the format and content expected in a commit message:
Brief (no more than 50 chars) one line description.
Elaborate summary of the changes made referencing why (motivation), what was
changed and how it was tested. Note also any changes to documentation made to
remain consistent with the code changes, wrapping text at 72 chars/line.
Jira: FAB-100
Change-Id: LONGHEXHASH
Signed-off-by: Your Name your.email@example.org
AnotherExampleHeader: An Example of another Value
The Gerrit server provides a precommit hook to autogenerate the Change-Id which
is one time use.
**Recommended reading:** [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/)
## Avoid Pushing Untested Work to a Gerrit Server
To avoid pushing untested work to Gerrit.
Check your work at least three times before pushing your change to Gerrit.
Be mindful of what information you are publishing.
## Keeping Track of Changes
- Set Gerrit to send you emails:
- Gerrit will add you to the email distribution list for a change if a
developer adds you as a reviewer, or if you comment on a specific Patch
Set.
- Opening a change in Gerrit's review interface is a quick way to follow that
change.
- Watch projects in the Gerrit projects section at `Gerrit`, select at least
*New Changes, New Patch Sets, All Comments* and *Submitted Changes*.
Always track the projects you are working on; also see the feedback/comments
mailing list to learn and help others ramp up.
## Topic branches
Topic branches are temporary branches that you push to commit a set of
logically-grouped dependent commits:
To push changes from `REMOTE/master` tree to Gerrit for being reviewed as
a topic in **TopicName** use the following command as an example:
$ git push REMOTE HEAD:refs/for/master/TopicName
The topic will show up in the review :abbr:`UI` and in the
`Open Changes List`. Topic branches will disappear from the master
tree when its content is merged.
## Creating a Cover Letter for a Topic
You may decide whether or not you'd like the cover letter to appear in the
history.