diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0040a9d124..a3bd8ec06c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,6 +7,8 @@ * [Before starting work on a PR](#before-starting-work-on-a-pr) * [Before submitting a PR](#before-submitting-a-pr) * [Normal PR workflow](#normal-pr-workflow) + * [First PR example](#first-pr-example) + * [Updating your PR based on review comments](#updating-your-pr-based-on-review-comments) * [Assisted PR workflow](#assisted-pr-workflow) * [Re-vendor PRs](#re-vendor-prs) * [Stable branch backports](#stable-branch-backports) @@ -120,14 +122,364 @@ rework your branch. You should rework any relevant information from the GitHub comment section into your patch set because your patches are documented in the Git log, not the comment section. -For more information on GitHub "force push" workflows see "[Why and how to -correctly amend GitHub pull -requests](http://blog.adamspiers.org/2015/03/24/why-and-how-to-correctly-amend-github-pull-requests/)". - Your PR can contain more than one patch. Use as many patches as necessary to implement the request. Each PR should only cover one topic. If you mix up different items in your patches or PR, they will likely need to be reworked. +#### First PR example + +This section guides you through the process to create your first PR. We will +create a branch and in that branch we will change *this document*, which lives +in the Kata Containers community repository: + +- https://github.com/kata-containers/community + +This is the official location for this repository and is referred to as the +"upstream" repository. + +> **Note:** This section assumes no previous `git(1)` setup or knowledge. + +- Create a free GitHub account + + To raise PRs and create issues, you must have a GitHub account. + +- Basic Git setup + + First, install the `git` package for your distribution. Second, tell Git + your name and email address, if you haven't already, so they can be recorded + in your commits. + + ```sh + $ git config --global user.email "you@example.com" + $ git config --global user.name "Your Name" + ``` + + > **Note:** The email address you specify here must match your primary GitHub email address. + +- Create your own copy of the repository + + Click "fork" to create "your copy" of the repository you want to change on + https://github.com/kata-containers/community. This is an exact copy of the + upstream repository located at + `https://github.com/${your-github-username}/community` on the GitHub server. You + can make changes on this copy as we move through the example. + +- Prepare your environment + + > **Note:**: Most of the + > [Kata Containers repositories](https://github.com/kata-containers) + > contain code written in the + > [Go language (golang)](https://golang.org/). Go requires all code to be put + > inside the directory specified by the `$GOPATH` variable. Since this example PR + > is not using golang you do not need to + > [install golang](https://github.com/kata-containers/documentation/blob/master/Developer-Guide.md#requirements-to-build-individual-components). + > However it still makes sense to put the code in the standard location. + + ```sh + $ export GOPATH=${GOPATH:-$HOME/go} + $ mkdir -p "$GOPATH" + ``` + + > **Note:** The code above is safe to run whether you have golang installed + > or not. + > For further details on golang, refer to the + > [requirements section of the Kata Developer Guide](https://github.com/kata-containers/documentation/blob/master/Developer-Guide.md#requirements-to-build-individual-components). + + +- [Clone the upstream repository](https://help.github.com/articles/cloning-a-repository): + + "Cloning" is a term that means to create a *local copy* of a Git repository + that generally lives on a remote server. + + ```sh + $ dir="$GOPATH/src/github.com/kata-containers" + $ mkdir -p "$dir" + $ cd "$dir" + $ git clone https://github.com/kata-containers/community + $ cd community + ``` + + > **Note:** The previous Git command: + > + > - Creates a *local copy* of the upstream repository and switches to the + > `master` *branch*. + > - Creates an "alias" (name) for the upstream repository URL called `origin`. + + There are now *three* copies of the repository (all *exactly* the same): + + - The original upstream one (https://github.com/kata-containers/community) + + You do not (and cannot) make changes to this repository. PRs are a way of + allowing the project developers and administrators to review your work and + decide if they want to add your work to the upstream branch. + + > **Note:** Don't worry - even if you make a mistake, + > you *cannot* do any damage to this repository. + + - Your fork (`https://github.com/${your-github-username}/community`) on GitHub + + This is where you send or upload (`git push`) your PR branches. + + - Your *local copy* of the upstream repository + (https://github.com/kata-containers/community) + + This is where you actually make changes to your private copy of the + repository. + +- [Setup a "git remote"](https://help.github.com/articles/configuring-a-remote-for-a-fork): + + "What happened to my fork?". The following demonstrates where your fork is + and how you use it. + + Recall that your fork on the GitHub server is an *exact copy* of the + upstream repository that also lives on the GitHub server. That might not be + true moving forward because PRs are constantly merged into the upstream + repository. This means your fork will be out of date because it will not + contain the latest changes in the upstream repository. The same + problem also affects your local copy of the upstream repository. + + The way you keep your local copy up to date is to run `git pull` + periodically. This command downloads all the latest changes from "another + repository" into your local repository. + + You might ask how Git knows which repository to pull changes from. Simply, + it defaults to pull from the repository you `git clone`'d in previous steps. + In Git terminology that default repository is given two names: + + - The URL for the default upstream repository is called the `origin`. + + - The local branch that Git puts the copy of the upstream repository into is + called `master`. + + If you run `git push`, Git will try to upload any of your local changes + into the default repository (i.e. the `origin`). This will not work because + the `origin` is the upstream repository that you do not have permission to + change. + + You need to tell Git that your changes should be uploaded to your fork on + the GitHub server when you `git push` This is done by adding what is called + a "remote": + + ```sh + $ user="your-github-username" + $ git remote add github https://github.com/${user}/community + ``` + + > **Note:** The previous command adds an alias (name) for the URL of the + > fork you created on the GitHub server. This makes using the fork easier. + +- Create a new "topic branch" to do your work on: + + ```sh + $ git checkout -b fix-doc-bugs + ``` + + > **Warning:** *Never* make changes directly to the `master` branch - + > *always* create a new "topic branch" for PR work. + +- Make some changes + + In this example we modify the file you are reading: + + ```sh + $ $EDITOR CONTRIBUTING.md + ``` + +- Commit your changes to the current (`fix-doc-bugs`) branch and make sure you + use the correct [patch format](#patch-format): + + ```sh + $ git commit -as + ``` + +- Push your local `fix-doc-bugs` branch to your remote fork: + + The following command uploads your changes to *your fork on the GitHub server*: + + ```sh + $ git push -u github + ``` + > **Note:** The `-u` option tells `git` to "link" your local clone with your + > remote fork so that it will know from now on that the local repository and + > the remote fork refer to "the same" upstream repository. Strictly, you + > only need to use this option the first time you call `git push` for a new + > clone. + +- Create the PR: + - Browse to https://github.com/kata-containers/community. + - Click the "Compare & pull request" button that appears. + - Click the "Create pull request" button. + + > **Note:** You do not need to change any of the defaults on this page. + +The following is a summary of the components and terms we covered in this section: + +| Thing | Description | Summary | +|-|-|-| +| https://github.com/kata-containers/community | Official repository URL. | upstream | +| `https://github.com/${your-github-username}/community` | URL of your remote copy of the official repository. | fork | +| `$GOPATH/src/github.com/kata-containers/community` | Location of your local copy of the repository. | checkout or clone | +| `master` | Local *branch* containing a copy of the upstream. | `master` branch | +| `origin` | The "remote" name for the official repository. | `origin` remote | +| `github` | The "remote" name for your remote fork. | `github` remote | +| `fix-doc-bugs` | Local *branch* containing your PR changes. | `fix-doc-bugs` branch | + +You have setup your Git environment to do the following: + +| Branch | Operation | Description | +|-|-|-| +| `master` | `git pull` | Downloads changes from the `origin` remote (upstream repository) into the local `master` branch | +| `fix-doc-bugs` | `git push` | Uploads changes from your local PR branch to your fork on the GitHub server | + +##### Updating your PR based on review comments + +Let's say you received some review feedback that asked you to make some +changes to your PR. You have updated your local branch and committed those +review changes by creating three commits. There are now four commits in your +local branch: the original commit you created for the PR and three other +commits you created to apply the review changes to your branch. Your branch +now looks something like this: + +```sh +$ git log master.. --oneline --decorate=no +4928d57 docs: Fix typos and fold long lines +829c6c8 apply review feedback changes +7c9b1b2 remove blank lines +60e2b2b doh - missed one +``` + +> **Note:** The `git log` command compares your current branch (`fix-doc-bugs`) +> with the `master` branch and lists all the commmits, one per line. + +Since all four commits are related to *the same change* to fix spelling mistakes +and break long lines up into shorter lines, it makes sense to combine all four +commits into a *single commit* on your PR. To do this, complete the following +steps: + +- Update your branch + + You need to ensure your local copy of the upstream branch contains the + latest changes. + +- Rebase your changes against the `master` branch + + This operation might seem scary, but it is the way Git allows you to merge + all of your changes together. + +- Squash all the commits together + + "Squashing" means to combine all your commits into a single commit. All the + changes you made are saved and associated with a single commit, rather than + being spread across four commits. + +- Force-push the newly updated branch to your fork on GitHub + + This updates your PR with your new (*single*) commit. + +Taking each step in turn: + +- Update your branch + + First, update the `master` branch in your local copy of the upstream + repository: + + ```sh + $ cd $GOPATH/src/github.com/kata-containers/community + $ git checkout master + $ git pull + ``` + + The previous command downloads all the latest changes from the upstream + repository and adds them to your *local copy*. + + Now, switch back to your PR branch: + + ```sh + $ git checkout fix-doc-bugs + ``` + +- Start the rebase operation + + ```sh + $ git rebase -i master + ``` + + As an example, your editor window could appear as follows: + + ``` + pick 2e335ac docs: Fix typos and fold long lines + pick 6d6deb0 apply review feedback changes + pick 23bc01d remove blank lines + pick 3a4ba3f doh - missed one + ``` + +- In your editor, read the comments at the bottom of the screen. Next, without + modifying the first line (`pick 2e335ac docs: Fix typos and fold long + lines`), change the "`pick`" at the start of all the other lines to + "`squash`". + + As an example, your editor window could appear as follows: + + ``` + pick 2e335ac docs: Fix typos and fold long lines + squash 6d6deb0 apply review feedback changes + squash 23bc01d remove blank lines + squash 3a4ba3f doh - missed one + ``` + + Next, save and quit the editor window and Git puts you *back* into your + editor. Now, instead of showing you all the one line commit summaries, you + will see all the commit *messages*. These messages are descriptions for all the + commits you created. At this point you can modify the file as you wish. Once + you save and exit the editor, Git uses whatever is left in the file as the + commit message for your "squashed' commit. + + If you followed the example [first PR](#first-pr-example), + your first commit ("`2e335ac docs: Fix typos and fold long lines`") + is already in the [correct format](#patch-format). You keep the text for + your first commit and delete everything else in the editor window and update + if appropriate based on the review feedback. + + Save the file and quit the editor. Once this operation completes, the four + commits will have been converted into a single new commit. Check this by + running the `git log` command again: + + ```sh + $ git log master.. --oneline --decorate=no + 3ea3aef docs: Fix typo + ``` + +- Force push your updated local `fix-doc-bugs` branch to your remote fork: + + ```sh + $ git push -f github + ``` + + > **Notes:** + > + > - Not only does this command upload your changes to your fork, it also + > includes the *latest upstream changes* to your fork since you + > ran `git pull` in the master branch and then merged those changes into + > your PR branch. This is exactly what you want as your fork is now "up to + > date" with the upstream repository. + > + > - The `-f` option is a "force push". Since you created a new commit using + > `git rebase`, you must "overwrite" the old copy of your branch in your + > fork on GitHub. This is similar to saving a file in your editor because + > you are overwriting the old version you no longer want. GitHub + > recommends a force push to handle an update to your PR. This also means + > you do not have to create a new PR on GitHub because a force push + > effectively re-uses the initial PR you raised and includes your latest + > changes. + > + > For more information on GitHub "force push" workflows see "[Why and how to + > correctly amend GitHub pull + > requests](http://blog.adamspiers.org/2015/03/24/why-and-how-to-correctly-amend-github-pull-requests/)". + +Your PR is now updated on GitHub. To ensure team member are aware of this, +leave a message on the PR stating something like, "review feedback applied". +Then, the team is notified and able to re-review your PR more quickly. + ### Assisted PR workflow If your PR is deemed useful but you are struggling to update it based on