/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

Merging Github Pull Requests
============================

When a developer submits a Pull Request (PR) to the Apache Unomi project on GitHub, you can follow these steps to
accept and merge that PR into the Apache Unomi code base.

Step-by-step guide
------------------

1. Carefully review the PR

  Make sure that the code for the PR looks good and, ideally, includes JUnit tests that prove that the code works.
  Check which branch the PR is targeting and make sure you want the code to go into that branch
  If the PR is large or adds new files, then make sure the person who submitted the request has an Apache ICLA on file.
  Ask the contributor to fill out this form and follow the instructions on the form to sent it in to
  Apache: https://www.apache.org/licenses/icla.txt
  Check the code to ensure that it does not bring in any code or dependencies with licenses more restrictive than the
  Apache Software License (ASLv2). For example, we cannot bring in any code or dependencies that are under GPL or
  LGPL license.

2. Configure your Git client to map GitHub PRs to ref

  Add this to your Git config for the Apache Unomi project. If you already have a remote for GitHub then add the two
  lines that mention "refs" to it.

        [remote "github"]
        url = https://github.com/apache/incubator-unomi.git
        fetch = +refs/heads/*:refs/remotes/github/*
        fetch = +refs/pull/*/head:refs/remotes/github/pr/*

  NOTE: For the rest of this guide we will assume that Apache Git is the remote named "origin" and GitHub is the remote named "github".

3. Fetch the latest PR refs from GitHub

  Use git's fetch command to pull in the latest PR refs from GitHub.

        git fetch github

4. Checkout the PR code

  Now you can fetch the code for the Pull Request like so:

        git checkout pr/<pull request number>

5. Merge the PR into the desired branch

   First checkout the desired branch and make sure it is up to date, for example:

        git checkout master
        git pull origin

  Next, use the merge command to merge the code into the target branch. And make sure to include a
  "This closes #" message (be sure to include the # sign) so that Apache's GitHub integration feature will close the
  PR. For example:

        git merge -m "This closes pull request number #<pull request number>" pr/<pull request number>

6. Push the code

  Push the code to Apache Git.

        git push origin

  Thank the contributor for their code.
