mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-04-20 13:00:51 -07:00
596 lines
23 KiB
ReStructuredText
596 lines
23 KiB
ReStructuredText
===============================================
|
||
Memory Pool System pull request merge procedure
|
||
===============================================
|
||
|
||
:tag: proc.merge.pull-request
|
||
:author: Richard Brooksby
|
||
:organization: Ravenbrook Limited
|
||
:date: 2023-01-07
|
||
:confidentiality: public
|
||
:copyright: See `C. Copyright and License`_
|
||
:readership: MPS developers, trainee integrators
|
||
|
||
|
||
1. Introduction
|
||
---------------
|
||
|
||
This document contains a procedure for merging a branch received via a
|
||
GitHub "pull request".
|
||
|
||
Time to execute:
|
||
|
||
- first time: 2 hours
|
||
- second time: 30 minutes
|
||
- with practice: < 10 minutes
|
||
|
||
these are measurements_ taken during simple merges that passed automated tests.
|
||
|
||
.. _measurements: https://github.com/Ravenbrook/mps/pull/97#issuecomment-1381771818
|
||
|
||
Ravenbrook is currently (2023-01) `migrating the MPS project to git
|
||
(and GitHub) <https://github.com/Ravenbrook/mps/issues/98>`_ and that
|
||
will greatly simplify this procedure.
|
||
|
||
This procedure assumes a pull request has been received via GitHub,
|
||
but that dependency is light. The procedure can be varied for other
|
||
sources, even where the "pull request" is received by email or some
|
||
other traceable document.
|
||
|
||
This document was created as a combination of the process improvement
|
||
steps from our Perforce-based "Memory Pool System branching and
|
||
merging procedures" [GDR_2014-01-09]_ with Gareth Rees' email
|
||
containing the working steps for git / GitHub merges, "Re: Possible
|
||
MPS Help" [GDR_2020-09-03]_ .
|
||
|
||
|
||
2. Purpose
|
||
----------
|
||
|
||
The purpose of this procedure is:
|
||
|
||
1. get required changes in to the MPS
|
||
|
||
2. protect the MPS from introduction of defects
|
||
|
||
3. maintain and protect the permanent record of the MPS in Perforce
|
||
and Git, so that defects can be discovered, fixed, and prevented
|
||
|
||
As with any procedure, you can vary this one to meet this purpose, but
|
||
you should probably read section "`6. Rationale`_".
|
||
|
||
|
||
3. Pre-merge checklist
|
||
----------------------
|
||
|
||
Start by making a record for the merge. Make a comment on the pull
|
||
request with a permalink_ to the procedure you're following (this one)
|
||
and the start time, like::
|
||
|
||
Executing [proc.merge.pull-request](https://github.com/Ravenbrook/mps/blob/973fc087c9abff01a957b85bd17c4a2be434ae73/procedure/pull-request-merge.rst)
|
||
|
||
1. Start time 11:03.
|
||
|
||
The answers to the checklist questions should be "yes". If the answer
|
||
to a question isn't "yes", record that, and why (and maybe suggest
|
||
what to do about it). For example::
|
||
|
||
2. An automated test case isn't feasible as it would mean
|
||
introducing broken shell scripts to GitHub and watching for CI
|
||
errors.
|
||
|
||
When you finish the checklist, decide whether to start
|
||
`the merging procedure`_ by considering `2. Purpose`_.
|
||
|
||
#. Is there a permanent visible document (issue, job), referenced by
|
||
the branch, recording the problem that is solved by the changes in
|
||
the branch?
|
||
|
||
#. Does the branch solve the problem?
|
||
|
||
#. Is there an automated test case that demonstrates the problem
|
||
(without the branch) and that that the problem is solved (with the
|
||
branch)?
|
||
|
||
#. If there changes to the `MPS interface`_, are they documented?
|
||
|
||
#. If the changes to the MPS are significant and user-visible, is
|
||
there an update to the release notes
|
||
(``manual/source/release.rst``)?
|
||
|
||
#. Has there been a code review, and only review edits since?
|
||
|
||
#. Is the merge approved by an approving review?
|
||
|
||
The `Ravenbrook MPS repo on GitHub`_ is set to require an approving
|
||
review and GitHub will block a push (step 8) without one. If you
|
||
push an unapproved merge to Perforce, this will cause gitpushbot to
|
||
fail, and leave Perforce and GitHub out of sync. *Do not push to
|
||
Perforce without GitHub approval.*
|
||
|
||
#. Has the contributor licensed their work?
|
||
|
||
By default, the work is licensed if the contributor has not
|
||
expressed any kind of variation on the licensing of their work from
|
||
the material to which they are contributing. (See `"Licensing" in
|
||
"Contributing to the MPS" <../contributing.rst#licensing>`_.)
|
||
|
||
If they have expressed a variation, talk to them or get someone to
|
||
talk to them about the matter. *Do not start the merging
|
||
procedure*.
|
||
|
||
#. Does the branch, and its merge, build and pass tests?
|
||
|
||
CI should have run builds of both the branch, and a *trial merge*
|
||
[#trial-merge]_ of the pull request with master. Recent success by
|
||
CI is a strong indication that `the merging procedure`_ will be
|
||
quick and successful.
|
||
|
||
Look for build results in the pull request on GitHub. Expand "Show
|
||
all checks", and look for build success messages for both the
|
||
branch and for the pull request (the trial merge). If these
|
||
results are missing, inform sysadmins that CI isn't functioning.
|
||
|
||
You can also look for a build results in the logs of CI systems.
|
||
See `design.mps.ci.results <../design/tests.txt#ci-results>`__.
|
||
|
||
Are the build results up to date? If master has changed since the
|
||
date of the commit that kicked off the build (the one immediately
|
||
before the build results) then the build results are out of date.
|
||
Consider a *catch-up merge* from master to the branch to bring the
|
||
branch up to date and kick off new builds.
|
||
|
||
If there is a failed build *of the branch* you should not execute
|
||
`the merging procedure`_, but talk to the contributor about fixing
|
||
the branch.
|
||
|
||
If the branch built OK but there is a failed build *of the trial
|
||
merge*, you can still execute `the merging procedure`_ if you
|
||
believe that the failure is due to merge conflicts that you are
|
||
willing to resolve.
|
||
|
||
If you don't have recent build and test results for the merge, then
|
||
you can still try to execute `the merging procedure`_ if:
|
||
|
||
#. you believe there are only merge conflicts,
|
||
#. you're willing to try to resolve those conflicts, and
|
||
#. you're prepared to test on all target platforms.
|
||
|
||
.. [#trial-merge] CI is run against both the branch (labelled "push"),
|
||
and a `pull request merge branch`_ (labelled "pull
|
||
request") automatically created by GitHub.
|
||
|
||
.. _permalink: https://docs.github.com/en/repositories/working-with-files/using-files/getting-permanent-links-to-files
|
||
|
||
.. _pull request merge branch: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request
|
||
|
||
.. _Travis CI build history for the repo: https://app.travis-ci.com/github/Ravenbrook/mps/builds
|
||
|
||
.. _GitHub workflows for the repo: https://github.com/Ravenbrook/mps/actions
|
||
|
||
.. _MPS interface: https://www.ravenbrook.com/project/mps/master/manual/html/topic/interface.html
|
||
|
||
|
||
4. Prerequisite steps
|
||
---------------------
|
||
|
||
These steps will only rarely need repeating.
|
||
|
||
#. You need basic competence with Git: enough to understand what the
|
||
commands in `the merging procedure`_ do.
|
||
|
||
#. If the merge has conflicts, you will need competence in using Git
|
||
to resolve merge conflicts.
|
||
|
||
#. If you want to vary the procedure, you will need to understand how
|
||
Perforce Git Fusion [Perforce_2017]_ connects Ravenbrook's Perforce
|
||
repository to the `Ravenbrook MPS repo on GitHub`_.
|
||
|
||
#. Ensure your public SSH key is submitted in Perforce at
|
||
//.git-fusion/users/USER/keys/
|
||
|
||
This is the public key that the SSH used by your Git will use to
|
||
connect to perforce.ravenbrook.com.
|
||
|
||
**NOTE**: As of 2022-11, you may not be able to connect to Perforce
|
||
Git Fusion without specifying an old public key algorithm. See
|
||
`"Connecting to Git Fusion"
|
||
<https://info.ravenbrook.com/mail/2022/11/29/21-01-14/0/>`__.
|
||
|
||
#. Ensure your e-mail address is submitted in Perforce at
|
||
//.git-fusion/users/p4gf_usermap and matches your Perforce user
|
||
record.
|
||
|
||
#. Clone the Ravenbrook MPS GitHub repository and name the remote
|
||
"github" [#github]_. This will give you access to CI to
|
||
build and test the merge. (If you're an MPS developer you can use
|
||
your existing repo.) ::
|
||
|
||
git clone -o github git@github.com:Ravenbrook/mps.git
|
||
|
||
#. Set your e-mail address for commits to the repo to match the one in
|
||
your Perforce user record, e.g. from within the "mps" repo
|
||
directory ::
|
||
|
||
git config user.email spqr@ravenbrook.com
|
||
|
||
and possibly your name if you don't have that set in Git globally ::
|
||
|
||
git config user.name 'Julius Cesar'
|
||
|
||
#. Add the Git Fusion mps-public repo, which is the interface to
|
||
Ravenbrook's Perforce. From within the "mps" repo directory ::
|
||
|
||
git remote add perforce ssh://git@perforce.ravenbrook.com:1622/mps-public
|
||
|
||
.. [#github] There's nothing special about this name -- it's just
|
||
assumed in the examples in the procedure.
|
||
|
||
|
||
.. _the merging procedure:
|
||
|
||
5. Merging procedure
|
||
--------------------
|
||
|
||
Note: At any point before a successful "push" in step 7, this
|
||
procedure can be abandoned without harm. All work is local to your
|
||
working repo before that point.
|
||
|
||
1. `Fetch the pull request branch`_ to a local branch using the MPS
|
||
`durable branch naming convention`_, "branch/DATE/TOPIC".
|
||
|
||
If the branch already has a conventional name, and it's in the
|
||
`Ravenbrook MPS repo on GitHub`_ then fetch it with the existing
|
||
name, e.g. ::
|
||
|
||
git fetch github branch/2023-01-06/speed-hax:branch/2023-01-06/speed-hax
|
||
|
||
Otherwise, if the pull request is in the `Ravenbrook MPS repo on
|
||
GitHub`_, fetch it from the pull request and give it a conventional
|
||
name, like this ::
|
||
|
||
git fetch github pull/$PR/head:$BRANCH
|
||
|
||
For example ::
|
||
|
||
git fetch github pull/93/head:branch/2023-01-06/speed-hax
|
||
|
||
(This could happen if either the pull request is from a fork or the
|
||
branch has an unconventional name.)
|
||
|
||
If the branch to be merged is in a third-party repo, such as a fork
|
||
not on GitHub, you can fetch it using a remote, e.g.::
|
||
|
||
git remote add captain-contrib https://gitlab.com/captcontrib/mps.git
|
||
git fetch captain-contrib mps-speed-hax:branch/2023-01-06/speed-hax
|
||
|
||
Double check you've got the branch name right. Using the wrong
|
||
branch naming `causes permanent pollution in the Ravenbrook
|
||
Perforce repository
|
||
<https://info.ravenbrook.com/mail/2023/01/07/15-06-41/0/>`_.
|
||
|
||
2. Optionally, let other people know that you're working on a merge
|
||
into master. Negotiate to avoid racing them to push to the master
|
||
codeline (step 7) because that will create extra merging work.
|
||
|
||
3. Ensure your local master is up to date with Perforce::
|
||
|
||
git pull --ff-only perforce master
|
||
|
||
If you get an error, then GitHub's master and Perforce's master are
|
||
in out of sync, and this procedure fails.
|
||
|
||
Ensure your local master is not ahead of Perforce::
|
||
|
||
git push --dry-run perforce
|
||
|
||
If this shows anything other than "Everything up-to-date." then
|
||
GitHub's master and Perforce's master are in out of sync, and this
|
||
procedure fails.
|
||
|
||
[It may be possible to fix that here and now and continue. That's
|
||
a subject for a whole nother procedure that we don't currently
|
||
have. RB 2023-01-12]
|
||
|
||
4. Merge the branch in to your local master::
|
||
|
||
git merge --no-ff branch/2023-01-06/speed-hax
|
||
|
||
Edit the commit message to link it to *why* you are merging. Say
|
||
something like::
|
||
|
||
Merging branch/2023-01-06/speed-hax for GitHub pull request #93 <https://github.com/Ravenbrook/mps/pull/93>.
|
||
|
||
Do *not* just say "pull request #93" or just "#93" without a link,
|
||
because that number is local to, and only valid on GitHub. Bear
|
||
this in mind for other references. Do add any other links that
|
||
would increase traceability.
|
||
|
||
You may need to resolve conflicts. If you can't resolve conflicts
|
||
yourself, you may need to involve the original author of the
|
||
branch. If you still can't resolve conflicts, this procedure
|
||
fails.
|
||
|
||
5. Maybe build and test locally. If either
|
||
|
||
- the merge was non-trivial
|
||
- there has been any rebasing (see step 7)
|
||
- there were failed or missing build results from CI
|
||
|
||
then build and test the merge result locally if possible. For
|
||
example::
|
||
|
||
make -C code -f lii6gc.gmk testci testansi testpollnone testmmqa
|
||
|
||
See `design.mps.tests <../design/tests.txt>`_ for details and other
|
||
platforms.
|
||
|
||
If tests do not pass, review your conflict resolution from the
|
||
merge (step 4), and if that doesn't fix things, the procedure
|
||
fails, and you need to go back to the source of the branch,
|
||
e.g. the pull request and its original author. Something's wrong!
|
||
|
||
6. Maybe build and test using CI. As with step 5, if either
|
||
|
||
- the merge was non-trivial
|
||
- there has been any rebasing (see step 7)
|
||
- there were failed or missing build results from CI
|
||
|
||
then push the merge to a fresh branch in the `Ravenbrook MPS repo
|
||
on GitHub`_. This should trigger CI to build and testing on all
|
||
target platforms. ::
|
||
|
||
git push github HEAD:merge/2023-01-06/speed-hax
|
||
|
||
You will need to wait for results from CI. Look for a build
|
||
results in the `Travis CI build history for the repo`_ and in the
|
||
`GitHub workflows for the repo`_.
|
||
|
||
See build (step 5) about what to do if tests do not pass.
|
||
|
||
7. Submit your merged master and the branch to Perforce::
|
||
|
||
git push perforce master branch/2023-01-06/speed-hax
|
||
|
||
**Important**: Do *not* force this push.
|
||
|
||
If this fails, someone has submitted changes to the master codeline
|
||
since you started.
|
||
|
||
You can attempt to rebase your work on those changes::
|
||
|
||
git pull --rebase perforce
|
||
|
||
then go back to testing (step 5).
|
||
|
||
Alternatively, you could undo your merging work::
|
||
|
||
git reset --hard perforce/master
|
||
|
||
then go back to merging (step 4).
|
||
|
||
8. Optionally, if and *only if* the Perforce push (step 7) succeeded,
|
||
you can also push to GitHub::
|
||
|
||
git push github master branch/2023-01-06/speed-hax
|
||
|
||
If you don't do this, then within `30 minutes
|
||
<https://info.ravenbrook.com/infosys/robots/gitpushbot/etc/crontab>`_
|
||
check that the merge appears in `the commits in the Ravenbrook MPS
|
||
repo on GitHub <https://github.com/Ravenbrook/mps/commits/master>`_.
|
||
|
||
If they do not appear:
|
||
|
||
1. Check email for error messages from gitpushbot and resolve them.
|
||
|
||
2. Check (or ask a sysadmin to check) that gitpushbot is running
|
||
on Berunda and restart it if necessary, or ask a sysadmin to do
|
||
this.
|
||
|
||
9. Eyeball the pull request and related issues on GitHub to make sure
|
||
the merge was recorded correctly. Check that any issues *not
|
||
completely resolved* by the merge were not closed. Re-open them if
|
||
necessary.
|
||
|
||
10. Edit the comment you made in `3. Pre-merge checklist`_ to record
|
||
the end time of the merge and how long you spent merging, like::
|
||
|
||
6. End time 11:20. Merge took 17 mins.
|
||
|
||
.. _Fetch the pull request branch: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally#modifying-an-inactive-pull-request-locally
|
||
|
||
|
||
6. Rationale
|
||
------------
|
||
|
||
This section explains why the procedure is like it is. It's intended
|
||
for people who want to vary the procedure on the fly, or make
|
||
permanent changes to it. In the latter case, update this section!
|
||
|
||
[This section should argue the case in terms of section "`2. Purpose`_".
|
||
RB 2023-01-14]
|
||
|
||
|
||
6.1. Why not rebase or squash merge?
|
||
....................................
|
||
|
||
We would like to avoid rewriting history and the destruction of
|
||
information on the grounds that it destroys information that could be
|
||
important to the engineering of the MPS, such as tracking down
|
||
defects, comprehending the intention of changes. So want to
|
||
discourage rebasing or squashing.
|
||
|
||
We want to avoid fast-forwards of master. A fast-forward means there
|
||
is no commit that records the fact that there has been a merge, by
|
||
whom, from where, for what purpose, etc. It discards that
|
||
information. Therefore we want to discourage fast-forwards of master
|
||
in favour of merges. (Annoyingly, GitHub only provides `branch
|
||
protection that enforces the opposite
|
||
<https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/about-protected-branches#require-linear-history>`_!)
|
||
See also `6.3. Why the "durable" branch names?`_.
|
||
|
||
We also want to avoid `squash merges
|
||
<https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits>`_.
|
||
A squash merge compresses development history into a single commit,
|
||
destroying the record of what happened during development and the
|
||
connection to the branch.
|
||
|
||
Many developers use fast-forwards and squashes to simplify the
|
||
branching history so that it's easier to understand. Better tools and
|
||
interfaces are no doubt required for analysing Git history. These
|
||
will emerge. And they will be able to analyse the history that we are
|
||
creating today.
|
||
|
||
There is also a strong tendency among developers to "correct" mistakes
|
||
and edit history to reflect "what should have happened" or "what I
|
||
meant to do", treating history like code. But it's the function of
|
||
version control to protect software against well-intentioned mistakes.
|
||
Git is bad at remembering changes to history (it has no meta-history)
|
||
and so we should not edit it.
|
||
|
||
|
||
6.2. Why not press the GitHub merge button?
|
||
...........................................
|
||
|
||
We cannot use the GitHub pull request merge button because it would
|
||
put the GitHub master branch out of sync with (ahead of) Perforce.
|
||
Currently, Perforce is the authoritative home of the MPS, and the Git
|
||
repository is a mirror.
|
||
|
||
According to `GitHub's "About pull request merges"
|
||
<https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges>`_:
|
||
|
||
When you click the default Merge pull request option on a pull
|
||
request on GitHub.com, all commits from the feature branch are added
|
||
to the base branch in a merge commit.
|
||
|
||
`Travis CI builds and tests this merge in advance <https://docs.travis-ci.com/user/pull-requests/#how-pull-requests-are-built>`_:
|
||
|
||
Rather than build the commits that have been pushed to the branch
|
||
the pull request is from, we build the merge between the source
|
||
branch and the upstream branch.
|
||
|
||
When we use a GitHub CI on pull requests, that's also run on the merge
|
||
results. As `GitHub's pull request event documentation
|
||
<https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request>`_
|
||
says:
|
||
|
||
GITHUB_SHA for this event is the last merge commit of the pull
|
||
request merge branch.
|
||
|
||
So, `once Git becomes the home
|
||
<https://github.com/Ravenbrook/mps/issues/98>`_ we will be able to use
|
||
the button to to replace sections 4 and 5, the procedure, but not
|
||
section 3, the pre-merge checklist. We may be able to incorporate the
|
||
checklist into GitHub's interface using a `pull request template
|
||
<https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository>`_.
|
||
|
||
|
||
.. _durable branch naming convention:
|
||
|
||
6.3. Why the "durable" branch names?
|
||
....................................
|
||
|
||
It's common in Git culture to delete branches once they've been
|
||
merged [Ardalis_2017]_ but this destroys information that has been
|
||
invaluable to MPS quality in the past.
|
||
|
||
It destroys the connection between the branch name and a series of
|
||
changes made together, intentionally, for a purpose. That makes it
|
||
hard to identify those changes together. It makes it hard to *refer*
|
||
to those changes from documents and code (referring to the hash of the
|
||
last commit is not as good). It makes it hard to investigate the
|
||
intention of changes discovered by tools such as ``git blame`` or ``p4
|
||
annotate``.
|
||
|
||
Essentially, it throws away history and dissolves the branch into the
|
||
big global graph of git commits. That's not good configuration
|
||
management.
|
||
|
||
The MPS has an ongoing policy of retaining all of its intentional
|
||
history, and that includes branch names. Branch names in the MPS
|
||
repository are intended to last forever. That is why they have
|
||
"durable" names.
|
||
|
||
This policy has persisted over decades through more than one SCM
|
||
system, and will persist when Git has been replaced by the next one.
|
||
|
||
Note: `GitHub branch protection rules`_ are `enabled
|
||
<https://github.com/Ravenbrook/mps/settings/branches>`_ on the
|
||
`Ravenbrook MPS repo on GitHub`_ and should prevent deletion.
|
||
|
||
.. _Ravenbrook MPS repo on GitHub: https://github.com/Ravenbrook/mps
|
||
|
||
.. _GitHub branch protection rules: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/about-protected-branches#require-linear-history
|
||
|
||
|
||
A. References
|
||
-------------
|
||
|
||
.. [Ardalis_2017] "Why Delete Old Git Branches?"; Steve Ardalis;
|
||
2017-07-20;
|
||
<https://ardalis.com/why-delete-old-git-branches/>.
|
||
|
||
.. [GDR_2020-09-03] "Re: Possible MPS help"; Gareth Rees; 2020-09-03;
|
||
<https://info.ravenbrook.com/mail/2020/09/03/13-02-35/0/>.
|
||
|
||
.. [GDR_2014-01-09] "Memory Pool System branching and merging
|
||
procedures"; Gareth Rees; 2014-01-09;
|
||
<https://info.ravenbrook.com/project/mps/master/procedure/branch-merge>,
|
||
<https://github.com/Ravenbrook/mps/blob/e78c6e16735d7f16ef86a7f2f8356791a18c8a6e/procedure/branch-merge.rst>.
|
||
|
||
.. [Perforce_2017] "HelixCode Git Fusion Guide (2017.2)"; Perforce
|
||
Software; 2017;
|
||
<https://www.perforce.com/manuals/git-fusion/>.
|
||
|
||
|
||
B. Document History
|
||
-------------------
|
||
|
||
========== ===== ==================================================
|
||
2023-01-07 RB_ Created.
|
||
2023-01-13 RB_ Updates after `first attempt at execution`_.
|
||
2023-01-14 RB_ Updates after `second (successful) execution`_.
|
||
2023-01-23 RB_ Adding measurements.
|
||
2023-01-25 RB_ Responding to mini-review_.
|
||
2023-01-31 RB_ Adding instructions for recording the merge.
|
||
========== ===== ==================================================
|
||
|
||
.. _RB: mailto:rb@ravenbrook.com
|
||
|
||
.. _first attempt at execution: https://github.com/Ravenbrook/mps/pull/97#issuecomment-1380206348
|
||
|
||
.. _second (successful) execution: https://github.com/Ravenbrook/mps/pull/97#issuecomment-1381771818
|
||
|
||
.. _mini-review: https://github.com/Ravenbrook/mps/pull/97#discussion_r1085584810
|
||
|
||
|
||
C. Copyright and License
|
||
------------------------
|
||
|
||
Copyright © 2014–2023 `Ravenbrook Limited <https://www.ravenbrook.com/>`_.
|
||
|
||
Redistribution and use in source and binary forms, with or without
|
||
modification, are permitted provided that the following conditions are
|
||
met:
|
||
|
||
1. Redistributions of source code must retain the above copyright
|
||
notice, this list of conditions and the following disclaimer.
|
||
|
||
2. Redistributions in binary form must reproduce the above copyright
|
||
notice, this list of conditions and the following disclaimer in the
|
||
documentation and/or other materials provided with the distribution.
|
||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
||
.. checked with rst2html -v pull-request-merge.rst > /dev/null
|
||
.. end
|