##// END OF EJS Templates
project: added all source files and assets
marcink -
r1:854a839a default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,5 b''
1 [bumpversion]
2 current_version = 4.0.0
3 message = release: Bump version {current_version} to {new_version}
4
5 [bumpversion:file:rhodecode/VERSION]
@@ -0,0 +1,18 b''
1 [run]
2
3 branch = True
4
5 include =
6 rhodecode/lib/*
7 rhodecode/model/*
8 rhodecode/controllers/*
9
10 omit =
11 rhodecode/lib/vcs/remote/*
12 rhodecode/lib/dbmigrate/*
13
14 [report]
15
16 exclude_lines =
17 raise NotImplementedError
18
@@ -0,0 +1,38 b''
1 {
2 /*
3 * ENVIRONMENTS
4 * =================
5 */
6
7 // Define globals exposed by modern browsers.
8 "browser": true,
9
10 // Define globals exposed by jQuery.
11 "jquery": true,
12
13 /*
14 * ENFORCING OPTIONS
15 * =================
16 */
17
18 // Prohibit use of == and != in favor of === and !==.
19 "eqeqeq": true,
20
21 // Enforce tab width of 2 spaces.
22 "indent": 2,
23
24 // Prohibit use of a variable before it is defined.
25 "latedef": true,
26
27 // Enforce line length to 100 characters
28 "maxlen": 100,
29
30 // Require capitalized names for constructor functions.
31 "newcap": true,
32
33 // Enforce placing 'use strict' at the top function scope
34 "strict": true,
35
36 // Prohibit use of explicitly undeclared variables.
37 "undef": true
38 }
@@ -0,0 +1,31 b''
1 [DEFAULT]
2 done = false
3
4 [task:fixes_on_stable]
5 done = true
6
7 [task:changelog_updated]
8 done = true
9
10 [task:nix_dependencies_moved]
11 done = true
12
13 [task:bump_version]
14 done = true
15
16 [task:generate_js_routes]
17 done = true
18
19 [task:generate_api_docs]
20 done = true
21
22 [release]
23 state = prepared
24 version = 3.8.3
25
26 [task:updated_translation]
27
28 [task:updated_trial_license]
29
30 [task:generate_oss_licenses]
31
@@ -0,0 +1,18 b''
1 [main]
2 host = https://www.transifex.com
3
4 [RhodeCode.pot]
5 source_file = rhodecode/i18n/rhodecode.pot
6 source_lang = en
7 type = PO
8
9 trans.be = rhodecode/i18n/be/LC_MESSAGES/rhodecode.po
10 trans.de = rhodecode/i18n/de/LC_MESSAGES/rhodecode.po
11 trans.es = rhodecode/i18n/es/LC_MESSAGES/rhodecode.po
12 trans.fr = rhodecode/i18n/fr/LC_MESSAGES/rhodecode.po
13 trans.it = rhodecode/i18n/it/LC_MESSAGES/rhodecode.po
14 trans.ja = rhodecode/i18n/ja/LC_MESSAGES/rhodecode.po
15 trans.pl = rhodecode/i18n/pl/LC_MESSAGES/rhodecode.po
16 trans.pt = rhodecode/i18n/pt/LC_MESSAGES/rhodecode.po
17 trans.ru = rhodecode/i18n/ru/LC_MESSAGES/rhodecode.po
18 trans.zh = rhodecode/i18n/zh/LC_MESSAGES/rhodecode.po
@@ -0,0 +1,1 b''
1 .. include:: docs/release-notes/release-notes.rst No newline at end of file
@@ -0,0 +1,137 b''
1 module.exports = function(grunt) {
2 grunt.initConfig({
3
4 dirs: {
5 css: "rhodecode/public/css",
6 js: {
7 "src": "rhodecode/public/js/src",
8 "dest": "rhodecode/public/js"
9 }
10 },
11
12 concat: {
13 dist: {
14 src: [
15 // Base libraries
16 '<%= dirs.js.src %>/jquery-1.11.1.min.js',
17 '<%= dirs.js.src %>/logging.js',
18 '<%= dirs.js.src %>/bootstrap.js',
19 '<%= dirs.js.src %>/mousetrap.js',
20 '<%= dirs.js.src %>/moment.js',
21 '<%= dirs.js.src %>/appenlight-client-0.4.1.min.js',
22
23 // Plugins
24 '<%= dirs.js.src %>/plugins/jquery.pjax.js',
25 '<%= dirs.js.src %>/plugins/jquery.dataTables.js',
26 '<%= dirs.js.src %>/plugins/flavoured_checkbox.js',
27 '<%= dirs.js.src %>/plugins/jquery.auto-grow-input.js',
28 '<%= dirs.js.src %>/plugins/jquery.autocomplete.js',
29 '<%= dirs.js.src %>/plugins/jquery.debounce.js',
30 '<%= dirs.js.src %>/plugins/jquery.timeago.js',
31 '<%= dirs.js.src %>/plugins/jquery.timeago-extension.js',
32
33 // Select2
34 '<%= dirs.js.src %>/select2/select2.js',
35
36 // Code-mirror
37 '<%= dirs.js.src %>/codemirror/codemirror.js',
38 '<%= dirs.js.src %>/codemirror/codemirror_loadmode.js',
39 '<%= dirs.js.src %>/codemirror/codemirror_hint.js',
40 '<%= dirs.js.src %>/codemirror/codemirror_overlay.js',
41 '<%= dirs.js.src %>/codemirror/codemirror_placeholder.js',
42 // TODO: mikhail: this is an exception. Since the code mirror modes
43 // are loaded "on the fly", we need to keep them in a public folder
44 '<%= dirs.js.dest %>/mode/meta.js',
45 '<%= dirs.js.dest %>/mode/meta_ext.js',
46 '<%= dirs.js.dest %>/rhodecode/i18n/select2/translations.js',
47
48 // Rhodecode utilities
49 '<%= dirs.js.src %>/rhodecode/utils/array.js',
50 '<%= dirs.js.src %>/rhodecode/utils/string.js',
51 '<%= dirs.js.src %>/rhodecode/utils/pyroutes.js',
52 '<%= dirs.js.src %>/rhodecode/utils/ajax.js',
53 '<%= dirs.js.src %>/rhodecode/utils/autocomplete.js',
54 '<%= dirs.js.src %>/rhodecode/utils/colorgenerator.js',
55 '<%= dirs.js.src %>/rhodecode/utils/ie.js',
56 '<%= dirs.js.src %>/rhodecode/utils/os.js',
57
58 // Rhodecode widgets
59 '<%= dirs.js.src %>/rhodecode/widgets/multiselect.js',
60
61 // Rhodecode components
62 '<%= dirs.js.src %>/rhodecode/pyroutes.js',
63 '<%= dirs.js.src %>/rhodecode/codemirror.js',
64 '<%= dirs.js.src %>/rhodecode/comments.js',
65 '<%= dirs.js.src %>/rhodecode/constants.js',
66 '<%= dirs.js.src %>/rhodecode/files.js',
67 '<%= dirs.js.src %>/rhodecode/followers.js',
68 '<%= dirs.js.src %>/rhodecode/menus.js',
69 '<%= dirs.js.src %>/rhodecode/notifications.js',
70 '<%= dirs.js.src %>/rhodecode/permissions.js',
71 '<%= dirs.js.src %>/rhodecode/pjax.js',
72 '<%= dirs.js.src %>/rhodecode/pullrequests.js',
73 '<%= dirs.js.src %>/rhodecode/settings.js',
74 '<%= dirs.js.src %>/rhodecode/select2_widgets.js',
75 '<%= dirs.js.src %>/rhodecode/tooltips.js',
76 '<%= dirs.js.src %>/rhodecode/users.js',
77 '<%= dirs.js.src %>/rhodecode/appenlight.js',
78
79 // Rhodecode main module
80 '<%= dirs.js.src %>/rhodecode.js'
81 ],
82 dest: '<%= dirs.js.dest %>/scripts.js',
83 nonull: true
84 }
85 },
86
87 less: {
88 development: {
89 options: {
90 compress: false,
91 yuicompress: false,
92 optimization: 0
93 },
94 files: {
95 "<%= dirs.css %>/style.css": "<%= dirs.css %>/main.less"
96 }
97 },
98 production: {
99 options: {
100 compress: true,
101 yuicompress: true,
102 optimization: 2
103 },
104 files: {
105 "<%= dirs.css %>/style.css": "<%= dirs.css %>/main.less"
106 }
107 }
108 },
109
110 watch: {
111 less: {
112 files: ["<%= dirs.css %>/*.less"],
113 tasks: ["less:production"]
114 },
115 js: {
116 files: ["<%= dirs.js.src %>/**/*.js"],
117 tasks: ["concat:dist"]
118 }
119 },
120
121 jshint: {
122 rhodecode: {
123 src: '<%= dirs.js.src %>/rhodecode/**/*.js',
124 options: {
125 jshintrc: '.jshintrc'
126 }
127 }
128 }
129 });
130
131 grunt.loadNpmTasks('grunt-contrib-less');
132 grunt.loadNpmTasks('grunt-contrib-concat');
133 grunt.loadNpmTasks('grunt-contrib-watch');
134 grunt.loadNpmTasks('grunt-contrib-jshint');
135
136 grunt.registerTask('default', ['less:production', 'concat:dist']);
137 };
This diff has been collapsed as it changes many lines, (690 lines changed) Show them Hide them
@@ -0,0 +1,690 b''
1 This program is free software: you can redistribute it and/or modify
2 it under the terms of the GNU Affero General Public License, version 3
3 (only), as published by the Free Software Foundation.
4
5
6 This program incorporates work covered by the following copyright and
7 permission notice:
8
9 Copyright (c) 2014-2016 - packaging
10 file:
11 Copyright (c) 2008-2011 - msgpack-python
12 file:licenses/msgpack_license.txt
13
14 Both licensed under the Apache License, Version 2.0 (the "License");
15 you may not use this file except in compliance with the License.
16 You may obtain a copy of the License at
17
18 http://www.apache.org/licenses/LICENSE-2.0
19
20 Unless required by applicable law or agreed to in writing, software
21 distributed under the License is distributed on an "AS IS" BASIS,
22 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 See the License for the specific language governing permissions and
24 imitations under the License.
25
26
27 Below is the full text of GNU Affero General Public License, version 3
28
29
30 GNU AFFERO GENERAL PUBLIC LICENSE
31 Version 3, 19 November 2007
32
33 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
34 Everyone is permitted to copy and distribute verbatim copies
35 of this license document, but changing it is not allowed.
36
37 Preamble
38
39 The GNU Affero General Public License is a free, copyleft license for
40 software and other kinds of works, specifically designed to ensure
41 cooperation with the community in the case of network server software.
42
43 The licenses for most software and other practical works are designed
44 to take away your freedom to share and change the works. By contrast,
45 our General Public Licenses are intended to guarantee your freedom to
46 share and change all versions of a program--to make sure it remains free
47 software for all its users.
48
49 When we speak of free software, we are referring to freedom, not
50 price. Our General Public Licenses are designed to make sure that you
51 have the freedom to distribute copies of free software (and charge for
52 them if you wish), that you receive source code or can get it if you
53 want it, that you can change the software or use pieces of it in new
54 free programs, and that you know you can do these things.
55
56 Developers that use our General Public Licenses protect your rights
57 with two steps: (1) assert copyright on the software, and (2) offer
58 you this License which gives you legal permission to copy, distribute
59 and/or modify the software.
60
61 A secondary benefit of defending all users' freedom is that
62 improvements made in alternate versions of the program, if they
63 receive widespread use, become available for other developers to
64 incorporate. Many developers of free software are heartened and
65 encouraged by the resulting cooperation. However, in the case of
66 software used on network servers, this result may fail to come about.
67 The GNU General Public License permits making a modified version and
68 letting the public access it on a server without ever releasing its
69 source code to the public.
70
71 The GNU Affero General Public License is designed specifically to
72 ensure that, in such cases, the modified source code becomes available
73 to the community. It requires the operator of a network server to
74 provide the source code of the modified version running there to the
75 users of that server. Therefore, public use of a modified version, on
76 a publicly accessible server, gives the public access to the source
77 code of the modified version.
78
79 An older license, called the Affero General Public License and
80 published by Affero, was designed to accomplish similar goals. This is
81 a different license, not a version of the Affero GPL, but Affero has
82 released a new version of the Affero GPL which permits relicensing under
83 this license.
84
85 The precise terms and conditions for copying, distribution and
86 modification follow.
87
88 TERMS AND CONDITIONS
89
90 0. Definitions.
91
92 "This License" refers to version 3 of the GNU Affero General Public License.
93
94 "Copyright" also means copyright-like laws that apply to other kinds of
95 works, such as semiconductor masks.
96
97 "The Program" refers to any copyrightable work licensed under this
98 License. Each licensee is addressed as "you". "Licensees" and
99 "recipients" may be individuals or organizations.
100
101 To "modify" a work means to copy from or adapt all or part of the work
102 in a fashion requiring copyright permission, other than the making of an
103 exact copy. The resulting work is called a "modified version" of the
104 earlier work or a work "based on" the earlier work.
105
106 A "covered work" means either the unmodified Program or a work based
107 on the Program.
108
109 To "propagate" a work means to do anything with it that, without
110 permission, would make you directly or secondarily liable for
111 infringement under applicable copyright law, except executing it on a
112 computer or modifying a private copy. Propagation includes copying,
113 distribution (with or without modification), making available to the
114 public, and in some countries other activities as well.
115
116 To "convey" a work means any kind of propagation that enables other
117 parties to make or receive copies. Mere interaction with a user through
118 a computer network, with no transfer of a copy, is not conveying.
119
120 An interactive user interface displays "Appropriate Legal Notices"
121 to the extent that it includes a convenient and prominently visible
122 feature that (1) displays an appropriate copyright notice, and (2)
123 tells the user that there is no warranty for the work (except to the
124 extent that warranties are provided), that licensees may convey the
125 work under this License, and how to view a copy of this License. If
126 the interface presents a list of user commands or options, such as a
127 menu, a prominent item in the list meets this criterion.
128
129 1. Source Code.
130
131 The "source code" for a work means the preferred form of the work
132 for making modifications to it. "Object code" means any non-source
133 form of a work.
134
135 A "Standard Interface" means an interface that either is an official
136 standard defined by a recognized standards body, or, in the case of
137 interfaces specified for a particular programming language, one that
138 is widely used among developers working in that language.
139
140 The "System Libraries" of an executable work include anything, other
141 than the work as a whole, that (a) is included in the normal form of
142 packaging a Major Component, but which is not part of that Major
143 Component, and (b) serves only to enable use of the work with that
144 Major Component, or to implement a Standard Interface for which an
145 implementation is available to the public in source code form. A
146 "Major Component", in this context, means a major essential component
147 (kernel, window system, and so on) of the specific operating system
148 (if any) on which the executable work runs, or a compiler used to
149 produce the work, or an object code interpreter used to run it.
150
151 The "Corresponding Source" for a work in object code form means all
152 the source code needed to generate, install, and (for an executable
153 work) run the object code and to modify the work, including scripts to
154 control those activities. However, it does not include the work's
155 System Libraries, or general-purpose tools or generally available free
156 programs which are used unmodified in performing those activities but
157 which are not part of the work. For example, Corresponding Source
158 includes interface definition files associated with source files for
159 the work, and the source code for shared libraries and dynamically
160 linked subprograms that the work is specifically designed to require,
161 such as by intimate data communication or control flow between those
162 subprograms and other parts of the work.
163
164 The Corresponding Source need not include anything that users
165 can regenerate automatically from other parts of the Corresponding
166 Source.
167
168 The Corresponding Source for a work in source code form is that
169 same work.
170
171 2. Basic Permissions.
172
173 All rights granted under this License are granted for the term of
174 copyright on the Program, and are irrevocable provided the stated
175 conditions are met. This License explicitly affirms your unlimited
176 permission to run the unmodified Program. The output from running a
177 covered work is covered by this License only if the output, given its
178 content, constitutes a covered work. This License acknowledges your
179 rights of fair use or other equivalent, as provided by copyright law.
180
181 You may make, run and propagate covered works that you do not
182 convey, without conditions so long as your license otherwise remains
183 in force. You may convey covered works to others for the sole purpose
184 of having them make modifications exclusively for you, or provide you
185 with facilities for running those works, provided that you comply with
186 the terms of this License in conveying all material for which you do
187 not control copyright. Those thus making or running the covered works
188 for you must do so exclusively on your behalf, under your direction
189 and control, on terms that prohibit them from making any copies of
190 your copyrighted material outside their relationship with you.
191
192 Conveying under any other circumstances is permitted solely under
193 the conditions stated below. Sublicensing is not allowed; section 10
194 makes it unnecessary.
195
196 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
197
198 No covered work shall be deemed part of an effective technological
199 measure under any applicable law fulfilling obligations under article
200 11 of the WIPO copyright treaty adopted on 20 December 1996, or
201 similar laws prohibiting or restricting circumvention of such
202 measures.
203
204 When you convey a covered work, you waive any legal power to forbid
205 circumvention of technological measures to the extent such circumvention
206 is effected by exercising rights under this License with respect to
207 the covered work, and you disclaim any intention to limit operation or
208 modification of the work as a means of enforcing, against the work's
209 users, your or third parties' legal rights to forbid circumvention of
210 technological measures.
211
212 4. Conveying Verbatim Copies.
213
214 You may convey verbatim copies of the Program's source code as you
215 receive it, in any medium, provided that you conspicuously and
216 appropriately publish on each copy an appropriate copyright notice;
217 keep intact all notices stating that this License and any
218 non-permissive terms added in accord with section 7 apply to the code;
219 keep intact all notices of the absence of any warranty; and give all
220 recipients a copy of this License along with the Program.
221
222 You may charge any price or no price for each copy that you convey,
223 and you may offer support or warranty protection for a fee.
224
225 5. Conveying Modified Source Versions.
226
227 You may convey a work based on the Program, or the modifications to
228 produce it from the Program, in the form of source code under the
229 terms of section 4, provided that you also meet all of these conditions:
230
231 a) The work must carry prominent notices stating that you modified
232 it, and giving a relevant date.
233
234 b) The work must carry prominent notices stating that it is
235 released under this License and any conditions added under section
236 7. This requirement modifies the requirement in section 4 to
237 "keep intact all notices".
238
239 c) You must license the entire work, as a whole, under this
240 License to anyone who comes into possession of a copy. This
241 License will therefore apply, along with any applicable section 7
242 additional terms, to the whole of the work, and all its parts,
243 regardless of how they are packaged. This License gives no
244 permission to license the work in any other way, but it does not
245 invalidate such permission if you have separately received it.
246
247 d) If the work has interactive user interfaces, each must display
248 Appropriate Legal Notices; however, if the Program has interactive
249 interfaces that do not display Appropriate Legal Notices, your
250 work need not make them do so.
251
252 A compilation of a covered work with other separate and independent
253 works, which are not by their nature extensions of the covered work,
254 and which are not combined with it such as to form a larger program,
255 in or on a volume of a storage or distribution medium, is called an
256 "aggregate" if the compilation and its resulting copyright are not
257 used to limit the access or legal rights of the compilation's users
258 beyond what the individual works permit. Inclusion of a covered work
259 in an aggregate does not cause this License to apply to the other
260 parts of the aggregate.
261
262 6. Conveying Non-Source Forms.
263
264 You may convey a covered work in object code form under the terms
265 of sections 4 and 5, provided that you also convey the
266 machine-readable Corresponding Source under the terms of this License,
267 in one of these ways:
268
269 a) Convey the object code in, or embodied in, a physical product
270 (including a physical distribution medium), accompanied by the
271 Corresponding Source fixed on a durable physical medium
272 customarily used for software interchange.
273
274 b) Convey the object code in, or embodied in, a physical product
275 (including a physical distribution medium), accompanied by a
276 written offer, valid for at least three years and valid for as
277 long as you offer spare parts or customer support for that product
278 model, to give anyone who possesses the object code either (1) a
279 copy of the Corresponding Source for all the software in the
280 product that is covered by this License, on a durable physical
281 medium customarily used for software interchange, for a price no
282 more than your reasonable cost of physically performing this
283 conveying of source, or (2) access to copy the
284 Corresponding Source from a network server at no charge.
285
286 c) Convey individual copies of the object code with a copy of the
287 written offer to provide the Corresponding Source. This
288 alternative is allowed only occasionally and noncommercially, and
289 only if you received the object code with such an offer, in accord
290 with subsection 6b.
291
292 d) Convey the object code by offering access from a designated
293 place (gratis or for a charge), and offer equivalent access to the
294 Corresponding Source in the same way through the same place at no
295 further charge. You need not require recipients to copy the
296 Corresponding Source along with the object code. If the place to
297 copy the object code is a network server, the Corresponding Source
298 may be on a different server (operated by you or a third party)
299 that supports equivalent copying facilities, provided you maintain
300 clear directions next to the object code saying where to find the
301 Corresponding Source. Regardless of what server hosts the
302 Corresponding Source, you remain obligated to ensure that it is
303 available for as long as needed to satisfy these requirements.
304
305 e) Convey the object code using peer-to-peer transmission, provided
306 you inform other peers where the object code and Corresponding
307 Source of the work are being offered to the general public at no
308 charge under subsection 6d.
309
310 A separable portion of the object code, whose source code is excluded
311 from the Corresponding Source as a System Library, need not be
312 included in conveying the object code work.
313
314 A "User Product" is either (1) a "consumer product", which means any
315 tangible personal property which is normally used for personal, family,
316 or household purposes, or (2) anything designed or sold for incorporation
317 into a dwelling. In determining whether a product is a consumer product,
318 doubtful cases shall be resolved in favor of coverage. For a particular
319 product received by a particular user, "normally used" refers to a
320 typical or common use of that class of product, regardless of the status
321 of the particular user or of the way in which the particular user
322 actually uses, or expects or is expected to use, the product. A product
323 is a consumer product regardless of whether the product has substantial
324 commercial, industrial or non-consumer uses, unless such uses represent
325 the only significant mode of use of the product.
326
327 "Installation Information" for a User Product means any methods,
328 procedures, authorization keys, or other information required to install
329 and execute modified versions of a covered work in that User Product from
330 a modified version of its Corresponding Source. The information must
331 suffice to ensure that the continued functioning of the modified object
332 code is in no case prevented or interfered with solely because
333 modification has been made.
334
335 If you convey an object code work under this section in, or with, or
336 specifically for use in, a User Product, and the conveying occurs as
337 part of a transaction in which the right of possession and use of the
338 User Product is transferred to the recipient in perpetuity or for a
339 fixed term (regardless of how the transaction is characterized), the
340 Corresponding Source conveyed under this section must be accompanied
341 by the Installation Information. But this requirement does not apply
342 if neither you nor any third party retains the ability to install
343 modified object code on the User Product (for example, the work has
344 been installed in ROM).
345
346 The requirement to provide Installation Information does not include a
347 requirement to continue to provide support service, warranty, or updates
348 for a work that has been modified or installed by the recipient, or for
349 the User Product in which it has been modified or installed. Access to a
350 network may be denied when the modification itself materially and
351 adversely affects the operation of the network or violates the rules and
352 protocols for communication across the network.
353
354 Corresponding Source conveyed, and Installation Information provided,
355 in accord with this section must be in a format that is publicly
356 documented (and with an implementation available to the public in
357 source code form), and must require no special password or key for
358 unpacking, reading or copying.
359
360 7. Additional Terms.
361
362 "Additional permissions" are terms that supplement the terms of this
363 License by making exceptions from one or more of its conditions.
364 Additional permissions that are applicable to the entire Program shall
365 be treated as though they were included in this License, to the extent
366 that they are valid under applicable law. If additional permissions
367 apply only to part of the Program, that part may be used separately
368 under those permissions, but the entire Program remains governed by
369 this License without regard to the additional permissions.
370
371 When you convey a copy of a covered work, you may at your option
372 remove any additional permissions from that copy, or from any part of
373 it. (Additional permissions may be written to require their own
374 removal in certain cases when you modify the work.) You may place
375 additional permissions on material, added by you to a covered work,
376 for which you have or can give appropriate copyright permission.
377
378 Notwithstanding any other provision of this License, for material you
379 add to a covered work, you may (if authorized by the copyright holders of
380 that material) supplement the terms of this License with terms:
381
382 a) Disclaiming warranty or limiting liability differently from the
383 terms of sections 15 and 16 of this License; or
384
385 b) Requiring preservation of specified reasonable legal notices or
386 author attributions in that material or in the Appropriate Legal
387 Notices displayed by works containing it; or
388
389 c) Prohibiting misrepresentation of the origin of that material, or
390 requiring that modified versions of such material be marked in
391 reasonable ways as different from the original version; or
392
393 d) Limiting the use for publicity purposes of names of licensors or
394 authors of the material; or
395
396 e) Declining to grant rights under trademark law for use of some
397 trade names, trademarks, or service marks; or
398
399 f) Requiring indemnification of licensors and authors of that
400 material by anyone who conveys the material (or modified versions of
401 it) with contractual assumptions of liability to the recipient, for
402 any liability that these contractual assumptions directly impose on
403 those licensors and authors.
404
405 All other non-permissive additional terms are considered "further
406 restrictions" within the meaning of section 10. If the Program as you
407 received it, or any part of it, contains a notice stating that it is
408 governed by this License along with a term that is a further
409 restriction, you may remove that term. If a license document contains
410 a further restriction but permits relicensing or conveying under this
411 License, you may add to a covered work material governed by the terms
412 of that license document, provided that the further restriction does
413 not survive such relicensing or conveying.
414
415 If you add terms to a covered work in accord with this section, you
416 must place, in the relevant source files, a statement of the
417 additional terms that apply to those files, or a notice indicating
418 where to find the applicable terms.
419
420 Additional terms, permissive or non-permissive, may be stated in the
421 form of a separately written license, or stated as exceptions;
422 the above requirements apply either way.
423
424 8. Termination.
425
426 You may not propagate or modify a covered work except as expressly
427 provided under this License. Any attempt otherwise to propagate or
428 modify it is void, and will automatically terminate your rights under
429 this License (including any patent licenses granted under the third
430 paragraph of section 11).
431
432 However, if you cease all violation of this License, then your
433 license from a particular copyright holder is reinstated (a)
434 provisionally, unless and until the copyright holder explicitly and
435 finally terminates your license, and (b) permanently, if the copyright
436 holder fails to notify you of the violation by some reasonable means
437 prior to 60 days after the cessation.
438
439 Moreover, your license from a particular copyright holder is
440 reinstated permanently if the copyright holder notifies you of the
441 violation by some reasonable means, this is the first time you have
442 received notice of violation of this License (for any work) from that
443 copyright holder, and you cure the violation prior to 30 days after
444 your receipt of the notice.
445
446 Termination of your rights under this section does not terminate the
447 licenses of parties who have received copies or rights from you under
448 this License. If your rights have been terminated and not permanently
449 reinstated, you do not qualify to receive new licenses for the same
450 material under section 10.
451
452 9. Acceptance Not Required for Having Copies.
453
454 You are not required to accept this License in order to receive or
455 run a copy of the Program. Ancillary propagation of a covered work
456 occurring solely as a consequence of using peer-to-peer transmission
457 to receive a copy likewise does not require acceptance. However,
458 nothing other than this License grants you permission to propagate or
459 modify any covered work. These actions infringe copyright if you do
460 not accept this License. Therefore, by modifying or propagating a
461 covered work, you indicate your acceptance of this License to do so.
462
463 10. Automatic Licensing of Downstream Recipients.
464
465 Each time you convey a covered work, the recipient automatically
466 receives a license from the original licensors, to run, modify and
467 propagate that work, subject to this License. You are not responsible
468 for enforcing compliance by third parties with this License.
469
470 An "entity transaction" is a transaction transferring control of an
471 organization, or substantially all assets of one, or subdividing an
472 organization, or merging organizations. If propagation of a covered
473 work results from an entity transaction, each party to that
474 transaction who receives a copy of the work also receives whatever
475 licenses to the work the party's predecessor in interest had or could
476 give under the previous paragraph, plus a right to possession of the
477 Corresponding Source of the work from the predecessor in interest, if
478 the predecessor has it or can get it with reasonable efforts.
479
480 You may not impose any further restrictions on the exercise of the
481 rights granted or affirmed under this License. For example, you may
482 not impose a license fee, royalty, or other charge for exercise of
483 rights granted under this License, and you may not initiate litigation
484 (including a cross-claim or counterclaim in a lawsuit) alleging that
485 any patent claim is infringed by making, using, selling, offering for
486 sale, or importing the Program or any portion of it.
487
488 11. Patents.
489
490 A "contributor" is a copyright holder who authorizes use under this
491 License of the Program or a work on which the Program is based. The
492 work thus licensed is called the contributor's "contributor version".
493
494 A contributor's "essential patent claims" are all patent claims
495 owned or controlled by the contributor, whether already acquired or
496 hereafter acquired, that would be infringed by some manner, permitted
497 by this License, of making, using, or selling its contributor version,
498 but do not include claims that would be infringed only as a
499 consequence of further modification of the contributor version. For
500 purposes of this definition, "control" includes the right to grant
501 patent sublicenses in a manner consistent with the requirements of
502 this License.
503
504 Each contributor grants you a non-exclusive, worldwide, royalty-free
505 patent license under the contributor's essential patent claims, to
506 make, use, sell, offer for sale, import and otherwise run, modify and
507 propagate the contents of its contributor version.
508
509 In the following three paragraphs, a "patent license" is any express
510 agreement or commitment, however denominated, not to enforce a patent
511 (such as an express permission to practice a patent or covenant not to
512 sue for patent infringement). To "grant" such a patent license to a
513 party means to make such an agreement or commitment not to enforce a
514 patent against the party.
515
516 If you convey a covered work, knowingly relying on a patent license,
517 and the Corresponding Source of the work is not available for anyone
518 to copy, free of charge and under the terms of this License, through a
519 publicly available network server or other readily accessible means,
520 then you must either (1) cause the Corresponding Source to be so
521 available, or (2) arrange to deprive yourself of the benefit of the
522 patent license for this particular work, or (3) arrange, in a manner
523 consistent with the requirements of this License, to extend the patent
524 license to downstream recipients. "Knowingly relying" means you have
525 actual knowledge that, but for the patent license, your conveying the
526 covered work in a country, or your recipient's use of the covered work
527 in a country, would infringe one or more identifiable patents in that
528 country that you have reason to believe are valid.
529
530 If, pursuant to or in connection with a single transaction or
531 arrangement, you convey, or propagate by procuring conveyance of, a
532 covered work, and grant a patent license to some of the parties
533 receiving the covered work authorizing them to use, propagate, modify
534 or convey a specific copy of the covered work, then the patent license
535 you grant is automatically extended to all recipients of the covered
536 work and works based on it.
537
538 A patent license is "discriminatory" if it does not include within
539 the scope of its coverage, prohibits the exercise of, or is
540 conditioned on the non-exercise of one or more of the rights that are
541 specifically granted under this License. You may not convey a covered
542 work if you are a party to an arrangement with a third party that is
543 in the business of distributing software, under which you make payment
544 to the third party based on the extent of your activity of conveying
545 the work, and under which the third party grants, to any of the
546 parties who would receive the covered work from you, a discriminatory
547 patent license (a) in connection with copies of the covered work
548 conveyed by you (or copies made from those copies), or (b) primarily
549 for and in connection with specific products or compilations that
550 contain the covered work, unless you entered into that arrangement,
551 or that patent license was granted, prior to 28 March 2007.
552
553 Nothing in this License shall be construed as excluding or limiting
554 any implied license or other defenses to infringement that may
555 otherwise be available to you under applicable patent law.
556
557 12. No Surrender of Others' Freedom.
558
559 If conditions are imposed on you (whether by court order, agreement or
560 otherwise) that contradict the conditions of this License, they do not
561 excuse you from the conditions of this License. If you cannot convey a
562 covered work so as to satisfy simultaneously your obligations under this
563 License and any other pertinent obligations, then as a consequence you may
564 not convey it at all. For example, if you agree to terms that obligate you
565 to collect a royalty for further conveying from those to whom you convey
566 the Program, the only way you could satisfy both those terms and this
567 License would be to refrain entirely from conveying the Program.
568
569 13. Remote Network Interaction; Use with the GNU General Public License.
570
571 Notwithstanding any other provision of this License, if you modify the
572 Program, your modified version must prominently offer all users
573 interacting with it remotely through a computer network (if your version
574 supports such interaction) an opportunity to receive the Corresponding
575 Source of your version by providing access to the Corresponding Source
576 from a network server at no charge, through some standard or customary
577 means of facilitating copying of software. This Corresponding Source
578 shall include the Corresponding Source for any work covered by version 3
579 of the GNU General Public License that is incorporated pursuant to the
580 following paragraph.
581
582 Notwithstanding any other provision of this License, you have
583 permission to link or combine any covered work with a work licensed
584 under version 3 of the GNU General Public License into a single
585 combined work, and to convey the resulting work. The terms of this
586 License will continue to apply to the part which is the covered work,
587 but the work with which it is combined will remain governed by version
588 3 of the GNU General Public License.
589
590 14. Revised Versions of this License.
591
592 The Free Software Foundation may publish revised and/or new versions of
593 the GNU Affero General Public License from time to time. Such new versions
594 will be similar in spirit to the present version, but may differ in detail to
595 address new problems or concerns.
596
597 Each version is given a distinguishing version number. If the
598 Program specifies that a certain numbered version of the GNU Affero General
599 Public License "or any later version" applies to it, you have the
600 option of following the terms and conditions either of that numbered
601 version or of any later version published by the Free Software
602 Foundation. If the Program does not specify a version number of the
603 GNU Affero General Public License, you may choose any version ever published
604 by the Free Software Foundation.
605
606 If the Program specifies that a proxy can decide which future
607 versions of the GNU Affero General Public License can be used, that proxy's
608 public statement of acceptance of a version permanently authorizes you
609 to choose that version for the Program.
610
611 Later license versions may give you additional or different
612 permissions. However, no additional obligations are imposed on any
613 author or copyright holder as a result of your choosing to follow a
614 later version.
615
616 15. Disclaimer of Warranty.
617
618 THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
619 APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
620 HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
621 OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
622 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
623 PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
624 IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
625 ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
626
627 16. Limitation of Liability.
628
629 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
630 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
631 THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
632 GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
633 USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
634 DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
635 PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
636 EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
637 SUCH DAMAGES.
638
639 17. Interpretation of Sections 15 and 16.
640
641 If the disclaimer of warranty and limitation of liability provided
642 above cannot be given local legal effect according to their terms,
643 reviewing courts shall apply local law that most closely approximates
644 an absolute waiver of all civil liability in connection with the
645 Program, unless a warranty or assumption of liability accompanies a
646 copy of the Program in return for a fee.
647
648 END OF TERMS AND CONDITIONS
649
650 How to Apply These Terms to Your New Programs
651
652 If you develop a new program, and you want it to be of the greatest
653 possible use to the public, the best way to achieve this is to make it
654 free software which everyone can redistribute and change under these terms.
655
656 To do so, attach the following notices to the program. It is safest
657 to attach them to the start of each source file to most effectively
658 state the exclusion of warranty; and each file should have at least
659 the "copyright" line and a pointer to where the full notice is found.
660
661 <one line to give the program's name and a brief idea of what it does.>
662 Copyright (C) <year> <name of author>
663
664 This program is free software: you can redistribute it and/or modify
665 it under the terms of the GNU Affero General Public License as published by
666 the Free Software Foundation, either version 3 of the License, or
667 (at your option) any later version.
668
669 This program is distributed in the hope that it will be useful,
670 but WITHOUT ANY WARRANTY; without even the implied warranty of
671 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
672 GNU Affero General Public License for more details.
673
674 You should have received a copy of the GNU Affero General Public License
675 along with this program. If not, see <http://www.gnu.org/licenses/>.
676
677 Also add information on how to contact you by electronic and paper mail.
678
679 If your software can interact with users remotely through a computer
680 network, you should also make sure that it provides a way for users to
681 get its source. For example, if your program is a web application, its
682 interface could display a "Source" link that leads users to an archive
683 of the code. There are many ways you could offer source, and different
684 solutions will be better for different programs; see section 13 for the
685 specific requirements.
686
687 You should also get your employer (if you work as a programmer) or school,
688 if any, to sign a "copyright disclaimer" for the program, if necessary.
689 For more information on this, and how to apply and follow the GNU AGPL, see
690 <http://www.gnu.org/licenses/>.
@@ -0,0 +1,48 b''
1 # top level files
2 include test.ini
3 include MANIFEST.in
4 include README.rst
5 include rhodecode/VERSION
6
7 # docs
8 recursive-include docs *
9
10 # init.d
11 recursive-include init.d *
12
13 # translations
14 recursive-include rhodecode/i18n *
15
16 # bin stuff
17 recursive-include rhodecode/bin *
18
19 # hook templates
20 recursive-include rhodecode/config/hook_templates *
21
22 # non-python core stuff
23 recursive-include rhodecode *.cfg
24 recursive-include rhodecode *.json
25 recursive-include rhodecode *.ini_tmpl
26 recursive-include rhodecode *.sh
27
28 # images, css
29 include rhodecode/public/css/*.css
30 include rhodecode/public/images/*.*
31
32 # sound files
33 include rhodecode/public/sounds/*.mp3
34 include rhodecode/public/sounds/*.wav
35
36 # fonts
37 recursive-include rhodecode/public/fonts/ProximaNova *
38 recursive-include rhodecode/public/fonts/RCIcons *
39
40 # js
41 recursive-include rhodecode/public/js *
42
43 # templates
44 recursive-include rhodecode/templates *
45
46 # skip any tests files
47 recursive-exclude rhodecode/tests *
48
@@ -0,0 +1,39 b''
1
2 WEBPACK=./node_modules/webpack/bin/webpack.js
3 GRUNT=grunt
4 NODE_PATH=./node_modules
5 FLAKE8=flake8 setup.py pytest_pylons/ rhodecode/ --select=E124 --ignore=E711,E712,E510,E121,E122,E126,E127,E128,E501,F401 --max-line-length=100 --exclude=*rhodecode/lib/dbmigrate/*,*rhodecode/tests/*,*rhodecode/lib/vcs/utils/*
6 CI_PREFIX=enterprise
7
8 .PHONY: help clean test test-clean test-lint test-only
9
10 help:
11 @echo "TODO: describe Makefile"
12
13 clean: test-clean
14 find . -type f \( -iname '*.c' -o -iname '*.pyc' -o -iname '*.so' \) -exec rm '{}' ';'
15
16 test: test-clean test-lint test-only
17
18 test-clean:
19 rm -rf coverage.xml htmlcov junit.xml pylint.log result
20
21 test-lint:
22 if [ "$$IN_NIX_SHELL" = "1" ]; then \
23 $(FLAKE8); \
24 else \
25 $(FLAKE8) --format=pylint --exit-zero > pylint.log; \
26 fi
27
28 test-only:
29 PYTHONHASHSEED=random py.test -vv -r xw --cov=rhodecode --cov-report=term-missing --cov-report=html rhodecode/tests/
30
31 web-build:
32 NODE_PATH=$(NODE_PATH) $(GRUNT)
33
34 web-test:
35 @echo "no test for our javascript, yet!"
36
37 docs-bootstrap:
38 (cd docs; nix-build default.nix -o result)
39 @echo "Please go to docs folder and run make html"
@@ -0,0 +1,101 b''
1 =========
2 RhodeCode
3 =========
4
5 About
6 -----
7
8 ``RhodeCode`` is a fast and powerful management tool for Mercurial_ and GIT_
9 and Subversion_ with a built in push/pull server, full text search,
10 pull requests and powerfull code-review system. It works on http/https and
11 has a few unique features like:
12 - plugable architecture
13 - advanced permission system with IP restrictions
14 - rich set of authentication plugins including LDAP,
15 ActiveDirectory, Atlassian Crowd, Http-Headers, Pam, Token-Auth.
16 - live code-review chat
17 - full web based file editing
18 - unified multi vcs support
19 - snippets (gist) system
20 - integration with all 3rd party issue trackers
21
22 RhodeCode also provides rich API, and multiple event hooks so it's easy
23 integrable with existing external systems.
24
25 RhodeCode is similar in some respects to gitlab_, github_ or bitbucket_,
26 however RhodeCode can be run as standalone hosted application on your own server.
27 RhodeCode can be installed on \*nix or Windows systems.
28
29 RhodeCode uses `PEP386 versioning <http://www.python.org/dev/peps/pep-0386/>`_
30
31 Installation
32 ------------
33 Please visit https://docs.rhodecode.com/RhodeCode-Control/tasks/install-cli.html
34 for more details
35
36
37 Source code
38 -----------
39
40 The latest sources can be obtained from official RhodeCode instance
41 https://code.rhodecode.com
42
43
44 RhodeCode Features
45 ------------------
46
47 Check out all features of RhodeCode at https://rhodecode.com/features
48
49 License
50 -------
51
52 ``RhodeCode`` is dual-licensed with AGPLv3 and commercial license.
53 Please see LICENSE.txt file for details.
54
55
56 Getting help
57 ------------
58
59 Listed bellow are various support resources that should help.
60
61 .. note::
62
63 Please try to read the documentation before posting any issues, especially
64 the **troubleshooting section**
65
66 - Official issue tracker `RhodeCode Issue tracker <https://issues.rhodecode.com>`_
67
68 - Search our community portal `Community portal <https://community.rhodecode.com>`_
69
70 - Join #rhodecode on FreeNode (irc.freenode.net)
71 or use http://webchat.freenode.net/?channels=rhodecode for web access to irc.
72
73 - You can also follow RhodeCode on twitter **@RhodeCode** where we often post
74 news and other interesting stuff about RhodeCode.
75
76
77 Online documentation
78 --------------------
79
80 Online documentation for the current version of RhodeCode is available at
81 - http://rhodecode.com/docs
82
83 You may also build the documentation for yourself - go into ``docs/`` and run::
84
85 nix-build default.nix -o result && make clean html
86
87 (You need to have sphinx_ installed to build the documentation. If you don't
88 have sphinx_ installed you can install it via the command:
89 ``pip install sphinx``)
90
91 .. _virtualenv: http://pypi.python.org/pypi/virtualenv
92 .. _python: http://www.python.org/
93 .. _sphinx: http://sphinx.pocoo.org/
94 .. _mercurial: http://mercurial.selenic.com/
95 .. _bitbucket: http://bitbucket.org/
96 .. _github: http://github.com/
97 .. _gitlab: http://gitlab.com/
98 .. _subversion: http://subversion.tigris.org/
99 .. _git: http://git-scm.com/
100 .. _celery: http://celeryproject.org/
101 .. _vcs: http://pypi.python.org/pypi/vcs
@@ -0,0 +1,47 b''
1 README - Quickstart
2 ===================
3
4 This folder contains functional tests and the automation of specification
5 examples. Details about testing can be found in
6 `/docs-internal/testing/index.rst`.
7
8
9 Setting up your Rhodecode Enterprise instance
10 ---------------------------------------------
11
12 The tests will create users and repositories as needed, so you can start with a
13 new and empty instance.
14
15 Use the following example call for the database setup of Enterprise::
16
17 paster setup-rhodecode \
18 --user=admin \
19 --email=admin@example.com \
20 --password=secret \
21 --api-key=9999999999999999999999999999999999999999 \
22 your-enterprise-config.ini
23
24 This way the username, password and auth token of the admin user will match the
25 defaults from the test run.
26
27
28 Usage
29 -----
30
31 1. Make sure your Rhodecode Enterprise instance is running at
32 http://localhost:5000.
33
34 2. Enter `nix-shell` from the acceptance_tests folder::
35
36 cd acceptance_tests
37 nix-shell -I ~/dev
38
39 Make sure that `rcpkgs` and `rcnixpkgs` are available on the nix path.
40
41 3. Run the tests::
42
43 py.test -c example.ini -vs
44
45 The parameter ``-vs`` allows you to see debugging output during the test
46 run. Check ``py.test --help`` and the documentation at http://pytest.org to
47 learn all details about the test runner.
This diff has been collapsed as it changes many lines, (575 lines changed) Show them Hide them
@@ -0,0 +1,575 b''
1 ################################################################################
2 ################################################################################
3 # RhodeCode Enterprise - configuration file #
4 # Built-in functions and variables #
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 # #
7 ################################################################################
8
9 [DEFAULT]
10 debug = true
11 pdebug = false
12 ################################################################################
13 ## Uncomment and replace with the email address which should receive ##
14 ## any error reports after an application crash ##
15 ## Additionally these settings will be used by the RhodeCode mailing system ##
16 ################################################################################
17 #email_to = admin@localhost
18 #error_email_from = paste_error@localhost
19 #app_email_from = rhodecode-noreply@localhost
20 #error_message =
21 #email_prefix = [RhodeCode]
22
23 #smtp_server = mail.server.com
24 #smtp_username =
25 #smtp_password =
26 #smtp_port =
27 #smtp_use_tls = false
28 #smtp_use_ssl = true
29 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
30 #smtp_auth =
31
32 [server:main]
33 ## COMMON ##
34 host = 127.0.0.1
35 port = 5000
36
37 ##########################
38 ## WAITRESS WSGI SERVER ##
39 ##########################
40 use = egg:waitress#main
41 ## number of worker threads
42 threads = 5
43 ## MAX BODY SIZE 100GB
44 max_request_body_size = 107374182400
45 ## Use poll instead of select, fixes file descriptors limits problems.
46 ## May not work on old windows systems.
47 asyncore_use_poll = true
48
49
50 ##########################
51 ## GUNICORN WSGI SERVER ##
52 ##########################
53 ## run with gunicorn --log-config <inifile.ini> --paste <inifile.ini>
54 #use = egg:gunicorn#main
55 ## Sets the number of process workers. You must set `instance_id = *`
56 ## when this option is set to more than one worker, recommended
57 ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers
58 ## The `instance_id = *` must be set in the [app:main] section below
59 #workers = 1
60 ## number of threads for each of the worker, must be set to 1 for gevent
61 ## generally recommened to be at 1
62 #threads = 1
63 ## process name
64 #proc_name = rhodecode
65 ## type of worker class, one of sync, gevent
66 ## recommended for bigger setup is using of of other than sync one
67 #worker_class = sync
68 ## max number of requests that worker will handle before being gracefully
69 ## restarted, could prevent memory leaks
70 #max_requests = 1000
71 #max_requests_jitter = 30
72 ## ammount of time a worker can spend with handling a request before it
73 ## gets killed and restarted. Set to 6hrs
74 #timeout = 21600
75
76
77 ## prefix middleware for RhodeCode, disables force_https flag.
78 ## allows to set RhodeCode under a prefix in server.
79 ## eg https://server.com/<prefix>. Enable `filter-with =` option below as well.
80 #[filter:proxy-prefix]
81 #use = egg:PasteDeploy#prefix
82 #prefix = /<your-prefix>
83
84 [app:main]
85 use = egg:rhodecode-enterprise-ce
86 ## enable proxy prefix middleware, defined below
87 #filter-with = proxy-prefix
88
89 # During development the we want to have the debug toolbar enabled
90 pyramid.includes =
91 pyramid_debugtoolbar
92 rhodecode.utils.debugtoolbar
93 rhodecode.lib.middleware.request_wrapper
94
95 pyramid.reload_templates = true
96
97 debugtoolbar.hosts = 0.0.0.0/0
98 debugtoolbar.exclude_prefixes =
99 /css
100 /fonts
101 /images
102 /js
103
104 ## RHODECODE PLUGINS ##
105 rhodecode.includes =
106 rhodecode.api
107
108
109 # api prefix url
110 rhodecode.api.url = /_admin/api
111
112
113 ## END RHODECODE PLUGINS ##
114
115 full_stack = true
116
117 ## Serve static files via RhodeCode, disable to serve them via HTTP server
118 static_files = true
119
120 ## Optional Languages
121 ## en(default), be, de, es, fr, it, ja, pl, pt, ru, zh
122 lang = en
123
124 ## perform a full repository scan on each server start, this should be
125 ## set to false after first startup, to allow faster server restarts.
126 startup.import_repos = false
127
128 ## Uncomment and set this path to use archive download cache.
129 ## Once enabled, generated archives will be cached at this location
130 ## and served from the cache during subsequent requests for the same archive of
131 ## the repository.
132 #archive_cache_dir = /tmp/tarballcache
133
134 ## change this to unique ID for security
135 app_instance_uuid = rc-production
136
137 ## cut off limit for large diffs (size in bytes)
138 cut_off_limit_diff = 1024000
139 cut_off_limit_file = 256000
140
141 ## use cache version of scm repo everywhere
142 vcs_full_cache = true
143
144 ## force https in RhodeCode, fixes https redirects, assumes it's always https
145 ## Normally this is controlled by proper http flags sent from http server
146 force_https = false
147
148 ## use Strict-Transport-Security headers
149 use_htsts = false
150
151 ## number of commits stats will parse on each iteration
152 commit_parse_limit = 25
153
154 ## git rev filter option, --all is the default filter, if you need to
155 ## hide all refs in changelog switch this to --branches --tags
156 git_rev_filter = --branches --tags
157
158 # Set to true if your repos are exposed using the dumb protocol
159 git_update_server_info = false
160
161 ## RSS/ATOM feed options
162 rss_cut_off_limit = 256000
163 rss_items_per_page = 10
164 rss_include_diff = false
165
166 ## gist URL alias, used to create nicer urls for gist. This should be an
167 ## url that does rewrites to _admin/gists/<gistid>.
168 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
169 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
170 gist_alias_url =
171
172 ## List of controllers (using glob pattern syntax) that AUTH TOKENS could be
173 ## used for access.
174 ## Adding ?auth_token = <token> to the url authenticates this request as if it
175 ## came from the the logged in user who own this authentication token.
176 ##
177 ## Syntax is <ControllerClass>:<function_pattern>.
178 ## To enable access to raw_files put `FilesController:raw`.
179 ## To enable access to patches add `ChangesetController:changeset_patch`.
180 ## The list should be "," separated and on a single line.
181 ##
182 ## Recommended controllers to enable:
183 # ChangesetController:changeset_patch,
184 # ChangesetController:changeset_raw,
185 # FilesController:raw,
186 # FilesController:archivefile,
187 # GistsController:*,
188 api_access_controllers_whitelist =
189
190 ## default encoding used to convert from and to unicode
191 ## can be also a comma separated list of encoding in case of mixed encodings
192 default_encoding = UTF-8
193
194 ## instance-id prefix
195 ## a prefix key for this instance used for cache invalidation when running
196 ## multiple instances of rhodecode, make sure it's globally unique for
197 ## all running rhodecode instances. Leave empty if you don't use it
198 instance_id =
199
200 ## alternative return HTTP header for failed authentication. Default HTTP
201 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
202 ## handling that causing a series of failed authentication calls.
203 ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code
204 ## This will be served instead of default 401 on bad authnetication
205 auth_ret_code =
206
207 ## use special detection method when serving auth_ret_code, instead of serving
208 ## ret_code directly, use 401 initially (Which triggers credentials prompt)
209 ## and then serve auth_ret_code to clients
210 auth_ret_code_detection = false
211
212 ## locking return code. When repository is locked return this HTTP code. 2XX
213 ## codes don't break the transactions while 4XX codes do
214 lock_ret_code = 423
215
216 ## allows to change the repository location in settings page
217 allow_repo_location_change = true
218
219 ## allows to setup custom hooks in settings page
220 allow_custom_hooks_settings = true
221
222 ## generated license token, goto license page in RhodeCode settings to obtain
223 ## new token
224 license_token =
225
226 ## supervisor connection uri, for managing supervisor and logs.
227 supervisor.uri =
228 ## supervisord group name/id we only want this RC instance to handle
229 supervisor.group_id = dev
230
231 ## Display extended labs settings
232 labs_settings_active = true
233
234 ####################################
235 ### CELERY CONFIG ####
236 ####################################
237 use_celery = false
238 broker.host = localhost
239 broker.vhost = rabbitmqhost
240 broker.port = 5672
241 broker.user = rabbitmq
242 broker.password = qweqwe
243
244 celery.imports = rhodecode.lib.celerylib.tasks
245
246 celery.result.backend = amqp
247 celery.result.dburi = amqp://
248 celery.result.serialier = json
249
250 #celery.send.task.error.emails = true
251 #celery.amqp.task.result.expires = 18000
252
253 celeryd.concurrency = 2
254 #celeryd.log.file = celeryd.log
255 celeryd.log.level = debug
256 celeryd.max.tasks.per.child = 1
257
258 ## tasks will never be sent to the queue, but executed locally instead.
259 celery.always.eager = false
260
261 ####################################
262 ### BEAKER CACHE ####
263 ####################################
264 # default cache dir for templates. Putting this into a ramdisk
265 ## can boost performance, eg. %(here)s/data_ramdisk
266 cache_dir = %(here)s/data
267
268 ## locking and default file storage for Beaker. Putting this into a ramdisk
269 ## can boost performance, eg. %(here)s/data_ramdisk/cache/beaker_data
270 beaker.cache.data_dir = %(here)s/data/cache/beaker_data
271 beaker.cache.lock_dir = %(here)s/data/cache/beaker_lock
272
273 beaker.cache.regions = super_short_term, short_term, long_term, sql_cache_short, auth_plugins, repo_cache_long
274
275 beaker.cache.super_short_term.type = memory
276 beaker.cache.super_short_term.expire = 10
277 beaker.cache.super_short_term.key_length = 256
278
279 beaker.cache.short_term.type = memory
280 beaker.cache.short_term.expire = 60
281 beaker.cache.short_term.key_length = 256
282
283 beaker.cache.long_term.type = memory
284 beaker.cache.long_term.expire = 36000
285 beaker.cache.long_term.key_length = 256
286
287 beaker.cache.sql_cache_short.type = memory
288 beaker.cache.sql_cache_short.expire = 10
289 beaker.cache.sql_cache_short.key_length = 256
290
291 # default is memory cache, configure only if required
292 # using multi-node or multi-worker setup
293 #beaker.cache.auth_plugins.type = ext:database
294 #beaker.cache.auth_plugins.lock_dir = %(here)s/data/cache/auth_plugin_lock
295 #beaker.cache.auth_plugins.url = postgresql://postgres:secret@localhost/rhodecode
296 #beaker.cache.auth_plugins.url = mysql://root:secret@127.0.0.1/rhodecode
297 #beaker.cache.auth_plugins.sa.pool_recycle = 3600
298 #beaker.cache.auth_plugins.sa.pool_size = 10
299 #beaker.cache.auth_plugins.sa.max_overflow = 0
300
301 beaker.cache.repo_cache_long.type = memorylru_base
302 beaker.cache.repo_cache_long.max_items = 4096
303 beaker.cache.repo_cache_long.expire = 2592000
304
305 # default is memorylru_base cache, configure only if required
306 # using multi-node or multi-worker setup
307 #beaker.cache.repo_cache_long.type = ext:memcached
308 #beaker.cache.repo_cache_long.url = localhost:11211
309 #beaker.cache.repo_cache_long.expire = 1209600
310 #beaker.cache.repo_cache_long.key_length = 256
311
312 ####################################
313 ### BEAKER SESSION ####
314 ####################################
315
316 ## .session.type is type of storage options for the session, current allowed
317 ## types are file, ext:memcached, ext:database, and memory(default).
318 beaker.session.type = file
319 beaker.session.data_dir = %(here)s/data/sessions/data
320
321 ## db based session, fast, and allows easy management over logged in users ##
322 #beaker.session.type = ext:database
323 #beaker.session.table_name = db_session
324 #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode
325 #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode
326 #beaker.session.sa.pool_recycle = 3600
327 #beaker.session.sa.echo = false
328
329 beaker.session.key = rhodecode
330 beaker.session.secret = develop-rc-uytcxaz
331 beaker.session.lock_dir = %(here)s/data/sessions/lock
332
333 ## Secure encrypted cookie. Requires AES and AES python libraries
334 ## you must disable beaker.session.secret to use this
335 #beaker.session.encrypt_key = <key_for_encryption>
336 #beaker.session.validate_key = <validation_key>
337
338 ## sets session as invalid(also logging out user) if it haven not been
339 ## accessed for given amount of time in seconds
340 beaker.session.timeout = 2592000
341 beaker.session.httponly = true
342 #beaker.session.cookie_path = /<your-prefix>
343
344 ## uncomment for https secure cookie
345 beaker.session.secure = false
346
347 ## auto save the session to not to use .save()
348 beaker.session.auto = false
349
350 ## default cookie expiration time in seconds, set to `true` to set expire
351 ## at browser close
352 #beaker.session.cookie_expires = 3600
353
354 ###################################
355 ## SEARCH INDEXING CONFIGURATION ##
356 ###################################
357
358 search.module = rhodecode.lib.index.whoosh
359 search.location = %(here)s/data/index
360
361 ###################################
362 ## ERROR AND LOG HANDLING SYSTEM ##
363 ###################################
364
365 ## Appenlight is tailored to work with RhodeCode, see
366 ## http://appenlight.com for details how to obtain an account
367
368 ## appenlight integration enabled
369 appenlight = false
370
371 appenlight.server_url = https://api.appenlight.com
372 appenlight.api_key = YOUR_API_KEY
373 ;appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5
374
375 # used for JS client
376 appenlight.api_public_key = YOUR_API_PUBLIC_KEY
377
378 ## TWEAK AMOUNT OF INFO SENT HERE
379
380 ## enables 404 error logging (default False)
381 appenlight.report_404 = false
382
383 ## time in seconds after request is considered being slow (default 1)
384 appenlight.slow_request_time = 1
385
386 ## record slow requests in application
387 ## (needs to be enabled for slow datastore recording and time tracking)
388 appenlight.slow_requests = true
389
390 ## enable hooking to application loggers
391 appenlight.logging = true
392
393 ## minimum log level for log capture
394 appenlight.logging.level = WARNING
395
396 ## send logs only from erroneous/slow requests
397 ## (saves API quota for intensive logging)
398 appenlight.logging_on_error = false
399
400 ## list of additonal keywords that should be grabbed from environ object
401 ## can be string with comma separated list of words in lowercase
402 ## (by default client will always send following info:
403 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
404 ## start with HTTP* this list be extended with additional keywords here
405 appenlight.environ_keys_whitelist =
406
407 ## list of keywords that should be blanked from request object
408 ## can be string with comma separated list of words in lowercase
409 ## (by default client will always blank keys that contain following words
410 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
411 ## this list be extended with additional keywords set here
412 appenlight.request_keys_blacklist =
413
414 ## list of namespaces that should be ignores when gathering log entries
415 ## can be string with comma separated list of namespaces
416 ## (by default the client ignores own entries: appenlight_client.client)
417 appenlight.log_namespace_blacklist =
418
419
420 ################################################################################
421 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
422 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
423 ## execute malicious code after an exception is raised. ##
424 ################################################################################
425 #set debug = false
426
427
428 ##############
429 ## STYLING ##
430 ##############
431 debug_style = true
432
433 #########################################################
434 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
435 #########################################################
436 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30
437 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode
438 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode
439
440 # see sqlalchemy docs for other advanced settings
441
442 ## print the sql statements to output
443 sqlalchemy.db1.echo = false
444 ## recycle the connections after this ammount of seconds
445 sqlalchemy.db1.pool_recycle = 3600
446 sqlalchemy.db1.convert_unicode = true
447
448 ## the number of connections to keep open inside the connection pool.
449 ## 0 indicates no limit
450 #sqlalchemy.db1.pool_size = 5
451
452 ## the number of connections to allow in connection pool "overflow", that is
453 ## connections that can be opened above and beyond the pool_size setting,
454 ## which defaults to five.
455 #sqlalchemy.db1.max_overflow = 10
456
457
458 ##################
459 ### VCS CONFIG ###
460 ##################
461 vcs.server.enable = true
462 vcs.server = localhost:9900
463 # Available protocols: pyro4, http
464 vcs.server.protocol = pyro4
465
466 # available impl:
467 # vcsserver.scm_app (EE only, for testing),
468 # rhodecode.lib.middleware.utils.scm_app_http
469 # pyro4
470 #vcs.scm_app_implementation = rhodecode.lib.middleware.utils.scm_app_http
471
472 vcs.server.log_level = debug
473 vcs.start_server = true
474 vcs.backends = hg, git, svn
475 vcs.connection_timeout = 3600
476 ## Compatibility version when creating SVN repositories. Defaults to newest version when commented out.
477 ## Available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible
478 #vcs.svn.compatible_version = pre-1.8-compatible
479
480 ################################
481 ### LOGGING CONFIGURATION ####
482 ################################
483 [loggers]
484 keys = root, routes, rhodecode, sqlalchemy, beaker, pyro4, templates, whoosh_indexer
485
486 [handlers]
487 keys = console, console_sql
488
489 [formatters]
490 keys = generic, color_formatter, color_formatter_sql
491
492 #############
493 ## LOGGERS ##
494 #############
495 [logger_root]
496 level = NOTSET
497 handlers = console
498
499 [logger_routes]
500 level = DEBUG
501 handlers =
502 qualname = routes.middleware
503 ## "level = DEBUG" logs the route matched and routing variables.
504 propagate = 1
505
506 [logger_beaker]
507 level = DEBUG
508 handlers =
509 qualname = beaker.container
510 propagate = 1
511
512 [logger_pyro4]
513 level = DEBUG
514 handlers =
515 qualname = Pyro4
516 propagate = 1
517
518 [logger_templates]
519 level = INFO
520 handlers =
521 qualname = pylons.templating
522 propagate = 1
523
524 [logger_rhodecode]
525 level = DEBUG
526 handlers =
527 qualname = rhodecode
528 propagate = 1
529
530 [logger_sqlalchemy]
531 level = INFO
532 handlers = console_sql
533 qualname = sqlalchemy.engine
534 propagate = 0
535
536 [logger_whoosh_indexer]
537 level = DEBUG
538 handlers =
539 qualname = whoosh_indexer
540 propagate = 1
541
542 ##############
543 ## HANDLERS ##
544 ##############
545
546 [handler_console]
547 class = StreamHandler
548 args = (sys.stderr,)
549 level = DEBUG
550 formatter = color_formatter
551
552 [handler_console_sql]
553 class = StreamHandler
554 args = (sys.stderr,)
555 level = DEBUG
556 formatter = color_formatter_sql
557
558 ################
559 ## FORMATTERS ##
560 ################
561
562 [formatter_generic]
563 class = rhodecode.lib.logging_formatter.Pyro4AwareFormatter
564 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
565 datefmt = %Y-%m-%d %H:%M:%S
566
567 [formatter_color_formatter]
568 class = rhodecode.lib.logging_formatter.ColorFormatter
569 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
570 datefmt = %Y-%m-%d %H:%M:%S
571
572 [formatter_color_formatter_sql]
573 class = rhodecode.lib.logging_formatter.ColorFormatterSql
574 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
575 datefmt = %Y-%m-%d %H:%M:%S
@@ -0,0 +1,96 b''
1 """gunicorn config hooks"""
2
3 import multiprocessing
4 import sys
5 import threading
6 import traceback
7
8
9 # GLOBAL #
10 errorlog = '-'
11 accesslog = '-'
12 loglevel = 'debug'
13
14 # SECURITY #
15 limit_request_line = 4094
16 limit_request_fields = 100
17 limit_request_field_size = 8190
18
19 # SERVER MECHANICS #
20 # None == system temp dir #
21 worker_tmp_dir = None
22 tmp_upload_dir = None
23 #proc_name =
24
25 # self adjust workers based on CPU #
26 #workers = multiprocessing.cpu_count() * 2 + 1
27
28 access_log_format = '[%(p)s] %(h)15s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" request_time:%(L)s'
29
30 # For the gevent worker classes #
31 # this limits the maximum number of simultaneous clients that #
32 # a single process can handle. #
33 #worker_connections = 10
34
35 # Max requests to handle by each worker before restarting it, #
36 # could prevent memory leaks #
37 #max_requests = 1000
38 #max_requests_jitter = 30
39
40
41 # If a worker does not notify the master process in this #
42 # number of seconds it is killed and a new worker is spawned #
43 # to replace it. #
44 #timeout = 3600
45
46 access_log_format = (
47 '[%(p)-10s] %(h)s time:%(L)s %(l)s %(u)s '
48 '%(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"')
49
50
51 def post_fork(server, worker):
52 server.log.info("[<%s>] worker spawned", worker.pid)
53
54
55 def pre_fork(server, worker):
56 pass
57
58
59 def pre_exec(server):
60 server.log.info("Forked child, re-executing.")
61
62
63 def when_ready(server):
64 server.log.info("Server is ready. Spawning workers")
65
66
67 def worker_int(worker):
68 worker.log.info("[<%-10s>] worker received INT or QUIT signal", worker.pid)
69
70 # get traceback info
71 id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
72 code = []
73 for thread_id, stack in sys._current_frames().items():
74 code.append(
75 "\n# Thread: %s(%d)" % (id2name.get(thread_id, ""), thread_id))
76 for fname, lineno, name, line in traceback.extract_stack(stack):
77 code.append('File: "%s", line %d, in %s' % (fname, lineno, name))
78 if line:
79 code.append(" %s" % (line.strip()))
80 worker.log.debug("\n".join(code))
81
82
83 def worker_abort(worker):
84 worker.log.info("[<%-10s>] worker received SIGABRT signal", worker.pid)
85
86
87 def pre_request(worker, req):
88 return
89 worker.log.debug("[<%-10s>] PRE WORKER: %s %s",
90 worker.pid, req.method, req.path)
91
92
93 def post_request(worker, req, environ, resp):
94 return
95 worker.log.debug("[<%-10s>] POST WORKER: %s %s resp: %s", worker.pid,
96 req.method, req.path, resp.status_code) No newline at end of file
@@ -0,0 +1,1 b''
1 Example init scripts. No newline at end of file
@@ -0,0 +1,61 b''
1 ; Sample supervisor RhodeCode config file.
2 ;
3 ; For more information on the config file, please see:
4 ; http://supervisord.org/configuration.html
5 ;
6 ; Note: shell expansion ("~" or "$HOME") is not supported. Environment
7 ; variables can be expanded using this syntax: "%(ENV_HOME)s".
8
9 [unix_http_server]
10 file=/tmp/supervisor.sock ; (the path to the socket file)
11 ;chmod=0700 ; socket file mode (default 0700)
12 ;chown=nobody:nogroup ; socket file uid:gid owner
13 ;username=user ; (default is no username (open server))
14 ;password=123 ; (default is no password (open server))
15
16 [supervisord]
17 logfile=/home/ubuntu/rhodecode/supervisord.log ; (main log file;default $CWD/supervisord.log)
18 logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
19 logfile_backups=10 ; (num of main logfile rotation backups;default 10)
20 loglevel=info ; (log level;default info; others: debug,warn,trace)
21 pidfile=/home/ubuntu/rhodecode/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
22 nodaemon=true ; (start in foreground if true;default false)
23 minfds=1024 ; (min. avail startup file descriptors;default 1024)
24 minprocs=200 ; (min. avail process descriptors;default 200)
25 ;umask=022 ; (process file creation umask;default 022)
26 user=ubuntu ; (default is current user, required if root)
27 ;identifier=supervisor ; (supervisord identifier, default is 'supervisor')
28 ;directory=/tmp ; (default is not to cd during start)
29 ;nocleanup=true ; (don't clean up tempfiles at start;default false)
30 ;childlogdir=/tmp ; ('AUTO' child log dir, default $TEMP)
31 environment=HOME=/home/ubuntu,LANG=en_US.UTF-8 ; (key value pairs to add to environment)
32 ;strip_ansi=false ; (strip ansi escape codes in logs; def. false)
33
34 ; the below section must remain in the config file for RPC
35 ; (supervisorctl/web interface) to work, additional interfaces may be
36 ; added by defining them in separate rpcinterface: sections
37 [rpcinterface:supervisor]
38 supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
39
40 [supervisorctl]
41 serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
42 ;username=chris ; should be same as http_username if set
43 ;password=123 ; should be same as http_password if set
44
45
46 ; restart with supervisorctl restart rhodecode:*
47 [program:rhodecode]
48 numprocs = 1
49 numprocs_start = 5000
50 directory=/home/ubuntu/rhodecode/source
51 command = /home/ubuntu/rhodecode/venv/bin/paster serve /home/ubuntu/rhodecode/source/prod.ini
52 process_name = %(program_name)s_%(process_num)04d
53 redirect_stderr=true
54 stdout_logfile=/home/ubuntu/rhodecode/rhodecode.log
55
56 [program:rhodecode_workers]
57 numproces = 1
58 directory = /home/ubuntu/rhodecode/source
59 command = /home/ubuntu/rhodecode/venv/bin/paster celeryd /home/ubuntu/rhodecode/source/prod.ini --autoscale=10,2
60 redirect_stderr=true
61 stdout_logfile=/%(here)s/rhodecode_workers.log
This diff has been collapsed as it changes many lines, (541 lines changed) Show them Hide them
@@ -0,0 +1,541 b''
1 ################################################################################
2 ################################################################################
3 # RhodeCode Enterprise - configuration file #
4 # Built-in functions and variables #
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 # #
7 ################################################################################
8
9 [DEFAULT]
10 debug = true
11 pdebug = false
12 ################################################################################
13 ## Uncomment and replace with the email address which should receive ##
14 ## any error reports after an application crash ##
15 ## Additionally these settings will be used by the RhodeCode mailing system ##
16 ################################################################################
17 #email_to = admin@localhost
18 #error_email_from = paste_error@localhost
19 #app_email_from = rhodecode-noreply@localhost
20 #error_message =
21 #email_prefix = [RhodeCode]
22
23 #smtp_server = mail.server.com
24 #smtp_username =
25 #smtp_password =
26 #smtp_port =
27 #smtp_use_tls = false
28 #smtp_use_ssl = true
29 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
30 #smtp_auth =
31
32 [server:main]
33 ## COMMON ##
34 host = 127.0.0.1
35 port = 5000
36
37 ##########################
38 ## WAITRESS WSGI SERVER ##
39 ##########################
40 use = egg:waitress#main
41 ## number of worker threads
42 threads = 5
43 ## MAX BODY SIZE 100GB
44 max_request_body_size = 107374182400
45 ## Use poll instead of select, fixes file descriptors limits problems.
46 ## May not work on old windows systems.
47 asyncore_use_poll = true
48
49
50 ##########################
51 ## GUNICORN WSGI SERVER ##
52 ##########################
53 ## run with gunicorn --log-config <inifile.ini> --paste <inifile.ini>
54 #use = egg:gunicorn#main
55 ## Sets the number of process workers. You must set `instance_id = *`
56 ## when this option is set to more than one worker, recommended
57 ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers
58 ## The `instance_id = *` must be set in the [app:main] section below
59 #workers = 1
60 ## number of threads for each of the worker, must be set to 1 for gevent
61 ## generally recommened to be at 1
62 #threads = 1
63 ## process name
64 #proc_name = rhodecode
65 ## type of worker class, one of sync, gevent
66 ## recommended for bigger setup is using of of other than sync one
67 #worker_class = sync
68 ## max number of requests that worker will handle before being gracefully
69 ## restarted, could prevent memory leaks
70 #max_requests = 1000
71 #max_requests_jitter = 30
72 ## ammount of time a worker can spend with handling a request before it
73 ## gets killed and restarted. Set to 6hrs
74 #timeout = 21600
75
76
77 ## prefix middleware for RhodeCode, disables force_https flag.
78 ## allows to set RhodeCode under a prefix in server.
79 ## eg https://server.com/<prefix>. Enable `filter-with =` option below as well.
80 #[filter:proxy-prefix]
81 #use = egg:PasteDeploy#prefix
82 #prefix = /<your-prefix>
83
84 [app:main]
85 use = egg:rhodecode-enterprise-ce
86 ## enable proxy prefix middleware, defined below
87 #filter-with = proxy-prefix
88
89 full_stack = true
90
91 ## Serve static files via RhodeCode, disable to serve them via HTTP server
92 static_files = true
93
94 ## Optional Languages
95 ## en(default), be, de, es, fr, it, ja, pl, pt, ru, zh
96 lang = en
97
98 ## perform a full repository scan on each server start, this should be
99 ## set to false after first startup, to allow faster server restarts.
100 startup.import_repos = false
101
102 ## Uncomment and set this path to use archive download cache.
103 ## Once enabled, generated archives will be cached at this location
104 ## and served from the cache during subsequent requests for the same archive of
105 ## the repository.
106 #archive_cache_dir = /tmp/tarballcache
107
108 ## change this to unique ID for security
109 app_instance_uuid = rc-production
110
111 ## cut off limit for large diffs (size in bytes)
112 cut_off_limit_diff = 1024000
113 cut_off_limit_file = 256000
114
115 ## use cache version of scm repo everywhere
116 vcs_full_cache = true
117
118 ## force https in RhodeCode, fixes https redirects, assumes it's always https
119 ## Normally this is controlled by proper http flags sent from http server
120 force_https = false
121
122 ## use Strict-Transport-Security headers
123 use_htsts = false
124
125 ## number of commits stats will parse on each iteration
126 commit_parse_limit = 25
127
128 ## git rev filter option, --all is the default filter, if you need to
129 ## hide all refs in changelog switch this to --branches --tags
130 git_rev_filter = --branches --tags
131
132 # Set to true if your repos are exposed using the dumb protocol
133 git_update_server_info = false
134
135 ## RSS/ATOM feed options
136 rss_cut_off_limit = 256000
137 rss_items_per_page = 10
138 rss_include_diff = false
139
140 ## gist URL alias, used to create nicer urls for gist. This should be an
141 ## url that does rewrites to _admin/gists/<gistid>.
142 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
143 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
144 gist_alias_url =
145
146 ## List of controllers (using glob pattern syntax) that AUTH TOKENS could be
147 ## used for access.
148 ## Adding ?auth_token = <token> to the url authenticates this request as if it
149 ## came from the the logged in user who own this authentication token.
150 ##
151 ## Syntax is <ControllerClass>:<function_pattern>.
152 ## To enable access to raw_files put `FilesController:raw`.
153 ## To enable access to patches add `ChangesetController:changeset_patch`.
154 ## The list should be "," separated and on a single line.
155 ##
156 ## Recommended controllers to enable:
157 # ChangesetController:changeset_patch,
158 # ChangesetController:changeset_raw,
159 # FilesController:raw,
160 # FilesController:archivefile,
161 # GistsController:*,
162 api_access_controllers_whitelist =
163
164 ## default encoding used to convert from and to unicode
165 ## can be also a comma separated list of encoding in case of mixed encodings
166 default_encoding = UTF-8
167
168 ## instance-id prefix
169 ## a prefix key for this instance used for cache invalidation when running
170 ## multiple instances of rhodecode, make sure it's globally unique for
171 ## all running rhodecode instances. Leave empty if you don't use it
172 instance_id =
173
174 ## alternative return HTTP header for failed authentication. Default HTTP
175 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
176 ## handling that causing a series of failed authentication calls.
177 ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code
178 ## This will be served instead of default 401 on bad authnetication
179 auth_ret_code =
180
181 ## use special detection method when serving auth_ret_code, instead of serving
182 ## ret_code directly, use 401 initially (Which triggers credentials prompt)
183 ## and then serve auth_ret_code to clients
184 auth_ret_code_detection = false
185
186 ## locking return code. When repository is locked return this HTTP code. 2XX
187 ## codes don't break the transactions while 4XX codes do
188 lock_ret_code = 423
189
190 ## allows to change the repository location in settings page
191 allow_repo_location_change = true
192
193 ## allows to setup custom hooks in settings page
194 allow_custom_hooks_settings = true
195
196 ## generated license token, goto license page in RhodeCode settings to obtain
197 ## new token
198 license_token =
199
200 ## supervisor connection uri, for managing supervisor and logs.
201 supervisor.uri =
202 ## supervisord group name/id we only want this RC instance to handle
203 supervisor.group_id = prod
204
205 ## Display extended labs settings
206 labs_settings_active = true
207
208 ####################################
209 ### CELERY CONFIG ####
210 ####################################
211 use_celery = false
212 broker.host = localhost
213 broker.vhost = rabbitmqhost
214 broker.port = 5672
215 broker.user = rabbitmq
216 broker.password = qweqwe
217
218 celery.imports = rhodecode.lib.celerylib.tasks
219
220 celery.result.backend = amqp
221 celery.result.dburi = amqp://
222 celery.result.serialier = json
223
224 #celery.send.task.error.emails = true
225 #celery.amqp.task.result.expires = 18000
226
227 celeryd.concurrency = 2
228 #celeryd.log.file = celeryd.log
229 celeryd.log.level = debug
230 celeryd.max.tasks.per.child = 1
231
232 ## tasks will never be sent to the queue, but executed locally instead.
233 celery.always.eager = false
234
235 ####################################
236 ### BEAKER CACHE ####
237 ####################################
238 # default cache dir for templates. Putting this into a ramdisk
239 ## can boost performance, eg. %(here)s/data_ramdisk
240 cache_dir = %(here)s/data
241
242 ## locking and default file storage for Beaker. Putting this into a ramdisk
243 ## can boost performance, eg. %(here)s/data_ramdisk/cache/beaker_data
244 beaker.cache.data_dir = %(here)s/data/cache/beaker_data
245 beaker.cache.lock_dir = %(here)s/data/cache/beaker_lock
246
247 beaker.cache.regions = super_short_term, short_term, long_term, sql_cache_short, auth_plugins, repo_cache_long
248
249 beaker.cache.super_short_term.type = memory
250 beaker.cache.super_short_term.expire = 10
251 beaker.cache.super_short_term.key_length = 256
252
253 beaker.cache.short_term.type = memory
254 beaker.cache.short_term.expire = 60
255 beaker.cache.short_term.key_length = 256
256
257 beaker.cache.long_term.type = memory
258 beaker.cache.long_term.expire = 36000
259 beaker.cache.long_term.key_length = 256
260
261 beaker.cache.sql_cache_short.type = memory
262 beaker.cache.sql_cache_short.expire = 10
263 beaker.cache.sql_cache_short.key_length = 256
264
265 # default is memory cache, configure only if required
266 # using multi-node or multi-worker setup
267 #beaker.cache.auth_plugins.type = ext:database
268 #beaker.cache.auth_plugins.lock_dir = %(here)s/data/cache/auth_plugin_lock
269 #beaker.cache.auth_plugins.url = postgresql://postgres:secret@localhost/rhodecode
270 #beaker.cache.auth_plugins.url = mysql://root:secret@127.0.0.1/rhodecode
271 #beaker.cache.auth_plugins.sa.pool_recycle = 3600
272 #beaker.cache.auth_plugins.sa.pool_size = 10
273 #beaker.cache.auth_plugins.sa.max_overflow = 0
274
275 beaker.cache.repo_cache_long.type = memorylru_base
276 beaker.cache.repo_cache_long.max_items = 4096
277 beaker.cache.repo_cache_long.expire = 2592000
278
279 # default is memorylru_base cache, configure only if required
280 # using multi-node or multi-worker setup
281 #beaker.cache.repo_cache_long.type = ext:memcached
282 #beaker.cache.repo_cache_long.url = localhost:11211
283 #beaker.cache.repo_cache_long.expire = 1209600
284 #beaker.cache.repo_cache_long.key_length = 256
285
286 ####################################
287 ### BEAKER SESSION ####
288 ####################################
289
290 ## .session.type is type of storage options for the session, current allowed
291 ## types are file(default), ext:memcached, ext:database, and memory.
292 #beaker.session.type = file
293
294 ## db based session, fast, and allows easy management over logged in users ##
295 #beaker.session.type = ext:database
296 #beaker.session.lock_dir = %(here)s/data/cache/session_db_lock
297 #beaker.session.table_name = db_session
298 #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode
299 #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode
300 #beaker.session.sa.pool_recycle = 3600
301 #beaker.session.sa.echo = false
302
303 beaker.session.key = rhodecode
304 beaker.session.secret = production-rc-uytcxaz
305
306 ## Secure encrypted cookie. Requires AES and AES python libraries
307 ## you must disable beaker.session.secret to use this
308 #beaker.session.encrypt_key = <key_for_encryption>
309 #beaker.session.validate_key = <validation_key>
310
311 ## sets session as invalid(also logging out user) if it haven not been
312 ## accessed for given amount of time in seconds
313 beaker.session.timeout = 2592000
314 beaker.session.httponly = true
315 #beaker.session.cookie_path = /<your-prefix>
316
317 ## uncomment for https secure cookie
318 beaker.session.secure = false
319
320 ## auto save the session to not to use .save()
321 beaker.session.auto = false
322
323 ## default cookie expiration time in seconds, set to `true` to set expire
324 ## at browser close
325 #beaker.session.cookie_expires = 3600
326
327 ###################################
328 ## SEARCH INDEXING CONFIGURATION ##
329 ###################################
330
331 search.module = rhodecode.lib.index.whoosh
332 search.location = %(here)s/data/index
333
334 ###################################
335 ## ERROR AND LOG HANDLING SYSTEM ##
336 ###################################
337
338 ## Appenlight is tailored to work with RhodeCode, see
339 ## http://appenlight.com for details how to obtain an account
340
341 ## appenlight integration enabled
342 appenlight = false
343
344 appenlight.server_url = https://api.appenlight.com
345 appenlight.api_key = YOUR_API_KEY
346 ;appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5
347
348 # used for JS client
349 appenlight.api_public_key = YOUR_API_PUBLIC_KEY
350
351 ## TWEAK AMOUNT OF INFO SENT HERE
352
353 ## enables 404 error logging (default False)
354 appenlight.report_404 = false
355
356 ## time in seconds after request is considered being slow (default 1)
357 appenlight.slow_request_time = 1
358
359 ## record slow requests in application
360 ## (needs to be enabled for slow datastore recording and time tracking)
361 appenlight.slow_requests = true
362
363 ## enable hooking to application loggers
364 appenlight.logging = true
365
366 ## minimum log level for log capture
367 appenlight.logging.level = WARNING
368
369 ## send logs only from erroneous/slow requests
370 ## (saves API quota for intensive logging)
371 appenlight.logging_on_error = false
372
373 ## list of additonal keywords that should be grabbed from environ object
374 ## can be string with comma separated list of words in lowercase
375 ## (by default client will always send following info:
376 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
377 ## start with HTTP* this list be extended with additional keywords here
378 appenlight.environ_keys_whitelist =
379
380 ## list of keywords that should be blanked from request object
381 ## can be string with comma separated list of words in lowercase
382 ## (by default client will always blank keys that contain following words
383 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
384 ## this list be extended with additional keywords set here
385 appenlight.request_keys_blacklist =
386
387 ## list of namespaces that should be ignores when gathering log entries
388 ## can be string with comma separated list of namespaces
389 ## (by default the client ignores own entries: appenlight_client.client)
390 appenlight.log_namespace_blacklist =
391
392
393 ################################################################################
394 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
395 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
396 ## execute malicious code after an exception is raised. ##
397 ################################################################################
398 set debug = false
399
400
401 ##############
402 ## STYLING ##
403 ##############
404 debug_style = false
405
406 #########################################################
407 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
408 #########################################################
409 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30
410 sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode
411 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode
412
413 # see sqlalchemy docs for other advanced settings
414
415 ## print the sql statements to output
416 sqlalchemy.db1.echo = false
417 ## recycle the connections after this ammount of seconds
418 sqlalchemy.db1.pool_recycle = 3600
419 sqlalchemy.db1.convert_unicode = true
420
421 ## the number of connections to keep open inside the connection pool.
422 ## 0 indicates no limit
423 #sqlalchemy.db1.pool_size = 5
424
425 ## the number of connections to allow in connection pool "overflow", that is
426 ## connections that can be opened above and beyond the pool_size setting,
427 ## which defaults to five.
428 #sqlalchemy.db1.max_overflow = 10
429
430
431 ##################
432 ### VCS CONFIG ###
433 ##################
434 vcs.server.enable = true
435 vcs.server = localhost:9900
436 # Available protocols: pyro4, http
437 vcs.server.protocol = pyro4
438 vcs.server.log_level = info
439 vcs.start_server = false
440 vcs.backends = hg, git, svn
441 vcs.connection_timeout = 3600
442 ## Compatibility version when creating SVN repositories. Defaults to newest version when commented out.
443 ## Available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible
444 #vcs.svn.compatible_version = pre-1.8-compatible
445
446 ################################
447 ### LOGGING CONFIGURATION ####
448 ################################
449 [loggers]
450 keys = root, routes, rhodecode, sqlalchemy, beaker, pyro4, templates, whoosh_indexer
451
452 [handlers]
453 keys = console, console_sql
454
455 [formatters]
456 keys = generic, color_formatter, color_formatter_sql
457
458 #############
459 ## LOGGERS ##
460 #############
461 [logger_root]
462 level = NOTSET
463 handlers = console
464
465 [logger_routes]
466 level = DEBUG
467 handlers =
468 qualname = routes.middleware
469 ## "level = DEBUG" logs the route matched and routing variables.
470 propagate = 1
471
472 [logger_beaker]
473 level = DEBUG
474 handlers =
475 qualname = beaker.container
476 propagate = 1
477
478 [logger_pyro4]
479 level = DEBUG
480 handlers =
481 qualname = Pyro4
482 propagate = 1
483
484 [logger_templates]
485 level = INFO
486 handlers =
487 qualname = pylons.templating
488 propagate = 1
489
490 [logger_rhodecode]
491 level = DEBUG
492 handlers =
493 qualname = rhodecode
494 propagate = 1
495
496 [logger_sqlalchemy]
497 level = INFO
498 handlers = console_sql
499 qualname = sqlalchemy.engine
500 propagate = 0
501
502 [logger_whoosh_indexer]
503 level = DEBUG
504 handlers =
505 qualname = whoosh_indexer
506 propagate = 1
507
508 ##############
509 ## HANDLERS ##
510 ##############
511
512 [handler_console]
513 class = StreamHandler
514 args = (sys.stderr,)
515 level = INFO
516 formatter = generic
517
518 [handler_console_sql]
519 class = StreamHandler
520 args = (sys.stderr,)
521 level = WARN
522 formatter = generic
523
524 ################
525 ## FORMATTERS ##
526 ################
527
528 [formatter_generic]
529 class = rhodecode.lib.logging_formatter.Pyro4AwareFormatter
530 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
531 datefmt = %Y-%m-%d %H:%M:%S
532
533 [formatter_color_formatter]
534 class = rhodecode.lib.logging_formatter.ColorFormatter
535 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
536 datefmt = %Y-%m-%d %H:%M:%S
537
538 [formatter_color_formatter_sql]
539 class = rhodecode.lib.logging_formatter.ColorFormatterSql
540 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
541 datefmt = %Y-%m-%d %H:%M:%S
@@ -0,0 +1,6 b''
1 [channelstream]
2 admin_secret = secret
3 secret = secret
4 port = 9800
5 demo = false
6 allow_posting_from = 127.0.0.1
@@ -0,0 +1,215 b''
1 # Nix environment for the community edition
2 #
3 # This shall be as lean as possible, just producing the Enterprise
4 # derivation. For advanced tweaks to pimp up the development environment we use
5 # "shell.nix" so that it does not have to clutter this file.
6
7 { pkgs ? (import <nixpkgs> {})
8 , pythonPackages ? "python27Packages"
9 , pythonExternalOverrides ? self: super: {}
10 , doCheck ? true
11 }:
12
13 let pkgs_ = pkgs; in
14
15 let
16 pkgs = pkgs_.overridePackages (self: super: {
17 # Override subversion derivation to
18 # - activate python bindings
19 # - set version to 1.8
20 subversion = super.subversion18.override {
21 httpSupport = true;
22 pythonBindings = true;
23 python = self.python27Packages.python;
24 };
25 });
26
27 inherit (pkgs.lib) fix extends;
28
29 basePythonPackages = with builtins; if isAttrs pythonPackages
30 then pythonPackages
31 else getAttr pythonPackages pkgs;
32
33 elem = builtins.elem;
34 basename = path: with pkgs.lib; last (splitString "/" path);
35 startsWith = prefix: full: let
36 actualPrefix = builtins.substring 0 (builtins.stringLength prefix) full;
37 in actualPrefix == prefix;
38
39 src-filter = path: type: with pkgs.lib;
40 let
41 ext = last (splitString "." path);
42 in
43 !elem (basename path) [
44 ".git" ".hg" "__pycache__" ".eggs" "node_modules"
45 "build" "data" "tmp"] &&
46 !elem ext ["egg-info" "pyc"] &&
47 !startsWith "result" path;
48
49 rhodecode-enterprise-ce-src = builtins.filterSource src-filter ./.;
50
51 # Load the generated node packages
52 nodePackages = pkgs.callPackage "${pkgs.path}/pkgs/top-level/node-packages.nix" rec {
53 self = nodePackages;
54 generated = pkgs.callPackage ./pkgs/node-packages.nix { inherit self; };
55 };
56
57 # TODO: Should be taken automatically out of the generates packages.
58 # apps.nix has one solution for this, although I'd prefer to have the deps
59 # from package.json mapped in here.
60 nodeDependencies = with nodePackages; [
61 grunt
62 grunt-contrib-concat
63 grunt-contrib-jshint
64 grunt-contrib-less
65 grunt-contrib-watch
66 jshint
67 ];
68
69 pythonGeneratedPackages = self: basePythonPackages.override (a: {
70 inherit self;
71 })
72 // (scopedImport {
73 self = self;
74 super = basePythonPackages;
75 inherit pkgs;
76 inherit (pkgs) fetchurl fetchgit;
77 } ./pkgs/python-packages.nix);
78
79 pythonOverrides = import ./pkgs/python-packages-overrides.nix {
80 inherit
81 basePythonPackages
82 pkgs;
83 };
84
85 pythonLocalOverrides = self: super: {
86 rhodecode-enterprise-ce =
87 let
88 version = "${builtins.readFile ./rhodecode/VERSION}";
89 linkNodeModules = ''
90 echo "Link node packages"
91 # TODO: check if this adds stuff as a dependency, closure size
92 rm -fr node_modules
93 mkdir -p node_modules
94 ${pkgs.lib.concatMapStrings (dep: ''
95 ln -sfv ${dep}/lib/node_modules/${dep.pkgName} node_modules/
96 '') nodeDependencies}
97 echo "DONE: Link node packages"
98 '';
99 in super.rhodecode-enterprise-ce.override (attrs: {
100
101 inherit doCheck;
102 name = "rhodecode-enterprise-ce-${version}";
103 version = version;
104 src = rhodecode-enterprise-ce-src;
105
106 buildInputs =
107 attrs.buildInputs ++
108 (with self; [
109 pkgs.nodePackages.grunt-cli
110 pkgs.subversion
111 pytest-catchlog
112 rc_testdata
113 ]);
114
115 propagatedBuildInputs = attrs.propagatedBuildInputs ++ (with self; [
116 rhodecode-tools
117 ]);
118
119 # TODO: johbo: Make a nicer way to expose the parts. Maybe
120 # pkgs/default.nix?
121 passthru = {
122 inherit myPythonPackagesUnfix;
123 pythonPackages = self;
124 };
125
126 LC_ALL = "en_US.UTF-8";
127 LOCALE_ARCHIVE =
128 if pkgs.stdenv ? glibc
129 then "${pkgs.glibcLocales}/lib/locale/locale-archive"
130 else "";
131
132 # Somewhat snappier setup of the development environment
133 # TODO: move into shell.nix
134 # TODO: think of supporting a stable path again, so that multiple shells
135 # can share it.
136 shellHook = ''
137 tmp_path=$(mktemp -d)
138 export PATH="$tmp_path/bin:$PATH"
139 export PYTHONPATH="$tmp_path/${self.python.sitePackages}:$PYTHONPATH"
140 mkdir -p $tmp_path/${self.python.sitePackages}
141 python setup.py develop --prefix $tmp_path --allow-hosts ""
142 '' + linkNodeModules;
143
144 preCheck = ''
145 export PATH="$out/bin:$PATH"
146 '';
147
148 postCheck = ''
149 rm -rf $out/lib/${self.python.libPrefix}/site-packages/pytest_pylons
150 rm -rf $out/lib/${self.python.libPrefix}/site-packages/rhodecode/tests
151 '';
152
153 preBuild = linkNodeModules + ''
154 grunt
155 rm -fr node_modules
156 '';
157
158 postInstall = ''
159 # python based programs need to be wrapped
160 ln -s ${self.supervisor}/bin/supervisor* $out/bin/
161 ln -s ${self.gunicorn}/bin/gunicorn $out/bin/
162 ln -s ${self.PasteScript}/bin/paster $out/bin/
163
164 # rhodecode-tools
165 # TODO: johbo: re-think this. Do the tools import anything from enterprise?
166 ln -s ${self.rhodecode-tools}/bin/rhodecode-* $out/bin/
167
168 # note that condition should be restricted when adding further tools
169 for file in $out/bin/*; do #*/
170 wrapProgram $file \
171 --prefix PYTHONPATH : $PYTHONPATH \
172 --set PYTHONHASHSEED random
173 done
174
175 mkdir $out/etc
176 cp configs/production.ini $out/etc
177
178 echo "Writing meta information for rccontrol to nix-support/rccontrol"
179 mkdir -p $out/nix-support/rccontrol
180 cp -v rhodecode/VERSION $out/nix-support/rccontrol/version
181 echo "DONE: Meta information for rccontrol written"
182
183 # TODO: johbo: Make part of ac-tests
184 if [ ! -f rhodecode/public/js/scripts.js ]; then
185 echo "Missing scripts.js"
186 exit 1
187 fi
188 if [ ! -f rhodecode/public/css/style.css ]; then
189 echo "Missing style.css"
190 exit 1
191 fi
192 '';
193
194 });
195
196 rc_testdata = self.buildPythonPackage rec {
197 name = "rc_testdata-0.7.0";
198 src = pkgs.fetchhg {
199 url = "https://code.rhodecode.com/upstream/rc_testdata";
200 rev = "v0.7.0";
201 sha256 = "0w3z0zn8lagr707v67lgys23sl6pbi4xg7pfvdbw58h3q384h6rx";
202 };
203 };
204
205 };
206
207 # Apply all overrides and fix the final package set
208 myPythonPackagesUnfix =
209 (extends pythonExternalOverrides
210 (extends pythonLocalOverrides
211 (extends pythonOverrides
212 pythonGeneratedPackages)));
213 myPythonPackages = (fix myPythonPackagesUnfix);
214
215 in myPythonPackages.rhodecode-enterprise-ce
@@ -0,0 +1,15 b''
1 .. _vcs-http:
2
3 ========================================
4 Transition to HTTP based communication
5 ========================================
6
7 We are in the process of replacing the Pyro4 based communication with an HTTP
8 based implementation. Currently both backends are supported and can be
9 activated via various settings in the configuration.
10
11 To run the system in full HTTP based mode, use the following settings::
12
13 vcs.hooks.protocol = http
14 vcs.scm_app_implementation = rhodecode.lib.middleware.utils.scm_app_http
15 vcs.server.protocol = http
@@ -0,0 +1,23 b''
1
2 ======================================
3 VCS client and VCSServer integration
4 ======================================
5
6 Enterprise uses the VCSServer as a backend to provide version control
7 functionalities. This section describes the components in Enterprise which talk
8 to the VCSServer.
9
10 The client library is implemented in :mod:`rhodecode.lib.vcs`. For HTTP based
11 access of the command line clients special middlewares and utilities are
12 implemented in :mod:`rhodecode.lib.middleware`.
13
14
15
16
17 .. toctree::
18 :maxdepth: 2
19
20 http-transition
21 middleware
22 vcsserver
23 subversion
@@ -0,0 +1,4 b''
1 # building the docs
2 cd docs
3 nix-build default.nix -o result
4 make clean html No newline at end of file
@@ -0,0 +1,177 b''
1 # Makefile for Sphinx documentation
2 #
3
4 # You can set these variables from the command line.
5 SPHINXOPTS =
6 SPHINXBUILD = ./result/bin/sphinx-build
7 PAPER =
8 BUILDDIR = _build
9
10 # User-friendly check for sphinx-build
11 ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
12 $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
13 endif
14
15 # Internal variables.
16 PAPEROPT_a4 = -D latex_paper_size=a4
17 PAPEROPT_letter = -D latex_paper_size=letter
18 ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
19 # the i18n builder cannot share the environment and doctrees with the others
20 I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
21
22 .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
23
24 help:
25 @echo "Please use \`make <target>' where <target> is one of"
26 @echo " html to make standalone HTML files"
27 @echo " dirhtml to make HTML files named index.html in directories"
28 @echo " singlehtml to make a single large HTML file"
29 @echo " pickle to make pickle files"
30 @echo " json to make JSON files"
31 @echo " htmlhelp to make HTML files and a HTML help project"
32 @echo " qthelp to make HTML files and a qthelp project"
33 @echo " devhelp to make HTML files and a Devhelp project"
34 @echo " epub to make an epub"
35 @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
36 @echo " latexpdf to make LaTeX files and run them through pdflatex"
37 @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
38 @echo " text to make text files"
39 @echo " man to make manual pages"
40 @echo " texinfo to make Texinfo files"
41 @echo " info to make Texinfo files and run them through makeinfo"
42 @echo " gettext to make PO message catalogs"
43 @echo " changes to make an overview of all changed/added/deprecated items"
44 @echo " xml to make Docutils-native XML files"
45 @echo " pseudoxml to make pseudoxml-XML files for display purposes"
46 @echo " linkcheck to check all external links for integrity"
47 @echo " doctest to run all doctests embedded in the documentation (if enabled)"
48
49 clean:
50 rm -rf $(BUILDDIR)/*
51
52 html:
53 $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
54 @echo
55 @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
56
57 dirhtml:
58 $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
59 @echo
60 @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
61
62 singlehtml:
63 $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
64 @echo
65 @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
66
67 pickle:
68 $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
69 @echo
70 @echo "Build finished; now you can process the pickle files."
71
72 json:
73 $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
74 @echo
75 @echo "Build finished; now you can process the JSON files."
76
77 htmlhelp:
78 $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
79 @echo
80 @echo "Build finished; now you can run HTML Help Workshop with the" \
81 ".hhp project file in $(BUILDDIR)/htmlhelp."
82
83 qthelp:
84 $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
85 @echo
86 @echo "Build finished; now you can run "qcollectiongenerator" with the" \
87 ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
88 @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/RhodeCodeInstaller.qhcp"
89 @echo "To view the help file:"
90 @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/RhodeCodeInstaller.qhc"
91
92 devhelp:
93 $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
94 @echo
95 @echo "Build finished."
96 @echo "To view the help file:"
97 @echo "# mkdir -p $$HOME/.local/share/devhelp/RhodeCodeInstaller"
98 @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/RhodeCodeInstaller"
99 @echo "# devhelp"
100
101 epub:
102 $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
103 @echo
104 @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
105
106 latex:
107 $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
108 @echo
109 @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
110 @echo "Run \`make' in that directory to run these through (pdf)latex" \
111 "(use \`make latexpdf' here to do that automatically)."
112
113 latexpdf:
114 $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
115 @echo "Running LaTeX files through pdflatex..."
116 $(MAKE) -C $(BUILDDIR)/latex all-pdf
117 @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
118
119 latexpdfja:
120 $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
121 @echo "Running LaTeX files through platex and dvipdfmx..."
122 $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
123 @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
124
125 text:
126 $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
127 @echo
128 @echo "Build finished. The text files are in $(BUILDDIR)/text."
129
130 man:
131 $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
132 @echo
133 @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
134
135 texinfo:
136 $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
137 @echo
138 @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
139 @echo "Run \`make' in that directory to run these through makeinfo" \
140 "(use \`make info' here to do that automatically)."
141
142 info:
143 $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
144 @echo "Running Texinfo files through makeinfo..."
145 make -C $(BUILDDIR)/texinfo info
146 @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
147
148 gettext:
149 $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
150 @echo
151 @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
152
153 changes:
154 $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
155 @echo
156 @echo "The overview file is in $(BUILDDIR)/changes."
157
158 linkcheck:
159 $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
160 @echo
161 @echo "Link check complete; look for any errors in the above output " \
162 "or in $(BUILDDIR)/linkcheck/output.txt."
163
164 doctest:
165 $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
166 @echo "Testing of doctests in the sources finished, look at the " \
167 "results in $(BUILDDIR)/doctest/output.txt."
168
169 xml:
170 $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
171 @echo
172 @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
173
174 pseudoxml:
175 $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
176 @echo
177 @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
@@ -0,0 +1,18 b''
1 {% extends "!layout.html" %}
2 {% set css_files = css_files + ['_static/add.css'] %}
3
4 {% block footer %}
5 {{ super() }}
6
7 <script>
8 (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
9 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
10 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
11 })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
12
13 ga('create', 'UA-55639800-3', 'auto');
14 ga('send', 'pageview');
15
16 </script>
17
18 {% endblock %}
@@ -0,0 +1,22 b''
1 .. _permissions-info-anon-ref:
2
3 Anonymous Users
4 ---------------
5
6 By default, |RCM| provides |repo| access for registered users only. It can be
7 configured to be **world-open** in terms of read and write permissions. This
8 configuration is called "Anonymous Access" and allows |RCM| to be used as a
9 public hub where unregistered users have access to your |repos|.
10
11 Anonymous access is useful for open source projects, universities,
12 or if running inside a restricted internal corporate network to serve
13 documents to all employees. Anonymous users get the default user permission
14 settings that are applied across the whole |RCM| system.
15
16 To enable anonymous access to your |repos|, use the following steps:
17
18 1. From the |RCM| interface, select :menuselection:`Admin --> Permissions`.
19 2. On the Application tab, check the :guilabel:`Allow anonymous access` box.
20 3. Select :guilabel:`Save`.
21 4. To set the anonymous user access permissions, which are based on the
22 default user settings, see :ref:`permissions-default-ref`.
@@ -0,0 +1,20 b''
1 .. _permissions-add-user:
2
3 Adding Users
4 ------------
5
6 To create a new user, use the following steps.
7
8 1. Select :menuselection:`Admin --> Users` in the top menu.
9 2. Select the :guilabel:`Add User` button at the top right.
10 3. Set the user credentials.
11 4. Select :guilabel:`Save`.
12
13 Once the user is created you can set which groups they belong to using the
14 following steps:
15
16 1. From the :menuselection:`Admin --> Users Groups` page select
17 :guilabel:`edit` beside the user group you want to include them in.
18 2. On the :guilabel:`Settings` page, move the user from
19 :guilabel:`Available Members` into :guilabel:`Chosen Members` and
20 :guilabel:`Save`. No newline at end of file
@@ -0,0 +1,222 b''
1 .. _admin-tricks:
2
3 One-time Admin Tasks
4 --------------------
5
6 * :ref:`web-analytics`
7 * :ref:`admin-tricks-license`
8 * :ref:`announcements`
9 * :ref:`md-rst`
10 * :ref:`repo-stats`
11 * :ref:`server-side-merge`
12 * :ref:`remap-rescan`
13 * :ref:`custom-hooks`
14 * :ref:`clear-repo-cache`
15 * :ref:`set-repo-pub`
16 * :ref:`ping`
17
18 .. _web-analytics:
19
20 Adding Web Analytics
21 ^^^^^^^^^^^^^^^^^^^^
22
23 If you wish to add a Google Analytics, or any other kind of tracker to your
24 |RCE| instance you can add the necessary codes to the header or footer
25 section of each instance using the following steps:
26
27 1. From the |RCE| interface, select
28 :menuselection:`Admin --> Settings --> Global`
29 2. To add a tracking code to you instance, enter it in the header or footer
30 section and select **Save**
31
32 Use the example templates in the drop-down menu to set up your configuration.
33
34 .. _admin-tricks-license:
35
36 Licence Key Management
37 ^^^^^^^^^^^^^^^^^^^^^^
38
39 To manage your license key, go to
40 :menuselection:`Admin --> Settings --> License`.
41 On this page you can see the license key details. If you need a new license,
42 or have questions about your current one, contact support@rhodecode.com
43
44 .. _announcements:
45
46 Server-wide Announcements
47 ^^^^^^^^^^^^^^^^^^^^^^^^^
48
49 If you need to make a server-wide announcement to all users,
50 you can add a message to be displayed using the following steps:
51
52 1. From the |RCE| interface, select
53 :menuselection:`Admin --> Settings --> Global`
54 2. To add a message that will be displayed to all users,
55 select :guilabel:`Server Announcement` from the drop-down menu and
56 change the ``var message = "TYPE YOUR MESSAGE HERE";`` example line.
57 3. Select :guilabel:`Save`, and you will see the message once your page
58 refreshes.
59
60 .. image:: ../images/server-wide-announcement.png
61 :alt: Server Wide Announcement
62
63 .. _md-rst:
64
65 Markdown or RST Rendering
66 ^^^^^^^^^^^^^^^^^^^^^^^^^
67
68 |RCE| can use `Markdown`_ or `reStructured Text`_ in commit message,
69 code review messages, and inline comments. To set the default to either,
70 select your preference from the drop-down menu on the
71 :menuselection:`Admin --> Settings --> Visual` page and select
72 :guilabel:`Save settings`.
73
74 .. _repo-stats:
75
76 Enabling Repository Statistics
77 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
78
79 To enable |repo| statistics, use the following steps:
80
81 1. From the |RCE| interface, open
82 :menuselection:`Admin --> Repositories` and select
83 :guilabel:`Edit` beside the |repo| for which you wish to enable statistics.
84 2. Check the :guilabel:`Enable statistics` box, and select :guilabel:`Save`
85
86 .. _server-side-merge:
87
88 Enabling Server-side Merging
89 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
90
91 To enable server-side merging, use the following steps:
92
93 1. From the |RCE| interface, open :menuselection:`Admin --> Settings --> VCS`
94 2. Check the :guilabel:`Server-side merge` box, and select
95 :guilabel:`Save Settings`
96
97 If you encounter slow performance with server-side merging enabled, check the
98 speed at which your server is performing actions. When server-side merging is
99 enabled, the following actions occurs on the server.
100
101 * A |pr| is created in the database.
102 * A shadow |repo| is created as a working environment for the |pr|.
103 * On display, |RCE| checks if the |pr| can be merged.
104
105 To check how fast the shadow |repo| creation is occurring on your server, use
106 the following steps:
107
108 1. Log into your server and create a directory in your |repos| folder.
109 2. Clone a |repo| that is showing slow performance and time the action.
110
111 .. code-block:: bash
112
113 # One option is to use the time command
114 $ time hg clone SOURCE_REPO TARGET
115
116 .. _remap-rescan:
117
118 Remap and Rescan Repositories
119 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120
121 You may want to Remap and rescan the |repos| that |RCE| is managing to ensure
122 the system is always up-to-date. This is useful after importing, deleting,
123 or carrying out general cleaning up operations. To do this use the
124 following steps:
125
126 1. From the |RCE|, open
127 :menuselection:`Admin --> Settings --> Remap and rescan`
128 2. Click :guilabel:`Rescan Repositories`
129
130 Check the additional options if needed:
131
132 * :guilabel:`Destroy old data`: Useful for purging deleted repository
133 information from the database.
134 * :guilabel:`Invalidate cache for all repositories`: Use this to completely
135 remap all |repos|. Useful when importing or migrating |repos| to ensure all
136 new information is picked up.
137
138 .. _custom-hooks:
139
140 Adding Custom Hooks
141 ^^^^^^^^^^^^^^^^^^^
142
143 To add custom hooks to your instance, use the following steps:
144
145 1. Open :menuselection:`Admin --> Settings --> Hooks`
146 2. Add your custom hook details, you can use a file path to specify custom
147 hook scripts, for example: ``python:/path/to/custom_hook.py``
148 3. Select :guilabel:`Save`
149
150 Also, see the |RC| Extensions section of the :ref:`rc-tools` guide. |RC|
151 Extensions can be used to add additional hooks to your instance and comes
152 with a number of pre-built plugins if you chose to install them.
153
154 .. _clear-repo-cache:
155
156 Clearing |repo| cache
157 ^^^^^^^^^^^^^^^^^^^^^
158
159 If you need to clear the cache for a particular |repo|, use the following steps:
160
161 1. Open :menuselection:`Admin --> Repositories` and select :guilabel:`Edit`
162 beside the |repo| whose cache you wish to clear.
163 2. On the |repo| settings page, go to the :guilabel:`Caches` tab and select
164 :guilabel:`Invalidate repository cache`.
165
166 .. _set-lang:
167
168 Changing Default Language
169 ^^^^^^^^^^^^^^^^^^^^^^^^^
170
171 To change the default language of a |RCE| instance, change the language code
172 in the :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. To
173 do this, use the following steps.
174
175 1. Open the :file:`rhodecode.ini` file and set the required language code.
176
177 .. code-block:: ini
178
179 ## Optional Languages
180 ## en(default), de, fr, it, ja, pl, pt, ru, zh
181 lang = de
182
183 2. Restart the |RCE| instance and check that the language has been updated.
184
185 .. code-block:: bash
186
187 $ rccontrol restart enterprise-2
188 Instance "enterprise-2" successfully stopped.
189 Instance "enterprise-2" successfully started.
190
191 .. image:: ../images/language.png
192
193 .. _set-repo-pub:
194
195 Setting Repositories to Publish
196 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
197
198 To automatically promote your local |repos| to public after pushing to |RCE|,
199 enable the :guilabel:`Set repositories as publishing` option on the
200 :menuselection:`Admin --> Settings --> VCS` page.
201
202 .. note::
203
204 This option is enabled by default on most |RCE| versions, but if upgrading
205 from a 1.7.x version it could be disabled on upgrade due to inheriting
206 older default settings.
207
208 .. _ping:
209
210 Pinging the |RCE| Server
211 ^^^^^^^^^^^^^^^^^^^^^^^^
212
213 You can check the IP Address of your |RCE| instance using the
214 following URL: ``{instance-URL}/_admin/ping``.
215
216 .. code-block:: bash
217
218 $ curl https://your.rhodecode.url/_admin/ping
219 pong[rce-7880] => 203.0.113.23
220
221 .. _Markdown: http://daringfireball.net/projects/markdown/
222 .. _reStructured Text: http://docutils.sourceforge.net/docs/index.html
@@ -0,0 +1,114 b''
1 .. _apache-conf-eg:
2
3 Apache Configuration Examples
4 -----------------------------
5
6 Use the following example to securely configure your Apache HTTP virtual hosts
7 file.
8
9 .. code-block:: apache
10
11 <VirtualHost *:80>
12 ServerName hg.myserver.com
13 ServerAlias hg.myserver.com
14
15 <Proxy *>
16 Order allow,deny
17 Allow from all
18 </Proxy>
19
20 # important !
21 # Directive to properly generate url (clone url) for pylons
22
23 ProxyPreserveHost On
24
25 #rhodecode instance
26 ProxyPass / http://127.0.0.1:5000/
27 ProxyPassReverse / http://127.0.0.1:5000/
28
29 # Set strict HTTPS
30 Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
31
32 # Set x-frame options
33 Header always append X-Frame-Options SAMEORIGIN
34
35 # To enable https use line below
36 # SetEnvIf X-Url-Scheme https HTTPS=1
37
38 # Secure your Diffie-hellmann deployment
39 SSLProtocol all -SSLv2 -SSLv3
40 SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
41 SSLHonorCipherOrder on
42 SSLOpenSSLConfCmd DHParameters "{path to dhparams.pem}"
43
44 </VirtualHost>
45
46 Use the following example to configure Apache for a multi-node setup. The
47 timeout setting should be increased if you experience timeouts when working
48 with large |repos|.
49
50 .. code-block:: apache
51
52 #
53 # Timeout: The number of seconds before receives and sends time out.
54 #
55 Timeout 600
56
57 <VirtualHost *:80>
58
59 ProxyRequests off
60
61 #important !
62 #Directive to properly generate url (clone url) for pylons
63 ProxyPreserveHost On
64
65 ServerName your.rce.com
66 ServerAlias your.rce.com
67
68 <Proxy balancer://mycluster>
69 # WebHead1
70 BalancerMember http://10.58.1.171:10002 route=1
71 # WebHead2
72 BalancerMember http://10.58.1.172:10001 route=2
73
74 # Security "technically we aren't blocking
75 # anyone but this the place to make those
76 # chages
77 Order Deny,Allow
78 Deny from none
79 Allow from all
80
81 # Load Balancer Settings
82 # We will be configuring a simple Round
83 # Robin style load balancer. This means
84 # that all webheads take an equal share of
85 # of the load.
86 ProxySet stickysession=ROUTEID
87
88 </Proxy>
89
90 # balancer-manager
91 # This tool is built into the mod_proxy_balancer
92 # module and will allow you to do some simple
93 # modifications to the balanced group via a gui
94 # web interface.
95 <Location /balancer-manager>
96 SetHandler balancer-manager
97
98 # recommend locking this one down to your
99 # your office
100 Order deny,allow
101 Allow from all
102 </Location>
103
104 # Point of Balance
105 # This setting will allow to explicitly name the
106 # the location in the site that we want to be
107 # balanced, in this example we will balance "/"
108 # or everything in the site.
109 ProxyPass /balancer-manager !
110 ProxyPass / balancer://mycluster/
111
112 ProxyPassReverse / balancer://mycluster/
113
114 </VirtualHost>
@@ -0,0 +1,15 b''
1 .. _apache-ws-ref:
2
3 Apache HTTP Server Configuration
4 --------------------------------
5
6 To set up your Apache Web Server for optimal performance and security, use
7 the information in the following sections.
8
9 .. toctree::
10
11 apache-diffie-hellman
12 apache-conf-examples
13 apache-subdirectory
14 apache-reverse-proxy
15 apache-wsgi-coding
@@ -0,0 +1,34 b''
1 .. _dh-apache:
2
3 Diffie-Hellman Security
4 -----------------------
5
6 To secure your web server, the `Guide to Deploying Diffie-Hellman for TLS`_
7 contains important information worth reading. This link contains some good
8 `secure Apache configuration`_ examples.
9
10 To secure your deployment of Diffie-Hellman, configure the following:
11
12 1. Generate a strong Diffie-hellman group, 2048-bit or stronger.
13
14 .. code-block:: bash
15
16 # to generate your dhparam.pem file, run in the terminal
17 openssl dhparam -out /etc/apache/ssl/dhparam.pem 2048
18
19 2. Configure your server to only use modern, secure cipher suites in the
20 virtual hosts configuration file.
21
22 .. code-block:: apache
23
24 # Set the protocol to only use modern, secure cipher suites.
25 SSLProtocol all -SSLv2 -SSLv3
26 SSLHonorCipherOrder on
27 SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
28
29 # Specify your DH params file as follows
30 SSLOpenSSLConfCmd DHParameters "{path to dhparams.pem}"
31
32
33 .. _Guide to Deploying Diffie-Hellman for TLS: https://weakdh.org/sysadmin.html
34 .. _secure Apache configuration: http://www.apache-ssl.org/httpd.conf.example
@@ -0,0 +1,33 b''
1 Apache Reverse Proxy
2 ^^^^^^^^^^^^^^^^^^^^
3
4 Here is a sample configuration file for using Apache as a reverse proxy.
5
6 .. code-block:: apache
7
8 <VirtualHost *:80>
9 ServerName hg.myserver.com
10 ServerAlias hg.myserver.com
11
12 ## uncomment root directive if you want to serve static files by nginx
13 ## requires static_files = false in .ini file
14 DocumentRoot /path/to/installation/rhodecode/public
15
16 <Proxy *>
17 Order allow,deny
18 Allow from all
19 </Proxy>
20
21 #important !
22 #Directive to properly generate url (clone url) for pylons
23 ProxyPreserveHost On
24
25 #rhodecode instance
26 ProxyPass / http://127.0.0.1:5000/
27 ProxyPassReverse / http://127.0.0.1:5000/
28
29 #to enable https use line below
30 #SetEnvIf X-Url-Scheme https HTTPS=1
31
32 </VirtualHost>
33
@@ -0,0 +1,32 b''
1 .. _apache-sub-ref:
2
3 Apache URL Prefix Configuration
4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5
6 Use the following example to configure Apache to use a URL prefix.
7
8 .. code-block:: apache
9
10 <Location /<someprefix> > # Change <someprefix> into your chosen prefix
11 ProxyPass http://127.0.0.1:5000/<someprefix>
12 ProxyPassReverse http://127.0.0.1:5000/<someprefix>
13 SetEnvIf X-Url-Scheme https HTTPS=1
14 </Location>
15
16 In addition to the regular Apache setup you will need to add the following
17 lines into the ``rhodecode.ini`` file.
18
19 * In the the ``[app:main]`` section of your ``rhodecode.ini`` file add the
20 following line.
21
22 .. code-block:: ini
23
24 filter-with = proxy-prefix
25
26 * At the end of the ``rhodecode.ini`` file add the following section.
27
28 .. code-block:: ini
29
30 [filter:proxy-prefix]
31 use = egg:PasteDeploy#prefix
32 prefix = /<someprefix> # Change <someprefix> into your chosen prefix
@@ -0,0 +1,55 b''
1 .. _apache-wsgi-ref:
2
3 Apache WSGI Configuration
4 ^^^^^^^^^^^^^^^^^^^^^^^^^
5
6 |RCM| can also be set up with Apache under ``mod_wsgi``. To configure this
7 use the following steps.
8
9 1. Install ``mod_wsgi`` using the following command:
10 ``aptitude install libapache2-mod-wsgi``.
11 2. Enable ``mod_wsgi`` using the following command: ``a2enmod wsgi``
12 3. Create a ``wsgi`` dispatch script, using the following examples.
13
14 .. code-block:: bash
15
16 WSGIDaemonProcess pylons \
17 threads=4 \
18 # check the python virtual env location
19 python-path=/home/web/rhodecode/pyenv/lib/python2.6/site-packages
20 # Check the install location
21 WSGIScriptAlias / /home/web/rhodecode/dispatch.wsgi
22 WSGIPassAuthorization On
23 # user=www-data group=www-data # Enable if running Apache as root
24
25 .. note::
26
27 Do not set ``processes=num`` in this configuration file. Running |RCE| in
28 multiprocess mode with Apache is not supported.
29
30 The following is an example ``wsgi`` dispatch script.
31
32 .. code-block:: python
33
34 import os
35 os.environ["HGENCODING"] = "UTF-8"
36 os.environ['PYTHON_EGG_CACHE'] = '/home/web/rhodecode/.egg-cache'
37
38 # Set the current dir
39 os.chdir('/home/web/rhodecode/')
40
41 import site
42 site.addsitedir("/home/web/rhodecode/pyenv/lib/python2.6/site-packages")
43
44 from paste.deploy import loadapp
45 from paste.script.util.logging_config import fileConfig
46
47 fileConfig('/home/web/rhodecode/production.ini')
48 application = loadapp('config:/home/web/rhodecode/production.ini')
49
50 .. note::
51
52 When using `mod_wsgi` the same version of |hg| must be running in your
53 system's |PY| environment and on |RCM|. To check the |RCM| version,
54 on the interface go to
55 :menuselection:`Admin --> Settings --> System Info`
@@ -0,0 +1,127 b''
1 .. _backup-ref:
2
3 Backup and Restore
4 ==================
5
6 *“The condition of any backup is unknown until a restore is attempted.”*
7 `Schrödinger's Backup`_
8
9 To snapshot an instance of |RCE|, and save its settings, you need to backup the
10 following parts of the system at the same time.
11
12 * The |repos| managed by the instance.
13 * The |RCE| database.
14 * Any configuration files or extensions that you've configured.
15
16 .. important::
17
18 Ideally you should script all of these functions so that it creates a
19 backup snapshot of your system at a particular timestamp and then run that
20 script regularly.
21
22 Backup Details
23 --------------
24
25 To backup the relevant parts of |RCE| required to restore your system, use
26 the information in this section to identify what is important to you.
27
28 Repository Backup
29 ^^^^^^^^^^^^^^^^^
30
31 To back up your |repos|, use the API to get a list of all |repos| managed,
32 and then clone them to your backup location.
33
34 Use the ``get_repos`` method to list all your managed |repos|,
35 and use the ``clone_uri`` information that is returned. See the :ref:`api`
36 for more information.
37
38 .. important::
39
40 This will not work for |svn| |repos|. Currently the only way to back up
41 your |svn| |repos| is to make a copy of them.
42
43 It is also important to note, that you can only restore the |svn| |repos|
44 using the same version as they were saved with.
45
46 Database Backup
47 ^^^^^^^^^^^^^^^
48
49 The instance database contains all the |RCE| permissions settings,
50 and user management information. To backup your database,
51 export it using the following appropriate example, and then move it to your
52 backup location:
53
54 .. code-block:: bash
55
56 # For MySQL DBs
57 $ mysqldump -u <uname> -p <pass> db_name > mysql-db-backup
58
59 # For PostgreSQL DBs
60 $ pg_dump dbname > postgresql-db-backup
61
62 # For SQLlite
63 $ sqlite3 rhodecode.db ‘.dump’ > sqlite-db-backup
64
65
66 The default |RCE| SQLite database location is
67 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.db`
68
69 If running MySQL or PostgreSQL databases, you will have configured these
70 separately, for more information see :ref:`rhodecode-database-ref`
71
72 Configuration File Backup
73 ^^^^^^^^^^^^^^^^^^^^^^^^^
74
75 Depending on your setup, you could have a number of configuration files that
76 should be backed up. You may have some, or all of the configuration files
77 listed in the :ref:`config-rce-files` section. Ideally you should back these
78 up at the same time as the database and |repos|.
79
80 Gist Backup
81 ^^^^^^^^^^^
82
83 To backup the gists on your |RCE| instance you can use the ``get_users`` and
84 ``get_gists`` API methods to fetch the gists for each user on the instance.
85
86 Extension Backups
87 ^^^^^^^^^^^^^^^^^
88
89 You should also backup any extensions added in the
90 :file:`home/{user}/.rccontrol/{instance-id}/rcextensions` directory.
91
92 Full-text Search Backup
93 ^^^^^^^^^^^^^^^^^^^^^^^
94
95 You may also have full text search set up, but the index can be rebuild from
96 re-imported |repos| if necessary. You will most likely want to backup your
97 :file:`mapping.ini` file if you've configured that. For more information, see
98 the :ref:`indexing-ref` section.
99
100 Restoration Steps
101 -----------------
102
103 To restore an instance of |RCE| from its backed up components, use the
104 following steps.
105
106 1. Install a new instance of |RCE|.
107 2. Once installed, configure the instance to use the backed up
108 :file:`rhodecode.ini` file. Ensure this file points to the backed up
109 database, see the :ref:`config-database` section.
110 3. Restart |RCE| and remap and rescan your |repos|, see the
111 :ref:`remap-rescan` section.
112
113 Post Restoration Steps
114 ^^^^^^^^^^^^^^^^^^^^^^
115
116 Once you have restored your |RCE| instance to basic functionality, you can
117 then work on restoring any specific setup changes you had made.
118
119 * To recreate the |RCE| index, use the backed up :file:`mapping.ini` file if
120 you had made changes and rerun the indexer. See the
121 :ref:`indexing-ref` section for details.
122 * To reconfigure any extensions, copy the backed up extensions into the
123 :file:`/home/{user}/.rccontrol/{instance-id}/rcextensions` and also specify
124 any custom hooks if necessary. See the :ref:`integrations-ref` section for
125 details.
126
127 .. _Schrödinger's Backup: http://novabackup.novastor.com/blog/schrodingers-backup-good-bad-backup/
@@ -0,0 +1,23 b''
1 .. _clean-up-cmds:
2
3 |RCT| Clean Up Commands
4 =======================
5
6 |RCT| comes with a number of functions which can be used to administer your
7 |RCE| instances. Two of these can be used to automate the cleanup of gists
8 and |repos|
9
10 rhodecode-cleanup-gists
11 -----------------------
12
13 Use this command to delete gists within RhodeCode Enterprise. It takes a
14 number of options for specifying the kind of gists you want deleted, and it
15 is possible to run these commands from a cron job or cleanup script. For more
16 information, see the :ref:`tools-cli`
17
18 rhodecode-cleanup-repos
19 -----------------------
20
21 Use this command to delete |repos| from your |RCE| instances. It takes
22 a number of options specifying the kind of |repos| you want deleted. For more
23 information, see the :ref:`tools-cli`
@@ -0,0 +1,74 b''
1 .. _config-files:
2
3 Configuration Files Overview
4 ============================
5
6 |RCE| and |RCC| have a number of different configuration files. The following
7 is a brief explanation of each, and links to their associated configuration
8 sections.
9
10 .. rst-class:: dl-horizontal
11
12 \- **rhodecode.ini**
13 Default location:
14 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini`
15
16 This is the main |RCE| configuration file and controls much of its
17 default behaviour. It is also used to configure certain customer
18 settings. Here are some of the most common reasons to make changes to
19 this file.
20
21 * :ref:`config-database`
22 * :ref:`set-up-mail`
23 * :ref:`increase-gunicorn`
24 * :ref:`x-frame`
25
26 \- **mapping.ini**
27 Default location:
28 :file:`/home/{user}/.rccontrol/{instance-id}/mapping.ini`
29
30 This file is used to control the |RCE| indexer. It comes configured
31 to index your instance. To change the default configuration, see
32 :ref:`advanced-indexing`.
33
34 \- **vcsserver.ini**
35 Default location:
36 :file:`/home/{user}/.rccontrol/{vcsserver-id}/vcsserver.ini`
37
38 The VCS Server handles the connection between your |repos| and |RCE|.
39 See the :ref:`vcs-server` section for configuration options and more
40 detailed information.
41
42 \- **supervisord.ini**
43 Default location:
44 :file:`/home/{user}/.rccontrol/supervisor/supervisord.ini`
45
46 |RCC| uses Supervisor to monitor and manage installed instances of
47 |RCE| and the VCS Server. |RCC| will manage this file completely,
48 unless you install |RCE| in self-managed mode. For more information,
49 see the :ref:`Supervisor Setup<control:supervisor-setup>` section.
50
51 \- **.rccontrol.ini**
52 Default location: :file:`/home/{user}/.rccontrol.ini`
53
54 This file contains the instances that |RCC| starts at boot, which is all
55 by default, but for more information, see
56 the :ref:`Manually Start At Boot <control:set-start-boot>` section.
57
58 \- **.rhoderc**
59 Default location: :file:`/home/{user}/.rhoderc`
60
61 This file is used by the |RCE| API when accessing an instance from a
62 remote machine. The API checks this file for connection and
63 authentication details. For more details, see the :ref:`config-rhoderc`
64 section.
65
66 \- **MANIFEST**
67 Default location: :file:`/home/{user}/.rccontrol/cache/MANIFEST`
68
69 |RCC| uses this file to source the latest available builds from the
70 secure |RC| download channels. The only reason to mess with this file
71 is if you need to do an offline installation,
72 see the :ref:`Offline Installation<control:offline-installer-ref>`
73 instructions, otherwise |RCC| will completely manage this file.
74
@@ -0,0 +1,32 b''
1 .. _default-perms:
2
3 Default User Permissions
4 ------------------------
5
6 There are two ways in which the default user settings work:
7
8 System-wide Level
9 ^^^^^^^^^^^^^^^^^
10
11 On a system-wide level, you can set the default user permissions so that
12 all new users are given a certain set of permissions unless individually
13 tailored, or added to a user group. For more information about system-wide
14 default permissions, see the :ref:`permissions-info-anon-ref` and
15 :ref:`permissions-default-ref` sections.
16
17 User Group Level
18 ^^^^^^^^^^^^^^^^
19
20 On a user group level, you can set the default user settings for the user
21 group, and all users within that group will get those default permissions
22 unless individually tailored. For more information about setting default
23 permissions for all the different entities, see the
24 :ref:`permissions-default-ref` section.
25
26 For more detailed information about managing the different permissions
27 settings, see the following sections:
28
29 * :ref:`permissions-info-anon-ref`
30 * :ref:`permissions-add-user`
31 * :ref:`permissions-default-ref`
32 * :ref:`permissions-info-add-group-ref` No newline at end of file
@@ -0,0 +1,136 b''
1 .. _debug-mode:
2
3 Enabling Debug Mode
4 -------------------
5
6 To enable debug mode on a |RCE| instance you need to set the debug property
7 in the :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. To
8 do this, use the following steps
9
10 1. Open the file and set the ``debug`` line to ``true``
11 2. Restart you instance using the ``rccontrol restart`` command,
12 see the following example:
13
14 You can also set the log level, the follow are the valid options;
15 ``debug``, ``info``, ``warning``, or ``fatal``.
16
17 .. code-block:: ini
18
19 [DEFAULT]
20 debug = true
21 pdebug = false
22
23 .. code-block:: bash
24
25 # Restart your instance
26 $ rccontrol restart enterprise-1
27 Instance "enterprise-1" successfully stopped.
28 Instance "enterprise-1" successfully started.
29
30 Debug and Logging Configuration
31 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32
33 Further debugging and logging settings can also be set in the
34 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file.
35
36 In the logging section, the various packages that run with |RCE| can have
37 different debug levels set. If you want to increase the logging level change
38 ``level = DEBUG`` line to one of the valid options.
39
40 You also need to change the log level for handlers. See the example
41 ``##handler`` section below. The ``handler`` level takes the same options as
42 the ``debug`` level.
43
44 .. code-block:: ini
45
46 ################################
47 ### LOGGING CONFIGURATION ####
48 ################################
49 [loggers]
50 keys = root, routes, rhodecode, sqlalchemy, beaker, pyro4, templates, whoosh_indexer
51
52 [handlers]
53 keys = console, console_sql, file, file_rotating
54
55 [formatters]
56 keys = generic, color_formatter, color_formatter_sql
57
58 #############
59 ## LOGGERS ##
60 #############
61 [logger_root]
62 level = NOTSET
63 handlers = console
64
65 [logger_routes]
66 level = DEBUG
67 handlers =
68 qualname = routes.middleware
69 ## "level = DEBUG" logs the route matched and routing variables.
70 propagate = 1
71
72 [logger_beaker]
73 level = DEBUG
74 handlers =
75 qualname = beaker.container
76 propagate = 1
77
78 [logger_pyro4]
79 level = DEBUG
80 handlers =
81 qualname = Pyro4
82 propagate = 1
83
84 [logger_templates]
85 level = INFO
86 handlers =
87 qualname = pylons.templating
88 propagate = 1
89
90 [logger_rhodecode]
91 level = DEBUG
92 handlers =
93 qualname = rhodecode
94 propagate = 1
95
96 [logger_sqlalchemy]
97 level = INFO
98 handlers = console_sql
99 qualname = sqlalchemy.engine
100 propagate = 0
101
102 [logger_whoosh_indexer]
103 level = DEBUG
104 handlers =
105 qualname = whoosh_indexer
106 propagate = 1
107
108 ##############
109 ## HANDLERS ##
110 ##############
111
112 [handler_console]
113 class = StreamHandler
114 args = (sys.stderr,)
115 level = INFO
116 formatter = generic
117
118 [handler_console_sql]
119 class = StreamHandler
120 args = (sys.stderr,)
121 level = WARN
122 formatter = generic
123
124 [handler_file]
125 class = FileHandler
126 args = ('rhodecode.log', 'a',)
127 level = INFO
128 formatter = generic
129
130 [handler_file_rotating]
131 class = logging.handlers.TimedRotatingFileHandler
132 # 'D', 5 - rotate every 5days
133 # you can set 'h', 'midnight'
134 args = ('rhodecode.log', 'D', 5, 10,)
135 level = INFO
136 formatter = generic
@@ -0,0 +1,50 b''
1 .. _glossary:
2
3 Glossary
4 ========
5
6 .. glossary::
7
8 DVCS
9 Distributed Version Control System, usually referring to |git| or |hg|.
10
11 Extension
12 An extension extends the capabilities of, or the data available to,
13 an existing software application.
14
15 Full-text Search
16 Indexing all files and |repos| managed by |RCE| and
17 making this data searchable from the interface.
18
19 Gist
20 A note that can only be edited by the author and shared using its
21 link within others. The sharing permissions can be set during
22 its creation.
23
24 Gunicorn
25 A Python WSGI HTTP Server used by |RCE|.
26
27 Hook
28 A hook intercepts function calls, messages, or events passed between
29 software components and can be used to trigger plugins, or their
30 extensions.
31
32 Horizontal scaling
33 Adding more machines or workers into your pool of resources.
34
35 Instance
36 A single installed version of one of the |RC| products. It could
37 refer to |RCE| or the VCS server depending on the context.
38
39 Plugin
40 A Plugin is software that adds a specific feature to an existing
41 software application.
42
43 tmpfs
44 Temporary file storage kept in volatile memory instead of persistent
45 storage.
46
47 VCS Server
48 The VCS Server handles the abstraction layer between the
49 supported version control systems and RhodeCode Enterprise.
50
@@ -0,0 +1,235 b''
1 .. _indexing-ref:
2
3 Full-text Search
4 ----------------
5
6 By default |RCM| uses `Whoosh`_ to index |repos| and provide full-text search.
7 To run the indexer you need to use an |authtoken| with admin rights to all
8 |repos|.
9
10 To index new content added, you have the option to set the indexer up in a
11 number of ways, for example:
12
13 * Call the indexer via a cron job. We recommend running this nightly,
14 unless you need everything indexed immediately.
15 * Set the indexer to infinitely loop and reindex as soon as it has run its
16 cycle.
17 * Hook the indexer up with your CI server to reindex after each push.
18
19 The indexer works by indexing new commits added since the last run. If you
20 wish to build a brand new index from scratch each time,
21 use the ``force`` option in the configuration file.
22
23 .. important::
24
25 You need to have |RCT| installed, see :ref:`install-tools`. Since |RCE|
26 3.5.0 they are installed by default.
27
28 To set up indexing, use the following steps:
29
30 1. :ref:`config-rhoderc`, if running tools remotely.
31 2. :ref:`run-index`
32 3. :ref:`set-index`
33 4. :ref:`advanced-indexing`
34
35 .. _config-rhoderc:
36
37 Configure the ``.rhoderc`` File
38 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39
40 |RCT| uses the :file:`/home/{user}/.rhoderc` file for connection details
41 to |RCM| instances. If this file is not automatically created,
42 you can configure it using the following example. You need to configure the
43 details for each instance you want to index.
44
45 .. code-block:: bash
46
47 # Check the instance details
48 # of the instance you want to index
49 $ rccontrol status
50
51 - NAME: enterprise-1
52 - STATUS: RUNNING
53 - TYPE: Momentum
54 - VERSION: 1.5.0
55 - URL: http://127.0.0.1:10000
56
57 To get your API Token, on the |RCM| interface go to
58 :menuselection:`username --> My Account --> Auth tokens`
59
60 .. code-block:: ini
61
62 # Configure .rhoderc with matching details
63 # This allows the indexer to connect to the instance
64 [instance:enterprise-1]
65 api_host = http://127.0.0.1:10000
66 api_key = <auth token goes here>
67 repo_dir = /home/<username>/repos
68
69 .. _run-index:
70
71 Run the Indexer
72 ^^^^^^^^^^^^^^^
73
74 Run the indexer using the following command, and specify the instance you
75 want to index:
76
77 .. code-block:: bash
78
79 # From inside a virtualevv
80 (venv)$ rhodecode-index --instance-name=enterprise-1
81
82 # Using default installation
83 $ /home/user/.rccontrol/enterprise-4/profile/bin/rhodecode-index \
84 --instance-name=enterprise-4
85
86 # Using a custom mapping file
87 $ /home/user/.rccontrol/enterprise-4/profile/bin/rhodecode-index \
88 --instance-name=enterprise-4 \
89 --mapping=/home/user/.rccontrol/enterprise-4/mapping.ini
90
91 .. note::
92
93 |RCT| require |PY| 2.7 to run.
94
95 .. _set-index:
96
97 Schedule the Indexer
98 ^^^^^^^^^^^^^^^^^^^^
99
100 To schedule the indexer, configure the crontab file to run the indexer inside
101 your |RCT| virtualenv using the following steps.
102
103 1. Open the crontab file, using ``crontab -e``.
104 2. Add the indexer to the crontab, and schedule it to run as regularly as you
105 wish.
106 3. Save the file.
107
108 .. code-block:: bash
109
110 $ crontab -e
111
112 # The virtualenv can be called using its full path, so for example you can
113 # put this example into the crontab
114
115 # Run the indexer daily at 4am using the default mapping settings
116 * 4 * * * /home/ubuntu/.virtualenv/rhodecode-venv/bin/rhodecode-index \
117 --instance-name=enterprise-1
118
119 # Run the indexer every Sunday at 3am using default mapping
120 * 3 * * 0 /home/ubuntu/.virtualenv/rhodecode-venv/bin/rhodecode-index \
121 --instance-name=enterprise-1
122
123 # Run the indexer every 15 minutes
124 # using a specially configured mapping file
125 */15 * * * * ~/.rccontrol/enterprise-4/profile/bin/rhodecode-index \
126 --instance-name=enterprise-4 \
127 --mapping=/home/user/.rccontrol/enterprise-4/mapping.ini
128
129 .. _advanced-indexing:
130
131 Advanced Indexing
132 ^^^^^^^^^^^^^^^^^
133
134 |RCT| indexes based on the :file:`mapping.ini` file. To configure your index,
135 you can specify different options in this file. The default location is:
136
137 * :file:`/home/{user}/.rccontrol/{instance-id}/mapping.ini`, using default
138 |RCT|.
139 * :file:`~/venv/lib/python2.7/site-packages/rhodecode_tools/templates/mapping.ini`,
140 when using ``virtualenv``.
141
142 .. note::
143
144 If you need to create the :file:`mapping.ini` file, use the |RCT|
145 ``rhodecode-index --create-mapping path/to/file`` API call. For details,
146 see the :ref:`tools-cli` section.
147
148 The indexer runs in a random order to prevent a failing |repo| from stopping
149 a build. To configure different indexing scenarios, set the following options
150 inside the :file:`mapping.ini` and specify the altered file using the
151 ``--mapping`` option.
152
153 * ``index_files`` : Index the specified file types.
154 * ``skip_files`` : Do not index the specified file types.
155 * ``index_files_content`` : Index the content of the specified file types.
156 * ``skip_files_content`` : Do not index the content of the specified files.
157 * ``force`` : Create a fresh index on each run.
158 * ``max_filesize`` : Files larger than the set size will not be indexed.
159 * ``commit_parse_limit`` : Set the batch size when indexing commit messages.
160 Set to a lower number to lessen memory load.
161 * ``repo_limit`` : Set the maximum number or |repos| indexed per run.
162 * ``[INCLUDE]`` : Set |repos| you want indexed. This takes precedent over
163 ``[EXCLUDE]``.
164 * ``[EXCLUDE]`` : Set |repos| you do not want indexed. Exclude can be used to
165 not index branches, forks, or log |repos|.
166
167 At the end of the file you can specify conditions for specific |repos| that
168 will override the default values. To configure your indexer,
169 use the following example :file:`mapping.ini` file.
170
171 .. code-block:: ini
172
173 [__DEFAULT__]
174 # default patterns for indexing files and content of files.
175 # Binary files are skipped by default.
176
177 # Index python and markdown files
178 index_files = *.py, *.md
179
180 # Do not index these file types
181 skip_files = *.svg, *.log, *.dump, *.txt
182
183 # Index both file types and their content
184 index_files_content = *.cpp, *.ini, *.py
185
186 # Index file names, but not file content
187 skip_files_content = *.svg,
188
189 # Force rebuilding an index from scratch. Each repository will be rebuild
190 # from scratch with a global flag. Use local flag to rebuild single repos
191 force = false
192
193 # Do not index files larger than 385KB
194 max_filesize = 385KB
195
196 # Limit commit indexing to 500 per batch
197 commit_parse_limit = 500
198
199 # Limit each index run to 25 repos
200 repo_limit = 25
201
202 # __INCLUDE__ is more important that __EXCLUDE__.
203
204 [__INCLUDE__]
205 # Include all repos with these names
206
207 docs/* = 1
208 lib/* = 1
209
210 [__EXCLUDE__]
211 # Do not include the following repo in index
212
213 dev-docs/* = 1
214 legacy-repos/* = 1
215 *-dev/* = 1
216
217 # Each repo that needs special indexing is a separate section below.
218 # In each section set the options to override the global configuration
219 # parameters above.
220 # If special settings are not configured, the global configuration values
221 # above are inherited. If no special repositories are
222 # defined here RhodeCode will use the API to ask for all repositories
223
224 # For this repo use different settings
225 [special-repo]
226 commit_parse_limit = 20,
227 skip_files = *.idea, *.xml,
228
229 # For another repo use different settings
230 [another-special-repo]
231 index_files = *,
232 max_filesize = 800MB
233 commit_parse_limit = 20000
234
235 .. _Whoosh: https://pypi.python.org/pypi/Whoosh/
@@ -0,0 +1,41 b''
1 .. _lab-settings:
2
3 Lab Settings
4 ============
5
6 |RCE| Lab Settings is for delivering features which may require an additional
7 level of support to optimize for production scenarios. To enable lab settings,
8 use the following instructions:
9
10 1. Open the |RCE| configuration file,
11 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini`
12
13 2. Add the following configuration option in the ``[app:main]`` section.
14
15 .. code-block:: bash
16
17 [app:main]
18
19 ## Display extended labs settings
20 labs_settings_active = true
21
22 3. Restart your |RCE| instance
23
24 .. code-block:: bash
25
26 $ rccontrol restart enterprise-1
27
28 4. You will see the labs setting on the
29 :menuselection:`Admin --> Settings --> labs` page.
30
31 .. image:: ../images/lab-setting.png
32
33 Available Lab Extras
34 --------------------
35
36 Once lab settings are enabled, the following features are available.
37
38 .. toctree::
39 :maxdepth: 1
40
41 svn-http
@@ -0,0 +1,71 b''
1 Nginx Configuration Example
2 ---------------------------
3
4 Use the following example to configure Nginx as a your web server.
5
6 .. code-block:: nginx
7
8 upstream rc {
9
10 server 127.0.0.1:5000;
11
12 # add more instances for load balancing
13 # server 127.0.0.1:5001;
14 # server 127.0.0.1:5002;
15 }
16
17 ## gist alias
18
19 server {
20 listen 443;
21 server_name gist.myserver.com;
22 access_log /var/log/nginx/gist.access.log;
23 error_log /var/log/nginx/gist.error.log;
24
25 ssl on;
26 ssl_certificate gist.rhodecode.myserver.com.crt;
27 ssl_certificate_key gist.rhodecode.myserver.com.key;
28
29 ssl_session_timeout 5m;
30
31 ssl_protocols SSLv3 TLSv1;
32 ssl_ciphers DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5;
33 ssl_prefer_server_ciphers on;
34 add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
35
36 # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
37 ssl_dhparam /etc/nginx/ssl/dhparam.pem;
38
39 rewrite ^/(.+)$ https://rhodecode.myserver.com/_admin/gists/$1;
40 rewrite (.*) https://rhodecode.myserver.com/_admin/gists;
41 }
42
43 server {
44 listen 443;
45 server_name rhodecode.myserver.com;
46 access_log /var/log/nginx/rhodecode.access.log;
47 error_log /var/log/nginx/rhodecode.error.log;
48
49 ssl on;
50 ssl_certificate rhodecode.myserver.com.crt;
51 ssl_certificate_key rhodecode.myserver.com.key;
52
53 ssl_session_timeout 5m;
54
55 ssl_protocols SSLv3 TLSv1;
56 ssl_ciphers DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5;
57 ssl_prefer_server_ciphers on;
58
59 ## uncomment root directive if you want to serve static files by nginx
60 ## requires static_files = false in .ini file
61 # root /path/to/installation/rhodecode/public;
62
63 include /etc/nginx/proxy.conf;
64 location / {
65 try_files $uri @rhode;
66 }
67
68 location @rhode {
69 proxy_pass http://rc;
70 }
71 }
@@ -0,0 +1,14 b''
1 .. _nginx-ws-ref:
2
3 Nginx Configuration
4 ===================
5
6 To set up your Nginx Web Server for optimal performance and security, use
7 the information in the following sections.
8
9 .. toctree::
10
11 nginx-diffie-hellman
12 nginx-config-example
13 nginx-tuning
14 nginx-url-prefix
@@ -0,0 +1,34 b''
1 .. _dh-nginx:
2
3 Diffie-Hellman Security
4 -----------------------
5
6 To secure your web server, the `Guide to Deploying Diffie-Hellman for TLS`_
7 contains important information worth reading. This link contains a good
8 `nginx secure configuration`_ example. The documentation below also contains
9 good security settings with some additional |RCE| specific examples.
10
11 To secure your deployment of Diffie-Hellman, configure the following:
12
13 * Generate a strong Diffie-hellman group, 2048-bit or stronger.
14
15 .. code-block:: bash
16
17 # to generate your dhparam.pem file, run in the terminal
18 openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
19
20 * Configure your server to only use modern, secure cipher suites in the
21 virtual hosts configuration file.
22
23 .. code-block:: nginx
24
25 # Set the TLS protocols and to only use modern, secure cipher suites.
26 ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
27 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
28 ssl_prefer_server_ciphers on;
29
30 # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
31 ssl_dhparam /etc/nginx/ssl/dhparam.pem;
32
33 .. _Guide to Deploying Diffie-Hellman for TLS: https://weakdh.org/sysadmin.html
34 .. _nginx secure configuration: https://gist.github.com/plentz/6737338
@@ -0,0 +1,33 b''
1 .. _nginx-tuning:
2
3 Nginx Tuning
4 ------------
5
6 Set the following properties in your ``/etc/nginx/proxy.conf`` so it does not
7 timeout during large pushes.
8
9 .. code-block:: nginx
10
11 proxy_redirect off;
12 proxy_set_header Host $host;
13
14 ## needed for container auth
15 # proxy_set_header REMOTE_USER $remote_user;
16 # proxy_set_header X-Forwarded-User $remote_user;
17
18 proxy_set_header X-Url-Scheme $scheme;
19 proxy_set_header X-Host $http_host;
20 proxy_set_header X-Real-IP $remote_addr;
21 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
22 proxy_set_header Proxy-host $proxy_host;
23 proxy_buffering off;
24 proxy_connect_timeout 7200;
25 proxy_send_timeout 7200;
26 proxy_read_timeout 7200;
27 proxy_buffers 8 32k;
28 # Set this to a larger number if you experience timeouts
29 client_max_body_size 1024m;
30 client_body_buffer_size 128k;
31 large_client_header_buffers 8 64k;
32 add_header X-Frame-Options SAMEORIGIN;
33 add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
@@ -0,0 +1,33 b''
1 .. _nginx_url-pre:
2
3 Nginx URL Prefix Configuration
4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5
6 Use the following example to configure Nginx to use a URL prefix.
7
8 .. code-block:: nginx
9
10 location /foo {
11 rewrite /foo(.*) /$1 break;
12 proxy_pass http://localhost:3200;
13 proxy_redirect off;
14 proxy_set_header Host $host;
15 }
16
17 In addition to the Nginx configuration you will need to add the following
18 lines into the ``rhodecode.ini`` file.
19
20 * In the the ``[app:main]`` section of your ``rhodecode.ini`` file add the
21 following line.
22
23 .. code-block:: ini
24
25 filter-with = proxy-prefix
26
27 * At the end of the ``rhodecode.ini`` file add the following section.
28
29 .. code-block:: ini
30
31 [filter:proxy-prefix]
32 use = egg:PasteDeploy#prefix
33 prefix = /<someprefix> # Change <someprefix> into your chosen prefix
@@ -0,0 +1,12 b''
1 .. _public-access:
2
3 Public Access
4 -------------
5
6 By default |RCM| allows users to read all **public** |repos|. User
7 permissions and |repo| access can be configured explicitly,
8 and those permissions will override any default settings. The default
9 settings can be found under the following section:
10
11 * :menuselection:`Admin --> Permissions --> Object`
12 * :menuselection:`Admin --> Permissions --> Global`
@@ -0,0 +1,68 b''
1 .. _repo-xtra:
2
3 Repository Extra Fields
4 =======================
5
6 Extra fields attached to a |repo| allow you to configure additional actions for
7 |RCX|. To install and read more about |RCX|, see the :ref:`install-rcx` section.
8
9 Enabling Extra Fields
10 ---------------------
11
12 To enable extra fields on |repos|, use the following steps:
13
14 1. Go to the :menuselection:`Admin --> Settings --> Visual` page.
15 2. Check the :guilabel:`Use repository extra fields` box.
16 3. Save your changes.
17
18
19 Configuring Extra Fields
20 ------------------------
21
22 To configure extra fields per repository, use the following steps:
23
24 1. Go to :menuselection:`Admin --> Repositories` and select :guilabel:`Edit`
25 beside the |repo| to which you wish to add extra fields.
26 2. On the |repo| settings page, select the :guilabel:`Extra fields` tab.
27
28 .. image:: ../images/extra-repo-fields.png
29
30
31 Example Usage
32 -------------
33
34 To use the extra fields in an extension, see the example below. For more
35 information and examples, see the :ref:`integrations-ref` section.
36
37 .. code-block:: python
38
39 call = load_extension('http_notify.py')
40 if call:
41 url = 'http://default.url' # <url for post data>
42
43 # possibly extract the URL from extra fields
44 call = load_extension('extra_fields.py')
45 if call:
46 repo_extra_fields = call(**kwargs)
47 # now update if we have extra fields, they have precedence
48 # this way users can store any configuration inside the database per
49 # repo
50 for key, data in repo_extra_fields.items():
51 kwargs[key] = data['field_value']
52
53 # an endpoint url data will be sent to, fetched from extra fields
54 # if exists, or fallback to default
55 kwargs['URL'] = kwargs.pop('webhook_url', None) or url
56
57 # fetch pushed commits, from commit_ids list
58 call = load_extension('extract_commits.py')
59 extracted_commits = {}
60 if call:
61 extracted_commits = call(**kwargs)
62 # store the commits for the next call chain
63 kwargs['COMMITS'] = extracted_commits
64
65 # set additional keys and values to be sent via POST to given URL
66 kwargs['caller_type'] = 'rhodecode'
67 kwargs['date'] = time.time() # import time before
68 call(**kwargs)
@@ -0,0 +1,56 b''
1 .. _repo-hooks:
2
3 |RCE| Repository Hooks
4 ======================
5
6 |RCE| installs hooks inside each of the |repos| that it manages. These
7 hooks enable users to execute custom actions based on certain events.
8 This is the complete list of |repos| hooks and the events which trigger them:
9
10 .. rst-class:: dl-horizontal
11
12 \--CREATE_REPO_HOOK
13 Any time a |repo| is created.
14
15 \--CREATE_REPO_GROUP_HOOK
16 Any time a |repo| group is created.
17
18 \--CREATE_USER_HOOK
19 Any time a user is created.
20
21 \--DELETE_REPO_HOOK
22 Any time a |repo| is created.
23
24 \--DELETE_USER_HOOK
25 Any time a user is deleted.
26
27 \--PRE_CREATE_USER_HOOK
28 Any time a user is created but before the action is executed by |RCE|.
29
30 \--PRE_PULL
31 Any pull from a |repo| but before the action is executed by |RCE|.
32
33 \--PRE_PUSH
34 Any push to a |repo| but before the action is executed by |RCE|.
35
36 \--POST_PUSH
37 After any push to a |repo|.
38
39 \--PUSH_HOOK
40 Any push to a |repo|, including editing tags or branches.
41 Commits via API actions that update references are also counted.
42
43 \--PULL_HOOK
44 Any pull from a Repository.
45
46 Using Repository Hooks
47 ----------------------
48
49 To use these hooks you need to install |RCX|. For more information, see the
50 :ref:`install-rcx` section.
51
52 Creating Extensions
53 -------------------
54
55 To create your own extensions using these hooks, see the :ref:`dev-plug`
56 section.
@@ -0,0 +1,30 b''
1 .. _repo-it:
2
3 Repository Issue Tracker
4 ========================
5
6 You can set an issue tracker connection in two ways with |RCE|.
7
8 * At instance level, for more information see the
9 :ref:`rhodecode-issue-trackers-ref` section.
10 * At |repo| level. This allows you to configure a |repo| to use a different
11 issue tracker to the default one.
12
13 Set an Issue Tracker per Repository
14 -----------------------------------
15
16 To configure a |repo| to work with a different issue tracker to the default one,
17 use the following steps:
18
19 1. Open :menuselection:`Admin --> Repositories --> repo name --> Edit --> Issue Tracker`
20 2. Uncheck the :guilabel:`Inherit from default settings` box.
21 3. Click :guilabel:`Add New`.
22 4. Fill in the following settings:
23
24 * :guilabel:`Description`: A name for this set of rules.
25 * :guilabel:`Pattern`: The regular expression that will match issues
26 tagged in commit messages, or more see :ref:`issue-tr-eg-ref`.
27 * :guilabel:`URL`: The URL to your issue tracker.
28 * :guilabel:`Prefix`: The prefix with which you want to mark issues.
29
30 5. Click :guilabel:`Save`.
@@ -0,0 +1,45 b''
1 .. _set-repo-perms:
2
3 Setting Repository Permissions
4 ------------------------------
5
6 To set the permissions on an individual |repo|, use the following steps:
7
8 1. Open :menuselection:`Admin --> Repositories` and select
9 :guilabel:`edit` beside the |repo| you wish to configure.
10 2. On the |repo| settings page you will see a number of tabs. Exploring these
11 you will find the following main configuration options for a |repo|.
12 3. Once you make changes, select :guilabel:`Save`
13
14 * :guilabel:`Repository group`: Lets you to add a |repo| to a |repo| group.
15 * :guilabel:`Owner`: Lets you change the |repo| owner. Useful when users are
16 moving roles within an organisation.
17 * :guilabel:`Enable automatic locking`: For more information,
18 see :ref:`repo-locking`
19 * :guilabel:`User Access`: On the permissions tab you can add users,
20 or user groups, and set the permissions each has for that |repo|.
21 * :guilabel:`Invalidate repository cache`: On the Caches tab you can delete
22 the |repo| cache, sometimes needed when mirroring.
23
24 .. _set-repo-group-perms:
25
26 Setting Repository Group Permissions
27 ------------------------------------
28
29 To set the permissions on a Repository Group, use the following steps:
30
31 1. Open :menuselection:`Admin --> Repository groups` and select
32 :guilabel:`edit` beside the |repo| you wish to configure.
33 2. On the |repo| group settings page you will see a number of tabs. Exploring
34 these you will find the following main configuration options:
35
36 * :guilabel:`Owner`: Lets you change the group owner. Useful when users are
37 moving roles within an organisation.
38 * :guilabel:`Group parent`: Lets you add the |repo| group as a sub-group
39 of a larger group, i.e. :guilabel:`QA-Repos >> QA-Repos-Berlin`
40 * :guilabel:`Enable automatic locking`: For more information,
41 see :ref:`repo-locking`
42 * :guilabel:`User Access`: On the permissions tab you can add users,
43 or user groups, and set the permissions each has for that |repo| group.
44 * :guilabel:`Add Child Group`: Allows you to add sub-repository-groups
45 that will all share the same permissions.
@@ -0,0 +1,48 b''
1 .. _per-repo-vcs:
2
3 Repository VCS Settings
4 =======================
5
6 You can configure |repo| VCS (Version Control System) settings at a global
7 level, and individually per |repo|. Global settings are applied by default.
8 If you configure individual settings per |repo|, these will remain unaffected
9 by any subsequent global changes.
10
11 Set Global Repository Settings
12 ------------------------------
13
14 To configure |repo| settings across your |RCE| instance use the following steps:
15
16 1. Go to to the :menuselection:`Admin --> Settings --> VCS` page.
17 2. Configure the following |repo| options:
18
19 * :guilabel:`Web`: Require SSL if necessary.
20 * :guilabel:`Hooks`: Enable built in hooks.
21 * :guilabel:`Mercurial Settings`: Configure |hg| specific settings.
22 * :guilabel:`Repositories Location`: Set the file system |repos| location.
23 * :guilabel:`Subversion Settings`: Configure |svn| specific settings.
24 * :guilabel:`Pull Request Settings`: Enable the listed additional |pr|
25 features.
26
27 3. Click :guilabel:`Save`.
28
29
30 Set Individual Repository Settings
31 ----------------------------------
32
33 To configure specific VCS settings for an individual |repo|, use the following
34 steps:
35
36 1. Go to to the :menuselection:`Admin --> Repositories --> Edit --> VCS` page.
37 2. Uncheck the :guilabel:`Inherit from global settings` box.
38 3. Configure the following |repo| options:
39
40 * :guilabel:`Hooks`: Enable built in hooks.
41 * :guilabel:`Mercurial Settings` (|hg| Only): Configure |hg| specific
42 settings.
43 * :guilabel:`Subversion Settings` (|svn| Only): Configure |svn| specific
44 settings.
45 * :guilabel:`Pull Request Settings` (|git| and |hg| Only): Enable the
46 listed additional |pr| features.
47
48 3. Click :guilabel:`Save`.
@@ -0,0 +1,95 b''
1 .. _rhodecode-reset-ref:
2
3 Settings Management
4 -------------------
5
6 All |RCE| settings can be set from the user interface, but in the event that
7 it somehow becomes unavailable you can use ``ishell`` inside your |RCE|
8 ``virtualenv`` to carry out emergency measures.
9
10 .. warning::
11
12 Logging into the |RCE| database with ``iShell`` should only be done by an
13 experienced and knowledgeable database administrator.
14
15 Reset Admin Account Privileges
16 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17
18 If you accidentally remove your admin privileges from the admin account you
19 can restore them using ``ishell``. Use the following example to reset your
20 account permissions.
21
22 .. code-block:: bash
23
24 # Open iShell from the terminal
25 $ .rccontrol/enterprise-5/profile/bin/paster \
26 ishell .rccontrol/enterprise-5/rhodecode.ini
27
28 .. code-block:: mysql
29
30 # Use this example to change user permissions
31 In [1]: adminuser = User.get_by_username('username')
32 In [2]: adminuser.admin = True
33 In [3]: Session.add(adminuser);Session().commit()
34 In [4]: exit()
35
36 Set to read global ``.hgrc`` file
37 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38
39 By default, |RCE| does not read global ``hgrc`` files in
40 ``/etc/mercurial/hgrc`` or ``/etc/mercurial/hgrc.d`` because it
41 can lead to issues. This is set in the ``rhodecode_ui`` table for which
42 there is no UI. If you need to edit this you can
43 manually change the settings using SQL statements with ``ishell``. Use the
44 following example to make changes to this table.
45
46 .. code-block:: bash
47
48 # Open iShell from the terminal
49 $ .rccontrol/enterprise-5/profile/bin/paster \
50 ishell.rccontrol/enterprise-5/rhodecode.ini
51
52 .. code-block:: mysql
53
54 # Use this example to enable global .hgrc access
55 In [4]: new_option = RhodeCodeUi()
56 In [5]: new_option.ui_section='web'
57 In [6]: new_option.ui_key='allow_push'
58 In [7]: new_option.ui_value='*'
59 In [8]: Session().add(new_option);Session().commit()
60
61 Manually Reset Password
62 ^^^^^^^^^^^^^^^^^^^^^^^
63
64 If you need to manually reset a user password, use the following steps.
65
66 1. Navigate to your |RCE| install location.
67 2. Run the interactive ``ishell`` prompt.
68 3. Set a new password.
69
70 Use the following code example to carry out these steps.
71
72 .. code-block:: bash
73
74 # starts the ishell interactive prompt
75 $ .rccontrol/enterprise-5/profile/bin/paster \
76 ishell .rccontrol/enterprise-5/rhodecode.ini
77
78 .. code-block:: mysql
79
80 from rhodecode.lib.auth import generate_auth_token
81 from rhodecode.lib.auth import get_crypt_password
82
83 # Enter the user name whose password you wish to change
84 my_user = 'USERNAME'
85 u = User.get_by_username(my_user)
86
87 # If this fails then the user does not exist
88 u.auth_token = generate_auth_token(my_user)
89
90 # Set the new password
91 u.password = get_crypt_password('PASSWORD')
92
93 Session().add(u)
94 Session().commit()
95 exit
@@ -0,0 +1,26 b''
1 .. _backup:
2
3 ====================
4 Backing up RhodeCode
5 ====================
6
7
8 Settings
9 --------
10
11 Just copy your .ini file, it contains all RhodeCode settings.
12
13 Whoosh index
14 ------------
15
16 Whoosh index is located in **/data/index** directory where you installed
17 RhodeCode ie. the same place where the ini file is located
18
19
20 Database
21 --------
22
23 When using sqlite just copy rhodecode.db.
24 Any other database engine requires a manual backup operation.
25
26 Database backup will contain all gathered statistics No newline at end of file
@@ -0,0 +1,31 b''
1 .. _instance-basics:
2
3 3 Basic User Security Steps
4 ===========================
5
6 By implementing the following user configuration tasks, you will help to
7 secure your |RCE| instances.
8
9
10 Define the Instance Wide Default User
11 -------------------------------------
12
13 The default user settings are applied across the whole instance. You should
14 define the default user so that newly created users immediately have
15 permission settings attached to their profile. For more information about
16 defining the default user settings, see the :ref:`default-perms` section.
17
18 Configure Specific User Groups
19 ------------------------------
20
21 By defining user groups, it allows you to put users into them and
22 have the group permissions applied to their profile. For more information about
23 defining the default user settings, see the :ref:`user-admin-set` section.
24
25 Define the Default User in Each Group
26 -------------------------------------
27
28 Apart from the system wide user permissions, each user group can apply its
29 settings to the default user permissions within the scope of the group. To
30 set the default user's permissions inside a user group, see the
31 :ref:`permissions-info-repo-group-access` section.
@@ -0,0 +1,19 b''
1 .. _settip-ip-white:
2
3 Setting IP Restrictions
4 =======================
5
6 To restrict access to your |RCE| instance you can set an IP Whitelist that
7 will only allow access from specific IP Addresses. This is useful for
8 ensuring only users on the company VPN can access the instance.
9
10 To set this, go to
11 :menuselection:`Username --> Permissions --> IP Whitelist`, and add the safe
12 range of IP Addresses to the list.
13
14 .. important::
15
16 Add the IP Address that you are currently using first,
17 otherwise you'll lock yourself out of the instance.
18
19 .. image:: ../images/ip-whitey.png
@@ -0,0 +1,57 b''
1 .. _x-frame:
2
3 Securing HTTPS Connections
4 --------------------------
5
6 * To secure your |RCE| instance against `Cross Frame Scripting`_ exploits, you
7 should configure your webserver ``x-frame-options`` setting.
8
9 * To configure your instance for `HTTP Strict Transport Security`_, you need to
10 configure the ``Strict-Transport-Security`` setting.
11
12 Nginx
13 ^^^^^
14
15 In your nginx configuration, add the following lines in the correct files. For
16 more detailed information see the :ref:`nginx-ws-ref` section.
17
18 .. code-block:: nginx
19
20 # Add this line to the nginx.conf file
21 add_header X-Frame-Options SAMEORIGIN;
22
23 # This line needs to be added inside your virtual hosts block/file
24 add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
25
26 Apache
27 ^^^^^^
28
29 In your :file:`apache2.conf` file, add the following line. For more detailed
30 information see the :ref:`apache-ws-ref` section.
31
32 .. code-block:: apache
33
34 # Add this to your virtual hosts file
35 Header always append X-Frame-Options SAMEORIGIN
36
37 # Add this line in your virtual hosts file
38 Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
39
40 |RCE| Configuration
41 ^^^^^^^^^^^^^^^^^^^
42
43 |RCE| can also be configured to force strict *https* connections and Strict
44 Transport Security. To set this, configure the following options to ``true``
45 in the :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file.
46
47 .. code-block:: ini
48
49 ## force https in RhodeCode, fixes https redirects, assumes it's always https
50 force_https = false
51
52 ## use Strict-Transport-Security headers
53 use_htsts = false
54
55
56 .. _Cross Frame Scripting: https://www.owasp.org/index.php/Cross_Frame_Scripting
57 .. _HTTP Strict Transport Security: https://www.owasp.org/index.php/HTTP_Strict_Transport_Security No newline at end of file
@@ -0,0 +1,179 b''
1 .. _sec-your-server:
2
3 Securing Your Server
4 --------------------
5
6 |RCE| runs on your hardware, and while it is developed with security in mind
7 it is also important that you ensure your servers are well secured. In this
8 section we will cover some basic security practices that are best to
9 configure when setting up your |RCE| instances.
10
11 SSH Keys
12 ^^^^^^^^
13
14 Using SSH keys to access your server provides more security than using the
15 standard username and password combination. To set up your SSH Keys, use the
16 following steps:
17
18 1. On your local machine create the public/private key combination. The
19 private key you will keep, and the matching public key is copied to the
20 server. Setting a passphrase here is optional, if you set one you will
21 always be prompted for it when logging in.
22
23 .. code-block:: bash
24
25 # Generate SSH Keys
26 user@ubuntu:~$ ssh-keygen -t rsa
27
28 .. code-block:: bash
29
30 Generating public/private rsa key pair.
31 Enter file in which to save the key (/home/user/.ssh/id_rsa):
32 Created directory '/home/user/.ssh'.
33 Enter passphrase (empty for no passphrase):
34 Enter same passphrase again:
35 Your identification has been saved in /home/user/.ssh/id_rsa.
36 Your public key has been saved in /home/user/.ssh/id_rsa.pub.
37 The key fingerprint is:
38 02:82:38:95:e5:30:d2:ad:17:60:15:7f:94:17:9f:30 user@ubuntu
39 The key's randomart image is:
40 +--[ RSA 2048]----+
41
42 2. SFTP to your server, and copy the public key to the ``~/.ssh`` folder.
43
44 .. code-block:: bash
45
46 # SFTP to your server
47 $ sftp user@hostname
48
49 # copy your public key
50 sftp> mput /home/user/.ssh/id_rsa.pub /home/user/.ssh
51 Uploading /home/user/.ssh/id_rsa.pub to /home/user/.ssh/id_rsa.pub
52 /home/user/.ssh/id_rsa.pub 100% 394 0.4KB/s 00:00
53
54 3. On your server, add the public key to the :file:`~/.ssh/authorized_keys`
55 file.
56
57 .. code-block:: bash
58
59 $ cat /home/user/.ssh/id_rsa.pub > /home/user/.ssh/authorized_keys
60
61 You should now be able to log into your server using your SSH
62 Keys. If you've added a passphrase you'll be asked for it. For more
63 information about using SSH keys with |RCE| |repos|, see the
64 :ref:`ssh-connection` section.
65
66 VPN Whitelist
67 ^^^^^^^^^^^^^
68
69 Most company networks will have a VPN. If you need to set one up, there are
70 many tutorials online for how to do that. Getting it right requires good
71 knowledge and attention to detail. Once set up, you can configure your
72 |RCE| instances to only allow user access from the VPN, to do this see the
73 :ref:`settip-ip-white` section.
74
75 Public Key Infrastructure and SSL/TLS Encryption
76 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
77
78 Public key infrastructure (PKI) is a system that creates, manages, and
79 validates certificates for identifying nodes on a network and encrypting
80 communication between them. SSL or TLS certificates can be used to
81 authenticate different entities with one another. To read more about PKIs,
82 see the `OpenSSL PKI tutorial`_ site, or this `Cloudflare PKI post`_.
83
84 If the network you are running is SSL/TLS encrypted, you can configure |RCE|
85 to always use secure connections using the ``force_https`` and ``use_htsts``
86 options in the :file:`/home/user/.rccontrol/instance-id/rhodecode.ini` file.
87 For more details, see the :ref:`x-frame` section.
88
89 FireWalls and Ports
90 ^^^^^^^^^^^^^^^^^^^
91
92 Setting up a network firewall for your internal traffic is a good way
93 of keeping it secure by blocking off any ports that should not be used.
94 Additionally, you can set non-default ports for certain functions which adds
95 an extra layer of security to your setup.
96
97 A well configured firewall will restrict access to everything except the
98 services you need to remain open. By exposing fewer services you reduce the
99 number of potential vulnerabilities.
100
101 There are a number of different firewall solutions, but for most Linux systems
102 using the built in `IpTables`_ firewall should suffice. On BSD systems you
103 can use `IPFILTER`_ or `IPFW`_. Use the following examples, and the IpTables
104 documentation to configure your IP Tables on Ubuntu.
105
106 Changing the default SSH port.
107
108 .. code-block:: bash
109
110 # Open SSH config file and change to port 10022
111 vi /etc/ssh/sshd_config
112
113 # What ports, IPs and protocols we listen for
114 Port 10022
115
116 Setting IP Table rules for SSH traffic. It is important to note that the
117 default policy of your IpTables can differ and it is worth checking how each
118 is configured. The options are *ACCEPT*, *REJECT*, *DROP*, or *LOG*. The
119 usual practice is to block access on all ports and then enable access only on
120 the ports you with to expose.
121
122 .. code-block:: bash
123
124 # Check iptables policy
125 $ sudo iptables -L
126
127 Chain INPUT (policy ACCEPT)
128 target prot opt source destination
129
130 Chain FORWARD (policy ACCEPT)
131 target prot opt source destination
132
133 Chain OUTPUT (policy ACCEPT)
134 target prot opt source destination
135
136 # Close all ports by default
137 $ sudo iptables -P INPUT DROP
138
139 $ sudo iptables -L
140 Chain INPUT (policy DROP)
141 target prot opt source destination
142 DROP all -- anywhere anywhere
143
144 Chain FORWARD (policy ACCEPT)
145 target prot opt source destination
146
147 Chain OUTPUT (policy ACCEPT)
148 target prot opt source destination
149
150 .. code-block:: bash
151
152 # Deny outbound SSH traffic
153 sudo iptables -A OUTPUT -p tcp --dport 10022 -j DROP
154
155 # Allow incoming SSH traffic on port 10022
156 sudo iptables -A INPUT -p tcp --dport 10022 -j ACCEPT
157
158 # Allow incoming HTML traffic on port 80 and 443
159 iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
160 iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
161
162 Saving your IP Table rules, and restoring them from file.
163
164 .. code-block:: bash
165
166 # Save you IP Table Rules
167 iptables-save
168
169 # Save your IP Table Rules to a file
170 sudo sh -c "iptables-save > /etc/iptables.rules"
171
172 # Restore your IP Table rules from file
173 iptables-restore < /etc/iptables.rules
174
175 .. _OpenSSL PKI tutorial: https://pki-tutorial.readthedocs.org/en/latest/#
176 .. _Cloudflare PKI post: https://blog.cloudflare.com/how-to-build-your-own-public-key-infrastructure/
177 .. _IpTables: https://help.ubuntu.com/community/IptablesHowTo
178 .. _IPFW: https://www.freebsd.org/doc/handbook/firewalls-ipfw.html
179 .. _IPFILTER: https://www.freebsd.org/doc/handbook/firewalls-ipf.html
@@ -0,0 +1,15 b''
1 .. _sec-tips:
2
3 =============
4 Security Tips
5 =============
6
7 The following section contains security tips for ensuring your |RCE|
8 instances are configured in as secure a manner as possible.
9
10 .. toctree::
11
12 sec-your-server
13 sec-x-frame
14 sec-instance-basics
15 sec-ip-white
@@ -0,0 +1,69 b''
1 .. _permissions-default-ref:
2
3 Setting Default Permissions
4 ---------------------------
5
6 Default permissions allow you to configure |RCM| so that when a new |repo|, user group,
7 or user is created their permissions are already defined. To set default permissions you need administrator
8 privileges. See the following sections for setting up your permissions system:
9
10 * :ref:`user-default-ref`
11 * :ref:`user-group-default-ref`
12 * :ref:`repo-default-ref`
13 * :ref:`repo-group-default-ref`
14
15 .. _user-default-ref:
16
17 Setting User defaults
18 ^^^^^^^^^^^^^^^^^^^^^
19
20 To set default user permissions, use the following steps.
21
22 1. From the |RCM| interface, select :menuselection:`Admin --> Permissions`
23 2. Select the :guilabel:`Global` tab from the left-hand menu. The permissions
24 set on this screen apply to users and user-groups across the whole instance.
25 3. Save your changes
26
27 .. _user-group-default-ref:
28
29 Setting User Group defaults
30 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
31
32 To set default user group permissions, use the following steps.
33
34 1. From the |RCM| interface, select :menuselection:`Admin --> User groups`
35 2. Select :guilabel:`Permissions`, and configure the default user
36 permissions. All users will get these permissions unless
37 individually set.
38 3. Select :guilabel:`Global permissions`, and if you wish to configure
39 non-standard behaviour, uncheck the
40 :guilabel:`inherit from default settings` box and configure the desired
41 permissions
42 4. Save your changes
43
44 .. _repo-default-ref:
45
46 Setting Repository defaults
47 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
48
49 To set default |repo| permissions, use the following steps.
50
51 1. From the |RCM| interface, select :menuselection:`Admin --> Permissions`
52 2. Select the :guilabel:`Object` tab from the left-hand menu and set the
53 |perm| permissions
54 3. Save your changes
55
56 .. _repo-group-default-ref:
57
58 Setting Repository Group defaults
59 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
60
61 To set default Repository Group permissions, use the following steps.
62
63 1. From the |RCM| interface, select :menuselection:`Admin --> Repository Groups`
64 2. Select :guilabel:`Edit` beside the |repo| group you wish to configure
65 3. On the left-hand pane select :guilabel:`Permissions`
66 4. Set the default permissions for all |repos| created in this group
67 5. Save your changes
68
69 .. |perm| replace:: :guilabel:`None, Read, Write, or Admin`
@@ -0,0 +1,26 b''
1 .. _permissions-info-add-group-ref:
2
3 Repository Administration
4 =========================
5
6 Repository permissions in |RCM| can be managed in a number of different ways.
7 This overview should give you an insight into how you could adopt particular
8 settings for your needs:
9
10 * Global |repo| permissions: This allows you to set the default permissions
11 for each new |repo| created within |RCM|, see :ref:`repo-default-ref`. All
12 |repos| created will inherit these permissions unless explicitly configured.
13 * Individual |repo| permissions: To set individual |repo| permissions,
14 see :ref:`set-repo-perms`.
15 * Repository Group permissions: This allows you to define the permissions for
16 a group, and all |repos| created within that group will inherit the same
17 permissions.
18
19 .. toctree::
20
21 repo-perm-steps
22 repo-extra-fields
23 repo-hooks
24 repo-issue-tracker
25 repo-vcs
26
@@ -0,0 +1,25 b''
1 .. _permissions-info-repo-group-access:
2
3 Setting User Group Permissions
4 ------------------------------
5
6 To set User Group |repo| permissions, use follow these steps:
7
8 1. From the |RCE| interface, select
9 :menuselection:`Admin --> User Group --> Add User Group`
10 2. Enter a group name and description, and select :guilabel:`Save`
11 3. Select :guilabel:`edit` beside the new User Group. On the following
12 screen you will see a number of tabs. Exploring these
13 you will find the following most used options:
14
15 * :guilabel:`Owner`: This allows you to change the User Group owner. As
16 super-admin you will still have access to this, but changing the owner lets
17 you delegate the user group management to another manager.
18 * :guilabel:`Members`: This allows you to added or remove users from the
19 group.
20 * :guilabel:`User Permissions`: On the permissions tab you can set the
21 permissions for each member. If not individually set, the members will
22 inherit the default user permissions.
23 * :guilabel:`Inherit from default settings`: On the Global Permissions tab
24 you can uncheck this option and explicitly configure the permissions for
25 the group.
@@ -0,0 +1,84 b''
1 .. _svn-http:
2
3 |svn| With Write Over HTTP
4 --------------------------
5
6 To use |svn| with write access, the currently supported method is over HTTP.
7 This requires you to configure your local machine so that it can access your
8 |RCE| instance.
9
10 Prerequisites
11 ^^^^^^^^^^^^^
12
13 - Enable lab setting on your |RCE| instance, see :ref:`lab-settings`.
14 - You need to install the following tools on your local machine: ``Apache`` and
15 ``mod_dav_svn``. Use the following Ubuntu as an example.
16
17 .. code-block:: bash
18
19 $ sudo apt-get install apache2 libapache2-mod-svn
20
21 Once installed you need to enable ``dav_svn``:
22
23 .. code-block:: bash
24
25 $ sudo a2enmod dav_svn
26
27 Configuring Apache Setup
28 ^^^^^^^^^^^^^^^^^^^^^^^^
29
30 .. tip::
31
32 It is recommended to run Apache on a port other than 80, due to possible
33 conflicts with other HTTP servers like nginx. To do this, set the
34 ``Listen`` parameter in the ``/etc/apache2/ports.conf`` file, for example
35 ``Listen 8090``
36
37 It is also recommended to run apache as the same user as |RCE|, otherwise
38 permission issues could occur. To do this edit the ``/etc/apache2/envvars``
39
40 .. code-block:: apache
41
42 export APACHE_RUN_USER=ubuntu
43 export APACHE_RUN_GROUP=ubuntu
44
45 1. To configure Apache, create and edit a virtual hosts file, for example
46 :file:`/etc/apache2/sites-available/default.conf`, or create another
47 virtual hosts file and add a location section inside the
48 ``<VirtualHost>`` section.
49
50 .. code-block:: apache
51
52 <Location />
53 DAV svn
54 # Must be explicit path, relative not supported
55 SVNParentPath /PATH/TO/REPOSITORIES
56 SVNListParentPath On
57 Allow from all
58 Order allow,deny
59 </Location>
60
61 .. note::
62
63 Once configured, check that you can see the list of repositories on your
64 |RCE| instance.
65
66 2. Go to the :menuselection:`Admin --> Settings --> Labs` page, and
67 enable :guilabel:`Proxy Subversion HTTP requests`, and specify the
68 :guilabel:`Subversion HTTP Server URL`.
69
70 Using |svn|
71 ^^^^^^^^^^^
72
73 Once |svn| has been enabled on your instance, you can use it using the
74 following examples. For more |svn| information, see the `Subversion Red Book`_
75
76 .. code-block:: bash
77
78 # To clone a repository
79 svn clone http://my-svn-server.example.com/my-svn-repo
80
81 # svn commit
82 svn commit
83
84 .. _Subversion Red Book: http://svnbook.red-bean.com/en/1.7/svn-book.html#svn.ref.svn
@@ -0,0 +1,29 b''
1 .. _rhodecode-admin-ref:
2
3 System Administration
4 =====================
5
6 The following are the most common system administration tasks.
7
8 .. only:: latex
9
10 * :ref:`vcs-server`
11 * :ref:`apache-ws-ref`
12 * :ref:`nginx-ws-ref`
13 * :ref:`rhodecode-tuning-ref`
14 * :ref:`indexing-ref`
15 * :ref:`rhodecode-reset-ref`
16
17 .. toctree::
18
19 config-files-overview
20 vcs-server
21 apache-config
22 nginx-config
23 backup-restore
24 tuning-rhodecode
25 indexing
26 reset-information
27 enable-debug
28 admin-tricks
29 cleanup-cmds
@@ -0,0 +1,163 b''
1 .. _system-overview-ref:
2
3 System Overview
4 ===============
5
6 Latest Version
7 --------------
8
9 * |release| on Unix and Windows systems.
10
11 System Architecture
12 -------------------
13
14 The following diagram shows a typical production architecture.
15
16 .. image:: ../images/architecture-diagram.png
17 :align: center
18
19 Supported Operating Systems
20 ---------------------------
21
22 Linux
23 ^^^^^
24
25 * Ubuntu 14.04
26 * CentOS 6.2 and 7
27 * Debian 7.8
28 * RedHat Fedora
29 * Arch Linux
30 * SUSE Linux
31
32 Windows
33 ^^^^^^^
34
35 * Windows Vista Ultimate 64bit
36 * Windows 7 Ultimate 64bit
37 * Windows 8 Professional 64bit
38 * Windows 8.1 Enterprise 64bit
39 * Windows Server 2008 64bit
40 * Windows Server 2008-R2 64bit
41 * Windows Server 2012 64bit
42
43 Supported Databases
44 -------------------
45
46 * SQLite
47 * MySQL
48 * MariaDB
49 * PostgreSQL
50
51 Supported Browsers
52 ------------------
53
54 * Chrome
55 * Safari
56 * Firefox
57 * Internet Explorer 10 & 11
58
59 System Requirements
60 -------------------
61
62 |RCM| performs best on machines with ultra-fast hard disks. Generally disk
63 performance is more important than CPU performance. In a corporate production
64 environment handling 1000s of users and |repos| you should deploy on a 12+
65 core 64GB RAM server. In short, the more RAM the better.
66
67 .. _config-rce-files:
68
69 Configuration Files
70 -------------------
71
72 * :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini`
73 * :file:`/home/{user}/.rccontrol/{instance-id}/mapping.ini`
74 * :file:`/home/{user}/.rccontrol/{vcsserver-id}/vcsserver.ini`
75 * :file:`/home/{user}/.rccontrol/supervisor/supervisord.ini`
76 * :file:`/home/{user}/.rccontrol.ini`
77 * :file:`/home/{user}/.rhoderc`
78 * :file:`/home/{user}/.rccontrol/cache/MANIFEST`
79
80 For more information, see the :ref:`config-files` section.
81
82 Log Files
83 ---------
84
85 * :file:`/home/{user}/.rccontrol/{instance-id}/enterprise.log`
86 * :file:`/home/{user}/.rccontrol/{vcsserver-id}/vcsserver.log`
87 * :file:`/home/{user}/.rccontrol/supervisor/supervisord.log`
88 * :file:`/tmp/rccontrol.log`
89 * :file:`/tmp/rhodecode_tools.log`
90
91 Storage Files
92 -------------
93
94 * :file:`/home/{user}/.rccontrol/{instance-id}/data/index/{index-file.toc}`
95 * :file:`/home/{user}/repos/.rc_gist_store`
96 * :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.db`
97 * :file:`/opt/rhodecode/store/{unique-hash}`
98
99 Default Repositories Location
100 -----------------------------
101
102 * :file:`/home/{user}/repos`
103
104 Connection Methods
105 ------------------
106
107 * HTTPS
108 * SSH
109 * |RCM| API
110
111 Internationalization Support
112 ----------------------------
113
114 Currently available in the following languages, see `Transifex`_ for the
115 latest details. If you want a new language added, please contact us. To
116 configure your language settings, see the :ref:`set-lang` section.
117
118 .. hlist::
119
120 * Belorussian
121 * Chinese
122 * French
123 * German
124 * Italian
125 * Japanese
126 * Portuguese
127 * Polish
128 * Russian
129 * Spanish
130
131 Licencing Information
132 ---------------------
133
134 * See licencing information `here`_
135
136 Peer-to-peer Failover Support
137 -----------------------------
138
139 * Yes
140
141 Additional Binaries
142 -------------------
143
144 * Yes, see :ref:`rhodecode-nix-ref` for full details.
145
146 Remote Connectivity
147 -------------------
148
149 * Available
150
151 Executable Files
152 ----------------
153
154 Windows: :file:`RhodeCode-installer-{version}.exe`
155
156 Deprecated Support
157 ------------------
158
159 - Internet Explorer 8 support deprecated since version 3.7.0.
160 - Internet Explorer 9 support deprecated since version 3.8.0.
161
162 .. _here: https://rhodecode.com/licenses/
163 .. _Transifex: https://www.transifex.com/projects/p/RhodeCode/
@@ -0,0 +1,22 b''
1 .. _change-encoding:
2
3 Change Default Encoding
4 -----------------------
5
6 |RCE| uses ``utf8`` encoding by default. You can change the default encoding
7 in the :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. To
8 change the default encoding used by |RCE|, set a new value for the
9 ``default_encoding``.
10
11 .. code-block:: ini
12
13 # default encoding used to convert from and to unicode
14 # can be also a comma separated list of encoding in case of mixed
15 # encodings
16 default_encoding = utf8
17
18 .. note::
19
20 Changing the default encoding will affect many parts of your |RCE|
21 installation, including committers names,
22 file names, and the encoding of commit messages.
@@ -0,0 +1,32 b''
1 .. _hg-lrg-loc:
2
3 Change the |hg| Large Files Location
4 ------------------------------------
5
6 |RCE| manages |hg| larges files from the following default location
7 :file:`/home/{user}/repos/.cache/largefiles`. If you wish to change this, use
8 the following steps:
9
10 1. Open ishell from the terminal and use it to log into the |RCE| database by
11 specifying the instance :file:`rhodecode.ini` file.
12
13 .. code-block:: bash
14
15 # Open iShell from the terminal and set ini file
16 $ .rccontrol/enterprise-1/profile/bin/paster ishell .rccontrol/enterprise-1/rhodecode.ini
17
18 2. Run the following commands, and ensure that |RCE| has write access to the
19 new directory:
20
21 .. code-block:: mysql
22
23 # Once logged into the database, use SQL to redirect
24 # the large files location
25 In [1]: from rhodecode.model.settings import SettingsModel
26 In [2]: SettingsModel().get_ui_by_key('usercache')
27 Out[2]: <RhodeCodeUi[largefiles]usercache=>/mnt/hgfs/shared/workspace/xxxx/.cache/largefiles]>
28
29 In [3]: largefiles_cache = SettingsModel().get_ui_by_key('usercache')
30 In [4]: largefiles_cache.ui_value = '/new/path’
31 In [5]: Session().add(largefiles_cache);Session().commit()
32
@@ -0,0 +1,111 b''
1 .. _increase-gunicorn:
2
3 Increase Gunicorn Workers
4 -------------------------
5
6 .. important::
7
8 If you increase the number of :term:`Gunicorn` workers, you also need to
9 increase the threadpool size of the VCS Server. The recommended size is
10 6 times the number of Gunicorn workers. To set this, see
11 :ref:`vcs-server-config-file`.
12
13 |RCE| comes with `Gunicorn`_ packaged in its Nix environment. To improve
14 performance you can increase the number of workers. To do this, use the
15 following steps:
16
17 1. Open the :file:`home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file.
18 2. In the ``[server:main]`` section, increase the number of Gunicorn
19 ``workers`` using the following formula :math:`(2 * Cores) + 1`.
20
21 .. code-block:: ini
22
23 [server:main]
24 host = 127.0.0.1
25 port = 10002
26 use = egg:gunicorn#main
27 workers = 1
28 threads = 1
29 proc_name = RhodeCodeEnterprise
30 worker_class = sync
31 max_requests = 1000
32 timeout = 3600
33
34 3. In the ``[app:main]`` section, set the ``instance_id`` property to ``*``.
35
36 .. code-block:: ini
37
38 # In the [app:main] section
39 [app:main]
40 # You must set `instance_id = *`
41 instance_id = *
42
43 4. Save your changes.
44 5. Restart your |RCE| instance, using the following command:
45
46 .. code-block:: bash
47
48 $ rccontrol restart enterprise-1
49
50 If you scale across different machines, each |RCM| instance
51 needs to store its data on a shared disk, preferably together with your
52 |repos|. This data directory contains template caches, a whoosh index,
53 and is used for task locking to ensure safety across multiple instances.
54 To do this, set the following properties in the :file:`rhodecode.ini` file to
55 set the shared location across all |RCM| instances.
56
57 .. code-block:: ini
58
59 cache_dir = /file/path # set to shared location
60 search.location = /file/path # set to shared location
61
62 ####################################
63 ### BEAKER CACHE ####
64 ####################################
65 beaker.cache.data_dir = /file/path # set to shared location
66 beaker.cache.lock_dir = /file/path # set to shared location
67
68
69
70 Gunicorn SSL support
71 --------------------
72
73
74 :term:`Gunicorn` wsgi server allows users to use HTTPS connection directly
75 without a need to use HTTP server like Nginx or Apache. To Configure
76 SSL support directly with :term:`Gunicorn` you need to simply add the key
77 and certificate paths to your configuration file.
78
79 1. Open the :file:`home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file.
80 2. In the ``[server:main]`` section, add two new variables
81 called `certfile` and `keyfile`.
82
83 .. code-block:: ini
84
85 [server:main]
86 host = 127.0.0.1
87 port = 10002
88 use = egg:gunicorn#main
89 workers = 1
90 threads = 1
91 proc_name = RhodeCodeEnterprise
92 worker_class = sync
93 max_requests = 1000
94 timeout = 3600
95 # adding ssl support
96 certfile = /home/ssl/my_server_com.pem
97 keyfile = /home/ssl/my_server_com.key
98
99 4. Save your changes.
100 5. Restart your |RCE| instance, using the following command:
101
102 .. code-block:: bash
103
104 $ rccontrol restart enterprise-1
105
106 After this is enabled you can *only* access your instances via https://
107 protocol. Check out more docs here `Gunicorn SSL Docs`_
108
109
110 .. _Gunicorn: http://gunicorn.org/
111 .. _Gunicorn SSL Docs: http://docs.gunicorn.org/en/stable/settings.html#ssl
@@ -0,0 +1,17 b''
1 .. _hg-auth-loop:
2
3 |hg| Authentication Tuning
4 --------------------------
5
6 When using external authentication tools such as LDAP with |hg|, a
7 password retry loop in |hg| can result in users being locked out due to too
8 many failed password attempts. To prevent this from happening, add the
9 following setting to your
10 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file, in the
11 ``[app:main]`` section.
12
13
14 .. code-block:: ini
15
16 [app:main]
17 auth_ret_code_detection = true
@@ -0,0 +1,17 b''
1 .. _cache-size:
2
3 Increase Cache Size
4 -------------------
5
6 When managing hundreds of |repos| from the main |RCE| interface the system
7 can become slow when the cache expires. Increasing the cache expiration
8 option improves the response times of the main user interface.
9 To increase your cache size, change the following default value in the
10 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. The value
11 is specified in seconds.
12
13 .. code-block:: ini
14
15 beaker.cache.long_term.expire=3600 # day (86400) week (604800)
16
17 .. note:: The |RCE| cache automatically expires for changed |repos|.
@@ -0,0 +1,23 b''
1 .. _db-session-ref:
2
3 Increase Database Performance
4 -----------------------------
5
6 To increase database performance switch to database-based user sessions.
7 File-based sessions are only suitable for smaller setups. The most common
8 issue being file limit errors which occur if there are lots of session files.
9 Therefore, in a large scale deployment, to give better performance,
10 scalability, and maintainability we recommend switching from file-based
11 sessions to database-based user sessions.
12
13 To switch to database-based user sessions uncomment the following section in
14 your :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file.
15
16 .. code-block:: ini
17
18 # db session
19 beaker.session.type = ext:database
20
21 # adjust this property to include your database credentials
22 beaker.session.sa.url = postgresql://postgres:<pass>@localhost/rhodecode
23 beaker.session.table_name = db_session
@@ -0,0 +1,42 b''
1 .. _data-mem:
2
3 Mount Cache Folders To Memory
4 -----------------------------
5
6 To increase the performance of folders containing cache data, you can mount
7 them to memory. The following folders specified in the :file:`rhodecode.ini`
8 file would benefit from this.
9
10 .. code-block:: ini
11
12 cache_dir = %(here)s/data
13 search.location = %(here)s/data/index
14
15 Use the following Ubuntu example to mount these to memory, or see your
16 particular |os| instructions. The expected performance benefit is
17 approximately 5%. You should ensure you allocate an adequate amount of memory
18 depending on your available resources.
19
20 .. code-block:: bash
21
22 # mount to memory with 2GB limit and 755 write permissions
23 mount -t tmpfs -o size=2G,mode=0755 tmpfs /home/user/.rccontrol/enterprise-1/data
24 mount -t tmpfs -o size=2G,mode=0755 tmpfs /home/user/.rccontrol/enterprise-1/data/index
25
26 .. _move-tmp:
27
28 Move ``tmp`` to TMPFS
29 ---------------------
30
31 |RCE| components heavily use the :file:`/tmp` folder, so moving your
32 :file:`/tmp` folder into to a RAM-based TMPS can lead to a noticeable
33 performance boost.
34
35 .. code-block:: bash
36
37 # mount tmp to memory with 2GB limit and 755 write permissions
38 mount -t tmpfs -o size=2G,mode=0755 tmpfs /tmp
39
40 For more information about TMPFS, see the documentation `here`_.
41
42 .. _here: https://wiki.archlinux.org/index.php/Tmpfs
@@ -0,0 +1,20 b''
1 .. _rhodecode-tuning-ref:
2
3 Tuning |RCE|
4 ============
5
6 To customize your |RCE| |version| installation for maximum performance you
7 may find some of the following methods useful.
8
9 .. toctree::
10
11 tuning-gunicorn
12 tuning-vcs-memory-cache
13 tuning-increase-db-performance
14 tuning-scale-horizontally
15 tuning-increase-cache-size
16 tuning-mount-cache-memory
17 tuning-change-encoding
18 tuning-change-large-file-dir
19 tuning-hg-auth-loop
20
@@ -0,0 +1,51 b''
1 .. _scale-horizontal:
2
3 Scale Horizontally
4 ------------------
5
6 Horizontal scaling means adding more machines or workers into your pool of
7 resources. Horizontally scaling |RCE| gives a huge performance increase,
8 especially under large traffic scenarios with a high number of requests. This
9 is very beneficial when |RCE| is serving many users simultaneously,
10 or if continuous integration servers are automatically pulling and pushing code.
11
12 To horizontally scale |RCE| you should use the following steps:
13
14 1. In the :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file,
15 set ``instance_id = *``. This enables |RCE| to use multiple nodes.
16 2. Define the number of worker threads using the formula
17 :math:`(2 * Cores) + 1`. For example 4 CPU cores would lead to
18 :math:`(2 * 4) + 1 = 9` workers. In some cases it's ok to increase number of
19 workers even beyond this formula. Generally the more workers, the more
20 simultaneous connections the system can handle.
21
22 It is recommended to create another dedicated |RCE| instance to handle
23 traffic from build farms or continuous integration servers.
24
25 .. note::
26
27 You should configure your load balancing accordingly. We recommend writing
28 load balancing rules that will separate regular user traffic from
29 automated process traffic like continuous servers or build bots.
30
31 If you scale across different machines, each |RCE| instance needs to store
32 its data on a shared disk, preferably together with your repositories. This
33 data directory contains template caches, a whoosh index,
34 and is used for task locking to ensure safety across multiple instances. To
35 do this, set the following properties in the
36 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file to set
37 the shared location across all |RCE| instances.
38
39 .. code-block:: ini
40
41 cache_dir = /file/path # set to shared directory location
42 search.location = /file/path # set to shared directory location
43 beaker.cache.data_dir = /file/path # set to shared directory location
44 beaker.cache.lock_dir = /file/path # set to shared directory location
45
46 .. note::
47
48 If Celery is used on each instance then you should run separate Celery
49 instances, but the message broker should be the same for all of them.
50 This excludes one RabbitMQ shared server.
51
@@ -0,0 +1,8 b''
1 .. _adjust-vcs-mem-cache:
2
3 Adjusting VCS Memory Cache
4 --------------------------
5
6 The VCS Server mamory cache can be adjusted to work best with the resources
7 available to your |RCE| instance. If you find that memory resources are under
8 pressure, see the :ref:`vcs-server-maintain` section for details.
@@ -0,0 +1,23 b''
1 .. _user-admin-set:
2
3 User Administration
4 ===================
5
6 |RCM| enables you to define permissions for the following entities within the
7 system; **users**, **user groups**, **repositories**, **repository groups**.
8
9 Within each one of these entities you can set default settings,
10 and then all users or |repos| inherit those default permission settings
11 unless individually defined. Each of these entities can have the following
12 permissions applied to it; |perm|.
13
14 .. toctree::
15
16 public-access
17 default-user-perms
18 adding-anonymous-user
19 adding-new-user
20 setting-default-permissions
21 setting-usergroup-permissions
22
23 .. |perm| replace:: **None**, **Read**, **Write**, or **Admin** No newline at end of file
@@ -0,0 +1,301 b''
1 .. _vcs-server:
2
3 VCS Server Management
4 ---------------------
5
6 The VCS Server handles |RCM| backend functionality. You need to configure
7 a VCS Server to run with a |RCM| instance. If you do not, you will be missing
8 the connection between |RCM| and its |repos|. This will cause error messages
9 on the web interface. You can run your setup in the following configurations,
10 currently the best performance is one VCS Server per |RCM| instance:
11
12 * One VCS Server per |RCM| instance.
13 * One VCS Server handling multiple instances.
14
15 .. important::
16
17 If your server locale settings are not correctly configured,
18 |RCE| and the VCS Server can run into issues. See this `Ask Ubuntu`_ post
19 which explains the problem and gives a solution.
20
21 For more information, see the following sections:
22
23 * :ref:`install-vcs`
24 * :ref:`config-vcs`
25 * :ref:`vcs-server-options`
26 * :ref:`vcs-server-versions`
27 * :ref:`vcs-server-maintain`
28 * :ref:`vcs-server-config-file`
29
30 .. _install-vcs:
31
32 VCS Server Installation
33 ^^^^^^^^^^^^^^^^^^^^^^^
34
35 To install a VCS Server, see
36 :ref:`Installing a VCS server <control:install-vcsserver>`.
37
38 .. _config-vcs:
39
40 Hooking |RCE| to its VCS Server
41 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42
43 To configure a |RCE| instance to use a VCS server, see
44 :ref:`Configuring the VCS Server connection <control:manually-vcsserver-ini>`.
45
46 .. _vcs-server-options:
47
48 |RCE| VCS Server Options
49 ^^^^^^^^^^^^^^^^^^^^^^^^
50
51 The following list shows the available options on the |RCM| side of the
52 connection to the VCS Server. The settings are configured per
53 instance in the
54 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file.
55
56 .. rst-class:: dl-horizontal
57
58 \vcs.backends <available-vcs-systems>
59 Set a comma-separated list of the |repo| options available from the
60 web interface. The default is ``hg, git, svn``,
61 which is all |repo| types available.
62
63 \vcs.connection_timeout <seconds>
64 Set the length of time in seconds that the VCS Server waits for
65 requests to process. After the timeout expires,
66 the request is closed. The default is ``3600``. Set to a higher
67 number if you experience network latency, or timeout issues with very
68 large push/pull requests.
69
70 \vcs.server.enable <boolean>
71 Enable or disable the VCS Server. The available options are ``true`` or
72 ``false``. The default is ``true``.
73
74 \vcs.server <host:port>
75 Set the host, either hostname or IP Address, and port of the VCS server
76 you wish to run with your |RCM| instance.
77
78 .. code-block:: ini
79
80 ##################
81 ### VCS CONFIG ###
82 ##################
83 # set this line to match your VCS Server
84 vcs.server = 127.0.0.1:10004
85 # Set to False to disable the VCS Server
86 vcs.server.enable = True
87 vcs.backends = hg, git, svn
88 vcs.connection_timeout = 3600
89
90
91 .. _vcs-server-versions:
92
93 VCS Server Versions
94 ^^^^^^^^^^^^^^^^^^^
95
96 An updated version of the VCS Server is released with each |RCE| version. Use
97 the VCS Server number that matches with the |RCE| version to pair the
98 appropriate ones together. For |RCE| versions pre 3.3.0,
99 VCS Server 1.X.Y works with |RCE| 3.X.Y, for example:
100
101 * VCS Server 1.0.0 works with |RCE| 3.0.0
102 * VCS Server 1.2.2 works with |RCE| 3.2.2
103
104 For |RCE| versions post 3.3.0, the VCS Server and |RCE| version numbers
105 match, for example:
106
107 * VCS Server |release| works with |RCE| |release|
108
109 .. _vcs-server-maintain:
110
111 VCS Server Memory Optimization
112 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
113
114 To configure the VCS server to manage the cache efficiently, you need to
115 configure the following options in the
116 :file:`/home/{user}/.rccontrol/{vcsserver-id}/vcsserver.ini` file. Once
117 configured, restart the VCS Server.
118
119 .. rst-class:: dl-horizontal
120
121 \beaker.cache.repo_object.type = memorylru
122 Configures the cache to discard the least recently used items.
123 This setting takes the following valid options:
124
125 * ``memorylru``: The default setting, which removes the least recently
126 used items from the cache.
127 * ``memory``: Runs the VCS Server without clearing the cache.
128 * ``nocache``: Runs the VCS Server without a cache. This will
129 dramatically reduce the VCS Server performance.
130
131 \beaker.cache.repo_object.max_items = 100
132 Sets the maximum number of items stored in the cache, before the cache
133 starts to be cleared.
134
135 As a general rule of thumb, running this value at 120 resulted in a
136 5GB cache. Running it at 240 resulted in a 9GB cache. Your results
137 will differ based on usage patterns and |repo| sizes.
138
139 Tweaking this value to run at a fairly constant memory load on your
140 server will help performance.
141
142 To clear the cache completely, you can restart the VCS Server.
143
144 .. important::
145
146 While the VCS Server handles a restart gracefully on the web interface,
147 it will drop connections during push/pull requests. So it is recommended
148 you only perform this when there is very little traffic on the instance.
149
150 Use the following example to restart your VCS Server,
151 for full details see the :ref:`RhodeCode Control CLI <control:rcc-cli>`.
152
153 .. code-block:: bash
154
155 $ rccontrol status
156
157 .. code-block:: vim
158
159 - NAME: vcsserver-1
160 - STATUS: RUNNING
161 - TYPE: VCSServer
162 - VERSION: 1.0.0
163 - URL: http://127.0.0.1:10001
164
165 $ rccontrol restart vcsserver-1
166 Instance "vcsserver-1" successfully stopped.
167 Instance "vcsserver-1" successfully started.
168
169 .. _vcs-server-config-file:
170
171 VCS Server Configuration
172 ^^^^^^^^^^^^^^^^^^^^^^^^
173
174 You can configure settings for multiple VCS Servers on your
175 system using their individual configuration files. Use the following
176 properties inside the configuration file to set up your system. The default
177 location is :file:`home/{user}/.rccontrol/{vcsserver-id}/vcsserver.ini`.
178 For a more detailed explanation of the logger levers, see :ref:`debug-mode`.
179
180 .. rst-class:: dl-horizontal
181
182 \host <ip-address>
183 Set the host on which the VCS Server will run.
184
185 \port <int>
186 Set the port number on which the VCS Server will be available.
187
188 \locale <locale_utf>
189 Set the locale the VCS Server expects.
190
191 \threadpool_size <int>
192 Set the size of the threadpool used to communicate
193 with the WSGI workers. This should be at least 6 times the number of
194 WSGI worker processes.
195
196 \timeout <seconds>
197 Set the timeout for RPC communication in seconds.
198
199 .. note::
200
201 After making changes, you need to restart your VCS Server to pick them up.
202
203 .. code-block:: ini
204
205 ################################################################################
206 # RhodeCode VCSServer - configuration #
207 # #
208 ################################################################################
209
210 [DEFAULT]
211 host = 127.0.0.1
212 port = 9900
213 locale = en_US.UTF-8
214 # number of worker threads, this should be set based on a formula threadpool=N*6
215 # where N is number of RhodeCode Enterprise workers, eg. running 2 instances
216 # 8 gunicorn workers each would be 2 * 8 * 6 = 96, threadpool_size = 96
217 threadpool_size = 16
218 timeout = 0
219
220 # cache regions, please don't change
221 beaker.cache.regions = repo_object
222 beaker.cache.repo_object.type = memorylru
223 beaker.cache.repo_object.max_items = 1000
224
225 # cache auto-expires after N seconds
226 beaker.cache.repo_object.expire = 10
227 beaker.cache.repo_object.enabled = true
228
229
230 ################################
231 ### LOGGING CONFIGURATION ####
232 ################################
233 [loggers]
234 keys = root, vcsserver, pyro4, beaker
235
236 [handlers]
237 keys = console
238
239 [formatters]
240 keys = generic
241
242 #############
243 ## LOGGERS ##
244 #############
245 [logger_root]
246 level = NOTSET
247 handlers = console
248
249 [logger_vcsserver]
250 level = DEBUG
251 handlers =
252 qualname = vcsserver
253 propagate = 1
254
255 [logger_beaker]
256 level = DEBUG
257 handlers =
258 qualname = beaker
259 propagate = 1
260
261 [logger_pyro4]
262 level = DEBUG
263 handlers =
264 qualname = Pyro4
265 propagate = 1
266
267
268 ##############
269 ## HANDLERS ##
270 ##############
271
272 [handler_console]
273 class = StreamHandler
274 args = (sys.stderr,)
275 level = DEBUG
276 formatter = generic
277
278 [handler_file]
279 class = FileHandler
280 args = ('vcsserver.log', 'a',)
281 level = DEBUG
282 formatter = generic
283
284 [handler_file_rotating]
285 class = logging.handlers.TimedRotatingFileHandler
286 # 'D', 5 - rotate every 5days
287 # you can set 'h', 'midnight'
288 args = ('vcsserver.log', 'D', 5, 10,)
289 level = DEBUG
290 formatter = generic
291
292 ################
293 ## FORMATTERS ##
294 ################
295
296 [formatter_generic]
297 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
298 datefmt = %Y-%m-%d %H:%M:%S
299
300
301 .. _Ask Ubuntu: http://askubuntu.com/questions/162391/how-do-i-fix-my-locale-issue
This diff has been collapsed as it changes many lines, (2824 lines changed) Show them Hide them
@@ -0,0 +1,2824 b''
1 .. _api:
2
3 API Documentation
4 =================
5
6 The |RCE| API uses a single scheme for calling all API methods. The API is
7 implemented with JSON protocol in both directions. To send API requests to
8 your instance of |RCE|, use the following URL format
9 ``<your_server>/_admin``
10
11 .. note::
12
13 To use the API, you should configure the :file:`~/.rhoderc` file with
14 access details per instance. For more information, see
15 :ref:`config-rhoderc`.
16
17
18 API ACCESS FOR WEB VIEWS
19 ------------------------
20
21 API access can also be turned on for each web view in |RCE| that is
22 decorated with a `@LoginRequired` decorator. To enable API access, change
23 the standard login decorator to `@LoginRequired(api_access=True)`.
24
25 From |RCM| version 1.7.0 you can configure a white list
26 of views that have API access enabled by default. To enable these,
27 edit the |RCM| configuration ``.ini`` file. The default location is:
28
29 * |RCM| Pre-2.2.7 :file:`root/rhodecode/data/production.ini`
30 * |RCM| 3.0 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini`
31
32 To configure the white list, edit this section of the file. In this
33 configuration example, API access is granted to the patch/diff raw file and
34 archive.
35
36 .. code-block:: ini
37
38 ## List of controllers (using glob syntax) that AUTH TOKENS could be used for access.
39 ## Adding ?auth_token = <token> to the url authenticates this request as if it
40 ## came from the the logged in user who own this authentication token.
41 ##
42 ## Syntax is <ControllerClass>:<function_pattern>.
43 ## The list should be "," separated and on a single line.
44 ##
45 api_access_controllers_whitelist = ChangesetController:changeset_patch,ChangesetController:changeset_raw,ilesController:raw,FilesController:archivefile,
46
47 After this change, a |RCE| view can be accessed without login by adding a
48 GET parameter ``?auth_token=<auth_token>`` to a url. For example to
49 access the raw diff.
50
51 .. code-block:: html
52
53 http://<server>/<repo>/changeset-diff/<sha>?auth_token=<auth_token>
54
55 By default this is only enabled on RSS/ATOM feed views. Exposing raw diffs is a
56 good way to integrate with 3rd party services like code review, or build farms
57 that could download archives.
58
59 API ACCESS
60 ----------
61
62 All clients are required to send JSON-RPC spec JSON data.
63
64 .. code-block:: bash
65
66 {
67 "id:"<id>",
68 "auth_token":"<auth_token>",
69 "method":"<method_name>",
70 "args":{"<arg_key>":"<arg_val>"}
71 }
72
73 Example call for auto pulling from remote repositories using curl:
74
75 .. code-block:: bash
76
77 curl https://server.com/_admin/api -X POST -H 'content-type:text/plain' --data-binary '{"id":1,
78 "auth_token":"xe7cdb2v278e4evbdf5vs04v832v0efvcbcve4a3","method":"pull", "args":{"repo":"CPython"}}'
79
80 Provide those parameters:
81 - **id** A value of any type, which is used to match the response with the
82 request that it is replying to.
83 - **auth_token** for access and permission validation.
84 - **method** is name of method to call
85 - **args** is an ``key:value`` list of arguments to pass to method
86
87 .. note::
88
89 To get your |authtoken|, from the |RCE| interface,
90 go to:
91 :menuselection:`username --> My account --> Auth tokens`
92
93 For security reasons you should always create a dedicated |authtoken| for
94 API use only.
95
96
97 The |RCE| API will always return a JSON-RPC response:
98
99 .. code-block:: bash
100
101 {
102 "id": <id>, # matching id sent by request
103 "result": "<result>"|null, # JSON formatted result, null if any errors
104 "error": "null"|<error_message> # JSON formatted error (if any)
105 }
106
107 All responses from API will be with `HTTP/1.0 200 OK` status code.
108 If there is an error when calling the API, the *error* key will contain a
109 failure description and the *result* will be `null`.
110
111 API CLIENT
112 ----------
113
114 To install the |RCE| API, see :ref:`install-tools`. To configure the API per
115 instance, see the :ref:`rc-tools` section as you need to configure a
116 :file:`~/.rhoderc` file with your |authtokens|.
117
118 Once you have set up your instance API access, use the following examples to
119 get started.
120
121 .. code-block:: bash
122
123 # Getting the 'rhodecode' repository
124 # from a RhodeCode Enterprise instance
125 rhodecode-api --instance-name=enterprise-1 get_repo repoid:rhodecode
126
127 Calling method get_repo => http://127.0.0.1:5000
128 Server response
129 {
130 <json data>
131 }
132
133 # Creating a new mercurial repository called 'brand-new'
134 # with a description 'Repo-description'
135 rhodecode-api --instance-name=enterprise-1 create_repo repo_name:brand-new repo_type:hg description:Repo-description
136 {
137 "error": null,
138 "id": 1110,
139 "result": {
140 "msg": "Created new repository `brand-new`",
141 "success": true,
142 "task": null
143 }
144 }
145
146 A broken example, what not to do.
147
148 .. code-block:: bash
149
150 # A call missing the required arguments
151 # and not specifying the instance
152 rhodecode-api get_repo
153
154 Calling method get_repo => http://127.0.0.1:5000
155 Server response
156 "Missing non optional `repoid` arg in JSON DATA"
157
158 You can specify pure JSON using the ``--format`` parameter.
159
160 .. code-block:: bash
161
162 rhodecode-api --format=json get_repo repoid:rhodecode
163
164 In such case only output that this function shows is pure JSON, we can use that
165 and pipe output to some json formatter.
166
167 If output is in pure JSON format, you can pipe output to a JSON formatter.
168
169 .. code-block:: bash
170
171 rhodecode-api --instance-name=enterprise-1 --format=json get_repo repoid:rhodecode | python -m json.tool
172
173 API METHODS
174 -----------
175
176 Each method by default required following arguments.
177
178 .. code-block:: bash
179
180 id : "<id_for_response>"
181 auth_token : "<auth_token>"
182 method : "<method name>"
183 args : {}
184
185 Use each **param** from docs and put it in args, Optional parameters
186 are not required in args.
187
188 .. code-block:: bash
189
190 args: {"repoid": "rhodecode"}
191
192 .. Note: From this point on things are generated by the script in
193 `scripts/fabfile.py`. To change things below, update the docstrings in the
194 ApiController.
195
196 .. --- API DEFS MARKER ---
197
198 pull
199 ----
200
201 .. py:function:: pull(apiuser, repoid)
202
203 Triggers a pull on the given repository from a remote location. You
204 can use this to keep remote repositories up-to-date.
205
206 This command can only be run using an |authtoken| with admin
207 rights to the specified repository. For more information,
208 see :ref:`config-token-ref`.
209
210 This command takes the following options:
211
212 :param apiuser: This is filled automatically from the |authtoken|.
213 :type apiuser: AuthUser
214 :param repoid: The repository name or repository ID.
215 :type repoid: str or int
216
217 Example output:
218
219 .. code-block:: bash
220
221 id : <id_given_in_input>
222 result : {
223 "msg": "Pulled from `<repository name>`"
224 "repository": "<repository name>"
225 }
226 error : null
227
228 Example error output:
229
230 .. code-block:: bash
231
232 id : <id_given_in_input>
233 result : null
234 error : {
235 "Unable to pull changes from `<reponame>`"
236 }
237
238
239 strip
240 -----
241
242 .. py:function:: strip(apiuser, repoid, revision, branch)
243
244 Strips the given revision from the specified repository.
245
246 * This will remove the revision and all of its decendants.
247
248 This command can only be run using an |authtoken| with admin rights to
249 the specified repository.
250
251 This command takes the following options:
252
253 :param apiuser: This is filled automatically from the |authtoken|.
254 :type apiuser: AuthUser
255 :param repoid: The repository name or repository ID.
256 :type repoid: str or int
257 :param revision: The revision you wish to strip.
258 :type revision: str
259 :param branch: The branch from which to strip the revision.
260 :type branch: str
261
262 Example output:
263
264 .. code-block:: bash
265
266 id : <id_given_in_input>
267 result : {
268 "msg": "'Stripped commit <commit_hash> from repo `<repository name>`'"
269 "repository": "<repository name>"
270 }
271 error : null
272
273 Example error output:
274
275 .. code-block:: bash
276
277 id : <id_given_in_input>
278 result : null
279 error : {
280 "Unable to strip commit <commit_hash> from repo `<repository name>`"
281 }
282
283
284 rescan_repos
285 ------------
286
287 .. py:function:: rescan_repos(apiuser, remove_obsolete=<Optional:False>)
288
289 Triggers a rescan of the specified repositories.
290
291 * If the ``remove_obsolete`` option is set, it also deletes repositories
292 that are found in the database but not on the file system, so called
293 "clean zombies".
294
295 This command can only be run using an |authtoken| with admin rights to
296 the specified repository.
297
298 This command takes the following options:
299
300 :param apiuser: This is filled automatically from the |authtoken|.
301 :type apiuser: AuthUser
302 :param remove_obsolete: Deletes repositories from the database that
303 are not found on the filesystem.
304 :type remove_obsolete: Optional(``True`` | ``False``)
305
306 Example output:
307
308 .. code-block:: bash
309
310 id : <id_given_in_input>
311 result : {
312 'added': [<added repository name>,...]
313 'removed': [<removed repository name>,...]
314 }
315 error : null
316
317 Example error output:
318
319 .. code-block:: bash
320
321 id : <id_given_in_input>
322 result : null
323 error : {
324 'Error occurred during rescan repositories action'
325 }
326
327
328 invalidate_cache
329 ----------------
330
331 .. py:function:: invalidate_cache(apiuser, repoid, delete_keys=<Optional:False>)
332
333 Invalidates the cache for the specified repository.
334
335 This command can only be run using an |authtoken| with admin rights to
336 the specified repository.
337
338 This command takes the following options:
339
340 :param apiuser: This is filled automatically from |authtoken|.
341 :type apiuser: AuthUser
342 :param repoid: Sets the repository name or repository ID.
343 :type repoid: str or int
344 :param delete_keys: This deletes the invalidated keys instead of
345 just flagging them.
346 :type delete_keys: Optional(``True`` | ``False``)
347
348 Example output:
349
350 .. code-block:: bash
351
352 id : <id_given_in_input>
353 result : {
354 'msg': Cache for repository `<repository name>` was invalidated,
355 'repository': <repository name>
356 }
357 error : null
358
359 Example error output:
360
361 .. code-block:: bash
362
363 id : <id_given_in_input>
364 result : null
365 error : {
366 'Error occurred during cache invalidation action'
367 }
368
369
370 lock
371 ----
372
373 .. py:function:: lock(apiuser, repoid, locked=<Optional:None>, userid=<Optional:<OptionalAttr:apiuser>>)
374
375 Sets the lock state of the specified |repo| by the given user.
376 From more information, see :ref:`repo-locking`.
377
378 * If the ``userid`` option is not set, the repository is locked to the
379 user who called the method.
380 * If the ``locked`` parameter is not set, the current lock state of the
381 repository is displayed.
382
383 This command can only be run using an |authtoken| with admin rights to
384 the specified repository.
385
386 This command takes the following options:
387
388 :param apiuser: This is filled automatically from the |authtoken|.
389 :type apiuser: AuthUser
390 :param repoid: Sets the repository name or repository ID.
391 :type repoid: str or int
392 :param locked: Sets the lock state.
393 :type locked: Optional(``True`` | ``False``)
394 :param userid: Set the repository lock to this user.
395 :type userid: Optional(str or int)
396
397 Example error output:
398
399 .. code-block:: bash
400
401 id : <id_given_in_input>
402 result : {
403 'repo': '<reponame>',
404 'locked': <bool: lock state>,
405 'locked_since': <int: lock timestamp>,
406 'locked_by': <username of person who made the lock>,
407 'lock_reason': <str: reason for locking>,
408 'lock_state_changed': <bool: True if lock state has been changed in this request>,
409 'msg': 'Repo `<reponame>` locked by `<username>` on <timestamp>.'
410 or
411 'msg': 'Repo `<repository name>` not locked.'
412 or
413 'msg': 'User `<user name>` set lock state for repo `<repository name>` to `<new lock state>`'
414 }
415 error : null
416
417 Example error output:
418
419 .. code-block:: bash
420
421 id : <id_given_in_input>
422 result : null
423 error : {
424 'Error occurred locking repository `<reponame>`
425 }
426
427
428 get_locks
429 ---------
430
431 .. py:function:: get_locks(apiuser, userid=<Optional:<OptionalAttr:apiuser>>)
432
433 Displays all repositories locked by the specified user.
434
435 * If this command is run by a non-admin user, it returns
436 a list of |repos| locked by that user.
437
438 This command takes the following options:
439
440 :param apiuser: This is filled automatically from the |authtoken|.
441 :type apiuser: AuthUser
442 :param userid: Sets the userid whose list of locked |repos| will be
443 displayed.
444 :type userid: Optional(str or int)
445
446 Example output:
447
448 .. code-block:: bash
449
450 id : <id_given_in_input>
451 result : {
452 [repo_object, repo_object,...]
453 }
454 error : null
455
456
457 get_ip
458 ------
459
460 .. py:function:: get_ip(apiuser, userid=<Optional:<OptionalAttr:apiuser>>)
461
462 Displays the IP Address as seen from the |RCE| server.
463
464 * This command displays the IP Address, as well as all the defined IP
465 addresses for the specified user. If the ``userid`` is not set, the
466 data returned is for the user calling the method.
467
468 This command can only be run using an |authtoken| with admin rights to
469 the specified repository.
470
471 This command takes the following options:
472
473 :param apiuser: This is filled automatically from |authtoken|.
474 :type apiuser: AuthUser
475 :param userid: Sets the userid for which associated IP Address data
476 is returned.
477 :type userid: Optional(str or int)
478
479 Example output:
480
481 .. code-block:: bash
482
483 id : <id_given_in_input>
484 result : {
485 "server_ip_addr": "<ip_from_clien>",
486 "user_ips": [
487 {
488 "ip_addr": "<ip_with_mask>",
489 "ip_range": ["<start_ip>", "<end_ip>"],
490 },
491 ...
492 ]
493 }
494
495
496 show_ip
497 -------
498
499 .. py:function:: show_ip(apiuser, userid=<Optional:<OptionalAttr:apiuser>>)
500
501 Displays the IP Address as seen from the |RCE| server.
502
503 * This command displays the IP Address, as well as all the defined IP
504 addresses for the specified user. If the ``userid`` is not set, the
505 data returned is for the user calling the method.
506
507 This command can only be run using an |authtoken| with admin rights to
508 the specified repository.
509
510 This command takes the following options:
511
512 :param apiuser: This is filled automatically from |authtoken|.
513 :type apiuser: AuthUser
514 :param userid: Sets the userid for which associated IP Address data
515 is returned.
516 :type userid: Optional(str or int)
517
518 Example output:
519
520 .. code-block:: bash
521
522 id : <id_given_in_input>
523 result : {
524 "server_ip_addr": "<ip_from_clien>",
525 "user_ips": [
526 {
527 "ip_addr": "<ip_with_mask>",
528 "ip_range": ["<start_ip>", "<end_ip>"],
529 },
530 ...
531 ]
532 }
533
534
535 get_license_info
536 ----------------
537
538 .. py:function:: get_license_info(apiuser)
539
540 Returns the |RCE| license information.
541
542 :param apiuser: This is filled automatically from the |authtoken|.
543 :type apiuser: AuthUser
544
545 Example output:
546
547 .. code-block:: bash
548
549 id : <id_given_in_input>
550 result : {
551 'rhodecode_version': <rhodecode version>,
552 'token': <license token>,
553 'issued_to': <license owner>,
554 'issued_on': <license issue date>,
555 'expires_on': <license expiration date>,
556 'type': <license type>,
557 'users_limit': <license users limit>,
558 'key': <license key>
559 }
560 error : null
561
562
563 set_license_key
564 ---------------
565
566 .. py:function:: set_license_key(apiuser, key)
567
568 Sets the |RCE| license key.
569
570 :param apiuser: This is filled automatically from the |authtoken|.
571 :type apiuser: AuthUser
572 :param key: This is the license key to be set.
573 :type key: str
574
575 Example output:
576
577 .. code-block:: bash
578
579 id : <id_given_in_input>
580 result: {
581 "msg" : "updated license information",
582 "key": <key>
583 }
584 error: null
585
586 Example error output:
587
588 .. code-block:: bash
589
590 id : <id_given_in_input>
591 result : null
592 error : {
593 "license key is not valid"
594 or
595 "trial licenses cannot be uploaded"
596 or
597 "error occurred while updating license"
598 }
599
600
601 get_server_info
602 ---------------
603
604 .. py:function:: get_server_info(apiuser)
605
606 Returns the |RCE| server information.
607
608 This includes the running version of |RCE| and all installed
609 packages. This command takes the following options:
610
611 :param apiuser: This is filled automatically from the |authtoken|.
612 :type apiuser: AuthUser
613
614 Example output:
615
616 .. code-block:: bash
617
618 id : <id_given_in_input>
619 result : {
620 'modules': [<module name>,...]
621 'py_version': <python version>,
622 'platform': <platform type>,
623 'rhodecode_version': <rhodecode version>
624 }
625 error : null
626
627
628 get_user
629 --------
630
631 .. py:function:: get_user(apiuser, userid=<Optional:<OptionalAttr:apiuser>>)
632
633 Returns the information associated with a username or userid.
634
635 * If the ``userid`` is not set, this command returns the information
636 for the ``userid`` calling the method.
637
638 .. note::
639
640 Normal users may only run this command against their ``userid``. For
641 full privileges you must run this command using an |authtoken| with
642 admin rights.
643
644 This command takes the following options:
645
646 :param apiuser: This is filled automatically from the |authtoken|.
647 :type apiuser: AuthUser
648 :param userid: Sets the userid for which data will be returned.
649 :type userid: Optional(str or int)
650
651 Example output:
652
653 .. code-block:: bash
654
655 {
656 "error": null,
657 "id": <id>,
658 "result": {
659 "active": true,
660 "admin": false,
661 "api_key": "api-key",
662 "api_keys": [ list of keys ],
663 "email": "user@example.com",
664 "emails": [
665 "user@example.com"
666 ],
667 "extern_name": "rhodecode",
668 "extern_type": "rhodecode",
669 "firstname": "username",
670 "ip_addresses": [],
671 "language": null,
672 "last_login": "Timestamp",
673 "lastname": "surnae",
674 "permissions": {
675 "global": [
676 "hg.inherit_default_perms.true",
677 "usergroup.read",
678 "hg.repogroup.create.false",
679 "hg.create.none",
680 "hg.extern_activate.manual",
681 "hg.create.write_on_repogroup.false",
682 "hg.usergroup.create.false",
683 "group.none",
684 "repository.none",
685 "hg.register.none",
686 "hg.fork.repository"
687 ],
688 "repositories": { "username/example": "repository.write"},
689 "repositories_groups": { "user-group/repo": "group.none" },
690 "user_groups": { "user_group_name": "usergroup.read" }
691 },
692 "user_id": 32,
693 "username": "username"
694 }
695 }
696
697
698 get_users
699 ---------
700
701 .. py:function:: get_users(apiuser)
702
703 Lists all users in the |RCE| user database.
704
705 This command can only be run using an |authtoken| with admin rights to
706 the specified repository.
707
708 This command takes the following options:
709
710 :param apiuser: This is filled automatically from the |authtoken|.
711 :type apiuser: AuthUser
712
713 Example output:
714
715 .. code-block:: bash
716
717 id : <id_given_in_input>
718 result: [<user_object>, ...]
719 error: null
720
721
722 create_user
723 -----------
724
725 .. py:function:: create_user(apiuser, username, email, password=<Optional:''>, firstname=<Optional:''>, lastname=<Optional:''>, active=<Optional:True>, admin=<Optional:False>, extern_name=<Optional:'rhodecode'>, extern_type=<Optional:'rhodecode'>, force_password_change=<Optional:False>)
726
727 Creates a new user and returns the new user object.
728
729 This command can only be run using an |authtoken| with admin rights to
730 the specified repository.
731
732 This command takes the following options:
733
734 :param apiuser: This is filled automatically from the |authtoken|.
735 :type apiuser: AuthUser
736 :param username: Set the new username.
737 :type username: str or int
738 :param email: Set the user email address.
739 :type email: str
740 :param password: Set the new user password.
741 :type password: Optional(str)
742 :param firstname: Set the new user firstname.
743 :type firstname: Optional(str)
744 :param lastname: Set the new user surname.
745 :type lastname: Optional(str)
746 :param active: Set the user as active.
747 :type active: Optional(``True`` | ``False``)
748 :param admin: Give the new user admin rights.
749 :type admin: Optional(``True`` | ``False``)
750 :param extern_name: Set the authentication plugin name.
751 Using LDAP this is filled with LDAP UID.
752 :type extern_name: Optional(str)
753 :param extern_type: Set the new user authentication plugin.
754 :type extern_type: Optional(str)
755 :param force_password_change: Force the new user to change password
756 on next login.
757 :type force_password_change: Optional(``True`` | ``False``)
758
759 Example output:
760
761 .. code-block:: bash
762
763 id : <id_given_in_input>
764 result: {
765 "msg" : "created new user `<username>`",
766 "user": <user_obj>
767 }
768 error: null
769
770 Example error output:
771
772 .. code-block:: bash
773
774 id : <id_given_in_input>
775 result : null
776 error : {
777 "user `<username>` already exist"
778 or
779 "email `<email>` already exist"
780 or
781 "failed to create user `<username>`"
782 }
783
784
785 update_user
786 -----------
787
788 .. py:function:: update_user(apiuser, userid, username=<Optional:None>, email=<Optional:None>, password=<Optional:None>, firstname=<Optional:None>, lastname=<Optional:None>, active=<Optional:None>, admin=<Optional:None>, extern_type=<Optional:None>, extern_name=<Optional:None>)
789
790 Updates the details for the specified user, if that user exists.
791
792 This command can only be run using an |authtoken| with admin rights to
793 the specified repository.
794
795 This command takes the following options:
796
797 :param apiuser: This is filled automatically from |authtoken|.
798 :type apiuser: AuthUser
799 :param userid: Set the ``userid`` to update.
800 :type userid: str or int
801 :param username: Set the new username.
802 :type username: str or int
803 :param email: Set the new email.
804 :type email: str
805 :param password: Set the new password.
806 :type password: Optional(str)
807 :param firstname: Set the new first name.
808 :type firstname: Optional(str)
809 :param lastname: Set the new surname.
810 :type lastname: Optional(str)
811 :param active: Set the new user as active.
812 :type active: Optional(``True`` | ``False``)
813 :param admin: Give the user admin rights.
814 :type admin: Optional(``True`` | ``False``)
815 :param extern_name: Set the authentication plugin user name.
816 Using LDAP this is filled with LDAP UID.
817 :type extern_name: Optional(str)
818 :param extern_type: Set the authentication plugin type.
819 :type extern_type: Optional(str)
820
821
822 Example output:
823
824 .. code-block:: bash
825
826 id : <id_given_in_input>
827 result: {
828 "msg" : "updated user ID:<userid> <username>",
829 "user": <user_object>,
830 }
831 error: null
832
833 Example error output:
834
835 .. code-block:: bash
836
837 id : <id_given_in_input>
838 result : null
839 error : {
840 "failed to update user `<username>`"
841 }
842
843
844 delete_user
845 -----------
846
847 .. py:function:: delete_user(apiuser, userid)
848
849 Deletes the specified user from the |RCE| user database.
850
851 This command can only be run using an |authtoken| with admin rights to
852 the specified repository.
853
854 .. important::
855
856 Ensure all open pull requests and open code review
857 requests to this user are close.
858
859 Also ensure all repositories, or repository groups owned by this
860 user are reassigned before deletion.
861
862 This command takes the following options:
863
864 :param apiuser: This is filled automatically from the |authtoken|.
865 :type apiuser: AuthUser
866 :param userid: Set the user to delete.
867 :type userid: str or int
868
869 Example output:
870
871 .. code-block:: bash
872
873 id : <id_given_in_input>
874 result: {
875 "msg" : "deleted user ID:<userid> <username>",
876 "user": null
877 }
878 error: null
879
880 Example error output:
881
882 .. code-block:: bash
883
884 id : <id_given_in_input>
885 result : null
886 error : {
887 "failed to delete user ID:<userid> <username>"
888 }
889
890
891 get_user_group
892 --------------
893
894 .. py:function:: get_user_group(apiuser, usergroupid)
895
896 Returns the data of an existing user group.
897
898 This command can only be run using an |authtoken| with admin rights to
899 the specified repository.
900
901 :param apiuser: This is filled automatically from the |authtoken|.
902 :type apiuser: AuthUser
903 :param usergroupid: Set the user group from which to return data.
904 :type usergroupid: str or int
905
906 Example error output:
907
908 .. code-block:: bash
909
910 {
911 "error": null,
912 "id": <id>,
913 "result": {
914 "active": true,
915 "group_description": "group description",
916 "group_name": "group name",
917 "members": [
918 {
919 "name": "owner-name",
920 "origin": "owner",
921 "permission": "usergroup.admin",
922 "type": "user"
923 },
924 {
925 {
926 "name": "user name",
927 "origin": "permission",
928 "permission": "usergroup.admin",
929 "type": "user"
930 },
931 {
932 "name": "user group name",
933 "origin": "permission",
934 "permission": "usergroup.write",
935 "type": "user_group"
936 }
937 ],
938 "owner": "owner name",
939 "users": [],
940 "users_group_id": 2
941 }
942 }
943
944
945 get_user_groups
946 ---------------
947
948 .. py:function:: get_user_groups(apiuser)
949
950 Lists all the existing user groups within RhodeCode.
951
952 This command can only be run using an |authtoken| with admin rights to
953 the specified repository.
954
955 This command takes the following options:
956
957 :param apiuser: This is filled automatically from the |authtoken|.
958 :type apiuser: AuthUser
959
960 Example error output:
961
962 .. code-block:: bash
963
964 id : <id_given_in_input>
965 result : [<user_group_obj>,...]
966 error : null
967
968
969 create_user_group
970 -----------------
971
972 .. py:function:: create_user_group(apiuser, group_name, description=<Optional:''>, owner=<Optional:<OptionalAttr:apiuser>>, active=<Optional:True>)
973
974 Creates a new user group.
975
976 This command can only be run using an |authtoken| with admin rights to
977 the specified repository.
978
979 This command takes the following options:
980
981 :param apiuser: This is filled automatically from the |authtoken|.
982 :type apiuser: AuthUser
983 :param group_name: Set the name of the new user group.
984 :type group_name: str
985 :param description: Give a description of the new user group.
986 :type description: str
987 :param owner: Set the owner of the new user group.
988 If not set, the owner is the |authtoken| user.
989 :type owner: Optional(str or int)
990 :param active: Set this group as active.
991 :type active: Optional(``True`` | ``False``)
992
993 Example output:
994
995 .. code-block:: bash
996
997 id : <id_given_in_input>
998 result: {
999 "msg": "created new user group `<groupname>`",
1000 "user_group": <user_group_object>
1001 }
1002 error: null
1003
1004 Example error output:
1005
1006 .. code-block:: bash
1007
1008 id : <id_given_in_input>
1009 result : null
1010 error : {
1011 "user group `<group name>` already exist"
1012 or
1013 "failed to create group `<group name>`"
1014 }
1015
1016
1017 update_user_group
1018 -----------------
1019
1020 .. py:function:: update_user_group(apiuser, usergroupid, group_name=<Optional:''>, description=<Optional:''>, owner=<Optional:None>, active=<Optional:True>)
1021
1022 Updates the specified `user group` with the details provided.
1023
1024 This command can only be run using an |authtoken| with admin rights to
1025 the specified repository.
1026
1027 :param apiuser: This is filled automatically from the |authtoken|.
1028 :type apiuser: AuthUser
1029 :param usergroupid: Set the id of the `user group` to update.
1030 :type usergroupid: str or int
1031 :param group_name: Set the new name the `user group`
1032 :type group_name: str
1033 :param description: Give a description for the `user group`
1034 :type description: str
1035 :param owner: Set the owner of the `user group`.
1036 :type owner: Optional(str or int)
1037 :param active: Set the group as active.
1038 :type active: Optional(``True`` | ``False``)
1039
1040 Example output:
1041
1042 .. code-block:: bash
1043
1044 id : <id_given_in_input>
1045 result : {
1046 "msg": 'updated user group ID:<user group id> <user group name>',
1047 "user_group": <user_group_object>
1048 }
1049 error : null
1050
1051 Example error output:
1052
1053 .. code-block:: bash
1054
1055 id : <id_given_in_input>
1056 result : null
1057 error : {
1058 "failed to update user group `<user group name>`"
1059 }
1060
1061
1062 delete_user_group
1063 -----------------
1064
1065 .. py:function:: delete_user_group(apiuser, usergroupid)
1066
1067 Deletes the specified `user group`.
1068
1069 This command can only be run using an |authtoken| with admin rights to
1070 the specified repository.
1071
1072 This command takes the following options:
1073
1074 :param apiuser: filled automatically from apikey
1075 :type apiuser: AuthUser
1076 :param usergroupid:
1077 :type usergroupid: int
1078
1079 Example output:
1080
1081 .. code-block:: bash
1082
1083 id : <id_given_in_input>
1084 result : {
1085 "msg": "deleted user group ID:<user_group_id> <user_group_name>"
1086 }
1087 error : null
1088
1089 Example error output:
1090
1091 .. code-block:: bash
1092
1093 id : <id_given_in_input>
1094 result : null
1095 error : {
1096 "failed to delete user group ID:<user_group_id> <user_group_name>"
1097 or
1098 "RepoGroup assigned to <repo_groups_list>"
1099 }
1100
1101
1102 add_user_to_user_group
1103 ----------------------
1104
1105 .. py:function:: add_user_to_user_group(apiuser, usergroupid, userid)
1106
1107 Adds a user to a `user group`. If the user already exists in the group
1108 this command will return false.
1109
1110 This command can only be run using an |authtoken| with admin rights to
1111 the specified user group.
1112
1113 This command takes the following options:
1114
1115 :param apiuser: This is filled automatically from the |authtoken|.
1116 :type apiuser: AuthUser
1117 :param usergroupid: Set the name of the `user group` to which a
1118 user will be added.
1119 :type usergroupid: int
1120 :param userid: Set the `user_id` of the user to add to the group.
1121 :type userid: int
1122
1123 Example output:
1124
1125 .. code-block:: bash
1126
1127 id : <id_given_in_input>
1128 result : {
1129 "success": True|False # depends on if member is in group
1130 "msg": "added member `<username>` to user group `<groupname>` |
1131 User is already in that group"
1132
1133 }
1134 error : null
1135
1136 Example error output:
1137
1138 .. code-block:: bash
1139
1140 id : <id_given_in_input>
1141 result : null
1142 error : {
1143 "failed to add member to user group `<user_group_name>`"
1144 }
1145
1146
1147 remove_user_from_user_group
1148 ---------------------------
1149
1150 .. py:function:: remove_user_from_user_group(apiuser, usergroupid, userid)
1151
1152 Removes a user from a user group.
1153
1154 * If the specified user is not in the group, this command will return
1155 `false`.
1156
1157 This command can only be run using an |authtoken| with admin rights to
1158 the specified user group.
1159
1160 :param apiuser: This is filled automatically from the |authtoken|.
1161 :type apiuser: AuthUser
1162 :param usergroupid: Sets the user group name.
1163 :type usergroupid: str or int
1164 :param userid: The user you wish to remove from |RCE|.
1165 :type userid: str or int
1166
1167 Example output:
1168
1169 .. code-block:: bash
1170
1171 id : <id_given_in_input>
1172 result: {
1173 "success": True|False, # depends on if member is in group
1174 "msg": "removed member <username> from user group <groupname> |
1175 User wasn't in group"
1176 }
1177 error: null
1178
1179
1180 grant_user_permission_to_user_group
1181 -----------------------------------
1182
1183 .. py:function:: grant_user_permission_to_user_group(apiuser, usergroupid, userid, perm)
1184
1185 Set permissions for a user in a user group.
1186
1187 :param apiuser: This is filled automatically from the |authtoken|.
1188 :type apiuser: AuthUser
1189 :param usergroupid: Set the user group to edit permissions on.
1190 :type usergroupid: str or int
1191 :param userid: Set the user from whom you wish to set permissions.
1192 :type userid: str
1193 :param perm: (usergroup.(none|read|write|admin))
1194 :type perm: str
1195
1196 Example output:
1197
1198 .. code-block:: bash
1199
1200 id : <id_given_in_input>
1201 result : {
1202 "msg": "Granted perm: `<perm_name>` for user: `<username>` in user group: `<user_group_name>`",
1203 "success": true
1204 }
1205 error : null
1206
1207
1208 revoke_user_permission_from_user_group
1209 --------------------------------------
1210
1211 .. py:function:: revoke_user_permission_from_user_group(apiuser, usergroupid, userid)
1212
1213 Revoke a users permissions in a user group.
1214
1215 :param apiuser: This is filled automatically from the |authtoken|.
1216 :type apiuser: AuthUser
1217 :param usergroupid: Set the user group from which to revoke the user
1218 permissions.
1219 :type: usergroupid: str or int
1220 :param userid: Set the userid of the user whose permissions will be
1221 revoked.
1222 :type userid: str
1223
1224 Example output:
1225
1226 .. code-block:: bash
1227
1228 id : <id_given_in_input>
1229 result : {
1230 "msg": "Revoked perm for user: `<username>` in user group: `<user_group_name>`",
1231 "success": true
1232 }
1233 error : null
1234
1235
1236 grant_user_group_permission_to_user_group
1237 -----------------------------------------
1238
1239 .. py:function:: grant_user_group_permission_to_user_group(apiuser, usergroupid, sourceusergroupid, perm)
1240
1241 Give one user group permissions to another user group.
1242
1243 :param apiuser: This is filled automatically from the |authtoken|.
1244 :type apiuser: AuthUser
1245 :param usergroupid: Set the user group on which to edit permissions.
1246 :type usergroupid: str or int
1247 :param sourceusergroupid: Set the source user group to which
1248 access/permissions will be granted.
1249 :type sourceusergroupid: str or int
1250 :param perm: (usergroup.(none|read|write|admin))
1251 :type perm: str
1252
1253 Example output:
1254
1255 .. code-block:: bash
1256
1257 id : <id_given_in_input>
1258 result : {
1259 "msg": "Granted perm: `<perm_name>` for user group: `<source_user_group_name>` in user group: `<user_group_name>`",
1260 "success": true
1261 }
1262 error : null
1263
1264
1265 revoke_user_group_permission_from_user_group
1266 --------------------------------------------
1267
1268 .. py:function:: revoke_user_group_permission_from_user_group(apiuser, usergroupid, sourceusergroupid)
1269
1270 Revoke the permissions that one user group has to another.
1271
1272 :param apiuser: This is filled automatically from the |authtoken|.
1273 :type apiuser: AuthUser
1274 :param usergroupid: Set the user group on which to edit permissions.
1275 :type usergroupid: str or int
1276 :param sourceusergroupid: Set the user group from which permissions
1277 are revoked.
1278 :type sourceusergroupid: str or int
1279
1280 Example output:
1281
1282 .. code-block:: bash
1283
1284 id : <id_given_in_input>
1285 result : {
1286 "msg": "Revoked perm for user group: `<user_group_name>` in user group: `<target_user_group_name>`",
1287 "success": true
1288 }
1289 error : null
1290
1291
1292 get_pull_request
1293 ----------------
1294
1295 .. py:function:: get_pull_request(apiuser, repoid, pullrequestid)
1296
1297 Get a pull request based on the given ID.
1298
1299 :param apiuser: This is filled automatically from the |authtoken|.
1300 :type apiuser: AuthUser
1301 :param repoid: Repository name or repository ID from where the pull
1302 request was opened.
1303 :type repoid: str or int
1304 :param pullrequestid: ID of the requested pull request.
1305 :type pullrequestid: int
1306
1307 Example output:
1308
1309 .. code-block:: bash
1310
1311 "id": <id_given_in_input>,
1312 "result":
1313 {
1314 "pull_request_id": "<pull_request_id>",
1315 "url": "<url>",
1316 "title": "<title>",
1317 "description": "<description>",
1318 "status" : "<status>",
1319 "created_on": "<date_time_created>",
1320 "updated_on": "<date_time_updated>",
1321 "commit_ids": [
1322 ...
1323 "<commit_id>",
1324 "<commit_id>",
1325 ...
1326 ],
1327 "review_status": "<review_status>",
1328 "mergeable": {
1329 "status": "<bool>",
1330 "message": "<message>",
1331 },
1332 "source": {
1333 "clone_url": "<clone_url>",
1334 "repository": "<repository_name>",
1335 "reference":
1336 {
1337 "name": "<name>",
1338 "type": "<type>",
1339 "commit_id": "<commit_id>",
1340 }
1341 },
1342 "target": {
1343 "clone_url": "<clone_url>",
1344 "repository": "<repository_name>",
1345 "reference":
1346 {
1347 "name": "<name>",
1348 "type": "<type>",
1349 "commit_id": "<commit_id>",
1350 }
1351 },
1352 "author": <user_obj>,
1353 "reviewers": [
1354 ...
1355 {
1356 "user": "<user_obj>",
1357 "review_status": "<review_status>",
1358 }
1359 ...
1360 ]
1361 },
1362 "error": null
1363
1364
1365 get_pull_requests
1366 -----------------
1367
1368 .. py:function:: get_pull_requests(apiuser, repoid, status=<Optional:'new'>)
1369
1370 Get all pull requests from the repository specified in `repoid`.
1371
1372 :param apiuser: This is filled automatically from the |authtoken|.
1373 :type apiuser: AuthUser
1374 :param repoid: Repository name or repository ID.
1375 :type repoid: str or int
1376 :param status: Only return pull requests with the specified status.
1377 Valid options are.
1378 * ``new`` (default)
1379 * ``open``
1380 * ``closed``
1381 :type status: str
1382
1383 Example output:
1384
1385 .. code-block:: bash
1386
1387 "id": <id_given_in_input>,
1388 "result":
1389 [
1390 ...
1391 {
1392 "pull_request_id": "<pull_request_id>",
1393 "url": "<url>",
1394 "title" : "<title>",
1395 "description": "<description>",
1396 "status": "<status>",
1397 "created_on": "<date_time_created>",
1398 "updated_on": "<date_time_updated>",
1399 "commit_ids": [
1400 ...
1401 "<commit_id>",
1402 "<commit_id>",
1403 ...
1404 ],
1405 "review_status": "<review_status>",
1406 "mergeable": {
1407 "status": "<bool>",
1408 "message: "<message>",
1409 },
1410 "source": {
1411 "clone_url": "<clone_url>",
1412 "reference":
1413 {
1414 "name": "<name>",
1415 "type": "<type>",
1416 "commit_id": "<commit_id>",
1417 }
1418 },
1419 "target": {
1420 "clone_url": "<clone_url>",
1421 "reference":
1422 {
1423 "name": "<name>",
1424 "type": "<type>",
1425 "commit_id": "<commit_id>",
1426 }
1427 },
1428 "author": <user_obj>,
1429 "reviewers": [
1430 ...
1431 {
1432 "user": "<user_obj>",
1433 "review_status": "<review_status>",
1434 }
1435 ...
1436 ]
1437 }
1438 ...
1439 ],
1440 "error": null
1441
1442
1443 merge_pull_request
1444 ------------------
1445
1446 .. py:function:: merge_pull_request(apiuser, repoid, pullrequestid, userid=<Optional:<OptionalAttr:apiuser>>)
1447
1448 Merge the pull request specified by `pullrequestid` into its target
1449 repository.
1450
1451 :param apiuser: This is filled automatically from the |authtoken|.
1452 :type apiuser: AuthUser
1453 :param repoid: The Repository name or repository ID of the
1454 target repository to which the |pr| is to be merged.
1455 :type repoid: str or int
1456 :param pullrequestid: ID of the pull request which shall be merged.
1457 :type pullrequestid: int
1458 :param userid: Merge the pull request as this user.
1459 :type userid: Optional(str or int)
1460
1461 Example output:
1462
1463 .. code-block:: bash
1464
1465 "id": <id_given_in_input>,
1466 "result":
1467 {
1468 "executed": "<bool>",
1469 "failure_reason": "<int>",
1470 "merge_commit_id": "<merge_commit_id>",
1471 "possible": "<bool>"
1472 },
1473 "error": null
1474
1475
1476 close_pull_request
1477 ------------------
1478
1479 .. py:function:: close_pull_request(apiuser, repoid, pullrequestid, userid=<Optional:<OptionalAttr:apiuser>>)
1480
1481 Close the pull request specified by `pullrequestid`.
1482
1483 :param apiuser: This is filled automatically from the |authtoken|.
1484 :type apiuser: AuthUser
1485 :param repoid: Repository name or repository ID to which the pull
1486 request belongs.
1487 :type repoid: str or int
1488 :param pullrequestid: ID of the pull request to be closed.
1489 :type pullrequestid: int
1490 :param userid: Close the pull request as this user.
1491 :type userid: Optional(str or int)
1492
1493 Example output:
1494
1495 .. code-block:: bash
1496
1497 "id": <id_given_in_input>,
1498 "result":
1499 {
1500 "pull_request_id": "<int>",
1501 "closed": "<bool>"
1502 },
1503 "error": null
1504
1505
1506 comment_pull_request
1507 --------------------
1508
1509 .. py:function:: comment_pull_request(apiuser, repoid, pullrequestid, message=<Optional:None>, status=<Optional:None>, userid=<Optional:<OptionalAttr:apiuser>>)
1510
1511 Comment on the pull request specified with the `pullrequestid`,
1512 in the |repo| specified by the `repoid`, and optionally change the
1513 review status.
1514
1515 :param apiuser: This is filled automatically from the |authtoken|.
1516 :type apiuser: AuthUser
1517 :param repoid: The repository name or repository ID.
1518 :type repoid: str or int
1519 :param pullrequestid: The pull request ID.
1520 :type pullrequestid: int
1521 :param message: The text content of the comment.
1522 :type message: str
1523 :param status: (**Optional**) Set the approval status of the pull
1524 request. Valid options are:
1525 * not_reviewed
1526 * approved
1527 * rejected
1528 * under_review
1529 :type status: str
1530 :param userid: Comment on the pull request as this user
1531 :type userid: Optional(str or int)
1532
1533 Example output:
1534
1535 .. code-block:: bash
1536
1537 id : <id_given_in_input>
1538 result :
1539 {
1540 "pull_request_id": "<Integer>",
1541 "comment_id": "<Integer>"
1542 }
1543 error : null
1544
1545
1546 create_pull_request
1547 -------------------
1548
1549 .. py:function:: create_pull_request(apiuser, source_repo, target_repo, source_ref, target_ref, title, description=<Optional:''>, reviewers=<Optional:None>)
1550
1551 Creates a new pull request.
1552
1553 Accepts refs in the following formats:
1554
1555 * branch:<branch_name>:<sha>
1556 * branch:<branch_name>
1557 * bookmark:<bookmark_name>:<sha> (Mercurial only)
1558 * bookmark:<bookmark_name> (Mercurial only)
1559
1560 :param apiuser: This is filled automatically from the |authtoken|.
1561 :type apiuser: AuthUser
1562 :param source_repo: Set the source repository name.
1563 :type source_repo: str
1564 :param target_repo: Set the target repository name.
1565 :type target_repo: str
1566 :param source_ref: Set the source ref name.
1567 :type source_ref: str
1568 :param target_ref: Set the target ref name.
1569 :type target_ref: str
1570 :param title: Set the pull request title.
1571 :type title: str
1572 :param description: Set the pull request description.
1573 :type description: Optional(str)
1574 :param reviewers: Set the new pull request reviewers list.
1575 :type reviewers: Optional(list)
1576
1577
1578 update_pull_request
1579 -------------------
1580
1581 .. py:function:: update_pull_request(apiuser, repoid, pullrequestid, title=<Optional:''>, description=<Optional:''>, reviewers=<Optional:None>, update_commits=<Optional:None>, close_pull_request=<Optional:None>)
1582
1583 Updates a pull request.
1584
1585 :param apiuser: This is filled automatically from the |authtoken|.
1586 :type apiuser: AuthUser
1587 :param repoid: The repository name or repository ID.
1588 :type repoid: str or int
1589 :param pullrequestid: The pull request ID.
1590 :type pullrequestid: int
1591 :param title: Set the pull request title.
1592 :type title: str
1593 :param description: Update pull request description.
1594 :type description: Optional(str)
1595 :param reviewers: Update pull request reviewers list with new value.
1596 :type reviewers: Optional(list)
1597 :param update_commits: Trigger update of commits for this pull request
1598 :type: update_commits: Optional(bool)
1599 :param close_pull_request: Close this pull request with rejected state
1600 :type: close_pull_request: Optional(bool)
1601
1602 Example output:
1603
1604 .. code-block:: bash
1605
1606 id : <id_given_in_input>
1607 result :
1608 {
1609 "msg": "Updated pull request `63`",
1610 "pull_request": <pull_request_object>,
1611 "updated_reviewers": {
1612 "added": [
1613 "username"
1614 ],
1615 "removed": []
1616 },
1617 "updated_commits": {
1618 "added": [
1619 "<sha1_hash>"
1620 ],
1621 "common": [
1622 "<sha1_hash>",
1623 "<sha1_hash>",
1624 ],
1625 "removed": []
1626 }
1627 }
1628 error : null
1629
1630
1631 get_repo
1632 --------
1633
1634 .. py:function:: get_repo(apiuser, repoid, cache=<Optional:True>)
1635
1636 Gets an existing repository by its name or repository_id.
1637
1638 The members section so the output returns users groups or users
1639 associated with that repository.
1640
1641 This command can only be run using an |authtoken| with admin rights,
1642 or users with at least read rights to the |repo|.
1643
1644 :param apiuser: This is filled automatically from the |authtoken|.
1645 :type apiuser: AuthUser
1646 :param repoid: The repository name or repository id.
1647 :type repoid: str or int
1648 :param cache: use the cached value for last changeset
1649 :type: cache: Optional(bool)
1650
1651 Example output:
1652
1653 .. code-block:: bash
1654
1655 {
1656 "error": null,
1657 "id": <repo_id>,
1658 "result": {
1659 "clone_uri": null,
1660 "created_on": "timestamp",
1661 "description": "repo description",
1662 "enable_downloads": false,
1663 "enable_locking": false,
1664 "enable_statistics": false,
1665 "followers": [
1666 {
1667 "active": true,
1668 "admin": false,
1669 "api_key": "****************************************",
1670 "api_keys": [
1671 "****************************************"
1672 ],
1673 "email": "user@example.com",
1674 "emails": [
1675 "user@example.com"
1676 ],
1677 "extern_name": "rhodecode",
1678 "extern_type": "rhodecode",
1679 "firstname": "username",
1680 "ip_addresses": [],
1681 "language": null,
1682 "last_login": "2015-09-16T17:16:35.854",
1683 "lastname": "surname",
1684 "user_id": <user_id>,
1685 "username": "name"
1686 }
1687 ],
1688 "fork_of": "parent-repo",
1689 "landing_rev": [
1690 "rev",
1691 "tip"
1692 ],
1693 "last_changeset": {
1694 "author": "User <user@example.com>",
1695 "branch": "default",
1696 "date": "timestamp",
1697 "message": "last commit message",
1698 "parents": [
1699 {
1700 "raw_id": "commit-id"
1701 }
1702 ],
1703 "raw_id": "commit-id",
1704 "revision": <revision number>,
1705 "short_id": "short id"
1706 },
1707 "lock_reason": null,
1708 "locked_by": null,
1709 "locked_date": null,
1710 "members": [
1711 {
1712 "name": "super-admin-name",
1713 "origin": "super-admin",
1714 "permission": "repository.admin",
1715 "type": "user"
1716 },
1717 {
1718 "name": "owner-name",
1719 "origin": "owner",
1720 "permission": "repository.admin",
1721 "type": "user"
1722 },
1723 {
1724 "name": "user-group-name",
1725 "origin": "permission",
1726 "permission": "repository.write",
1727 "type": "user_group"
1728 }
1729 ],
1730 "owner": "owner-name",
1731 "permissions": [
1732 {
1733 "name": "super-admin-name",
1734 "origin": "super-admin",
1735 "permission": "repository.admin",
1736 "type": "user"
1737 },
1738 {
1739 "name": "owner-name",
1740 "origin": "owner",
1741 "permission": "repository.admin",
1742 "type": "user"
1743 },
1744 {
1745 "name": "user-group-name",
1746 "origin": "permission",
1747 "permission": "repository.write",
1748 "type": "user_group"
1749 }
1750 ],
1751 "private": true,
1752 "repo_id": 676,
1753 "repo_name": "user-group/repo-name",
1754 "repo_type": "hg"
1755 }
1756 }
1757
1758
1759 get_repos
1760 ---------
1761
1762 .. py:function:: get_repos(apiuser)
1763
1764 Lists all existing repositories.
1765
1766 This command can only be run using an |authtoken| with admin rights,
1767 or users with at least read rights to |repos|.
1768
1769 :param apiuser: This is filled automatically from the |authtoken|.
1770 :type apiuser: AuthUser
1771
1772 Example output:
1773
1774 .. code-block:: bash
1775
1776 id : <id_given_in_input>
1777 result: [
1778 {
1779 "repo_id" : "<repo_id>",
1780 "repo_name" : "<reponame>"
1781 "repo_type" : "<repo_type>",
1782 "clone_uri" : "<clone_uri>",
1783 "private": : "<bool>",
1784 "created_on" : "<datetimecreated>",
1785 "description" : "<description>",
1786 "landing_rev": "<landing_rev>",
1787 "owner": "<repo_owner>",
1788 "fork_of": "<name_of_fork_parent>",
1789 "enable_downloads": "<bool>",
1790 "enable_locking": "<bool>",
1791 "enable_statistics": "<bool>",
1792 },
1793 ...
1794 ]
1795 error: null
1796
1797
1798 get_repo_changeset
1799 ------------------
1800
1801 .. py:function:: get_repo_changeset(apiuser, repoid, revision, details=<Optional:'basic'>)
1802
1803 Returns information about a changeset.
1804
1805 Additionally parameters define the amount of details returned by
1806 this function.
1807
1808 This command can only be run using an |authtoken| with admin rights,
1809 or users with at least read rights to the |repo|.
1810
1811 :param apiuser: This is filled automatically from the |authtoken|.
1812 :type apiuser: AuthUser
1813 :param repoid: The repository name or repository id
1814 :type repoid: str or int
1815 :param revision: revision for which listing should be done
1816 :type revision: str
1817 :param details: details can be 'basic|extended|full' full gives diff
1818 info details like the diff itself, and number of changed files etc.
1819 :type details: Optional(str)
1820
1821
1822 get_repo_changesets
1823 -------------------
1824
1825 .. py:function:: get_repo_changesets(apiuser, repoid, start_rev, limit, details=<Optional:'basic'>)
1826
1827 Returns a set of changesets limited by the number of commits starting
1828 from the `start_rev` option.
1829
1830 Additional parameters define the amount of details returned by this
1831 function.
1832
1833 This command can only be run using an |authtoken| with admin rights,
1834 or users with at least read rights to |repos|.
1835
1836 :param apiuser: This is filled automatically from the |authtoken|.
1837 :type apiuser: AuthUser
1838 :param repoid: The repository name or repository ID.
1839 :type repoid: str or int
1840 :param start_rev: The starting revision from where to get changesets.
1841 :type start_rev: str
1842 :param limit: Limit the number of changesets to this amount
1843 :type limit: str or int
1844 :param details: Set the level of detail returned. Valid option are:
1845 ``basic``, ``extended`` and ``full``.
1846 :type details: Optional(str)
1847
1848 .. note::
1849
1850 Setting the parameter `details` to the value ``full`` is extensive
1851 and returns details like the diff itself, and the number
1852 of changed files.
1853
1854
1855 get_repo_nodes
1856 --------------
1857
1858 .. py:function:: get_repo_nodes(apiuser, repoid, revision, root_path, ret_type=<Optional:'all'>, details=<Optional:'basic'>)
1859
1860 Returns a list of nodes and children in a flat list for a given
1861 path at given revision.
1862
1863 It's possible to specify ret_type to show only `files` or `dirs`.
1864
1865 This command can only be run using an |authtoken| with admin rights,
1866 or users with at least read rights to |repos|.
1867
1868 :param apiuser: This is filled automatically from the |authtoken|.
1869 :type apiuser: AuthUser
1870 :param repoid: The repository name or repository ID.
1871 :type repoid: str or int
1872 :param revision: The revision for which listing should be done.
1873 :type revision: str
1874 :param root_path: The path from which to start displaying.
1875 :type root_path: str
1876 :param ret_type: Set the return type. Valid options are
1877 ``all`` (default), ``files`` and ``dirs``.
1878 :type ret_type: Optional(str)
1879 :param details: Returns extended information about nodes, such as
1880 md5, binary, and or content. The valid options are ``basic`` and
1881 ``full``.
1882 :type details: Optional(str)
1883
1884 Example output:
1885
1886 .. code-block:: bash
1887
1888 id : <id_given_in_input>
1889 result: [
1890 {
1891 "name" : "<name>"
1892 "type" : "<type>",
1893 "binary": "<true|false>" (only in extended mode)
1894 "md5" : "<md5 of file content>" (only in extended mode)
1895 },
1896 ...
1897 ]
1898 error: null
1899
1900
1901 create_repo
1902 -----------
1903
1904 .. py:function:: create_repo(apiuser, repo_name, repo_type, owner=<Optional:<OptionalAttr:apiuser>>, description=<Optional:''>, private=<Optional:False>, clone_uri=<Optional:None>, landing_rev=<Optional:'rev:tip'>, enable_statistics=<Optional:False>, enable_locking=<Optional:False>, enable_downloads=<Optional:False>, copy_permissions=<Optional:False>)
1905
1906 Creates a repository.
1907
1908 * If the repository name contains "/", all the required repository
1909 groups will be created.
1910
1911 For example "foo/bar/baz" will create |repo| groups "foo" and "bar"
1912 (with "foo" as parent). It will also create the "baz" repository
1913 with "bar" as |repo| group.
1914
1915 This command can only be run using an |authtoken| with at least
1916 write permissions to the |repo|.
1917
1918 :param apiuser: This is filled automatically from the |authtoken|.
1919 :type apiuser: AuthUser
1920 :param repo_name: Set the repository name.
1921 :type repo_name: str
1922 :param repo_type: Set the repository type; 'hg','git', or 'svn'.
1923 :type repo_type: str
1924 :param owner: user_id or username
1925 :type owner: Optional(str)
1926 :param description: Set the repository description.
1927 :type description: Optional(str)
1928 :param private:
1929 :type private: bool
1930 :param clone_uri:
1931 :type clone_uri: str
1932 :param landing_rev: <rev_type>:<rev>
1933 :type landing_rev: str
1934 :param enable_locking:
1935 :type enable_locking: bool
1936 :param enable_downloads:
1937 :type enable_downloads: bool
1938 :param enable_statistics:
1939 :type enable_statistics: bool
1940 :param copy_permissions: Copy permission from group in which the
1941 repository is being created.
1942 :type copy_permissions: bool
1943
1944
1945 Example output:
1946
1947 .. code-block:: bash
1948
1949 id : <id_given_in_input>
1950 result: {
1951 "msg": "Created new repository `<reponame>`",
1952 "success": true,
1953 "task": "<celery task id or None if done sync>"
1954 }
1955 error: null
1956
1957
1958 Example error output:
1959
1960 .. code-block:: bash
1961
1962 id : <id_given_in_input>
1963 result : null
1964 error : {
1965 'failed to create repository `<repo_name>`
1966 }
1967
1968
1969 add_field_to_repo
1970 -----------------
1971
1972 .. py:function:: add_field_to_repo(apiuser, repoid, key, label=<Optional:''>, description=<Optional:''>)
1973
1974 Adds an extra field to a repository.
1975
1976 This command can only be run using an |authtoken| with at least
1977 write permissions to the |repo|.
1978
1979 :param apiuser: This is filled automatically from the |authtoken|.
1980 :type apiuser: AuthUser
1981 :param repoid: Set the repository name or repository id.
1982 :type repoid: str or int
1983 :param key: Create a unique field key for this repository.
1984 :type key: str
1985 :param label:
1986 :type label: Optional(str)
1987 :param description:
1988 :type description: Optional(str)
1989
1990
1991 remove_field_from_repo
1992 ----------------------
1993
1994 .. py:function:: remove_field_from_repo(apiuser, repoid, key)
1995
1996 Removes an extra field from a repository.
1997
1998 This command can only be run using an |authtoken| with at least
1999 write permissions to the |repo|.
2000
2001 :param apiuser: This is filled automatically from the |authtoken|.
2002 :type apiuser: AuthUser
2003 :param repoid: Set the repository name or repository ID.
2004 :type repoid: str or int
2005 :param key: Set the unique field key for this repository.
2006 :type key: str
2007
2008
2009 update_repo
2010 -----------
2011
2012 .. py:function:: update_repo(apiuser, repoid, name=<Optional:None>, owner=<Optional:<OptionalAttr:apiuser>>, group=<Optional:None>, fork_of=<Optional:None>, description=<Optional:''>, private=<Optional:False>, clone_uri=<Optional:None>, landing_rev=<Optional:'rev:tip'>, enable_statistics=<Optional:False>, enable_locking=<Optional:False>, enable_downloads=<Optional:False>, fields=<Optional:''>)
2013
2014 Updates a repository with the given information.
2015
2016 This command can only be run using an |authtoken| with at least
2017 write permissions to the |repo|.
2018
2019 :param apiuser: This is filled automatically from the |authtoken|.
2020 :type apiuser: AuthUser
2021 :param repoid: repository name or repository ID.
2022 :type repoid: str or int
2023 :param name: Update the |repo| name.
2024 :type name: str
2025 :param owner: Set the |repo| owner.
2026 :type owner: str
2027 :param group: Set the |repo| group the |repo| belongs to.
2028 :type group: str
2029 :param fork_of: Set the master |repo| name.
2030 :type fork_of: str
2031 :param description: Update the |repo| description.
2032 :type description: str
2033 :param private: Set the |repo| as private. (True | False)
2034 :type private: bool
2035 :param clone_uri: Update the |repo| clone URI.
2036 :type clone_uri: str
2037 :param landing_rev: Set the |repo| landing revision. Default is
2038 ``tip``.
2039 :type landing_rev: str
2040 :param enable_statistics: Enable statistics on the |repo|,
2041 (True | False).
2042 :type enable_statistics: bool
2043 :param enable_locking: Enable |repo| locking.
2044 :type enable_locking: bool
2045 :param enable_downloads: Enable downloads from the |repo|,
2046 (True | False).
2047 :type enable_downloads: bool
2048 :param fields: Add extra fields to the |repo|. Use the following
2049 example format: ``field_key=field_val,field_key2=fieldval2``.
2050 Escape ', ' with \,
2051 :type fields: str
2052
2053
2054 fork_repo
2055 ---------
2056
2057 .. py:function:: fork_repo(apiuser, repoid, fork_name, owner=<Optional:<OptionalAttr:apiuser>>, description=<Optional:''>, copy_permissions=<Optional:False>, private=<Optional:False>, landing_rev=<Optional:'rev:tip'>)
2058
2059 Creates a fork of the specified |repo|.
2060
2061 * If using |RCE| with Celery this will immediately return a success
2062 message, even though the fork will be created asynchronously.
2063
2064 This command can only be run using an |authtoken| with fork
2065 permissions on the |repo|.
2066
2067 :param apiuser: This is filled automatically from the |authtoken|.
2068 :type apiuser: AuthUser
2069 :param repoid: Set repository name or repository ID.
2070 :type repoid: str or int
2071 :param fork_name: Set the fork name.
2072 :type fork_name: str
2073 :param owner: Set the fork owner.
2074 :type owner: str
2075 :param description: Set the fork descripton.
2076 :type description: str
2077 :param copy_permissions: Copy permissions from parent |repo|. The
2078 default is False.
2079 :type copy_permissions: bool
2080 :param private: Make the fork private. The default is False.
2081 :type private: bool
2082 :param landing_rev: Set the landing revision. The default is tip.
2083
2084 Example output:
2085
2086 .. code-block:: bash
2087
2088 id : <id_for_response>
2089 api_key : "<api_key>"
2090 args: {
2091 "repoid" : "<reponame or repo_id>",
2092 "fork_name": "<forkname>",
2093 "owner": "<username or user_id = Optional(=apiuser)>",
2094 "description": "<description>",
2095 "copy_permissions": "<bool>",
2096 "private": "<bool>",
2097 "landing_rev": "<landing_rev>"
2098 }
2099
2100 Example error output:
2101
2102 .. code-block:: bash
2103
2104 id : <id_given_in_input>
2105 result: {
2106 "msg": "Created fork of `<reponame>` as `<forkname>`",
2107 "success": true,
2108 "task": "<celery task id or None if done sync>"
2109 }
2110 error: null
2111
2112
2113 delete_repo
2114 -----------
2115
2116 .. py:function:: delete_repo(apiuser, repoid, forks=<Optional:''>)
2117
2118 Deletes a repository.
2119
2120 * When the `forks` parameter is set it's possible to detach or delete
2121 forks of deleted repository.
2122
2123 This command can only be run using an |authtoken| with admin
2124 permissions on the |repo|.
2125
2126 :param apiuser: This is filled automatically from the |authtoken|.
2127 :type apiuser: AuthUser
2128 :param repoid: Set the repository name or repository ID.
2129 :type repoid: str or int
2130 :param forks: Set to `detach` or `delete` forks from the |repo|.
2131 :type forks: Optional(str)
2132
2133 Example error output:
2134
2135 .. code-block:: bash
2136
2137 id : <id_given_in_input>
2138 result: {
2139 "msg": "Deleted repository `<reponame>`",
2140 "success": true
2141 }
2142 error: null
2143
2144
2145 comment_commit
2146 --------------
2147
2148 .. py:function:: comment_commit(apiuser, repoid, commit_id, message, userid=<Optional:<OptionalAttr:apiuser>>, status=<Optional:None>)
2149
2150 Set a commit comment, and optionally change the status of the commit.
2151 This command can be executed only using api_key belonging to user
2152 with admin rights, or repository administrator.
2153
2154 :param apiuser: This is filled automatically from the |authtoken|.
2155 :type apiuser: AuthUser
2156 :param repoid: Set the repository name or repository ID.
2157 :type repoid: str or int
2158 :param commit_id: Specify the commit_id for which to set a comment.
2159 :type commit_id: str
2160 :param message: The comment text.
2161 :type message: str
2162 :param userid: Set the user name of the comment creator.
2163 :type userid: Optional(str or int)
2164 :param status: status, one of 'not_reviewed', 'approved', 'rejected',
2165 'under_review'
2166 :type status: str
2167
2168 Example error output:
2169
2170 .. code-block:: json
2171
2172 {
2173 "id" : <id_given_in_input>,
2174 "result" : {
2175 "msg": "Commented on commit `<commit_id>` for repository `<repoid>`",
2176 "status_change": null or <status>,
2177 "success": true
2178 },
2179 "error" : null
2180 }
2181
2182
2183 changeset_comment
2184 -----------------
2185
2186 .. py:function:: changeset_comment(apiuser, repoid, revision, message, userid=<Optional:<OptionalAttr:apiuser>>, status=<Optional:None>)
2187
2188 .. deprecated:: 3.4.0
2189
2190 Please use method `comment_commit` instead.
2191
2192
2193 Set a changeset comment, and optionally change the status of the
2194 changeset.
2195
2196 This command can only be run using an |authtoken| with admin
2197 permissions on the |repo|.
2198
2199 :param apiuser: This is filled automatically from the |authtoken|.
2200 :type apiuser: AuthUser
2201 :param repoid: Set the repository name or repository ID.
2202 :type repoid: str or int
2203 :param revision: Specify the revision for which to set a comment.
2204 :type revision: str
2205 :param message: The comment text.
2206 :type message: str
2207 :param userid: Set the user name of the comment creator.
2208 :type userid: Optional(str or int)
2209 :param status: Set the comment status. The following are valid options:
2210 * not_reviewed
2211 * approved
2212 * rejected
2213 * under_review
2214 :type status: str
2215
2216 Example error output:
2217
2218 .. code-block:: json
2219
2220 {
2221 "id" : <id_given_in_input>,
2222 "result" : {
2223 "msg": "Commented on commit `<revision>` for repository `<repoid>`",
2224 "status_change": null or <status>,
2225 "success": true
2226 },
2227 "error" : null
2228 }
2229
2230
2231 grant_user_permission
2232 ---------------------
2233
2234 .. py:function:: grant_user_permission(apiuser, repoid, userid, perm)
2235
2236 Grant permissions for the specified user on the given repository,
2237 or update existing permissions if found.
2238
2239 This command can only be run using an |authtoken| with admin
2240 permissions on the |repo|.
2241
2242 :param apiuser: This is filled automatically from the |authtoken|.
2243 :type apiuser: AuthUser
2244 :param repoid: Set the repository name or repository ID.
2245 :type repoid: str or int
2246 :param userid: Set the user name.
2247 :type userid: str
2248 :param perm: Set the user permissions, using the following format
2249 ``(repository.(none|read|write|admin))``
2250 :type perm: str
2251
2252 Example output:
2253
2254 .. code-block:: bash
2255
2256 id : <id_given_in_input>
2257 result: {
2258 "msg" : "Granted perm: `<perm>` for user: `<username>` in repo: `<reponame>`",
2259 "success": true
2260 }
2261 error: null
2262
2263
2264 revoke_user_permission
2265 ----------------------
2266
2267 .. py:function:: revoke_user_permission(apiuser, repoid, userid)
2268
2269 Revoke permission for a user on the specified repository.
2270
2271 This command can only be run using an |authtoken| with admin
2272 permissions on the |repo|.
2273
2274 :param apiuser: This is filled automatically from the |authtoken|.
2275 :type apiuser: AuthUser
2276 :param repoid: Set the repository name or repository ID.
2277 :type repoid: str or int
2278 :param userid: Set the user name of revoked user.
2279 :type userid: str or int
2280
2281 Example error output:
2282
2283 .. code-block:: bash
2284
2285 id : <id_given_in_input>
2286 result: {
2287 "msg" : "Revoked perm for user: `<username>` in repo: `<reponame>`",
2288 "success": true
2289 }
2290 error: null
2291
2292
2293 grant_user_group_permission
2294 ---------------------------
2295
2296 .. py:function:: grant_user_group_permission(apiuser, repoid, usergroupid, perm)
2297
2298 Grant permission for a user group on the specified repository,
2299 or update existing permissions.
2300
2301 This command can only be run using an |authtoken| with admin
2302 permissions on the |repo|.
2303
2304 :param apiuser: This is filled automatically from the |authtoken|.
2305 :type apiuser: AuthUser
2306 :param repoid: Set the repository name or repository ID.
2307 :type repoid: str or int
2308 :param usergroupid: Specify the ID of the user group.
2309 :type usergroupid: str or int
2310 :param perm: Set the user group permissions using the following
2311 format: (repository.(none|read|write|admin))
2312 :type perm: str
2313
2314 Example output:
2315
2316 .. code-block:: bash
2317
2318 id : <id_given_in_input>
2319 result : {
2320 "msg" : "Granted perm: `<perm>` for group: `<usersgroupname>` in repo: `<reponame>`",
2321 "success": true
2322
2323 }
2324 error : null
2325
2326 Example error output:
2327
2328 .. code-block:: bash
2329
2330 id : <id_given_in_input>
2331 result : null
2332 error : {
2333 "failed to edit permission for user group: `<usergroup>` in repo `<repo>`'
2334 }
2335
2336
2337 revoke_user_group_permission
2338 ----------------------------
2339
2340 .. py:function:: revoke_user_group_permission(apiuser, repoid, usergroupid)
2341
2342 Revoke the permissions of a user group on a given repository.
2343
2344 This command can only be run using an |authtoken| with admin
2345 permissions on the |repo|.
2346
2347 :param apiuser: This is filled automatically from the |authtoken|.
2348 :type apiuser: AuthUser
2349 :param repoid: Set the repository name or repository ID.
2350 :type repoid: str or int
2351 :param usergroupid: Specify the user group ID.
2352 :type usergroupid: str or int
2353
2354 Example output:
2355
2356 .. code-block:: bash
2357
2358 id : <id_given_in_input>
2359 result: {
2360 "msg" : "Revoked perm for group: `<usersgroupname>` in repo: `<reponame>`",
2361 "success": true
2362 }
2363 error: null
2364
2365
2366 get_repo_group
2367 --------------
2368
2369 .. py:function:: get_repo_group(apiuser, repogroupid)
2370
2371 Return the specified |repo| group, along with permissions,
2372 and repositories inside the group
2373
2374 :param apiuser: This is filled automatically from the |authtoken|.
2375 :type apiuser: AuthUser
2376 :param repogroupid: Specify the name of ID of the repository group.
2377 :type repogroupid: str or int
2378
2379
2380 Example output:
2381
2382 .. code-block:: bash
2383
2384 {
2385 "error": null,
2386 "id": repo-group-id,
2387 "result": {
2388 "group_description": "repo group description",
2389 "group_id": 14,
2390 "group_name": "group name",
2391 "members": [
2392 {
2393 "name": "super-admin-username",
2394 "origin": "super-admin",
2395 "permission": "group.admin",
2396 "type": "user"
2397 },
2398 {
2399 "name": "owner-name",
2400 "origin": "owner",
2401 "permission": "group.admin",
2402 "type": "user"
2403 },
2404 {
2405 "name": "user-group-name",
2406 "origin": "permission",
2407 "permission": "group.write",
2408 "type": "user_group"
2409 }
2410 ],
2411 "owner": "owner-name",
2412 "parent_group": null,
2413 "repositories": [ repo-list ]
2414 }
2415 }
2416
2417
2418 get_repo_groups
2419 ---------------
2420
2421 .. py:function:: get_repo_groups(apiuser)
2422
2423 Returns all repository groups.
2424
2425 :param apiuser: This is filled automatically from the |authtoken|.
2426 :type apiuser: AuthUser
2427
2428
2429 create_repo_group
2430 -----------------
2431
2432 .. py:function:: create_repo_group(apiuser, group_name, description=<Optional:''>, owner=<Optional:<OptionalAttr:apiuser>>, copy_permissions=<Optional:False>)
2433
2434 Creates a repository group.
2435
2436 * If the repository group name contains "/", all the required repository
2437 groups will be created.
2438
2439 For example "foo/bar/baz" will create |repo| groups "foo" and "bar"
2440 (with "foo" as parent). It will also create the "baz" repository
2441 with "bar" as |repo| group.
2442
2443 This command can only be run using an |authtoken| with admin
2444 permissions.
2445
2446 :param apiuser: This is filled automatically from the |authtoken|.
2447 :type apiuser: AuthUser
2448 :param group_name: Set the repository group name.
2449 :type group_name: str
2450 :param description: Set the |repo| group description.
2451 :type description: str
2452 :param owner: Set the |repo| group owner.
2453 :type owner: str
2454 :param copy_permissions:
2455 :type copy_permissions:
2456
2457 Example output:
2458
2459 .. code-block:: bash
2460
2461 id : <id_given_in_input>
2462 result : {
2463 "msg": "Created new repo group `<repo_group_name>`"
2464 "repo_group": <repogroup_object>
2465 }
2466 error : null
2467
2468
2469 Example error output:
2470
2471 .. code-block:: bash
2472
2473 id : <id_given_in_input>
2474 result : null
2475 error : {
2476 failed to create repo group `<repogroupid>`
2477 }
2478
2479
2480 update_repo_group
2481 -----------------
2482
2483 .. py:function:: update_repo_group(apiuser, repogroupid, group_name=<Optional:''>, description=<Optional:''>, owner=<Optional:<OptionalAttr:apiuser>>, parent=<Optional:None>, enable_locking=<Optional:False>)
2484
2485 Updates repository group with the details given.
2486
2487 This command can only be run using an |authtoken| with admin
2488 permissions.
2489
2490 :param apiuser: This is filled automatically from the |authtoken|.
2491 :type apiuser: AuthUser
2492 :param repogroupid: Set the ID of repository group.
2493 :type repogroupid: str or int
2494 :param group_name: Set the name of the |repo| group.
2495 :type group_name: str
2496 :param description: Set a description for the group.
2497 :type description: str
2498 :param owner: Set the |repo| group owner.
2499 :type owner: str
2500 :param parent: Set the |repo| group parent.
2501 :type parent: str or int
2502 :param enable_locking: Enable |repo| locking. The default is false.
2503 :type enable_locking: bool
2504
2505
2506 delete_repo_group
2507 -----------------
2508
2509 .. py:function:: delete_repo_group(apiuser, repogroupid)
2510
2511 Deletes a |repo| group.
2512
2513 :param apiuser: This is filled automatically from the |authtoken|.
2514 :type apiuser: AuthUser
2515 :param repogroupid: Set the name or ID of repository group to be
2516 deleted.
2517 :type repogroupid: str or int
2518
2519 Example output:
2520
2521 .. code-block:: bash
2522
2523 id : <id_given_in_input>
2524 result : {
2525 'msg': 'deleted repo group ID:<repogroupid> <repogroupname>
2526 'repo_group': null
2527 }
2528 error : null
2529
2530 Example error output:
2531
2532 .. code-block:: bash
2533
2534 id : <id_given_in_input>
2535 result : null
2536 error : {
2537 "failed to delete repo group ID:<repogroupid> <repogroupname>"
2538 }
2539
2540
2541 grant_user_permission_to_repo_group
2542 -----------------------------------
2543
2544 .. py:function:: grant_user_permission_to_repo_group(apiuser, repogroupid, userid, perm, apply_to_children=<Optional:'none'>)
2545
2546 Grant permission for a user on the given repository group, or update
2547 existing permissions if found.
2548
2549 This command can only be run using an |authtoken| with admin
2550 permissions.
2551
2552 :param apiuser: This is filled automatically from the |authtoken|.
2553 :type apiuser: AuthUser
2554 :param repogroupid: Set the name or ID of repository group.
2555 :type repogroupid: str or int
2556 :param userid: Set the user name.
2557 :type userid: str
2558 :param perm: (group.(none|read|write|admin))
2559 :type perm: str
2560 :param apply_to_children: 'none', 'repos', 'groups', 'all'
2561 :type apply_to_children: str
2562
2563 Example output:
2564
2565 .. code-block:: bash
2566
2567 id : <id_given_in_input>
2568 result: {
2569 "msg" : "Granted perm: `<perm>` (recursive:<apply_to_children>) for user: `<username>` in repo group: `<repo_group_name>`",
2570 "success": true
2571 }
2572 error: null
2573
2574 Example error output:
2575
2576 .. code-block:: bash
2577
2578 id : <id_given_in_input>
2579 result : null
2580 error : {
2581 "failed to edit permission for user: `<userid>` in repo group: `<repo_group_name>`"
2582 }
2583
2584
2585 revoke_user_permission_from_repo_group
2586 --------------------------------------
2587
2588 .. py:function:: revoke_user_permission_from_repo_group(apiuser, repogroupid, userid, apply_to_children=<Optional:'none'>)
2589
2590 Revoke permission for a user in a given repository group.
2591
2592 This command can only be run using an |authtoken| with admin
2593 permissions on the |repo| group.
2594
2595 :param apiuser: This is filled automatically from the |authtoken|.
2596 :type apiuser: AuthUser
2597 :param repogroupid: Set the name or ID of the repository group.
2598 :type repogroupid: str or int
2599 :param userid: Set the user name to revoke.
2600 :type userid: str
2601 :param apply_to_children: 'none', 'repos', 'groups', 'all'
2602 :type apply_to_children: str
2603
2604 Example output:
2605
2606 .. code-block:: bash
2607
2608 id : <id_given_in_input>
2609 result: {
2610 "msg" : "Revoked perm (recursive:<apply_to_children>) for user: `<username>` in repo group: `<repo_group_name>`",
2611 "success": true
2612 }
2613 error: null
2614
2615 Example error output:
2616
2617 .. code-block:: bash
2618
2619 id : <id_given_in_input>
2620 result : null
2621 error : {
2622 "failed to edit permission for user: `<userid>` in repo group: `<repo_group_name>`"
2623 }
2624
2625
2626 grant_user_group_permission_to_repo_group
2627 -----------------------------------------
2628
2629 .. py:function:: grant_user_group_permission_to_repo_group(apiuser, repogroupid, usergroupid, perm, apply_to_children=<Optional:'none'>)
2630
2631 Grant permission for a user group on given repository group, or update
2632 existing permissions if found.
2633
2634 This command can only be run using an |authtoken| with admin
2635 permissions on the |repo| group.
2636
2637 :param apiuser: This is filled automatically from the |authtoken|.
2638 :type apiuser: AuthUser
2639 :param repogroupid: Set the name or id of repository group
2640 :type repogroupid: str or int
2641 :param usergroupid: id of usergroup
2642 :type usergroupid: str or int
2643 :param perm: (group.(none|read|write|admin))
2644 :type perm: str
2645 :param apply_to_children: 'none', 'repos', 'groups', 'all'
2646 :type apply_to_children: str
2647
2648 Example output:
2649
2650 .. code-block:: bash
2651
2652 id : <id_given_in_input>
2653 result : {
2654 "msg" : "Granted perm: `<perm>` (recursive:<apply_to_children>) for user group: `<usersgroupname>` in repo group: `<repo_group_name>`",
2655 "success": true
2656
2657 }
2658 error : null
2659
2660 Example error output:
2661
2662 .. code-block:: bash
2663
2664 id : <id_given_in_input>
2665 result : null
2666 error : {
2667 "failed to edit permission for user group: `<usergroup>` in repo group: `<repo_group_name>`"
2668 }
2669
2670
2671 revoke_user_group_permission_from_repo_group
2672 --------------------------------------------
2673
2674 .. py:function:: revoke_user_group_permission_from_repo_group(apiuser, repogroupid, usergroupid, apply_to_children=<Optional:'none'>)
2675
2676 Revoke permission for user group on given repository.
2677
2678 This command can only be run using an |authtoken| with admin
2679 permissions on the |repo| group.
2680
2681 :param apiuser: This is filled automatically from the |authtoken|.
2682 :type apiuser: AuthUser
2683 :param repogroupid: name or id of repository group
2684 :type repogroupid: str or int
2685 :param usergroupid:
2686 :param apply_to_children: 'none', 'repos', 'groups', 'all'
2687 :type apply_to_children: str
2688
2689 Example output:
2690
2691 .. code-block:: bash
2692
2693 id : <id_given_in_input>
2694 result: {
2695 "msg" : "Revoked perm (recursive:<apply_to_children>) for user group: `<usersgroupname>` in repo group: `<repo_group_name>`",
2696 "success": true
2697 }
2698 error: null
2699
2700 Example error output:
2701
2702 .. code-block:: bash
2703
2704 id : <id_given_in_input>
2705 result : null
2706 error : {
2707 "failed to edit permission for user group: `<usergroup>` in repo group: `<repo_group_name>`"
2708 }
2709
2710
2711 get_gist
2712 --------
2713
2714 .. py:function:: get_gist(apiuser, gistid, content=<Optional:False>)
2715
2716 Get the specified gist, based on the gist ID.
2717
2718 :param apiuser: This is filled automatically from the |authtoken|.
2719 :type apiuser: AuthUser
2720 :param gistid: Set the id of the private or public gist
2721 :type gistid: str
2722 :param content: Return the gist content. Default is false.
2723 :type content: Optional(bool)
2724
2725
2726 get_gists
2727 ---------
2728
2729 .. py:function:: get_gists(apiuser, userid=<Optional:<OptionalAttr:apiuser>>)
2730
2731 Get all gists for given user. If userid is empty returned gists
2732 are for user who called the api
2733
2734 :param apiuser: This is filled automatically from the |authtoken|.
2735 :type apiuser: AuthUser
2736 :param userid: user to get gists for
2737 :type userid: Optional(str or int)
2738
2739
2740 create_gist
2741 -----------
2742
2743 .. py:function:: create_gist(apiuser, files, owner=<Optional:<OptionalAttr:apiuser>>, gist_type=<Optional:u'public'>, lifetime=<Optional:-1>, acl_level=<Optional:u'acl_public'>, description=<Optional:''>)
2744
2745 Creates a new Gist.
2746
2747 :param apiuser: This is filled automatically from the |authtoken|.
2748 :type apiuser: AuthUser
2749 :param files: files to be added to the gist. The data structure has
2750 to match the following example::
2751
2752 {'filename': {'content':'...', 'lexer': null},
2753 'filename2': {'content':'...', 'lexer': null}}
2754
2755 :type files: dict
2756 :param owner: Set the gist owner, defaults to api method caller
2757 :type owner: Optional(str or int)
2758 :param gist_type: type of gist ``public`` or ``private``
2759 :type gist_type: Optional(str)
2760 :param lifetime: time in minutes of gist lifetime
2761 :type lifetime: Optional(int)
2762 :param acl_level: acl level for this gist, can be
2763 ``acl_public`` or ``acl_private`` If the value is set to
2764 ``acl_private`` only logged in users are able to access this gist.
2765 If not set it defaults to ``acl_public``.
2766 :type acl_level: Optional(str)
2767 :param description: gist description
2768 :type description: Optional(str)
2769
2770 Example output:
2771
2772 .. code-block:: bash
2773
2774 id : <id_given_in_input>
2775 result : {
2776 "msg": "created new gist",
2777 "gist": {}
2778 }
2779 error : null
2780
2781 Example error output:
2782
2783 .. code-block:: bash
2784
2785 id : <id_given_in_input>
2786 result : null
2787 error : {
2788 "failed to create gist"
2789 }
2790
2791
2792 delete_gist
2793 -----------
2794
2795 .. py:function:: delete_gist(apiuser, gistid)
2796
2797 Deletes existing gist
2798
2799 :param apiuser: filled automatically from apikey
2800 :type apiuser: AuthUser
2801 :param gistid: id of gist to delete
2802 :type gistid: str
2803
2804 Example output:
2805
2806 .. code-block:: bash
2807
2808 id : <id_given_in_input>
2809 result : {
2810 "deleted gist ID: <gist_id>",
2811 "gist": null
2812 }
2813 error : null
2814
2815 Example error output:
2816
2817 .. code-block:: bash
2818
2819 id : <id_given_in_input>
2820 result : null
2821 error : {
2822 "failed to delete gist ID:<gist_id>"
2823 }
2824
@@ -0,0 +1,37 b''
1 .. _authentication-ref:
2
3 Authentication Options
4 ======================
5
6 |RCE| provides a built in authentication plugin
7 ``rhodecode.lib.auth_rhodecode``. This is enabled by default and accessed
8 through the administrative interface. Additionally,
9 |RCE| provides a Pluggable Authentication System (PAS). This gives the
10 administrator greater control over how users authenticate with the system.
11
12 .. important::
13
14 You can disable the built in |RCM| authentication plugin
15 ``rhodecode.lib.auth_rhodecode`` and force all authentication to go
16 through your authentication plugin. However, if you do this,
17 and your external authentication tools fails, you will be unable to
18 access |RCM|.
19
20 |RCM| comes with the following user authentication management plugins:
21
22 .. only:: latex
23
24 * :ref:`config-ldap-ref`
25 * :ref:`config-pam-ref`
26 * :ref:`config-crowd-ref`
27 * :ref:`config-token-ref`
28
29 .. toctree::
30
31 ldap-config-steps
32 crowd-auth
33 pam-auth
34 token-auth
35 ssh-connection
36
37
@@ -0,0 +1,15 b''
1 .. _config-crowd-ref:
2
3 Crowd
4 -----
5
6 To enable Crowd authentication, use the following steps:
7
8 1. From the |RCM| interface, go to :menuselection:`Admin --> Authentication`
9 2. Enable the ``rhodecode.lib.auth_modules.auth_crowd`` library and select
10 :guilabel:`Save`
11 3. On the Crowd plugin settings section, do the following:
12
13 * Check the :guilabel:`Enable` checkbox
14 * Enter your Crowd server settings
15 * Select :guilabel:`Save`
@@ -0,0 +1,22 b''
1 .. _ldap-act-dir-ref:
2
3 Active Directory
4 ----------------
5
6 |RCM| can use Microsoft Active Directory for user authentication. This is
7 done through an LDAP or LDAPS connection to Active Directory. Use the
8 following example LDAP configuration setting to set your Active Directory
9 authentication.
10
11 .. code-block:: ini
12
13 # Set the Base DN
14 Base DN = OU=SBSUsers,OU=Users,OU=MyBusiness,DC=v3sys,DC=local
15 # Set the Active Directory SAM-Account-Name
16 Login Attribute = sAMAccountName
17 # Set the Active Directory user name
18 First Name Attribute = usernameame
19 # Set the Active Directory user surname
20 Last Name Attribute = user_surname
21 # Set the Active Directory user email
22 E-mail Attribute = userEmail No newline at end of file
@@ -0,0 +1,107 b''
1 .. _ldap-gloss-ref:
2
3 |LDAP| Glossary
4 ---------------
5
6 This topic aims to give you a concise overview of the different settings and
7 requirements that enabling |LDAP| on |RCE| requires.
8
9 Required settings
10 ^^^^^^^^^^^^^^^^^
11
12 The following LDAP attributes are required when enabling |LDAP| on |RCE|.
13
14 * **Hostname** or **IP Address**: Use a comma separated list for failover
15 support.
16 * **First Name**
17 * **Surname**
18 * **Email**
19 * **Port**: Port `389` for unencrypted LDAP or port `636` for SSL-encrypted
20 LDAP (LDAPS).
21 * **Base DN (Distinguished Name)**: The Distinguished Name (DN)
22 is how searches for users will be performed, and these searches can be
23 controlled by using an LDAP Filter or LDAP Search Scope. A DN is a sequence of
24 relative distinguished names (RDN) connected by commas. For example,
25
26 .. code-block:: vim
27
28 DN: cn='Monty Python',ou='people',dc='example',dc='com'
29
30 * **Connection security level**: The following are the valid types:
31
32 * *No encryption*: This connection type uses a plain non-encrypted connection.
33 * *LDAPS connection*: This connection type uses end-to-end SSL. To enable
34 an LDAPS connection you must set the following requirements:
35
36 * You must specify port `636`
37 * Certificate checks are required.
38 * To enable ``START_TLS`` on LDAP connection, set the path to the SSL
39 certificate in the default LDAP configuration file. The default
40 `ldap.conf` file is located in `/etc/openldap/ldap.conf`.
41
42 .. code-block:: vim
43
44 TLS_CACERT /etc/ssl/certs/ca.crt
45
46 * The LDAP username or account used to connect to |RCE|. This will be added
47 to the LDAP filter for locating the user object.
48 * For example, if an LDAP filter is specified as `LDAPFILTER`,
49 the login attribute is specified as `uid`, and the user connects as
50 `jsmith`, then the LDAP Filter will be like the following example.
51
52 .. code-block:: vim
53
54 (&(LDAPFILTER)(uid=jsmith))
55
56 * The LDAP search scope must be set. This limits how far LDAP will search for
57 a matching object.
58
59 * ``BASE`` Only allows searching of the Base DN.
60 * ``ONELEVEL`` Searches all entries under the Base DN,
61 but not the Base DN itself.
62 * ``SUBTREE`` Searches all entries below the Base DN, but not Base DN itself.
63
64 .. note::
65
66 When using ``SUBTREE`` LDAP filtering it is useful to limit object location.
67
68 Optional settings
69 ^^^^^^^^^^^^^^^^^
70
71 The following are optional when enabling LDAP on |RCM|
72
73 * An LDAP account is only required if the LDAP server does not allow
74 anonymous browsing of records.
75 * An LDAP password is only required if the LDAP server does not allow
76 anonymous browsing of records
77 * Using an LDAP filter is optional. An LDAP filter defined by `RFC 2254`_. This
78 is more useful that the LDAP Search Scope if set to `SUBTREE`. The filter
79 is useful for limiting which LDAP objects are identified as representing
80 Users for authentication. The filter is augmented by Login Attribute
81 below. This can commonly be left blank.
82 * Certificate Checks are only required if you need to use LDAPS.
83 You can use the following levels of LDAP service with RhodeCode Enterprise:
84
85 * **NEVER** : A serve certificate will never be requested or checked.
86 * **ALLOW** : A server certificate is requested. Failure to provide a
87 certificate or providing a bad certificate will not terminate the session.
88 * **TRY** : A server certificate is requested. Failure to provide a
89 certificate does not halt the session; providing a bad certificate
90 halts the session.
91 * **DEMAND** : A server certificate is requested and must be provided
92 and authenticated for the session to proceed.
93 * **HARD** : The same as DEMAND.
94
95 .. note::
96
97 Only **DEMAND** or **HARD** offer full SSL security while the other
98 options are vulnerable to man-in-the-middle attacks.
99
100 |RCE| uses ``OPENLDAP`` libraries. This allows **DEMAND** or
101 **HARD** LDAPS connections to use self-signed certificates or
102 certificates that do not have traceable certificates of authority.
103 To enable this functionality install the SSL certificates in the
104 following directory: `/etc/openldap/cacerts`
105
106
107 .. _RFC 2254: http://www.rfc-base.org/rfc-2254.html No newline at end of file
@@ -0,0 +1,88 b''
1 .. _config-ldap-ref:
2
3 LDAP
4 ----
5
6 |RCM| supports LDAP (Lightweight Directory Access Protocol) authentication.
7 All LDAP versions are supported, with the following |RCM| plugins managing each:
8
9 * For LDAPv3 use ``rhodecode.lib.auth_modules.auth_ldap_group``
10 * For older LDAP versions use ``rhodecode.lib.auth_modules.auth_ldap``
11
12 .. important::
13
14 The email used with your |RCE| super-admin account needs to match the email
15 address attached to your admin profile in LDAP. This is because
16 within |RCE| the user email needs to be unique, and multiple users
17 cannot share an email account.
18
19 Likewise, if as an admin you also have a user account, the email address
20 attached to the user account needs to be different.
21
22 LDAP Configuration Steps
23 ^^^^^^^^^^^^^^^^^^^^^^^^
24
25 To configure |LDAP|, use the following steps:
26
27 1. From the |RCM| interface, select
28 :menuselection:`Admin --> Authentication`
29 2. Enable the required plugin and select :guilabel:`Save`
30 3. Select the :guilabel:`Enabled` check box in the plugin configuration section
31 4. Add the required LDAP information and :guilabel:`Save`, for more details,
32 see :ref:`config-ldap-examples`
33
34 For a more detailed description of LDAP objects, see :ref:`ldap-gloss-ref`:
35
36 .. _config-ldap-examples:
37
38 Example LDAP configuration
39 ^^^^^^^^^^^^^^^^^^^^^^^^^^
40 .. code-block:: bash
41
42 # Auth Cache TTL
43 3600
44 # Host
45 https://ldap1.server.com/ldap-admin/,https://ldap2.server.com/ldap-admin/
46 # Port
47 389
48 # Account
49 cn=admin,dc=rhodecode,dc=com
50 # Password
51 ldap-user-password
52 # LDAP connection security
53 LDAPS
54 # Certificate checks level
55 DEMAND
56 # Base DN
57 cn=Rufus Magillacuddy,ou=users,dc=rhodecode,dc=com
58 # User Search Base
59 ou=groups,ou=users
60 # LDAP search filter
61 (objectClass=person)
62 # LDAP search scope
63 SUBTREE
64 # Login attribute
65 rmagillacuddy
66 # First Name Attribute
67 Rufus
68 # Last Name Attribute
69 Magillacuddy
70 # Email Attribute
71 LDAP-Registered@email.ac
72 # User Member of Attribute
73 Organizational Role
74 # Group search base
75 cn=users,ou=groups,dc=rhodecode,dc=com
76 # LDAP Group Search Filter
77 (objectclass=posixGroup)
78 # Group Name Attribute
79 users
80 # Group Member Of Attribute
81 cn
82 # Admin Groups
83 admin,devops,qa
84
85 .. toctree::
86
87 ldap-active-directory
88 ldap-authentication
@@ -0,0 +1,13 b''
1 LDAP Host hostname1,hostname2 # testing here
2 Port port
3 Account: `uid=admin,cn=users,cn=accounts,dc=localdomain,dc=tld`
4 Password: userpassword #Testing this here
5 Connection Security LDAPS
6 Certificate Checks ``NEVER``
7 Base DN cn=users,cn=accounts,dc=localdomain,dc=tld
8 LDAP Search Filter (objectClass=person)
9 LDAP Search Scope SUBTREE
10 Login Attribute uid
11 First Name Attribute givenname
12 Last Name Attribute sn
13 Email Attribute mail
@@ -0,0 +1,14 b''
1 .. _config-pam-ref:
2
3 PAM
4 ---
5
6 To enable PAM authentication, use the following steps:
7
8 1. From the |RCM| interface, go to :menuselection:`Admin --> Authentication`
9 2. Enable the ``rhodecode.lib.auth_modules.auth_pam`` library and select save
10 3. On the PAM plugin settings section, do the following:
11
12 * Check the :guilabel:`Enable` checkbox
13 * Enter your PAM server settings
14 * Select :guilabel:`Save`
@@ -0,0 +1,129 b''
1 .. _ssh-connection:
2
3 SSH Connection
4 --------------
5
6 If you wish to connect to your Git or Mercurial |repos| using SSH, use the
7 following instructions.
8
9 .. note::
10
11 SSH access with full |RCE| permissions will require an Admin |authtoken|.
12
13 You need to install the |RC| SSH tool on the server which is running
14 the |RCE| instance.
15
16 1. Gather the following information about the instance you wish to connect to:
17
18 * *Hostname*: Use the ``rccontrol status`` command to view instance details.
19 * *API key*: From the |RCE|, go to
20 :menuselection:`username --> My Account --> Auth Tokens`
21 * *Configuration file*: Identify the configuration file for that instance,
22 the default is :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini`
23 * Identify which |git| and |hg| packages your |RCM| instance is using.
24
25 * For |git|, see
26 :menuselection:`Admin --> Settings --> System Info`
27 * For |hg|, use the ``which hg`` command.
28
29 2. Clone the |RC| SSH script,
30 ``hg clone https://code.rhodecode.com/rhodecode-ssh``
31 3. Copy the ``sshwrapper.sample.ini``, and save it as ``sshwrapper.ini``
32 4. Configure the :file:`sshwrapper.ini` file using the following example:
33
34 .. code-block:: ini
35
36 [api]
37 host=http://localhost:10005
38 key=24a67076d69c84670132f55166ac79d1faafd660
39
40 [shell]
41 shell=/bin/bash -l
42
43 [vcs]
44 root=/path/to/repos/
45
46 [rhodecode]
47 config=/home/user/.rccontrol/enterprise-3/rhodecode.ini
48
49 [vcs:hg]
50 path=/usr/bin/hg
51
52 # should be a base dir for all git binaries, i.e. not ../bin/git
53 [vcs:git]
54 path=/usr/bin
55
56 [keys]
57 path=/home/user/.ssh/authorized_keys
58
59 5. Add the public key to your |RCE| instance server using the
60 :file:`addkey.py` script. This script automatically creates
61 the :file:`authorized_keys` file which was specified in your
62 :file:`sshwrapper.ini` configuration. Use the following example:
63
64 .. code-block:: bash
65
66 $ ./addkey.py --user username --shell --key /home/username/.ssh/id_rsa.pub
67
68 .. important::
69
70 To give SSH access to all users, you will need to maintain
71 each users |authtoken| in the :file:`authorized_keys` file.
72
73 6. Connect to your server using SSH from your local machine.
74
75 .. code-block:: bash
76
77 $ ssh user@localhost
78 Enter passphrase for key '/home/username/.ssh/id_rsa':
79
80 If you need to manually configure the ``authorized_keys`` file,
81 add a line for each key using the following example:
82
83 .. code-block:: vim
84
85 command="/home/user/.rhodecode-ssh/sshwrapper.py --user username --shell",
86 no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa yourpublickey
87
88 .. tip::
89
90 Best practice would be to create a special SSH user account with each
91 users |authtoken| attached.
92
93 |RCE| will manage the user permissions based on the |authtoken| supplied.
94 This would allow you to immediately revoke all SSH access by removing one
95 user from your server if you needed to.
96
97 See the following command line example of setting this up. These steps
98 take place on the server.
99
100 .. code-block:: bash
101
102 # On the RhodeCode Enterprise server
103 # set up user and clone SSH tool
104 $ sudo adduser testuser
105 $ sudo su - testuser
106 $ hg clone https://code.rhodecode.com/rhodecode-ssh
107 $ cd rhodecode-ssh
108
109 # Copy and modify the sshwrapper.ini as explained in step 4
110 $ cp sshwrapper.sample.ini sshwrapper.ini
111
112 $ cd ~
113 $ mkdir .ssh
114 $ touch .ssh/authorized_keys
115
116 # copy your ssh public key, id_rsa.pub, from your local machine
117 # to the server. We’ll use it in the next step
118
119 $ python addkey.py --user testuser --shell --key /path/to/id_rsa.pub
120
121 # Note: testssh - user on the rhodecode instance
122 $ chmod 755 sshwrapper.py
123
124 Test the connection from your local machine using the following example:
125
126 .. code-block:: bash
127
128 # Test connection using the ssh command from the local machine
129 $ ssh testuser@my-server.example.com
@@ -0,0 +1,76 b''
1 .. _config-token-ref:
2
3 Authentication Tokens
4 ---------------------
5
6 |RCE| has 4 different kinds of authentication tokens.
7
8 * *API tokens*: API tokens can only be used to execute |RCE| API operations.
9 You can store your API token and assign it to each instance in
10 the :file:`/home/{user}/.rhoderc` file. See the
11 example in :ref:`indexing-ref` section for more details.
12
13 * *Feed tokens*: The feed token can only be used to access the RSS feed.
14 Usually those are safe to store inside your RSS feed reader.
15
16 * *VCS tokens*: You can use these to authenticate with |git|, |hg| and |svn|
17 operations instead of a password. They are designed to be used with
18 CI Servers or other third party tools that require |repo| access.
19 They are also a good replacement for SSH based access.
20 To use these tokens you need be enabled special authentication method on
21 |RCE|, as they are disabled by default.
22 See :ref:`enable-vcs-tokens`.
23
24 * *Web Interface tokens*: These token allows users to access the web
25 interface of |RCE| without logging in.
26
27 You can add these tokens to an |RCE| server url, to expose the page content
28 based on the given token.
29
30 This is useful to integrate 3rd party systems, good example is to expose
31 raw diffs to another code-review system without having to worry about
32 authentication.
33
34 These tokens only work if a certain view is whitelisted
35 under `api_access_controllers_whitelist` inside
36 the :file:`rhodecode.ini` file.
37
38 .. code-block:: bash
39
40 # To download a repo without logging into Web UI
41 https://rhodecode.com/repo/archive/tip.zip?auth_token=<web-api-token>
42
43 # To show commit diff without logging into Web UI
44 https://rhodecode.com/repo/changeset-diff/<sha>?auth_token=<web-api-token>
45
46 .. _enable-vcs-tokens:
47
48 Enabling VCS Tokens
49 ^^^^^^^^^^^^^^^^^^^
50
51 To enable VCS Tokens, use the following steps:
52
53 1. Go to :menuselection:`Admin --> Authentication`.
54 2. Enable the ``rhodecode.lib.auth_modules.auth_token`` plugin.
55 3. Click :guilabel:`Save`.
56
57 Authentication Token Tips
58 ^^^^^^^^^^^^^^^^^^^^^^^^^
59
60 * Use Authentication Tokens instead of your password with external services.
61 * Create multiple Authentication Tokens on your account to enable
62 access to your |repos| with a different |authtoken| per method used.
63 * Set an expiry limit on certain tokens if you think it would be a good idea.
64
65 Creating Tokens
66 ^^^^^^^^^^^^^^^
67
68 To create authentication tokens for an user, use the following steps:
69
70 1. From the |RCM| interface go to
71 :menuselection:`Username --> My Account --> Auth tokens`.
72
73 2. Label and Add the tokens you wish to use with |RCE|.
74
75 .. image:: ../images/tokens.png
76
@@ -0,0 +1,13 b''
1 .. _code-approve-changes-ref:
2
3 Approve Code Changes
4 --------------------
5
6 To approve commits, use the following steps:
7
8 1. Open the commit for review
9 2. Leave your comments inline or in the message box.
10 3. Set the review status from the drop-down menu and select :guilabel:`Comment`
11
12 .. image:: ../images/set-ci-status.png
13 :alt: Setting Commit Status No newline at end of file
@@ -0,0 +1,27 b''
1 .. _code-review-ref:
2
3 Code Review
4 ===========
5
6 |RCM| provides two ways in which you can review code. You can review |prs| or
7 commits. To better understand |prs|, see the :ref:`pull-requests-ref`
8 and :ref:`collaborate-ref` sections. For more information about why
9 code review matters, see these posts on the topic:
10
11 * `Code Review - Fix Bugs Early and Often`_
12 * `Code Review - How to Convince a Skeptic`_
13 * `Code Review - Learn How NASA Codes`_
14
15 You can also use the |RCE| API set up continuous integration servers to leave
16 comments from a test suite. See the :ref:`api` and
17 :ref:`integrations-ref` sections for examples on how to set this up.
18
19 .. toctree::
20
21 review-diffs
22 approve-changes
23 reviewing-best-practices
24
25 .. _Code Review - Fix Bugs Early and Often: https://rhodecode.com/blog/code-review-fix-bugs-early-often/
26 .. _Code Review - How to Convince a Skeptic: https://rhodecode.com/blog/code-review-convince-skeptic/
27 .. _Code Review - Learn How NASA Codes: https://rhodecode.com/blog/code-review-learn-nasa-codes/
@@ -0,0 +1,42 b''
1 .. _code-diff-side-ref:
2
3 Reviewing Diffs
4 ---------------
5
6 Diffs are representations of changes made between different changesets of
7 a file. |RCE| provides 4 different types of diffs for each commit or
8 changeset, and depending on your preference you can use whichever for code
9 review purposes.
10
11 * Plain diff
12 * Full diff
13 * Side-by-side diff
14 * Raw diff
15
16 Reviewing Changes
17 -----------------
18
19 |RCM| displays all code changes made with each commit. Removed content is
20 marked in red and new content in green.
21
22 .. image:: ../images/plain-diff.png
23 :alt: Plain Diff
24
25 Side-By-Side Diffs
26 ------------------
27
28 To review code with a side-by-side diff, use the following steps:
29
30 1. Open the repository in which you wish to review a file
31 2. Select the revision you wish to review
32 3. Select the side-by-side diff icon beside the file name
33
34 .. image:: ../images/side-by-side-diff.png
35 :alt: Side by side diff
36
37
38 Notifying Users
39 ---------------
40
41 To notify other users of you comments, or requests for feedback,
42 see :ref:`review-notifications-ref`
@@ -0,0 +1,21 b''
1 .. _code-best-practices-ref:
2
3 Code Review - Best Practices
4 ----------------------------
5
6 The following is a list of best practices for reviewing code gathered from
7 various sources:
8
9 * **Implement a Core Review standard**, because the yield of the Code Review
10 phase is 50 to 80% better than that of the Test phase.
11 * Review between **100 and 300 lines of code** at a time and spend 30-60 minutes
12 doing it for best results.
13 * **Avoid code review meetings**, because meetings contributed only 4% of the
14 defects found in the code inspections.
15 * Slow down to a comfortable pace, as reviewers **slower than 400 lines per
16 hour are above average** in their ability to uncover defects. But when faster
17 than 450 lines/hour the defect density is below average in 87% of the cases.
18 * Take a time-out, because defects are found at relatively constant rates
19 through the first **60 minutes of inspection**. At that point the
20 checklist-style review levels off sharply; the other review styles level
21 off slightly later. In no case is a defect discovered after 90 minutes. No newline at end of file
@@ -0,0 +1,19 b''
1 Approve |prs|
2 -------------
3
4 To approve a |pr|, use the following steps:
5
6 1. Select :menuselection:`username --> Notifications --> Pull Requests`
7 and open the |pr| you with to approve
8 2. Leave your review comments inline, or in the commit message.
9 3. Leave a commit message that outlines the review.
10 4. Set the review status to :guilabel:`Approved`
11 5. Select :guilabel:`Comment`
12
13 If you approve the |pr|, you will be able to merge automatically if |RCM|
14 detects that it can do so safely. You will see this message:
15
16 :guilabel:`This pull request can be automatically merged.`
17
18 Otherwise you will need to merge the |pr| locally and push your changes, see
19 :ref:`manual-merge-requests-ref`.
@@ -0,0 +1,24 b''
1 .. _collaborate-ref:
2
3 Collaboration
4 =============
5
6 .. note::
7
8 Forking and branching does not work with |svn| |repos|.
9
10 Collaboration in |RCM| is accomplished through a combination of the following
11 functions:
12
13 .. only:: latex
14
15 * :ref:`review-notifications-ref`
16 * :ref:`forks-branches-ref`
17 * :ref:`pull-requests-ref`
18
19 .. toctree::
20
21 workflow
22 forks-branches
23 repo-locking
24
@@ -0,0 +1,31 b''
1 .. _merging-empty-repo-ref:
2
3 Merging Forks with an Empty Repository
4 ======================================
5
6 When a new repository is created, it has no commits. If the empty repository is
7 forked, neither |repo| will have any shared information to link them together,
8 making it impossible to create a |pr| to merge them.
9
10 To avoid this problem, create an initial commit on the new repository before
11 forking it. It can be accomplished, for example, by adding a README file to the
12 master repository and commiting it to the server before forking.
13
14 In case the fork was already made and you are unable to push or merge due to the
15 lack of a common commit between both repositories, the following steps would
16 enable you to fix this problem.
17
18 1. Create a commit on the master repository.
19 2. Pull the changes from the fork to the master repository, and rebase them
20 on top of the new commit.
21
22 .. code-block:: bash
23
24 #pull from the fork into master
25 $ hg pull -r fork-commit-id
26
27 3. If the changes were made locally, push the changes to the server.
28 4. On the forked repository, pull the changes from master.
29
30 Now you should be able to create a |pr| or merge between both repositories.
31
@@ -0,0 +1,101 b''
1 .. _forks-branches-ref:
2
3 Forking and Branching
4 ---------------------
5
6 Forking clones the original |repo| and creates an independent |repo|.
7 Branching allows you to develop independently
8 of the main branch based on the changeset branched, but remains linked to the
9 main |repo|.
10
11 Both provide excellent collaboration functionality,
12 and do not differ greatly, but you can find many online discussions
13 where people fight about the differences.
14
15 Fork a |repo|
16 ^^^^^^^^^^^^^
17
18 To fork a |repo|, use the following steps:
19
20 1. Select :menuselection:`Admin --> repositories`
21 2. Select the |repo| you wish to fork.
22 3. Select :menuselection:`Options --> Fork`
23 4. On the :guilabel:`Create fork` page, set the following properties:
24
25 * The fork name
26 * The fork description
27 * If the fork is private or public
28 * The copy permissions
29
30 Branch a |git| |repo|
31 ^^^^^^^^^^^^^^^^^^^^^
32
33 Currently branching is only supported from the command line but is picked up
34 on the web interface. To branch a |git| |repo| use the following example:
35
36 .. code-block:: bash
37
38 # branch and checkout
39 git branch new-branch
40 git checkout new-branch
41
42 # same function shorthand
43 git checkout -b new-branch
44
45 # Example usage
46 $ git checkout -b example-branch
47 Switched to a new branch 'example-branch'
48
49 $ git status
50 On branch example-branch
51 Initial commit
52 nothing to commit (create/copy files and use "git add" to track)
53 $ vi example-script.sh
54 $ git add example-script.sh
55 $ git commit -a -m "ghost script: initial file"
56 $ git push
57
58 Once it is pushed to the |RCM| server, you can switch to the newly created
59 branch using the following steps:
60
61 1. Select :menuselection:`Admin --> Repositories`.
62 2. Select the |repo| you branched.
63 3. Select :menuselection:`Switch To --> Branches` and choose the new branch.
64
65 For more information, your can read more here on the Git website,
66 `Git Branching`_.
67
68 Branch a |hg| |repo|
69 ^^^^^^^^^^^^^^^^^^^^
70
71 .. note::
72
73 To use branches in |hg| like |git|, use the `hg bookmark` option instead.
74 Also see the :ref:`bvb` section for more information.
75
76 To branch a |hg| |repo|, use the following example and push your changes to
77 the main |repo|. Once pushed, you can view the new branch in |RCE| by
78 selecting :menuselection:`Switch To --> Branches` from the |repo| page.
79
80 .. code-block:: bash
81
82 $ hg branch example-456
83 $ hg ci -m "branch: ticket #456"
84 $ hg push --new-branch
85
86 Bookmark a |hg| |repo|
87 ^^^^^^^^^^^^^^^^^^^^^^
88
89 Bookmarks are used in |hg| in much the same way as branches are in |git|. See
90 the `Mercurial Bookmarks`_ documentation for more information.
91
92 .. code-block:: bash
93
94 $ hg bookmark example-456
95 $ hg ci -m "branch: ticket #456"
96 $ hg push -B example-456
97
98 .. image:: ../images/branch-example.png
99
100 .. _Git Branching: http://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging
101 .. _Mercurial Bookmarks: https://mercurial.selenic.com/wiki/Bookmarks
@@ -0,0 +1,39 b''
1 .. _user-notify-ref:
2
3 Using Notifications
4 -------------------
5
6 To notify users of items that require their attention you can use the mention
7 function. The mention function allows you to use ``@username`` within |RCM|.
8 The notification function can be used within the following
9 items to highlight their need for attention:
10
11 * Commit messages
12 * Pull requests
13 * Inline comments
14 * Code review
15
16 .. note::
17
18 Mentioned users will receive an email and a notification.
19
20 Pull Request Notifications
21 --------------------------
22
23 To notify a user of a pull request, use the following steps.
24
25 1. Open the repository fork
26 2. Select :guilabel:`Open new pull request`
27 3. Add the :guilabel:`@username` in the :guilabel:`Pull request viewers`
28 input field.
29 4. Select :guilabel:`Submit Pull Request`
30
31 Commit Message Notifications
32 ----------------------------
33
34 To notify a user in a commit message, use the following steps.
35
36 1. Open a repository with commits in it.
37 2. Click on the commit message or revision number.
38 3. Add an :guilabel:`@username` in an inline comment or in your approval
39 comment and commit.
@@ -0,0 +1,35 b''
1 .. _merge-requests-ref:
2
3 Merge a |pr|
4 ------------
5
6 |RCM| can detect if it can automatically merge the changes in a |pr|. If it
7 can, you will see the following message:
8 :guilabel:`This pull request can be automatically merged.` To merge,
9 click the big blue button! To enable this feature, see :ref:`server-side-merge`.
10
11 .. image:: ../images/merge-pr-button.png
12
13 If you cannot automatically merge a |pr|, you will see one of the following
14 messages:
15
16 * :guilabel:`This pull request cannot be merged because of conflicts`
17 * :guilabel:`Reviewer approval is pending`
18
19 .. _manual-merge-requests-ref:
20
21 Manual Merge a |PR|
22 ^^^^^^^^^^^^^^^^^^^
23
24 If |RCM| cannot safely merge the changes in a |pr|,
25 usually due to conflicts, you need to manually merge the changes on the
26 command line. You can see more information for each |repo| type at the
27 following links:
28
29 * `Git Manual Merging`_
30 * `Mercurial Manual Merging`_
31 * `Subversion Manual Merging`_
32
33 .. _Git Manual Merging: http://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging
34 .. _Mercurial Manual Merging: http://hgbook.red-bean.com/read/a-tour-of-mercurial-merging-work.html
35 .. _Subversion Manual Merging: http://svnbook.red-bean.com/en/1.7/svn.branchmerge.basicmerging.html
@@ -0,0 +1,22 b''
1 Notifications Overview
2 ----------------------
3
4 |RCM| has an integrated notification system which alerts users to requests
5 that they have received. Notifications can occur for the following reasons:
6
7 * Pull request reviews
8 * Commit message mentions
9
10 When someone opens a |pr| on one of your |repos|, or adds you as a |pr|
11 reviewer, you will receive a notification in |RCE| and an email,
12 if not configured see :ref:`set-up-mail`. Also, during the review process you
13 receive notifications on the following actions:
14
15 * New comments
16 * Status changes
17 * Inline code review comments
18
19 Each notifications provides a link to take you directly to the issue.
20
21 .. image:: ../images/notifications.png
22 :alt: Notifying Colleagues
@@ -0,0 +1,34 b''
1 .. _open-requests-ref:
2
3 Open a |pr|
4 -----------
5
6 .. important::
7
8 To open a |pr|, it is necessary that the source and the target repositories
9 have at least one commit in common. For more information,
10 see :ref:`merging-empty-repo-ref`.
11
12
13 Once you have finished your work on a fork and want your work merged with the
14 original |repo|, you need to open a |pr|. To open a |pr| and send for
15 review, use the following steps:
16
17 1. Select
18 :menuselection:`Admin --> repositories --> repo name --> Options --> Create Pull Request`
19 2. On the :guilabel:`New Pull Request` page, enter the following information:
20
21 * The |pr| name.
22 * The |pr| description.
23 * Add the reviewer names in the :guilabel:`Pull Request Reviewer` field.
24
25 3. Review the changesets that make up the |pr|.
26 4. Select :guilabel:`Submit Pull Request`.
27
28 .. image:: ../images/open-pr.png
29 :alt: Open a pull request
30
31 The pull request can either be merged into the original repository,
32 or it can be declined due to issues during the review process. If issues
33 arise, you can fix them and update the |pr|. For more,
34 see :ref:`update-requests-ref`.
@@ -0,0 +1,7 b''
1 Pull Request Workflow
2 ---------------------
3
4 The following diagram represents a standard pull request workflow.
5
6 .. image:: ../images/pull-request-flow.png
7 :align: center
@@ -0,0 +1,47 b''
1 Pull request management
2 -----------------------
3
4 .. only:: html
5
6 There are two ways of tracking |prs| within |RCM|.
7
8 1. :ref:`prs-your-review`
9 2. :ref:`prs-per-repo`
10
11 .. _prs-your-review:
12
13 Pull requests for your review
14 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15
16 To view pull requests for your review, use the following steps:
17
18 1. From the |RCM| interface, Select
19 :menuselection:`username --> Notifications`
20 2. Select :guilabel:`Pull Requests`
21
22 .. image:: ../images/prs-for-my-review.png
23 :alt: pull requests for my review
24
25 .. _prs-per-repo:
26
27 Pull requests per |repo|
28 ^^^^^^^^^^^^^^^^^^^^^^^^
29
30 To view pull requests going to and from a |repo|, use the following steps:
31
32 1. Select the |repo| you wish to view
33 2. Select :guilabel:`Pull Requests` from the top menu
34 3. On the left-hand pane you will see the following options for |pr|
35 management on that |repo|:
36
37 * :guilabel:`Opened`: Pull requests opened on this |repo|.
38 * :guilabel:`Opened by me`: Pull requests you opened on this |repo|.
39 * :guilabel:`Awaiting my review`: Pull requests awaiting your review.
40 * :guilabel:`Closed`: Closed |prs| on this |repo|.
41 * :guilabel:`Awaiting review`: Pull requests still awaiting review on
42 this |repo|.
43 * :guilabel:`From this repo`: Pull requests opened on another |repo| with
44 the changes coming from this |repo|.
45
46 .. image:: ../images/pr-screen.png
47 :alt: pull request dashboard
@@ -0,0 +1,29 b''
1 .. _pull-requests-ref:
2
3 Pull Requests
4 =============
5
6 Once a |pr| is open, you can use a variety of different code review functions
7 to ensure the quality or style of code is appropriate for your standards. The
8 |pr| is then merged with the main branch when it is approved. The following
9 steps are an overview of the workflow:
10
11 1. Create a fork or branch of a |repo|.
12 2. Complete your works and open a pull request.
13 3. Notify users to review and approve the |pr|.
14 4. Merge the code to the target |repo|.
15
16 .. toctree::
17
18 pr-flow
19 pull-req-mgmt
20 open-pull-request.rst
21 review-pull-request.rst
22 update-pull-request
23 approve-pull-request.rst
24 merge-pull-request.rst
25 fixing-common-commits.rst
26
27
28
29
@@ -0,0 +1,15 b''
1 .. _repo-locking:
2
3 Repository Locking
4 ------------------
5
6 Repository locking means that when a user pulls from a |repo|,
7 only a push by that user will unlock it. This allows an
8 Admin to pull from a |repo| and ensure that no changes can be introduced. You
9 need Admin access to the |repo| to enable
10 |repo| locking. To enable |repo| locking, use the following steps.
11
12 1. From the |RCE| interface, select :menuselection:`Admin --> Repositories`,
13 then :guilabel:`Edit` beside the |repo| you wish to lock.
14 2. From the left-hand pane, select
15 :menuselection:`Advanced --> Lock Repository` No newline at end of file
@@ -0,0 +1,9 b''
1 .. _review-notifications-ref:
2
3 Notifications
4 =============
5
6 .. toctree::
7
8 notifications-overview
9 mention-reviewer-function
@@ -0,0 +1,27 b''
1 .. _review-requests-ref:
2
3 Review a |pr|
4 -------------
5
6 To review a pull request, use the following steps:
7
8 1. Open the review request from
9 :menuselection:`Admin --> Repositories --> repo name --> Pull Requests --> Awaiting my review`
10 2. Leave your review comments inline, or in the commit message.
11 3. Set the review status from one of the following options:
12
13 * :guilabel:`Not Reviewed`
14 * :guilabel:`Approved`
15 * :guilabel:`Approved & Closed`
16 * :guilabel:`Rejected`
17 * :guilabel:`Rejected & Closed`
18 * :guilabel:`Under Review`
19
20 4. Select Comment
21
22 When the |pr| is approved by all reviewers you will be able to merge
23 automatically if |RCM| detects that it can do so safely. You will see this
24 message: `This pull request can be automatically merged.`
25
26 If rejected, you can fix the issues raised during review and then update the
27 |pr|.
@@ -0,0 +1,9 b''
1 Supported Workflows
2 -------------------
3
4 |RCM| can be used to develop using a variety of different workflows.
5
6 * Centralized, using |svn|, |git|, or |hg| |repos|
7 * Feature-Branch, using |git| or |hg| |repos|
8 * Fork-Pull, using |git| or |hg| |repos|
9 * Gitflow, using |git| |repos|
@@ -0,0 +1,47 b''
1 .. _update-requests-ref:
2
3 Update a |pr|
4 -------------
5
6 .. important::
7
8 Updating a |pr| invalidates all previous reviews, and the status set by
9 each reviewer. This means all reviewers need to review and approve the
10 |pr| again.
11
12 If you have made changes on the fork or branch from where a |pr| originates,
13 you can update the |pr|, using the following steps:
14
15 1. Commit and push your changes to the |RCE| server.
16 2. Open the |pr| you wish to update, and select the :guilabel:`Update commits`
17 button.
18
19 .. image:: ../images/update-pr-button.png
20 :scale: 50 %
21 :alt: Update Pull Request
22 :align: Center
23
24
25 Once updated the following commit message will be automatically added to the
26 |pr|.
27
28 :guilabel:`Auto status change to "Under Review", pull request updated with 1 added, 0 removed commits.`
29
30 3. Review the new commit messages and changes as before,
31 4. Set the review status and click :guilabel:`Comment`
32
33 Inline Comments
34 ^^^^^^^^^^^^^^^
35
36 When updating a |pr|, inline comments can move around depending on which line
37 they are attached:
38
39 * If the line content changes but remains in place, the inline comment will
40 remain where it was originally.
41 * If the line to which the inline comment is attached moves, the comment will
42 move with it.
43 * If the diff changes substantially and the line to which the comment was
44 attached is no longer in the diff, the inline comment will be hidden but
45 with an icon to display it if necessary.
46
47
@@ -0,0 +1,70 b''
1 .. _branch-wf:
2
3 Branching Workflow
4 ==================
5
6 The branching workflow is usually used with specific guidelines about how to
7 use and name branches. A general rule of thumb is that each branch should be
8 specifically named and used for a defined purpose. See the
9 :ref:`forks-branches-ref` section for detailed steps about how to create
10 branches.
11
12 .. code-block:: bash
13
14 # Mercurial Branch
15 $ hg bookmark issue-568
16
17 # Git Branch
18 $ git branch issue-568
19 $ git checkout issue-568
20
21
22 Branching Overview
23 ------------------
24
25 .. image:: ../images/git-flow-diagram.png
26 :align: center
27
28 :Legend: The following code examples correspond with the numbered steps in
29 the diagram.
30
31 .. code-block:: bash
32
33 #1 clone your fork locally and pull the latest changes from upstream
34 $ git clone git://your-fork
35 $ git pull --rebase upstream master
36
37 #2 create a new branch
38 $ git checkout -b branch-1
39
40 #3 push the branch to your remote fork
41 $ git push origin branch-1
42
43 #4 Open a pull request from your fork to upstream/master
44
45 #5 Merge your pull request with the upstream/master
46 $ git merge --no-ff pull request
47
48 #6 pull and rebase your work plus any other work to your local branch
49 $ git checkout master
50 $ git pull --rebase upstream master
51
52 #7 push the new commit history to your fork
53 $ git push origin master
54
55
56
57 Setting up a Branching Workflow
58 -------------------------------
59
60 Setting up a branching workflow requires giving users access to the |repo|.
61 For more information, see the :ref:`permissions-info-add-group-ref` section.
62
63 Using a Branching Workflow
64 --------------------------
65
66 If you are on a team that uses a branching workflow, see the
67 :ref:`forks-branches-ref` section for how to create branches, and also the
68 :ref:`pull-requests-ref` section. You may also find the
69 :ref:`squash-rebase` section useful.
70
@@ -0,0 +1,43 b''
1 .. _fork-flow:
2
3 Forking Workflow
4 ================
5
6 The forking workflow means that everyone on a team has permission to fork a
7 |repo| and once they have completed their work, open a pull request to have it
8 accepted into the main |repo|.
9
10 In a forking workflow, not everyone will have write access to the main |repo|.
11 This means that only those with write access can merge |prs| once they have
12 been approved. Usually, the forking workflow is used with |hg|, and branching
13 with |git|.
14
15 Forking Overview
16 ----------------
17
18 .. image:: ../images/fork-flow.png
19 :align: center
20
21
22 Setting Up a Forking Workflow
23 -----------------------------
24
25 Setting up a forking workflow in |RCE| would look something like this.
26
27 1. Create a user group with write access.
28 2. Create a user group with read access.
29 3. Assign team members to the appropriate groups.
30 4. Users with contributions should open a pull request to
31 the main |repo| and set a user with write access as the reviewer.
32 5. Once the |pr| is approved, the write access user would merge it with the
33 main |repo|.
34
35 For more information about setting up user groups, see the :ref:`user-admin-set`
36 section.
37
38 Using a Forking Workflow
39 ------------------------
40
41 If you are on a team that uses a forking workflow, see the
42 :ref:`forks-branches-ref` section for how to fork a |repo|, and also the
43 :ref:`pull-requests-ref` section.
@@ -0,0 +1,14 b''
1 .. _workflow:
2
3 Workflow Support
4 ================
5
6 |RCE| supports a number of developer workflows depending on whichever setup
7 your team wishes to adopt. Use the information in the following sections to
8 get an idea of what may work best for you.
9
10 .. toctree::
11
12 workflow-fork
13 workflow-branch
14
@@ -0,0 +1,32 b''
1 # Try and keep this list alphabetical
2 # ui is for user interface elements and messages
3 # button - that's obvious
4
5 rst_epilog = '''
6 .. |AE| replace:: Appenlight
7 .. |authtoken| replace:: Authentication Token
8 .. |authtokens| replace:: **Auth Tokens**
9 .. |git| replace:: Git
10 .. |hg| replace:: Mercurial
11 .. |svn| replace:: Subversion
12 .. |LDAP| replace:: LDAP / Active Directory
13 .. |os| replace:: operating system
14 .. |OS| replace:: Operating System
15 .. |PY| replace:: Python
16 .. |pr| replace:: pull request
17 .. |prs| replace:: pull requests
18 .. |psf| replace:: Python Software Foundation
19 .. |repo| replace:: repository
20 .. |repos| replace:: repositories
21 .. |RCI| replace:: RhodeCode Control
22 .. |RCC| replace:: RhodeCode Control
23 .. |RCV| replace:: RhodeCode Enterprise
24 .. |RCM| replace:: RhodeCode Enterprise
25 .. |RCE| replace:: RhodeCode Enterprise
26 .. |RCX| replace:: RhodeCode Extensions
27 .. |RCT| replace:: RhodeCode Tools
28 .. |RCEBOLD| replace:: **RhodeCode Enterprise**
29 .. |RCEITALICS| replace:: `RhodeCode Enterprise`
30 .. |RC| replace:: RhodeCode
31 .. |RNS| replace:: Release Notes
32 '''
@@ -0,0 +1,317 b''
1 # -*- coding: utf-8 -*-
2 #
3 # RhodeCode Enterprise documentation build configuration file, created by
4 # sphinx-quickstart on Tue Nov 4 11:48:37 2014.
5 #
6 # This file is execfile()d with the current directory set to its
7 # containing dir.
8 #
9 # Note that not all possible configuration values are present in this
10 # autogenerated file.
11 #
12 # All configuration values have a default; values that are commented out
13 # serve to show the default.
14
15 import sys
16 import os
17 import datetime
18 import sphinx_rtd_theme
19
20 # If extensions (or modules to document with autodoc) are in another directory,
21 # add these directories to sys.path here. If the directory is relative to the
22 # documentation root, use os.path.abspath to make it absolute, like shown here.
23 sys.path.insert(0, os.path.abspath('.'))
24 import common
25
26 # -- General configuration ------------------------------------------------
27
28 # If your documentation needs a minimal Sphinx version, state it here.
29 #needs_sphinx = '1.0'
30
31 # Add any Sphinx extension module names here, as strings. They can be
32 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
33 # ones.
34 extensions = [
35 'sphinx.ext.intersphinx',
36 'sphinx.ext.todo',
37 'sphinx.ext.pngmath'
38 ]
39
40 intersphinx_mapping = {
41 'enterprise': ('https://docs.rhodecode.com/RhodeCode-Enterprise/', None),
42 'control': ('https://docs.rhodecode.com/RhodeCode-Control/', None),
43 }
44
45 if tags.has('dev'):
46 intersphinx_mapping.update({
47 'enterprise': ('https://ci.rhodecode.com/documentation/Momentum/', None),
48 'control': ('https://ci.rhodecode.com/documentation/Control/', None),
49 })
50
51
52 # Add any paths that contain templates here, relative to this directory.
53 templates_path = ['_templates']
54
55 # The suffix of source filenames.
56 source_suffix = '.rst'
57
58 # The encoding of source files.
59 #source_encoding = 'utf-8-sig'
60
61 # The master toctree document.
62 master_doc = 'index'
63
64 # The version info for the project you're documenting, acts as replacement for
65 # |version| and |release|, also used in various other places throughout the
66 # built documents.
67
68 # TODO: johbo: Move into common package for documentation utilities
69 def _get_version():
70 with open('../rhodecode/VERSION') as f:
71 return f.read().strip()
72
73 # The full version, including alpha/beta/rc tags.
74 release = _get_version()
75 # The short X.Y version.
76 version = '.'.join(release.split('.', 2)[:2]) # First two parts of release
77
78 # General information about the project.
79 project = u'RhodeCode Enterprise %s ' % _get_version()
80 copyright = u'2010-{now.year}, RhodeCode GmbH'.format(
81 now=datetime.datetime.today())
82
83
84 # The language for content autogenerated by Sphinx. Refer to documentation
85 # for a list of supported languages.
86 #language = None
87
88 rst_epilog = common.rst_epilog + """
89 .. |async| replace:: asynchronous
90 """
91
92 # There are two options for replacing |today|: either, you set today to some
93 # non-false value, then it is used:
94 #today = ''
95 # Else, today_fmt is used as the format for a strftime call.
96 #today_fmt = '%B %d, %Y'
97
98 # List of patterns, relative to source directory, that match files and
99 # directories to ignore when looking for source files.
100 exclude_patterns = [
101 # Special directories
102 '_build',
103 'result',
104
105 # Other RST files
106 'admin/rhodecode-backup.rst',
107 'auth/ldap-configuration-example.rst',
108 'issue-trackers/redmine.rst',
109 'known-issues/error-msg-guide.rst',
110 'tutorials/docs-build.rst',
111 'integrations/example-ext.py',
112 'collaboration/supported-workflows.rst',
113 ]
114
115
116 # The reST default role (used for this markup: `text`) to use for all
117 # documents.
118 #default_role = None
119
120 # If true, '()' will be appended to :func: etc. cross-reference text.
121 #add_function_parentheses = True
122
123 # If true, the current module name will be prepended to all description
124 # unit titles (such as .. function::).
125 #add_module_names = True
126
127 # If true, sectionauthor and moduleauthor directives will be shown in the
128 # output. They are ignored by default.
129 #show_authors = False
130
131 # The name of the Pygments (syntax highlighting) style to use.
132 pygments_style = 'sphinx'
133
134 # A list of ignored prefixes for module index sorting.
135 #modindex_common_prefix = []
136
137 # If true, keep warnings as "system message" paragraphs in the built documents.
138 keep_warnings = tags.has("dev")
139
140
141 # -- Options for HTML output ----------------------------------------------
142
143 # The theme to use for HTML and HTML Help pages. See the documentation for
144 # a list of builtin themes.
145 #html_theme = 'rctheme'
146 html_theme = 'sphinx_rtd_theme'
147
148 # Theme options are theme-specific and customize the look and feel of a theme
149 # further. For a list of options available for each theme, see the
150 # documentation.
151 #html_theme_options = {}
152 html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
153
154 # Add any paths that contain custom themes here, relative to this directory.
155 #html_theme_path = []
156
157 # The name for this set of Sphinx documents. If None, it defaults to
158 # "<project> v<release> documentation".
159 #html_title = None
160
161 # A shorter title for the navigation bar. Default is the same as html_title.
162 #html_short_title = None
163
164 # The name of an image file (relative to this directory) to place at the top
165 # of the sidebar.
166 #html_logo = None
167 html_sidebars = {
168 '**': ['globaltoc.html'],
169 }
170
171 # The name of an image file (within the static path) to use as favicon of the
172 # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
173 # pixels large.
174 html_favicon = 'images/favicon.ico'
175
176 # Add any paths that contain custom static files (such as style sheets) here,
177 # relative to this directory. They are copied after the builtin static files,
178 # so a file named "default.css" will overwrite the builtin "default.css".
179 html_static_path = ['static/css/add.css']
180
181 # Add any extra paths that contain custom files (such as robots.txt or
182 # .htaccess) here, relative to this directory. These files are copied
183 # directly to the root of the documentation.
184 #html_extra_path = []
185
186 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
187 # using the given strftime format.
188 #html_last_updated_fmt = '%b %d, %Y'
189
190 # If true, SmartyPants will be used to convert quotes and dashes to
191 # typographically correct entities.
192 #html_use_smartypants = True
193
194 # Custom sidebar templates, maps document names to template names.
195 #html_sidebars = {}
196
197 # Additional templates that should be rendered to pages, maps page names to
198 # template names.
199 #html_additional_pages = {}
200
201 # If false, no module index is generated.
202 #html_domain_indices = True
203
204 # If false, no index is generated.
205 #html_use_index = True
206
207 # If true, the index is split into individual pages for each letter.
208 #html_split_index = False
209
210 # If true, links to the reST sources are added to the pages.
211 #html_show_sourcelink = True
212
213 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
214 #html_show_sphinx = True
215
216 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
217 #html_show_copyright = True
218
219 # If true, an OpenSearch description file will be output, and all pages will
220 # contain a <link> tag referring to it. The value of this option must be the
221 # base URL from which the finished HTML is served.
222 #html_use_opensearch = ''
223
224 # This is the file name suffix for HTML files (e.g. ".xhtml").
225 #html_file_suffix = None
226
227 # Output file base name for HTML help builder.
228 htmlhelp_basename = 'rhodecode-enterprise'
229
230
231 # -- Options for LaTeX output ---------------------------------------------
232
233 latex_elements = {
234 'classoptions': ',oneside',
235 'babel': '\\usepackage[english]{babel}',
236
237 # The paper size ('letterpaper' or 'a4paper').
238 #'papersize': 'letterpaper',
239
240 # The font size ('10pt', '11pt' or '12pt').
241 #'pointsize': '10pt',
242
243 # Additional stuff for the LaTeX preamble.
244 #'preamble': '',
245 }
246
247 # Grouping the document tree into LaTeX files. List of tuples
248 # (source start file, target name, title,
249 # author, documentclass [howto, manual, or own class]).
250 latex_documents = [
251 ('index', 'RhodeCodeEnterprise.tex', u'RhodeCode Enterprise',
252 u'RhodeCode GmbH', 'manual'),
253 ]
254
255 # The name of an image file (relative to this directory) to place at the top of
256 # the title page.
257 #latex_logo = None
258
259 # For "manual" documents, if this is true, then toplevel headings are parts,
260 # not chapters.
261 #latex_use_parts = False
262
263 # If true, show page references after internal links.
264 latex_show_pagerefs = True
265
266 # If true, show URL addresses after external links.
267 latex_show_urls = 'footnote'
268
269 # Documents to append as an appendix to all manuals.
270 #latex_appendices = []
271
272 # If false, no module index is generated.
273 #latex_domain_indices = True
274
275 # Mode for literal blocks wider than the frame. Can be
276 # overflow, shrink or truncate
277 pdf_fit_mode = "truncate"
278
279
280 # -- Options for manual page output ---------------------------------------
281
282 # One entry per manual page. List of tuples
283 # (source start file, name, description, authors, manual section).
284 man_pages = [
285 ('index', 'rhodecodeenterprise', u'RhodeCode Enterprise',
286 [u'RhodeCode GmbH'], 1)
287 ]
288
289 # If true, show URL addresses after external links.
290 #man_show_urls = False
291
292
293 # -- Options for Texinfo output -------------------------------------------
294
295 # Grouping the document tree into Texinfo files. List of tuples
296 # (source start file, target name, title, author,
297 # dir menu entry, description, category)
298 texinfo_documents = [
299 ('index', 'RhodeCodeEnterprise', u'RhodeCode Enterprise',
300 u'RhodeCode Docs Team', 'RhodeCodeEnterprise', 'RhodeCode Docs Project',
301 'Miscellaneous'),
302 ]
303
304 # Documents to append as an appendix to all manuals.
305 #texinfo_appendices = []
306
307 # If false, no module index is generated.
308 #texinfo_domain_indices = True
309
310 # How to display URL addresses: 'footnote', 'no', or 'inline'.
311 #texinfo_show_urls = 'footnote'
312
313 # If true, do not generate a @detailmenu in the "Top" node's menu.
314 #texinfo_no_detailmenu = False
315
316 # We want to see todo notes in case of a pre-release build of the documentation
317 todo_include_todos = tags.has("dev")
@@ -0,0 +1,60 b''
1
2 =====
3 API
4 =====
5
6
7
8 Naming conventions
9 ==================
10
11 We keep the calls in the form ``{verb}_{noun}``.
12
13
14
15 Change and Deprecation
16 ======================
17
18 API deprecation is documented in the section :ref:`deprecated` together with
19 other notes about deprecated parts of the application.
20
21
22 Deprecated API calls
23 --------------------
24
25 - Make sure to add them into the section :ref:`deprecated`.
26
27 - Use `deprecated` inside of the call docstring to make our users aware of the
28 deprecation::
29
30 .. deprecated:: 1.2.3
31
32 Use `new_call_name` instead to fetch this information.
33
34 - Make sure to log on level `logging.WARNING` a message that the API call or
35 specific parameters are deprecated.
36
37 - If possible return deprecation information inside of the result from the API
38 call. Use the attribute `_warning_` to contain a message.
39
40
41 Changed API calls
42 -----------------
43
44 - If the change is significant, consider to use `versionchanged` in the
45 docstring::
46
47 .. versionchanged:: 1.2.3
48
49 Optional explanation if reasonable.
50
51
52 Added API calls
53 ---------------
54
55 - Use `versionadded` to document since which version this API call is
56 available::
57
58 .. versionadded:: 1.2.3
59
60 Optional explanation if reasonable.
@@ -0,0 +1,19 b''
1 .. _contributing:
2
3 Contributing to RhodeCode
4 =========================
5
6
7
8 Welcome to contribution guides and development docs of RhodeCode.
9
10
11
12 .. toctree::
13 :maxdepth: 1
14
15 testing/index
16 dev-setup
17 db-schema
18 dev-settings
19 api
@@ -0,0 +1,52 b''
1 =======================
2 DB Schema and Migration
3 =======================
4
5 To create or alter tables in the database it's necessary to change a couple of
6 files, apart from configuring the settings pointing to the latest database
7 schema.
8
9
10 Database Model and ORM
11 ----------------------
12
13 On ``rhodecode.model.db`` you will find the database definition of all tables and
14 fields. Any fresh install database will be correctly created by the definitions
15 here. So, any change to this files will affect the tests without having to change
16 any other file.
17
18 A second layer are the businness classes that are inside ``rhodecode.model``.
19
20
21 Database Migration
22 ------------------
23
24 Three files play a role when creating database migrations:
25
26 * Database schema inside ``rhodecode.lib.dbmigrate``
27 * Database version inside ``rhodecode.lib.dbmigrate``
28 * Configuration ``__dbversion__`` at ``rhodecode.__init__``
29
30
31 Schema is a snapshot of the database version BEFORE the migration. So, it's
32 the initial state before any changes were added. The name convention is
33 the latest release version where the snapshot were created, and not the
34 target version of this code.
35
36 Version is the method that will define how to UPGRADE/DOWNGRADE the database.
37
38 ``rhodecode.__init__`` contains only a variable that defines up to which version of
39 the database will be used to upgrade. Eg.: ``__dbversion__ = 45``
40
41
42 For examples on how to create those files, please see the existing code.
43
44
45 Migration Command
46 ^^^^^^^^^^^^^^^^^
47
48 After you changed the database ORM and migration files, you can run::
49
50 paster upgrade-db <ini-file>
51
52 And the database will be upgraded up to the version defined in the ``__init__`` file. No newline at end of file
@@ -0,0 +1,46 b''
1
2 ==========================
3 Settings for Development
4 ==========================
5
6
7 We have a few settings which are intended to be used only for development
8 purposes. This section contains an overview of them.
9
10
11
12 `debug_style`
13 =============
14
15 Enables the section "Style" in the application. This section provides an
16 overview of all components which are found in the frontend style of the
17 application.
18
19
20
21 `vcs.start_server`
22 ==================
23
24 Starts the server as a subprocess while the system comes up. Intended usage is
25 to ease development.
26
27
28
29 `[logging]`
30 ===========
31
32 Use this to configure loggig to your current needs. The documentation of
33 Python's `logging` module explains all details. The following snippets are
34 useful for day to day development work.
35
36
37 Mute SQL output
38 ---------------
39
40 They come out of the package `sqlalchemy.engine`::
41
42 [logger_sqlalchemy]
43 level = WARNING
44 handlers = console_sql
45 qualname = sqlalchemy.engine
46 propagate = 0
@@ -0,0 +1,141 b''
1
2 ===================
3 Development setup
4 ===================
5
6
7 RhodeCode Enterprise runs inside a Nix managed environment. This ensures build
8 environment dependencies are correctly declared and installed during setup.
9 It also enables atomic upgrades, rollbacks, and multiple instances of RhodeCode
10 Enterprise for efficient cluster management.
11
12 To set up RhodeCode Enterprise inside the Nix environment use the following steps:
13
14
15
16 Setup Nix Package Manager
17 -------------------------
18
19 To install the Nix Package Manager please run::
20
21 $ curl https://nixos.org/nix/install | sh
22
23 or go to https://nixos.org/nix/ and follow their installation instructions.
24 Once this is correctly set up on your system you should be able to use the
25 following commands:
26
27 * `nix-env`
28
29 * `nix-shell`
30
31
32 .. tip::
33
34 Update your channels frequently by running ``nix-channel --upgrade``.
35
36
37 Switch nix to latest STABLE channel
38 -----------------------------------
39
40 run::
41
42 nix-channel --add https://nixos.org/channels/nixos-16.03 nixpkgs
43
44 Followed by::
45
46 nix-channel --update
47
48
49 Clone the required repositories
50 -------------------------------
51
52 After Nix is set up, clone the RhodeCode Enterprise Community Edition, and
53 RhodeCode VCSServer repositories into the same directory.
54 To do this, use the following example::
55
56 mkdir rhodecode-develop && cd rhodecode-develop
57 hg clone https://code.rhodecode.com/rhodecode-enterprise-ce
58 hg clone https://code.rhodecode.com/rhodecode-vcsserver
59
60 .. note::
61
62 If you cannot clone the repository, please request read permissions.
63
64
65
66 Enter the Development Shell
67 ---------------------------
68
69 The final step is to start into the development shell. To do this run the
70 following command from inside the cloned repository::
71
72 cd ~/rhodecode-enterprise-ce
73 nix-shell --arg dev true
74
75 .. note::
76
77 On the first run, this will take a while to download and optionally compile
78 a few things. The next runs of it will be faster.
79
80
81
82 Creating a Development Configuration
83 ------------------------------------
84
85 To create a development environment for RhodeCode Enterprise,
86 use the following steps:
87
88 1. Create a copy of `~/rhodecode-enterprise-ce/configs/development.ini`
89 2. Adjust the configuration settings to your needs
90
91 .. note::
92
93 It is recommended to call it `dev.ini`.
94
95
96 Setup the Development Database
97 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
98
99 To create a development database use the following example. This is a one
100 time operation::
101
102 paster setup-rhodecode dev.ini \
103 --user=admin --password=secret \
104 --email=admin@example.com \
105 --repos=~/my_dev_repos
106
107
108 Start the Development Server
109 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
110
111 When starting the development server, you should start the vcsserver as a
112 separate process. To do this use one of the following examples:
113
114 1. Set the `start.vcs_server` flag in the ``dev.ini`` file to true. For example:
115
116 .. code-block:: python
117
118 ### VCS CONFIG ###
119 ##################
120 vcs.start_server = true
121 vcs.server = localhost:9900
122 vcs.server.log_level = debug
123
124 Then start the server using the following command: ``rcserver dev.ini``
125
126 2. Start the development server using the following example::
127
128 rcserver --with-vcsserver dev.ini
129
130 3. Start the development server in a different terminal using the following
131 example::
132
133 vcsserver
134
135
136 Run the Environment Tests
137 ^^^^^^^^^^^^^^^^^^^^^^^^^
138
139 Please make sure that the test are passing to verify that your environment is
140 set up correctly. More details about the tests are described in:
141 :file:`/docs/dev/testing`.
@@ -0,0 +1,28 b''
1
2
3 ============================
4 Testing and Specifications
5 ============================
6
7
8 .. toctree::
9 :maxdepth: 2
10
11 unit-and-functional
12 spec-by-example
13 naming-conventions
14
15
16
17 Overview
18 ========
19
20 We have a quite big test suite inside of :file:`rhodecode/tests` which is a mix
21 of unit tests and functional or integration tests. More details are in
22 :ref:`test-unit-and-functional`.
23
24
25 Apart from that we start to apply "Specification by Example" and maintain a
26 collection of such specifications together with an implementation so that it can
27 be validated in an automatic way. The files can be found in
28 :file:`acceptance_tests`. More details are in :ref:`test-spec-by-example`.
@@ -0,0 +1,29 b''
1
2 ====================
3 Naming conventions
4 ====================
5
6
7 Fixtures
8 ========
9
10 We found so far a few patterns emerging in our py.test fixtures. The naming
11 conventions for those are documented on this page.
12
13
14 Utilities - ``_util``
15 ---------------------
16
17 Used for fixtures which are used to ensure that the pre-conditions of the test
18 are met. Usually it does not matter so much for the test how they achieve
19 this. Most utilities will clean up automatically after themselves.
20
21 Use the suffix ``_util``.
22
23
24 Page objects - ``{route_name}_page``
25 ------------------------------------
26
27 Used as abstractions of pages.
28
29 Use the suffix ``_page`` and if possible use the route name as the prefix.
@@ -0,0 +1,75 b''
1
2 .. _test-spec-by-example:
3
4 ==========================
5 Specification by Example
6 ==========================
7
8
9 .. Avoid duplicating the quickstart instructions by importing the README
10 file.
11
12 .. include:: ../../../acceptance_tests/README.rst
13
14
15
16 Choices of technology and tools
17 ===============================
18
19
20 `nix` as runtime environment
21 ----------------------------
22
23 We settled to use the `nix` tools to provide us the needed environment for
24 running the tests.
25
26
27
28 `Gherkins` as specification language
29 ------------------------------------
30
31 To specify by example, we settled on Gherkins as the semi-formal specification
32 language.
33
34
35 `py.test` as a runner
36 ---------------------
37
38 After experimenting with `behave` and `py.test` our choice was `pytest-bdd`
39 because it allows us to use our existing knowledge about `py.test` and avoids
40 that we have to learn another tool.
41
42
43
44 Concepts
45 ========
46
47 The logic is structured around the design pattern of "page objects". The
48 documentation of `python-selemium` contains a few more details about this
49 pattern.
50
51
52
53 Page Objects
54 ------------
55
56 We introduce an abstraction class for every page which we have to interact with
57 in order to validate the specifications.
58
59 The implementation for the page objects is inside of the module
60 :mod:`page_objects`. The class :class:`page_objects.base.BasePage` should be
61 used as a base for all page object implementations.
62
63
64
65 Locators
66 --------
67
68 The specific information how to locate an element inside of the DOM tree of a
69 page is kept in a separate class. This class serves mainly as a data container,
70 it shall not contain any logic.
71
72 The reason for keeping the locators separate is that we expect a frequent need
73 for change whenever we work on our templates. In such a case it is more
74 efficient to have all locators together and update them there instead of having
75 to find all locators inside of the logic of a page object.
@@ -0,0 +1,61 b''
1
2 .. _test-unit-and-functional:
3
4 ===========================
5 Unit and Functional Tests
6 ===========================
7
8
9
10 py.test based test suite
11 ========================
12
13
14 The test suite is in the folder :file:`rhodecode/tests/` and should be run with
15 the test runner `py.test` inside of your `nix-shell` environment::
16
17 # In case you need the cythonized version
18 CYTHONIZE=1 python setup.py develop --prefix=$tmp_path
19
20 py.test rhodecode
21
22
23
24 py.test integration
25 -------------------
26
27 The integration with the test runner is based on the following three parts:
28
29 - `pytest_pylons` is a py.test plugin which does the integration with the
30 Pylons web framework. It sets up the Pylons environment based on a given ini
31 file.
32
33 Tests which depend on the Pylons environment to be set up must request the
34 fixture `pylonsapp`.
35
36 - :file:`rhodecode/tests/plugin.py` contains the integration of py.test with
37 RhodeCode Enterprise itself.
38
39 - :file:`conftest.py` plugins are used to provide a special integration for
40 certain groups of tests based on the directory location.
41
42
43
44 VCS backend selection
45 ---------------------
46
47 The py.test integration provides a parameter `--backends`. It will skip all
48 tests which are marked for other backends.
49
50 To run only Subversion tests::
51
52 py.test rhodecode --backends=svn
53
54
55
56 Frontend / Styling support
57 ==========================
58
59 All relevant style components have an example inside of the "Style" section
60 within the application. Enable the setting `debug_style` to make this section
61 visible in your local instance of the application.
@@ -0,0 +1,134 b''
1 { system ? builtins.currentSystem
2 }:
3
4 let
5
6 pkgs = import <nixpkgs> { inherit system; };
7
8 inherit (pkgs) fetchurl fetchgit;
9
10 buildPythonPackage = pkgs.python27Packages.buildPythonPackage;
11 python = pkgs.python27Packages.python;
12
13 Jinja2 = buildPythonPackage rec {
14 name = "Jinja2-2.7.3";
15 src = fetchurl {
16 url = "http://pypi.python.org/packages/source/J/Jinja2/${name}.tar.gz";
17 md5 = "b9dffd2f3b43d673802fe857c8445b1a";
18 };
19 propagatedBuildInputs = [ MarkupSafe ];
20 };
21
22 MarkupSafe = buildPythonPackage rec {
23 name = "MarkupSafe-0.23";
24 src = fetchurl {
25 url = "https://pypi.python.org/packages/source/M/MarkupSafe/${name}.tar.gz";
26 md5 = "f5ab3deee4c37cd6a922fb81e730da6e";
27 };
28 };
29
30 Pygments = buildPythonPackage rec {
31 name = "Pygments-2.0.2";
32 src = fetchurl {
33 url = "https://pypi.python.org/packages/source/P/Pygments/${name}.tar.gz";
34 md5 = "238587a1370d62405edabd0794b3ec4a";
35 };
36 };
37
38 alabaster = buildPythonPackage rec {
39 name = "alabaster-0.7.3";
40 src = fetchurl {
41 url = "https://pypi.python.org/packages/source/a/alabaster/${name}.tar.gz";
42 md5 = "67428d1383fd833f1282fed5deba0898";
43 };
44 };
45
46 six = buildPythonPackage rec {
47 name = "six-1.9.0";
48 src = fetchurl {
49 url = "https://pypi.python.org/packages/source/s/six/${name}.tar.gz";
50 md5 = "476881ef4012262dfc8adc645ee786c4";
51 };
52 };
53
54 snowballstemmer = buildPythonPackage rec {
55 name = "snowballstemmer-1.2.0";
56 src = fetchurl {
57 url = "https://pypi.python.org/packages/source/s/snowballstemmer/${name}.tar.gz";
58 md5 = "51f2ef829db8129dd0f2354f0b209970";
59 };
60 };
61
62 pytz = buildPythonPackage rec {
63 name = "pytz-2015.2";
64 src = fetchurl {
65 url = "https://pypi.python.org/packages/source/p/pytz/${name}.tar.gz";
66 md5 = "08440d994cfbbf13d3343362cc3173f7";
67 };
68 };
69
70 babel = buildPythonPackage rec {
71 name = "Babel-1.3";
72 src = fetchurl {
73 url = "https://pypi.python.org/packages/source/B/Babel/${name}.tar.gz";
74 md5 = "5264ceb02717843cbc9ffce8e6e06bdb";
75 };
76 propagatedBuildInputs = [
77 pytz
78 ];
79 };
80
81 Sphinx = buildPythonPackage (rec {
82 name = "Sphinx-1.3.1";
83 src = fetchurl {
84 url = "http://pypi.python.org/packages/source/S/Sphinx/${name}.tar.gz";
85 md5 = "8786a194acf9673464c5455b11fd4332";
86 };
87 propagatedBuildInputs = [
88 docutils
89 Jinja2
90 Pygments
91 alabaster
92 six
93 snowballstemmer
94 pytz
95 babel
96
97 # TODO: johbo: Had to include it here so that can be imported
98 sphinx_rtd_theme
99 ];
100 });
101
102 docutils = buildPythonPackage rec {
103 name = "docutils-0.12";
104 src = fetchurl {
105 url = "https://pypi.python.org/packages/source/d/docutils/${name}.tar.gz";
106 md5 = "4622263b62c5c771c03502afa3157768";
107 };
108 };
109
110 sphinx_rtd_theme = buildPythonPackage rec {
111 name = "sphinx_rtd_theme-0.1.9";
112 src = fetchurl {
113 url = "https://pypi.python.org/packages/source/s/sphinx_rtd_theme/${name}.tar.gz";
114 md5 = "86a25c8d47147c872e42dc84cc66f97b";
115 };
116
117 # Note: johbo: Sphinx needs this package and this package needs sphinx,
118 # ignore the requirements file to solve this cycle.
119 postPatch = ''
120 rm requirements.txt
121 touch requirements.txt
122 '';
123
124 # TODO: johbo: Tests would require sphinx and this creates recursion issues
125 doCheck = false;
126 };
127
128 in python.buildEnv.override {
129 inherit python;
130 extraLibs = [
131 Sphinx
132 sphinx_rtd_theme
133 ];
134 }
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -0,0 +1,84 b''
1 |RCM|
2 =====
3
4 |RCM| is a high-performance source code management and collaboration system.
5 It enables you to develop projects securely behind the firewall while
6 providing collaboration tools that work with |git|, |hg|,
7 and |svn| |repos|. The user interface allows you to create, edit,
8 and commit files and |repos| while managing their security permissions.
9
10 |RCM| provides the following features:
11
12 * Source code management.
13 * Extended permissions management.
14 * Integrated code collaboration tools.
15 * Integrated code review and notifications.
16 * Scalability provided by multi-node setup.
17 * Fully programmable automation API.
18 * Web-based hook management.
19 * Native |svn| support.
20 * Migration from existing databases.
21 * |RCM| SDK.
22 * Built-in analytics
23 * Pluggable authentication system.
24 * Support for |LDAP|, Crowd, CAS, PAM.
25 * Debug modes of operation.
26 * Private and public gists.
27 * Gists with limited lifetimes and within instance only sharing.
28 * Fully integrated code search function.
29 * Always on SSL connectivity.
30
31 .. only:: html
32
33 Table of Contents
34 -----------------
35
36 .. toctree::
37 :maxdepth: 1
38 :caption: Admin Documentation
39
40 install/quick-start
41 install/install-database
42 install/install-steps
43 admin/system-overview
44 nix/default-env
45 admin/system-admin
46 admin/user-admin
47 admin/setting-repo-perms
48 admin/security-tips
49 auth/auth
50 issue-trackers/issue-trackers
51 admin/lab-settings
52
53 .. toctree::
54 :maxdepth: 1
55 :caption: Feature Documentation
56
57 collaboration/collaboration
58 collaboration/review-notifications
59 collaboration/pull-requests
60 code-review/code-review
61
62 .. toctree::
63 :maxdepth: 1
64 :caption: Developer Documentation
65
66 api/api
67 tools/rhodecode-tools
68 integrations/integrations
69 contributing/contributing
70
71 .. toctree::
72 :maxdepth: 1
73 :caption: User Documentation
74
75 usage/basic-usage
76 tutorials/tutorials
77
78 .. toctree::
79 :maxdepth: 1
80 :caption: About
81
82 known-issues/known-issues
83 release-notes/release-notes
84 admin/glossary
@@ -0,0 +1,38 b''
1 .. _config-database:
2
3 Make Database Changes
4 ---------------------
5
6 .. important::
7
8 If you do change the |repo| database that |RCM| uses, then you will need to
9 upgrade the database, and also remap and rescan the |repos|. More detailed
10 information is available in the
11 :ref:`Alternative upgrade documentation <control:install-port>`.
12
13 If you need to change database connection details for a |RCM| instance,
14 use the following steps:
15
16 1. Open the :file:`rhodecode.ini` file for the instance you wish to edit. The
17 default location is
18 :file:`home/{user}/.rccontrol/{instance-id}/rhodecode.ini`
19 2. When you open the file, find the database configuration section,
20 and use the below example to change the
21 connection details:
22
23 .. code-block:: ini
24
25 #########################################################
26 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
27 #########################################################
28
29 # Default SQLite config
30 sqlalchemy.db1.url = sqlite:////home/brian/.rccontrol/enterprise-1/rhodecode.db
31
32 # Use this example for a PostgreSQL
33 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
34
35 # see sqlalchemy docs for other advanced settings
36 sqlalchemy.db1.echo = false
37 sqlalchemy.db1.pool_recycle = 3600
38 sqlalchemy.db1.convert_unicode = true
@@ -0,0 +1,71 b''
1
2 .. _config-celery:
3
4 Install Celery
5 --------------
6
7 To improve |RCM| performance you should install Celery_ as it makes
8 asynchronous tasks work efficiently. If you
9 install Celery you also need multi-broker support. The recommended message
10 broker is rabbitmq_. |RCM| works in sync
11 mode, but running Celery_ will give you a large speed improvement when
12 managing many big repositories.
13
14 If you want to run |RCM| with Celery you need to run ``celeryd`` using the
15 ``paster`` command and the message broker.
16 The ``paster`` command is already installed during |RCM| installation.
17
18 To install and configure Celery, use the following steps:
19
20 1. Install Celery and RabbitMQ, see the documentation on the Celery website for
21 `Celery installation`_ and `rabbitmq installation`_.
22 2. Enable Celery in the
23 :file:`home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file.
24 3. Run the Celery daemon with the ``paster`` command,
25 using the following example
26 ``.rccontrol/enterprise-1/profile/bin/paster celeryd .rccontrol/enterprise-1/rhodecode.ini``
27
28 .. code-block:: ini
29
30 # Set this section of the ini file to match your Celery installation
31 ####################################
32 ### CELERY CONFIG ####
33 ####################################
34 ## Set to true
35 use_celery = false
36 broker.host = localhost
37 broker.vhost = rabbitmqhost
38 broker.port = 5672
39 broker.user = rabbitmq
40 broker.password = qweqwe
41
42 celery.imports = rhodecode.lib.celerylib.tasks
43
44 celery.result.backend = amqp
45 celery.result.dburi = amqp://
46 celery.result.serialier = json
47
48 #celery.send.task.error.emails = true
49 #celery.amqp.task.result.expires = 18000
50
51 celeryd.concurrency = 2
52 #celeryd.log.file = celeryd.log
53 celeryd.log.level = debug
54 celeryd.max.tasks.per.child = 1
55
56 ## tasks will never be sent to the queue, but executed locally instead.
57 celery.always.eager = false
58
59 .. code-block:: bash
60
61 # Once the above is configured and saved
62 # Run celery with the paster command and specify the ini file
63 .rccontrol/enterprise-1/profile/bin/paster celeryd .rccontrol/enterprise-1/rhodecode.ini
64
65 .. _python: http://www.python.org/
66 .. _mercurial: http://mercurial.selenic.com/
67 .. _celery: http://celeryproject.org/
68 .. _rabbitmq: http://www.rabbitmq.com/
69 .. _rabbitmq installation: http://docs.celeryproject.org/en/latest/getting-started/brokers/rabbitmq.html
70 .. _Celery installation: http://docs.celeryproject.org/en/latest/getting-started/introduction.html#bundles
71 .. _virtualenv: http://docs.python-guide.org/en/latest/dev/virtualenvs/
@@ -0,0 +1,68 b''
1 .. _rhodecode-database-ref:
2
3 Supported Databases
4 ===================
5
6 .. important::
7
8 We do not recommend using SQLite in a production environment. It is
9 supported by |RCE| for evaluation purposes.
10
11 Database Overview
12 -----------------
13
14 Prior to installing |RCE| you should install and set up your database.
15 This means carrying out the following tasks:
16
17 1. Install the database software of your choice.
18 2. Using the relevant instructions, create a user on that database to use
19 with |RCE|.
20 3. Create a database, granting that user read/write access.
21 4. During |RCE| installation you will be prompted for these user credentials,
22 enter them where appropriate. These credentials will be what |RCE| uses
23 to read/write from the database tables.
24
25 Version Differences
26 -------------------
27
28 |RCE| releases 2(Major).x(Minor).x(Bug Fix) and 3.x.x use different database
29 schemas. Therefore, if you wish to run multiple instances using one database,
30 you can only do so using the same Minor Release numbered versions.
31 Though Bug Fix updates rarely have a database change, it is recommended to use
32 identical |RCE| version numbers for multi-instance setups.
33
34 You can use the same database server to run multiple databases for differing
35 version numbers, but you will need separate databases for each |RCE| version on
36 that server. You can specify the database during installation, use the
37 following example to configure the correct one.
38
39 .. code-block:: bash
40
41 Database type - [s]qlite, [m]ysql, [p]ostresql:
42 PostgreSQL selected
43 Database host [127.0.0.1]:
44 Database port [5432]:
45 Database username: rhodecode
46 Database password: somepassword
47 # Specify the database you with to use on that server
48 # for the RCE instance you are installing
49 Database name: example-db-name-for-2xx # The 2xx version database
50 Database name: example-db-name-for-3xx # The 3xx version database
51
52 Supported Databases
53 -------------------
54
55 |RCM| supports the following databases. The recommended encoding is Unicode
56 UTF-8.
57
58 .. only:: latex
59
60 * :ref:`install-sqlite-database`
61 * :ref:`install-mysql-database`
62 * :ref:`install-postgresql-database`
63
64 .. toctree::
65
66 using-mysql
67 using-postgresql
68 using-sqllite
@@ -0,0 +1,14 b''
1 .. _rhodecode-post-instal-ref:
2
3 Post Installation Tasks
4 =======================
5
6 The following tasks are the most common post installation requirements. Use
7 the information in these sections to configure your instance of |RCM|.
8
9 .. toctree::
10
11 setup-email
12 database-string
13 install-celery
14 migrate-repos
@@ -0,0 +1,23 b''
1 .. _mig-repos:
2
3 Migrating |repos|
4 -----------------
5
6 If you have installed |RCM| and have |repos| that you wish to migrate into
7 the system, use the following instructions.
8
9 1. On the |RCM| interface, check your |repo| storage location under
10 :menuselection:`Admin --> Settings --> System Info`. For example,
11 Storage location: /home/{username}/repos.
12
13 2. Copy the |repos| that you want |RCM| to manage to this location.
14 3. Remap and rescan the |repos|, see :ref:`remap-rescan`
15
16 .. important::
17
18 Directories create |repo| groups inside |RCM|.
19
20 Importing adds |RCM| git hooks to your |repos|.
21
22 You should verify if custom ``.hg`` or ``.hgrc`` files inside
23 repositories should be adjusted since |RCM| reads the content of them.
@@ -0,0 +1,102 b''
1 .. _quick-start:
2
3 Quick Start Guide
4 =================
5
6 .. important::
7
8 These are quick start instructions. To optimize your |RCE|,
9 |RCC|, and |RCT| usage, read the more detailed instructions in our guides.
10 For detailed installation instructions, see
11 :ref:`RhodeCode Control Documentation <control:rcc>`
12
13 .. tip::
14
15 If using a non-SQLite database, install and configure the database, create
16 a new user, and grant permissions. You will be prompted for this user's
17 credentials during |RCE| installation. See the relevant database
18 documentation for more details.
19
20 To get |RCM| up and running, run through the below steps:
21
22 1. Download the latest |RCC| installer from your `rhodecode.com`_ profile
23 page. If you don't have an account, sign up at `rhodecode.com/register`_.
24 2. Run the |RCC| installer and accept the End User Licence using the
25 following example:
26
27 .. code-block:: bash
28
29 $ chmod 755 RhodeCode-installer-linux-*
30 $ ./RhodeCode-installer-linux-*
31
32 3. Install a VCS Server, and configure it to start at boot.
33
34 .. code-block:: bash
35
36 $ rccontrol install VCSServer
37
38 Agree to the licence agreement? [y/N]: y
39 IP to start the server on [127.0.0.1]:
40 Port for the server to start [10005]:
41 Creating new instance: vcsserver-1
42 Installing RhodeCode VCSServer
43 Configuring RhodeCode VCS Server ...
44 Supervisord state is: RUNNING
45 Added process group vcsserver-1
46
47
48 4. Install |RCE|. If using MySQL or PostgreSQL, during installation you'll be
49 asked for your database credentials, so have them at hand. You don't need
50 any for SQLite.
51
52 .. code-block:: bash
53 :emphasize-lines: 11-16
54
55 $ rccontrol install Enterprise
56
57 Username [admin]: username
58 Password (min 6 chars):
59 Repeat for confirmation:
60 Email: your@mail.com
61 Respositories location [/home/brian/repos]:
62 IP to start the Enterprise server on [127.0.0.1]:
63 Port for the Enterprise server to use [10004]:
64 Database type - [s]qlite, [m]ysql, [p]ostresql:
65 PostgreSQL selected
66 Database host [127.0.0.1]:
67 Database port [5432]:
68 Database username: db-user-name
69 Database password: somepassword
70 Database name: example-db-name
71
72 5. Check the status of your installation. You |RCE| instance runs on the URL
73 displayed in the status message.
74
75 .. code-block:: bash
76
77 $ rccontrol status
78
79 - NAME: enterprise-1
80 - STATUS: RUNNING
81 - TYPE: Enterprise
82 - VERSION: 3.3.0
83 - URL: http://127.0.0.1:10003
84
85 - NAME: vcsserver-1
86 - STATUS: RUNNING
87 - TYPE: VCSServer
88 - VERSION: 3.3.0
89 - URL: http://127.0.0.1:10001
90
91 .. note::
92
93 Recommended post quick start install instructions:
94
95 * Read the documentation
96 * Carry out the :ref:`rhodecode-post-instal-ref`
97 * Set up :ref:`indexing-ref`
98 * Familiarise yourself with the :ref:`rhodecode-admin-ref` section.
99
100 .. _rhodecode.com/download/: https://rhodecode.com/download/
101 .. _rhodecode.com: https://rhodecode.com/
102 .. _rhodecode.com/register: https://rhodecode.com/register/
@@ -0,0 +1,34 b''
1 .. _set-up-mail:
2
3 Set up Email
4 ------------
5
6 To setup email with your |RCM| instance, open the default
7 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini`
8 file and uncomment and configure the email section. If it is not there,
9 use the below example to insert it.
10
11 Once configured you can check the settings for your |RCM| instance on the
12 :menuselection:`Admin --> Settings --> Email` page.
13
14 .. code-block:: ini
15
16 ################################################################################
17 ## Uncomment and replace with the email address which should receive ##
18 ## any error reports after an application crash ##
19 ## Additionally these settings will be used by the RhodeCode mailing system ##
20 ################################################################################
21 #email_to = admin@localhost
22 #error_email_from = paste_error@localhost
23 #app_email_from = rhodecode-noreply@localhost
24 #error_message =
25 #email_prefix = [RhodeCode]
26
27 #smtp_server = mail.server.com
28 #smtp_username =
29 #smtp_password =
30 #smtp_port =
31 #smtp_use_tls = false
32 #smtp_use_ssl = true
33 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
34 #smtp_auth =
@@ -0,0 +1,26 b''
1 .. _install-mysql-database:
2
3 MySQL or MariaDB
4 ----------------
5
6 To use a MySQL or MariaDB database you should install and configure the
7 database before installing |RCM|. This is because during |RCM| installation
8 you will setup a connection to your MySQL or MariaDB database. To work with
9 either, use the following steps:
10
11 1. Depending on your |os|, install a MySQL or MariaDB database following the
12 appropriate instructions from the `MySQL website`_ or `MariaDB website`_.
13 2. Configure the database with a username and password which you will use
14 with |RCM|.
15 3. Install |RCM|, and during installation select MySQL as your database.
16 4. Enter the following information during the database setup:
17
18 * Your network IP Address
19 * The port number for MySQL or MariaDB access.
20 The default port for both is ``3306``
21 * Your database username
22 * Your database password
23 * A new database name
24
25 .. _MySQL website: http://www.mysql.com/
26 .. _MariaDB website: https://mariadb.com/
@@ -0,0 +1,24 b''
1 .. _install-postgresql-database:
2
3 PostgreSQL
4 ----------
5
6 To use a PostgreSQL database you should install and configurevthe database
7 before installing |RCV|. This is becausevduring |RCV| installation you will
8 setup a connection to your PostgreSQL database. To work with PostgreSQL,
9 use the following steps:
10
11 1. Depending on your |os|, install avPostgreSQL database following the
12 appropriate instructions from the `PostgreSQL website`_.
13 2. Configure the database with a username and password which you will use
14 with |RCV|.
15 3. Install |RCV|, and during installation select PostgreSQL as your database.
16 4. Enter the following information to during the database setup:
17
18 * Your network IP Address
19 * The port number for MySQL access. The default MySQL port is ``5434``
20 * Your database username
21 * Your database password
22 * A new database name
23
24 .. _PostgreSQL website: http://www.postgresql.org/
@@ -0,0 +1,32 b''
1 .. _install-sqlite-database:
2
3 SQLite
4 ------
5
6 .. important::
7
8 We do not recommend using SQLite in a large development environment
9 as it has an internal locking mechanism which can become a performance
10 bottleneck when there are more than 5 concurrent users.
11
12 |RCM| installs SQLite as the default database if you do not specify another
13 during installation. SQLite is suitable for small teams,
14 projects with a low load, and evaluation purposes since it is built into
15 |RCM| and does not require any additional database server.
16
17 Using MySQL or PostgreSQL in an large setup gives you much greater
18 performance, and while migration tools exist to move from one database type
19 to another, it is better to get it right first time and to immediately use
20 MySQL or PostgreSQL when you deploy |RCM| in a production environment.
21
22 Migrating From SQLite to PostgreSQL
23 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24
25 If you started working with SQLite and now need to migrate your database
26 to PostgreSQL, you can contact support@rhodecode.com for some help. We have a
27 set of scripts that enable SQLite to PostgreSQL migration. These scripts have
28 been tested, and work with PostgreSQL 9.1+.
29
30 .. note::
31
32 There are no SQLite to MySQL or MariaDB scripts available.
@@ -0,0 +1,150 b''
1 .. _config-ext:
2
3 Configure |RCX|
4 ---------------
5
6 To get the the built in plugins and extensions working the way you want them
7 to, you have to configure them to work with your services. An overview of
8 what needs to be done is:
9
10 * :ref:`config-rcx-plugin` to carry out your desired actions once its hook is
11 triggered. There are default actions built in, but you may wish to alter
12 those.
13 * :ref:`config-rcx-hook` to execute actions for the plugin, when certain
14 actions are carried out with |RCE|.
15
16 .. _config-rcx-plugin:
17
18 Tweak a Default Plugin
19 ^^^^^^^^^^^^^^^^^^^^^^
20
21 Each of the default plugins comes with a standard configuration, but you may
22 wish to change those settings. In this example, the Redmine plugin watches
23 for the words defined in the ``HASH_REGEX`` variable and takes actions if one
24 of those words is used in conjunction with a ``#{number}``, which matches a
25 ticket number in Redmine. You can configure this to work differently based on
26 the `Redmine documentation`_.
27
28 .. code-block:: python
29 :emphasize-lines: 3-5, 37
30
31 import re
32
33 HASH_REGEX = re.compile(
34 r"(?:fix|fixes|fixing|close|closes|closing)\s*#([0-9]+)\b",
35 re.IGNORECASE)
36
37
38 def link_to_commit(repo_url, commit_id):
39 rev_url = '%s/changeset/%s' % (repo_url, commit_id)
40 return '"%s":%s' % (commit_id[:6], rev_url)
41
42
43 def run(*args, **kwargs):
44 issues = kwargs['RM_ISSUES']
45 if not issues:
46 return 0
47
48 # repo extra fields can control this, they should be propagated with
49 # extract repo fields
50 tracker_url = kwargs.get('redmine_tracker_url') or kwargs['RM_URL']
51 project_id = kwargs.get('redmine_project_id') or kwargs['RM_PROJECT']
52 api_key = kwargs.get('redmine_api_key') or kwargs['RM_APIKEY']
53
54 if project_id:
55 from redmine import Redmine
56 remote_redmine = Redmine(tracker_url, key=api_key)
57 project = remote_redmine.project.get(project_id)
58 repo_url = '%(server_url)s/%(repository)s' % kwargs
59 # for each fetched issue id make a redmine api call
60 for _id, details in issues.items():
61 commits = ', '.join([link_to_commit(repo_url,
62 x['raw_id'],)
63 for x in details])
64 issue = project.issues.get(int(_id))
65 if issue:
66 issue.notes = 'Issue resolved by %s' % (commits,)
67 issue.status_id = 3 # Resolved
68 issue.save()
69
70
71 .. _config-rcx-hook:
72
73 Configure a Hook
74 ^^^^^^^^^^^^^^^^
75
76 To configure the default hooks in the
77 :file:`/home/{user}/.rccontrol/{instance-id}/rcextensions/__init.py__` file,
78 use the following steps.
79
80 1. Configure the connection details, either in the file or import from a
81 dictionary. For these connection scenarios the following details need to
82 be configured.
83
84 * **REDMINE_URL** = '<redmine-url>'
85 * **REDMINE_API_KEY** = '<secret>'
86 * **SLACK_API_URL** = '<slack-url>?token=<secret>'
87 * **SLACK_API_KEY** = '<secret>'
88
89 2. You will also need to configure other variables, such as the
90 **SLACK_ROOM** or **RM_PROJECT** (Redmine Project). These set where the
91 commit message is posted. Various hooks can take different variables and
92 they are documented in the file.
93
94 3. Inside each hook you can then configure it to carry out actions
95 per service. In this example, the push hook is pushing to the Redmine and
96 Slack plugins on each push if the hook criteria are matched.
97
98 .. code-block:: python
99 :emphasize-lines: 21-29, 37-44
100
101 def _push_hook(*args, **kwargs):
102 kwargs['commit_ids'] = kwargs['pushed_revs']
103
104 call = load_extension('extra_fields.py')
105 if call:
106 repo_extra_fields = call(**kwargs)
107 # now update if we have extra fields, they have precedence
108 # this way users can store any configuration inside
109 # the database per repo
110 for key, data in repo_extra_fields.items():
111 kwargs[key] = data['field_value']
112
113 # fetch pushed commits
114 call = load_extension('extract_commits.py')
115 extracted_commits = {}
116 if call:
117 extracted_commits = call(**kwargs)
118 # store the commits for the next call chain
119 kwargs['COMMITS'] = extracted_commits
120
121 # slack !
122 call = load_extension('slack.py')
123 if call:
124 kwargs['INCOMING_WEBHOOK_URL'] = SLACK_API_URL
125 kwargs['SLACK_TOKEN'] = SLACK_API_KEY
126 kwargs['SLACK_ROOM'] = '#slack-channel'
127 kwargs['SLACK_FROM'] = 'Slack-Message-Poster'
128 kwargs['SLACK_FROM_ICON_EMOJI'] = ':slack-emoji:'
129 call(**kwargs)
130
131 # fetch issues from given commits
132 call = load_extension('extract_issues.py')
133 issues = {}
134 if call:
135 issues = call(**kwargs)
136
137 # redmine smart commits
138 call = load_extension('redmine_smart_commits.py')
139 if call:
140 kwargs['RM_URL'] = REDMINE_URL
141 kwargs['RM_APIKEY'] = REDMINE_API_KEY
142 kwargs['RM_PROJECT'] = None # uses extra_fields from repo
143 kwargs['RM_ISSUES'] = issues
144 call(**kwargs)
145
146 return 0
147 PUSH_HOOK = _push_hook
148
149
150 .. _Redmine documentation: http://www.redmine.org/projects/redmine/wiki/Rest_api
This diff has been collapsed as it changes many lines, (823 lines changed) Show them Hide them
@@ -0,0 +1,823 b''
1 """
2 rcextensions module.
3
4 """
5
6
7 import os
8 import imp
9 import string
10 import functools
11
12 here = os.path.dirname(os.path.abspath(__file__))
13 registered_extensions = dict()
14
15 class DotDict(dict):
16
17 def __contains__(self, k):
18 try:
19 return dict.__contains__(self, k) or hasattr(self, k)
20 except:
21 return False
22
23 # only called if k not found in normal places
24 def __getattr__(self, k):
25 try:
26 return object.__getattribute__(self, k)
27 except AttributeError:
28 try:
29 return self[k]
30 except KeyError:
31 raise AttributeError(k)
32
33 def __setattr__(self, k, v):
34 try:
35 object.__getattribute__(self, k)
36 except AttributeError:
37 try:
38 self[k] = v
39 except:
40 raise AttributeError(k)
41 else:
42 object.__setattr__(self, k, v)
43
44 def __delattr__(self, k):
45 try:
46 object.__getattribute__(self, k)
47 except AttributeError:
48 try:
49 del self[k]
50 except KeyError:
51 raise AttributeError(k)
52 else:
53 object.__delattr__(self, k)
54
55 def toDict(self):
56 return unserialize(self)
57
58 def __repr__(self):
59 keys = list(self.iterkeys())
60 keys.sort()
61 args = ', '.join(['%s=%r' % (key, self[key]) for key in keys])
62 return '%s(%s)' % (self.__class__.__name__, args)
63
64 @staticmethod
65 def fromDict(d):
66 return serialize(d)
67
68
69 def serialize(x):
70 if isinstance(x, dict):
71 return DotDict((k, serialize(v)) for k, v in x.iteritems())
72 elif isinstance(x, (list, tuple)):
73 return type(x)(serialize(v) for v in x)
74 else:
75 return x
76
77
78 def unserialize(x):
79 if isinstance(x, dict):
80 return dict((k, unserialize(v)) for k, v in x.iteritems())
81 elif isinstance(x, (list, tuple)):
82 return type(x)(unserialize(v) for v in x)
83 else:
84 return x
85
86
87 def load_extension(filename, async=False):
88 """
89 use to load extensions inside rcextension folder.
90 for example::
91
92 callback = load_extension('email.py', async=False)
93 if callback:
94 callback('foobar')
95
96 put file named email.py inside rcextensions folder to load it. Changing
97 async=True will make the call of the plugin async, it's useful for
98 blocking calls like sending an email or notification with APIs.
99 """
100 mod = ''.join(filename.split('.')[:-1])
101 loaded = imp.load_source(mod, os.path.join(here, filename))
102
103 callback = getattr(loaded, 'run', None)
104 if not callback:
105 raise Exception('Plugin missing `run` method')
106 if async:
107 # modify callback so it's actually an async call
108 def _async_callback(*args, **kwargs):
109 import threading
110 thr = threading.Thread(target=callback, args=args, kwargs=kwargs)
111 thr.start()
112 if kwargs.get('_async_block'):
113 del kwargs['_async_block']
114 thr.join()
115
116 return _async_callback
117 return callback
118
119
120 def _verify_kwargs(expected_parameters, kwargs):
121 """
122 Verify that exactly `expected_parameters` are passed in as `kwargs`.
123 """
124 expected_parameters = set(expected_parameters)
125 kwargs_keys = set(kwargs.keys())
126 if kwargs_keys != expected_parameters:
127 missing_kwargs = expected_parameters - kwargs_keys
128 unexpected_kwargs = kwargs_keys - expected_parameters
129 raise AssertionError(
130 "Missing parameters: %r, unexpected parameters: %s" %
131 (missing_kwargs, unexpected_kwargs))
132
133
134 def verify_kwargs(required_args):
135 """
136 decorator to verify extension calls arguments.
137
138 :param required_args:
139 """
140 def wrap(func):
141 def wrapper(*args, **kwargs):
142 _verify_kwargs(required_args, kwargs)
143 return func(*args, **kwargs)
144 return wrapper
145 return wrap
146
147
148 def register(name=None):
149 def wrap(func):
150 @functools.wraps(func)
151 def wrapper(*args, **kwargs):
152 # register load_extensions in kwargs, so we can chain plugins
153 kwargs['_load_extension'] = load_extension
154 # append this path for us to use added plugins or modules
155 import sys
156 _cur_path = os.path.dirname(os.path.abspath(__file__))
157 if _cur_path not in sys.path:
158 sys.path.append(_cur_path)
159
160 registered_extensions[func.__name__] = func
161 return func(*args, **kwargs)
162 return wrapper
163 return wrap
164
165 # =============================================================================
166 # END OF UTILITY FUNCTIONS HERE
167 # =============================================================================
168
169 # Additional mappings that are not present in the pygments lexers
170 # used for building stats
171 # format is {'ext':['Names']} eg. {'py':['Python']} note: there can be
172 # more than one name for extension
173 # NOTE: that this will override any mappings in LANGUAGES_EXTENSIONS_MAP
174 # build by pygments
175 EXTRA_MAPPINGS = {}
176
177 # additional lexer definitions for custom files it's overrides pygments lexers,
178 # and uses defined name of lexer to colorize the files. Format is {'ext':
179 # 'lexer_name'} List of lexers can be printed running:
180 # >> python -c "import pprint;from pygments import lexers;
181 # pprint.pprint([(x[0], x[1]) for x in lexers.get_all_lexers()]);"
182
183 EXTRA_LEXERS = {}
184
185
186 CONFIG = DotDict(
187 slack=DotDict(
188 api_key='api-key',
189 api_url='slack-incoming-hook-url',
190 default_room='#slack-channel',
191 default_plugin_config={},
192 ),
193 redmine=DotDict(
194 api_key='api-key',
195 default_tracker_url='https://redmine.tracker.url',
196 default_project_id=None,
197 default_status_resolved_id=3
198 ),
199 )
200
201 # slack conf
202 CONFIG.slack.default_plugin_config = {
203 'INCOMING_WEBHOOK_URL': CONFIG.slack.api_url,
204 'SLACK_TOKEN': CONFIG.slack.api_key,
205 'SLACK_ROOM': CONFIG.slack.default_room,
206 'SLACK_FROM': 'RhodeCode',
207 'SLACK_FROM_ICON_EMOJI': ':rhodecode:',
208 }
209
210 # redmine smart_pr configuration
211 def configure_redmine_smart_pr(issues, kwargs):
212 kwargs['REDMINE_ISSUES'] = issues
213 kwargs['redmine_tracker_url'] = kwargs.pop(
214 'redmine_tracker_url', '') or CONFIG.redmine.default_tracker_url
215 kwargs['redmine_api_key'] = kwargs.pop(
216 'redmine_api_key', '') or CONFIG.redmine.api_key
217 kwargs['redmine_project_id'] = kwargs.pop(
218 'redmine_project_id', '') or CONFIG.redmine.default_project_id
219
220
221 @register('CREATE_REPO_HOOK')
222 @verify_kwargs(
223 ['_load_extension', 'repo_name', 'repo_type', 'description', 'private',
224 'created_on', 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
225 'clone_uri', 'fork_id', 'group_id', 'created_by'])
226 def _create_repo_hook(*args, **kwargs):
227 """
228 POST CREATE REPOSITORY HOOK. This function will be executed after
229 each repository is created. kwargs available:
230
231 :param repo_name:
232 :param repo_type:
233 :param description:
234 :param private:
235 :param created_on:
236 :param enable_downloads:
237 :param repo_id:
238 :param user_id:
239 :param enable_statistics:
240 :param clone_uri:
241 :param fork_id:
242 :param group_id:
243 :param created_by:
244 """
245 return 0
246 CREATE_REPO_HOOK = _create_repo_hook
247
248
249 @register('CREATE_REPO_GROUP_HOOK')
250 @verify_kwargs(
251 ['_load_extension', 'group_name', 'group_parent_id', 'group_description',
252 'group_id', 'user_id', 'created_by', 'created_on', 'enable_locking'])
253 def _create_repo_group_hook(*args, **kwargs):
254 """
255 POST CREATE REPOSITORY GROUP HOOK, this function will be
256 executed after each repository group is created. kwargs available:
257
258 :param group_name:
259 :param group_parent_id:
260 :param group_description:
261 :param group_id:
262 :param user_id:
263 :param created_by:
264 :param created_on:
265 :param enable_locking:
266 """
267 return 0
268 CREATE_REPO_GROUP_HOOK = _create_repo_group_hook
269
270
271 @register('PRE_CREATE_USER_HOOK')
272 @verify_kwargs(
273 ['_load_extension', 'username', 'password', 'email', 'firstname',
274 'lastname', 'active', 'admin', 'created_by'])
275 def _pre_create_user_hook(*args, **kwargs):
276 """
277 PRE CREATE USER HOOK, this function will be executed before each
278 user is created, it returns a tuple of bool, reason.
279 If bool is False the user creation will be stopped and reason
280 will be displayed to the user. kwargs available:
281
282 :param username:
283 :param password:
284 :param email:
285 :param firstname:
286 :param lastname:
287 :param active:
288 :param admin:
289 :param created_by:
290 """
291
292 reason = 'allowed'
293 return True, reason
294 PRE_CREATE_USER_HOOK = _pre_create_user_hook
295
296
297 @register('CREATE_USER_HOOK')
298 @verify_kwargs(
299 ['_load_extension', 'username', 'full_name_or_username', 'full_contact',
300 'user_id', 'name', 'firstname', 'short_contact', 'admin', 'lastname',
301 'ip_addresses', 'extern_type', 'extern_name', 'email', 'api_key',
302 'api_keys', 'last_login', 'full_name', 'active', 'password', 'emails',
303 'inherit_default_permissions', 'created_by', 'created_on'])
304 def _create_user_hook(*args, **kwargs):
305 """
306 POST CREATE USER HOOK, this function will be executed after each user is created
307 kwargs available:
308
309 :param username:
310 :param full_name_or_username:
311 :param full_contact:
312 :param user_id:
313 :param name:
314 :param firstname:
315 :param short_contact:
316 :param admin:
317 :param lastname:
318 :param ip_addresses:
319 :param extern_type:
320 :param extern_name:
321 :param email:
322 :param api_key:
323 :param api_keys:
324 :param last_login:
325 :param full_name:
326 :param active:
327 :param password:
328 :param emails:
329 :param inherit_default_permissions:
330 :param created_by:
331 :param created_on:
332 """
333 return 0
334 CREATE_USER_HOOK = _create_user_hook
335
336
337 @register('DELETE_REPO_HOOK')
338 @verify_kwargs(
339 ['_load_extension', 'repo_name', 'repo_type', 'description', 'private',
340 'created_on', 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
341 'clone_uri', 'fork_id', 'group_id', 'deleted_by', 'deleted_on'])
342 def _delete_repo_hook(*args, **kwargs):
343 """
344 POST DELETE REPOSITORY HOOK, this function will be executed after
345 each repository deletion kwargs available:
346
347 :param repo_name:
348 :param repo_type:
349 :param description:
350 :param private:
351 :param created_on:
352 :param enable_downloads:
353 :param repo_id:
354 :param user_id:
355 :param enable_statistics:
356 :param clone_uri:
357 :param fork_id:
358 :param group_id:
359 :param deleted_by:
360 :param deleted_on:
361 """
362 return 0
363 DELETE_REPO_HOOK = _delete_repo_hook
364
365
366 @register('DELETE_USER_HOOK')
367 @verify_kwargs(
368 ['_load_extension', 'username', 'full_name_or_username', 'full_contact',
369 'user_id', 'name', 'firstname', 'short_contact', 'admin', 'lastname',
370 'ip_addresses', 'email', 'api_key', 'last_login', 'full_name', 'active',
371 'password', 'emails', 'inherit_default_permissions', 'deleted_by'
372 ])
373 def _delete_user_hook(*args, **kwargs):
374 """
375 POST DELETE USER HOOK, this function will be executed after each
376 user is deleted kwargs available:
377
378 :param username:
379 :param full_name_or_username:
380 :param full_contact:
381 :param user_id:
382 :param name:
383 :param firstname:
384 :param short_contact:
385 :param admin:
386 :param lastname:
387 :param ip_addresses:
388 :param ldap_dn:
389 :param email:
390 :param api_key:
391 :param last_login:
392 :param full_name:
393 :param active:
394 :param password:
395 :param emails:
396 :param inherit_default_permissions:
397 :param deleted_by:
398 """
399 return 0
400 DELETE_USER_HOOK = _delete_user_hook
401
402
403 @register('PRE_PUSH_HOOK')
404 @verify_kwargs(
405 ['_load_extension', 'server_url', 'config', 'scm', 'username',
406 'ip', 'action', 'repository', 'repo_store_path'])
407 def _pre_push_hook(*args, **kwargs):
408 """
409 Post push hook
410 kwargs available:
411
412 :param server_url: url of instance that triggered this hook
413 :param config: path to .ini config used
414 :param scm: type of VS 'git' or 'hg'
415 :param username: name of user who pushed
416 :param ip: ip of who pushed
417 :param action: push
418 :param repository: repository name
419 :param repo_store_path: full path to where repositories are stored
420 """
421 return 0
422 PRE_PUSH_HOOK = _pre_push_hook
423
424
425 @register('PUSH_HOOK')
426 @verify_kwargs(
427 ['_load_extension', 'server_url', 'config', 'scm', 'username',
428 'ip', 'action', 'repository', 'repo_store_path', 'pushed_revs'])
429 def _push_hook(*args, **kwargs):
430 """
431 POST PUSH HOOK, this function will be executed after each push it's
432 executed after the build-in hook that RhodeCode uses for logging pushes
433 kwargs available:
434
435 :param server_url: url of instance that triggered this hook
436 :param config: path to .ini config used
437 :param scm: type of VS 'git' or 'hg'
438 :param username: name of user who pushed
439 :param ip: ip of who pushed
440 :param action: push
441 :param repository: repository name
442 :param repo_store_path: full path to where repositories are stored
443 :param pushed_revs: list of pushed commit ids
444 """
445 # backward compat
446 kwargs['commit_ids'] = kwargs['pushed_revs']
447
448 # fetch extra fields from repository
449 call = load_extension('extra_fields.py')
450 _extra_fields = {}
451 if call:
452 repo_extra_fields = call(**kwargs)
453 # now update if we have extra fields, they have precedence
454 # this way users can store any configuration inside the database per
455 # repo
456 for key, data in repo_extra_fields.items():
457 kwargs[key] = data['field_value']
458 _extra_fields[key] = data['field_value']
459
460 # fetch pushed commits, from commit_ids list
461 call = load_extension('extract_commits.py')
462 extracted_commits = {}
463 if call:
464 extracted_commits = call(**kwargs)
465 # store the commits for the next call chain
466 kwargs['COMMITS'] = extracted_commits
467
468 # slack !
469 call = load_extension('slack_push_notify.py')
470 if call:
471 kwargs.update(CONFIG.slack.default_plugin_config)
472 call(**kwargs)
473
474 # fetch redmine issues from given commits
475 call = load_extension('extract_redmine_issues.py')
476 issues = {}
477 if call:
478 issues = call(**kwargs)
479
480 # redmine smart commits
481 call = load_extension('redmine_smart_commits.py')
482 if call:
483 kwargs['REDMINE_ISSUES'] = issues
484
485 kwargs['redmine_tracker_url'] = kwargs.pop(
486 'redmine_tracker_url', '') or CONFIG.redmine.default_tracker_url
487 kwargs['redmine_api_key'] = kwargs.pop(
488 'redmine_api_key', '') or CONFIG.redmine.api_key
489 kwargs['redmine_status_resolved_id'] = kwargs.pop(
490 'redmine_status_resolved_id', '') or CONFIG.redmine.default_status_resolved_id
491 kwargs['redmine_project_id'] = kwargs.pop(
492 'redmine_project_id', '') or CONFIG.redmine.default_project_id
493 call(**kwargs)
494
495 return 0
496 PUSH_HOOK = _push_hook
497
498
499 @register('PRE_PULL_HOOK')
500 @verify_kwargs(
501 ['_load_extension', 'server_url', 'config', 'scm', 'username', 'ip',
502 'action', 'repository'])
503 def _pre_pull_hook(*args, **kwargs):
504 """
505 Post pull hook
506 kwargs available::
507
508 :param server_url: url of instance that triggered this hook
509 :param config: path to .ini config used
510 :param scm: type of VS 'git' or 'hg'
511 :param username: name of user who pulled
512 :param ip: ip of who pulled
513 :param action: pull
514 :param repository: repository name
515 """
516 return 0
517 PRE_PULL_HOOK = _pre_pull_hook
518
519
520 @register('PULL_HOOK')
521 @verify_kwargs(
522 ['_load_extension', 'server_url', 'config', 'scm', 'username', 'ip',
523 'action', 'repository'])
524 def _pull_hook(*args, **kwargs):
525 """
526 POST PULL HOOK, this function will be executed after each push it's
527 executed after the build-in hook that RhodeCode uses for logging pulls
528
529 kwargs available:
530
531 :param server_url: url of instance that triggered this hook
532 :param config: path to .ini config used
533 :param scm: type of VS 'git' or 'hg'
534 :param username: name of user who pulled
535 :param ip: ip of who pulled
536 :param action: pull
537 :param repository: repository name
538 """
539 return 0
540 PULL_HOOK = _pull_hook
541
542
543 # =============================================================================
544 # PULL REQUEST RELATED HOOKS
545 # =============================================================================
546 @register('CREATE_PULL_REQUEST')
547 @verify_kwargs(
548 ['_load_extension', 'server_url', 'config', 'scm', 'username', 'ip',
549 'action', 'repository', 'pull_request_id', 'url', 'title', 'description',
550 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
551 'mergeable', 'source', 'target', 'author', 'reviewers'])
552 def _create_pull_request_hook(*args, **kwargs):
553 """
554
555 """
556 # extract extra fields and default reviewers from target
557 kwargs['REPOSITORY'] = kwargs['target']['repository']
558
559 call = load_extension('extra_fields.py')
560 if call:
561 repo_extra_fields = call(**kwargs)
562 # now update if we have extra fields, they have precedence
563 # this way users can store any configuration inside the database per
564 # repo
565 for key, data in repo_extra_fields.items():
566 kwargs[key] = data['field_value']
567
568 call = load_extension('default_reviewers.py')
569 if call:
570 # read default_reviewers key propagated from extra fields
571 kwargs['default_reviewers'] = map(string.strip, kwargs.pop(
572 'default_reviewers', '').split(','))
573 call(**kwargs)
574
575 # extract below from source repo as commits are there
576 kwargs['REPOSITORY'] = kwargs['source']['repository']
577
578 # # fetch pushed commits, from commit_ids list
579 # call = load_extension('extract_commits.py')
580 # extracted_commits = {}
581 # if call:
582 # extracted_commits = call(**kwargs)
583 # # store the commits for the next call chain
584 # kwargs['COMMITS'] = extracted_commits
585 #
586 # # fetch issues from given commits
587 # call = load_extension('extract_redmine_issues.py')
588 # issues = {}
589 # if call:
590 # issues = call(**kwargs)
591 #
592 # # redmine smart pr update
593 # call = load_extension('redmine_pr_flow.py')
594 # if call:
595 # # updates kwargs on the fly
596 # configure_redmine_smart_pr(issues=issues, kwargs=kwargs)
597 # call(**kwargs)
598 #
599 # # slack notification on merging PR
600 # call = load_extension('slack_message.py')
601 # if call:
602 # kwargs.update(CONFIG.slack.default_plugin_config)
603 # kwargs['SLACK_ROOM'] = '#develop'
604 # kwargs['SLACK_MESSAGE'] = 'Pull request <%s|#%s> (%s) was created.' % (
605 # kwargs.get('url'), kwargs.get('pull_request_id'), kwargs.get('title'))
606 #
607 # call(**kwargs)
608
609 return 0
610 CREATE_PULL_REQUEST = _create_pull_request_hook
611
612
613 @register('REVIEW_PULL_REQUEST')
614 @verify_kwargs(
615 ['_load_extension', 'server_url', 'config', 'scm', 'username', 'ip',
616 'action', 'repository', 'pull_request_id', 'url', 'title', 'description',
617 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
618 'mergeable', 'source', 'target', 'author', 'reviewers'])
619 def _review_pull_request_hook(*args, **kwargs):
620 """
621
622 """
623 # extract extra fields and default reviewers from target
624 kwargs['REPOSITORY'] = kwargs['target']['repository']
625
626 # fetch extra fields
627 call = load_extension('extra_fields.py')
628 if call:
629 repo_extra_fields = call(**kwargs)
630 # now update if we have extra fields, they have precedence
631 # this way users can store any configuration inside the database per
632 # repo
633 for key, data in repo_extra_fields.items():
634 kwargs[key] = data['field_value']
635
636 # extract below from source repo as commits are there
637 kwargs['REPOSITORY'] = kwargs['source']['repository']
638
639 # fetch pushed commits, from commit_ids list
640 call = load_extension('extract_commits.py')
641 extracted_commits = {}
642 if call:
643 extracted_commits = call(**kwargs)
644 # store the commits for the next call chain
645 kwargs['COMMITS'] = extracted_commits
646
647 # fetch issues from given commits
648 call = load_extension('extract_redmine_issues.py')
649 issues = {}
650 if call:
651 issues = call(**kwargs)
652
653 # redmine smart pr update
654 call = load_extension('redmine_pr_flow.py')
655 if call:
656 # updates kwargs on the fly
657 configure_redmine_smart_pr(issues=issues, kwargs=kwargs)
658 call(**kwargs)
659
660 return 0
661 REVIEW_PULL_REQUEST = _review_pull_request_hook
662
663
664 @register('UPDATE_PULL_REQUEST')
665 @verify_kwargs(
666 ['_load_extension', 'server_url', 'config', 'scm', 'username', 'ip',
667 'action', 'repository', 'pull_request_id', 'url', 'title', 'description',
668 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
669 'mergeable', 'source', 'target', 'author', 'reviewers'])
670 def _update_pull_request_hook(*args, **kwargs):
671 """
672
673 """
674 # extract extra fields and default reviewers from target
675 kwargs['REPOSITORY'] = kwargs['target']['repository']
676
677 # fetch extra fields
678 call = load_extension('extra_fields.py')
679 if call:
680 repo_extra_fields = call(**kwargs)
681 # now update if we have extra fields, they have precedence
682 # this way users can store any configuration inside the database per
683 # repo
684 for key, data in repo_extra_fields.items():
685 kwargs[key] = data['field_value']
686
687 # extract below from source repo as commits are there
688 kwargs['REPOSITORY'] = kwargs['source']['repository']
689
690 # fetch pushed commits, from commit_ids list
691 call = load_extension('extract_commits.py')
692 extracted_commits = {}
693 if call:
694 extracted_commits = call(**kwargs)
695 # store the commits for the next call chain
696 kwargs['COMMITS'] = extracted_commits
697
698 # fetch issues from given commits
699 call = load_extension('extract_redmine_issues.py')
700 issues = {}
701 if call:
702 issues = call(**kwargs)
703
704 # redmine smart pr updated
705 call = load_extension('redmine_pr_flow.py')
706 if call:
707 # updates kwargs on the fly
708 configure_redmine_smart_pr(issues=issues, kwargs=kwargs)
709 call(**kwargs)
710
711 return 0
712 UPDATE_PULL_REQUEST = _update_pull_request_hook
713
714
715 @register('MERGE_PULL_REQUEST')
716 @verify_kwargs(
717 ['_load_extension', 'server_url', 'config', 'scm', 'username', 'ip',
718 'action', 'repository', 'pull_request_id', 'url', 'title', 'description',
719 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
720 'mergeable', 'source', 'target', 'author', 'reviewers'])
721 def _merge_pull_request_hook(*args, **kwargs):
722 """
723
724 """
725 # extract extra fields and default reviewers from target
726 kwargs['REPOSITORY'] = kwargs['target']['repository']
727
728 # fetch extra fields
729 call = load_extension('extra_fields.py')
730 if call:
731 repo_extra_fields = call(**kwargs)
732 # now update if we have extra fields, they have precedence
733 # this way users can store any configuration inside the database per
734 # repo
735 for key, data in repo_extra_fields.items():
736 kwargs[key] = data['field_value']
737
738 # extract below from source repo as commits are there
739 kwargs['REPOSITORY'] = kwargs['source']['repository']
740
741 # fetch pushed commits, from commit_ids list
742 call = load_extension('extract_commits.py')
743 extracted_commits = {}
744 if call:
745 extracted_commits = call(**kwargs)
746 # store the commits for the next call chain
747 kwargs['COMMITS'] = extracted_commits
748
749 # fetch issues from given commits
750 call = load_extension('extract_redmine_issues.py')
751 issues = {}
752 if call:
753 issues = call(**kwargs)
754
755 # redmine smart pr update
756 call = load_extension('redmine_pr_flow.py')
757 if call:
758 # updates kwargs on the fly
759 configure_redmine_smart_pr(issues=issues, kwargs=kwargs)
760 call(**kwargs)
761
762 # slack notification on merging PR
763 call = load_extension('slack_message.py')
764 if call:
765 kwargs.update(CONFIG.slack.default_plugin_config)
766 kwargs['SLACK_ROOM'] = '#develop'
767 kwargs['SLACK_MESSAGE'] = 'Pull request <%s|#%s> (%s) was merged.' % (
768 kwargs.get('url'), kwargs.get('pull_request_id'), kwargs.get('title'))
769 call(**kwargs)
770
771 return 0
772 MERGE_PULL_REQUEST = _merge_pull_request_hook
773
774
775 @register('CLOSE_PULL_REQUEST')
776 @verify_kwargs(
777 ['_load_extension', 'server_url', 'config', 'scm', 'username', 'ip',
778 'action', 'repository', 'pull_request_id', 'url', 'title', 'description',
779 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
780 'mergeable', 'source', 'target', 'author', 'reviewers'])
781 def _close_pull_request_hook(*args, **kwargs):
782 """
783
784 """
785 # extract extra fields and default reviewers from target
786 kwargs['REPOSITORY'] = kwargs['target']['repository']
787
788 # fetch extra fields
789 call = load_extension('extra_fields.py')
790 if call:
791 repo_extra_fields = call(**kwargs)
792 # now update if we have extra fields, they have precedence
793 # this way users can store any configuration inside the database per
794 # repo
795 for key, data in repo_extra_fields.items():
796 kwargs[key] = data['field_value']
797
798 # extract below from source repo as commits are there
799 kwargs['REPOSITORY'] = kwargs['source']['repository']
800
801 # fetch pushed commits, from commit_ids list
802 call = load_extension('extract_commits.py')
803 extracted_commits = {}
804 if call:
805 extracted_commits = call(**kwargs)
806 # store the commits for the next call chain
807 kwargs['COMMITS'] = extracted_commits
808
809 # fetch issues from given commits
810 call = load_extension('extract_redmine_issues.py')
811 issues = {}
812 if call:
813 issues = call(**kwargs)
814
815 # redmine smart pr update
816 call = load_extension('redmine_pr_flow.py')
817 if call:
818 # updates kwargs on the fly
819 configure_redmine_smart_pr(issues=issues, kwargs=kwargs)
820 call(**kwargs)
821
822 return 0
823 CLOSE_PULL_REQUEST = _close_pull_request_hook
@@ -0,0 +1,59 b''
1 .. _dev-plug:
2
3 Developing Plugins/Extensions
4 -----------------------------
5
6 An Extension or a Plugin is simply a |PY| module with a ``run`` method that
7 expects a number of parameters, depending on which event it is listening
8 for. To get an extension working, use the following steps:
9
10 1. Create an extension or plugin using the below example.
11 2. Save the plugin inside the
12 :file:`/home/{user}/.rccontrol/{instance-id}/rcextensions` folder.
13 3. Add a hook to the
14 :file:`/home/{user}/.rccontrol/{instance-id}/rcextensions/__init__.py` file.
15 For more information, see :ref:`event-listener`.
16 4. Restart your |RCM| instance.
17
18 Extension example
19 ^^^^^^^^^^^^^^^^^
20
21 In the following example, the ``run`` method listens for a push to a |repo|
22 and parses the commit.
23
24 .. code-block:: python
25
26 def run(*args, **kwargs):
27
28 revs = kwargs.get('pushed_revs')
29 if not revs:
30 return 0
31
32 from rhodecode.lib.utils2 import extract_mentioned_users
33 from rhodecode.model.db import Repository
34
35 repo = Repository.get_by_repo_name(kwargs['repository'])
36 changesets = []
37 reviewers = []
38
39 # reviewer fields from extra_fields, users can store their custom
40 # reviewers inside the extra fields to pre-define a set of people who
41 # will get notifications about changesets
42 field_key = kwargs.get('reviewers_extra_field')
43 if field_key:
44 for xfield in repo.extra_fields:
45 if xfield.field_key == field_key:
46 reviewers.extend(xfield.field_value.split())
47
48 vcs_repo = repo.scm_instance_no_cache()
49 for rev in kwargs['pushed_revs']:
50 cs = vcs_repo.get_changeset(rev) # or get_commit. See API doc
51 cs_data = cs.__json__()
52 cs_data['mentions'] = extract_mentioned_users(cs_data['message'])
53 cs_data['reviewers'] = reviewers
54 # optionally add more logic to parse the commits, like reading extra
55 # fields of repository to read managers of reviewers
56 changesets.append(cs_data)
57
58 return changesets
59 No newline at end of file
@@ -0,0 +1,19 b''
1 .. _int-full-blown:
2
3 Extensions Extended Example
4 ---------------------------
5
6 This example
7 :file:`/home/{user}/.rccontrol/{instance-id}/rcextensions/__init.py__` file
8 has been highlighted to show a Redmine integration in full. To extend your
9 |RCE| instances, use the below example to integrate with other
10 applications.
11
12 This example file also contains a Slack integration, but it is not
13 highlighted.
14
15
16 .. literalinclude:: example-ext.py
17 :language: python
18 :emphasize-lines: 186,193-198,210-218,474-496,648-660,749-760,810-822
19 :linenos:
@@ -0,0 +1,86 b''
1 .. _hooks:
2
3 Hooks
4 -----
5
6 Within |RCM| there are two types of supported hooks.
7
8 * **Internal built-in hooks**: The internal |hg| or |git| hooks are
9 triggered by different VCS operations, like push, pull,
10 or clone and are non-configurable, but you can add your own VCS hooks,
11 see :ref:`custom-hooks`.
12 * **User defined hooks**: User defined hooks centre around the lifecycle of
13 certain actions such are |repo| creation, user creation etc. The actions
14 these hooks trigger can be rejected based on the API permissions of the
15 user calling them.
16
17 Those custom hooks can be called using |RCT|, see :ref:`rc-tools`. To create
18 a custom hook, see the :ref:`event-listener` section.
19
20 .. _event-listener:
21
22 Making your Extension listen for Events
23 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24
25 To create a hook to work with a plugin or extension,
26 you need configure a listener in the
27 :file:`/home/{user}/{instance-id}/rcextensions/__init__.py` file,
28 and use the ``load_extension`` method.
29
30 Use the following example to create your extensions.
31 In this example:
32
33 * The hook is calling the ``('my_post_push_extension.py')`` extension.
34 * The hook is listening to |RCM| for pushes to |repos|.
35 * This highlighted code is the hook, and configured in the ``__init__.py`` file.
36 * It is inserted into the ``def _pushhook(*args, **kwargs)`` section,
37 if it is not in the default ``__ini__.py`` file, use the below
38 non-highlighted section to create it.
39
40 .. code-block:: python
41 :emphasize-lines: 23-38
42
43 # ==========================================================================
44 # POST PUSH HOOK
45 # ==========================================================================
46
47 # this function will be executed after each push is executed after the
48 # build-in hook that RhodeCode uses for logging pushes
49 def _pushhook(*args, **kwargs):
50 """
51 Post push hook
52 kwargs available:
53
54 :param server_url: url of instance that triggered this hook
55 :param config: path to .ini config used
56 :param scm: type of VS 'git' or 'hg'
57 :param username: name of user who pushed
58 :param ip: ip of who pushed
59 :param action: push
60 :param repository: repository name
61 :param repo_store_path: full path to where repositories are stored
62 :param pushed_revs: list of pushed revisions
63 """
64
65 # Your hook code goes in here
66 call = load_extension('my_post_push_extension.py')
67 if call:
68 # extra arguments in kwargs
69 call_kwargs = dict()
70 call_kwargs.update(kwargs)
71 my_kw = {
72 'reviewers_extra_field': 'reviewers',
73 # defines if we have a comma
74 # separated list of reviewers
75 # in this repo stored in extra_fields
76 }
77 call_kwargs.update(my_kw) # pass in hook args
78 parsed_revs = call(**call_kwargs)
79 # returns list of dicts with changesets data
80
81 # Default code
82 return 0
83 PUSH_HOOK = _pushhook
84
85 Once your plugin and hook are configured, restart your instance of |RCM| and
86 your event listener will triggered as soon as a user pushes to a |repo|.
@@ -0,0 +1,55 b''
1 .. _install-rcx:
2
3 Install |RCX|
4 -------------
5
6 To install |RCX|, you need to have |RCT| installed. See the :ref:`install-tools`
7 and :ref:`tools-cli` sections. Use the ``--plugins`` option with
8 the ``rhodecode-extensions`` argument.
9
10 Upgrading |RCX|
11 ^^^^^^^^^^^^^^^
12
13 .. important::
14
15 You should back up any plugins or extensions that you have created before
16 continuing.
17
18 To upgrade your |RCX|, use the following example:
19
20 1. From inside the |RCT| virtualenv, upgrade to the latest version:
21
22 .. code-block:: bash
23
24 (venv)$ pip install -U https://my.rhodecode.com/dl/rhodecode-tools/latest
25 Downloading/unpacking https://my.rhodecode.com/dl/rhodecode-tools/latest
26 Downloading latest (143kB): 143kB downloaded
27 Running setup.py (path:/tmp/pip-9qYsxf-build/setup.py) egg_info
28 for package from https://my.rhodecode.com/dl/rhodecode-tools/latest
29
30 2. Once |RCT| are upgraded to the latest version, you can install the latest
31 extensions using the following example:
32
33 .. code-block:: bash
34
35 (venv)$ rhodecode-extensions --instance-name=enterprise-1 \
36 --ini-file=rhodecode.ini --plugins
37
38 Extension file already exists, do you want to overwrite it? [y/N]: y
39 Writen new extensions file to rcextensions
40 Copied hipchat_push_notify.py plugin to rcextensions
41 Copied jira_pr_flow.py plugin to rcextensions
42 Copied default_reviewers.py plugin to rcextensions
43 Copied extract_commits.py plugin to rcextensions
44 Copied extract_issues.py plugin to rcextensions
45 Copied redmine_pr_flow.py plugin to rcextensions
46 Copied extra_fields.py plugin to rcextensions
47 Copied jira_smart_commits.py plugin to rcextensions
48 Copied http_notify.py plugin to rcextensions
49 Copied slack_push_notify.py plugin to rcextensions
50 Copied slack_message.py plugin to rcextensions
51 Copied extract_jira_issues.py plugin to rcextensions
52 Copied extract_redmine_issues.py plugin to rcextensions
53 Copied redmine_smart_commits.py plugin to rcextensions
54 Copied send_mail.py plugin to rcextensions
55
@@ -0,0 +1,151 b''
1 .. _slack-int:
2
3 Integrate Slack
4 ===============
5
6 To integrate |RCE| and Slack, you need to configure some things on the Slack
7 side of the integration, and some things on the |RCE| side.
8
9 On the Slack side you need to allow incoming webhooks, see their
10 documentation on this, `Slack Webhooks`_. You will also need to get an
11 Authorization Token from Slack that will allow |RCE| to post to your account.
12
13 On the |RCE| side, this is an overview of what you need to do:
14
15 1. Configure the built-in Slack extensions to post to the correct Slack URL.
16 2. Set your Slack authentication details in the |RCX| :file:`__init.py__` file.
17 3. Configure the different hooks in the :file:`__init.py__` file to extract
18 whatever information you want from |RCE|, and then using the Slack extensions
19 post that information to your Slack channel.
20
21 .. hint::
22
23 The below examples should help you to get started. Once you have your
24 integration up and running, there is a more detailed Slack integration in
25 the :ref:`int-full-blown` section.
26
27 Configure Built-in Extensions
28 -----------------------------
29
30 |RCE| comes with 3 Slack extensions: ``slack_message.py``,
31 ``slack_push_notify.py``, and ``slack.py``. The default
32 location is :file:`/home/{user}/.rccontrol/{instance-id}/rcextensions`.
33
34 To enable these to post to your Slack account, configure each of
35 these files with the following Slack details.
36
37 .. code-block:: python
38
39 BASE_URL = 'https://your.slack.com/api/link'
40 INCOMING_WEBHOOK_URL = 'https://hooks.slack.com/services/your/hook/link'
41 API_VERSION = 1
42
43 Configure |RCE| to Post to Slack
44 --------------------------------
45
46 In the |RCX| :file:`__init.py__` file, configure your Slack authentication
47 details. The default location is
48 :file:`/home/{user}/.rccontrol/{instance-id}/rcextensions`
49
50 .. code-block:: python
51
52 CONFIG = DotDict(
53 slack=DotDict(
54 api_key='api-key',
55 api_url='slack-incoming-hook-url',
56 default_room='#slack-channel',
57 default_plugin_config={},
58 ),
59 )
60
61 # slack conf
62 CONFIG.slack.default_plugin_config = {
63 'INCOMING_WEBHOOK_URL': CONFIG.slack.api_url,
64 'SLACK_TOKEN': CONFIG.slack.api_key,
65 'SLACK_ROOM': CONFIG.slack.default_room,
66 'SLACK_FROM': 'RhodeCode',
67 'SLACK_FROM_ICON_EMOJI': ':rhodecode:',
68 }
69
70 Add Push Notifications to Slack
71 -------------------------------
72
73 To add notification to Slack when someone pushes to |RCE|, configure the push
74 hook to extract the commits pushed, and then call the built-in
75 ``slack_push_notify.py`` extension to post them into your chosen Slack
76 channel. To do this, add the following code to the push hook section of the
77 :file:`__init.py__` file
78
79 .. code-block:: python
80 :emphasize-lines: 10-16,18-22
81
82 def _push_hook(*args, **kwargs):
83 """
84 POST PUSH HOOK, this function will be executed after each push, it's
85 executed after the build-in hook that RhodeCode uses for logging pushes
86 kwargs available:
87 """
88 # backward compat
89 kwargs['commit_ids'] = kwargs['pushed_revs']
90
91 # fetch pushed commits, from commit_ids list
92 call = load_extension('extract_commits.py')
93 extracted_commits = {}
94 if call:
95 extracted_commits = call(**kwargs)
96 # store the commits for the next call chain
97 kwargs['COMMITS'] = extracted_commits
98
99 # slack !
100 call = load_extension('slack_push_notify.py')
101 if call:
102 kwargs.update(CONFIG.slack.default_plugin_config)
103 call(**kwargs)
104 return 0
105 PUSH_HOOK = _push_hook
106
107
108 Add Pull Request Notifications to Slack
109 ---------------------------------------
110
111 To add |pr| notifications to Slack, use the following example. This example
112 shows a merged |pr| notification. You can add similar notifications to the
113 following hooks in the :file:`__init.py__` file, and for those examples see
114 the :ref:`int-full-blown` section:
115
116 * ``_create_pull_request_hook``
117 * ``_review_pull_request_hook``
118 * ``_update_pull_request_hook``
119 * ``_close_pull_request_hook``
120
121 .. code-block:: python
122 :emphasize-lines: 5-23
123
124 def _merge_pull_request_hook(*args, **kwargs):
125 """
126
127 """
128 # extract below from source repo as commits are there
129 kwargs['REPOSITORY'] = kwargs['source']['repository']
130
131 # fetch pushed commits, from commit_ids list
132 call = load_extension('extract_commits.py')
133 extracted_commits = {}
134 if call:
135 extracted_commits = call(**kwargs)
136 # store the commits for the next call chain
137 kwargs['COMMITS'] = extracted_commits
138
139 # slack notification on merging PR
140 call = load_extension('slack_message.py')
141 if call:
142 kwargs.update(CONFIG.slack.default_plugin_config)
143 kwargs['SLACK_ROOM'] = '#develop'
144 kwargs['SLACK_MESSAGE'] = 'Pull request <%s|#%s> (%s) was merged.' % (
145 kwargs.get('url'), kwargs.get('pull_request_id'), kwargs.get('title'))
146 call(**kwargs)
147
148 return 0
149 MERGE_PULL_REQUEST = _merge_pull_request_hook
150
151 .. _Slack Webhooks: https://api.slack.com/incoming-webhooks
@@ -0,0 +1,25 b''
1 .. _integrations-ref:
2
3 Integrations and Extensions
4 ===========================
5
6 The integrations section references three concepts regularly,
7 so to clarify what is meant each time, read the following definitions:
8
9 * **Plugin**: A Plugin is software that adds a specific feature to
10 an existing software application.
11 * **Extension**: An extension extends the capabilities of,
12 or the data available to, an existing software application.
13 * **Hook**: A hook intercepts function calls, messages, or events passed
14 between software components and can be used to trigger plugins, or their
15 extensions.
16
17 .. toctree::
18
19 rcx
20 install-ext
21 config-ext
22 extensions
23 hooks
24 full-blown-example
25 int-slack
@@ -0,0 +1,53 b''
1 .. _rc-ext:
2
3 |RCX|
4 -----
5
6 |RCX| add additional functionality for push/pull/create/delete |repo| hooks.
7 These hooks can be used to send signals to build-bots such as `Jenkins`_. It
8 also adds built in plugin and extension support. Once installed, you will see
9 a :file:`rcextensions` folder in the instance directory, for example:
10 :file:`home/{user}/.rccontrol/{instance-id}/rcextensions`
11
12 Built-in Plugins
13 ^^^^^^^^^^^^^^^^
14
15 * A number of `Jira`_ plugins, enabling you to integrate with that issue
16 tracker: ``extract_jira_issues.py``, ``jira_pr_flow.py``,
17 ``jira_smart_commits.py``
18 * A number of `Redmine`_ plugins, enabling you to integrate with that issue
19 tracker: ``extract_redmine_issues.py``, ``redmine_pr_flow.py``,
20 ``redmine_smart_commits.py``.
21 * ``hipchat.py`` and ``hipchat_push.py`` enable you to integrate with
22 `HipChat`_ and set channel or user notifications.
23 * ``slack.py``, ``slack_message.py``, and ``slack_push_notify.py`` enable
24 you to integrate with `Slack`_ and set channel or user notifications.
25
26 Built-in Extensions
27 ^^^^^^^^^^^^^^^^^^^
28
29 * ``commit_parser.py``: Enables you to parse commit messages,
30 and set a list of users to get notifications about change sets.
31 * ``default_reviewers.py``: Enables you to add default reviewers to a |pr|.
32 * ``extra_fields.py``: Returns a list of extra fields added to a |repo|.
33 * ``http_notify``: Enables you to send data over a web hook.
34 * ``mail.py`` : This extension uses the |RCE| mail configuration from the
35 instance :file:`rhodecode.ini` file to send email.
36 * ``push_post.py``: Enables you to set up push based actions such as
37 automated Jenkins builds.
38
39 Event Listeners
40 ^^^^^^^^^^^^^^^
41
42 To enable the extensions to listen to the different events that they are
43 configured for, you need to also set up an event listener (hook). Event
44 listeners are configured in the
45 :file:`/home/{user}/.rccontrol/{instance-id}/rcextensions/__init.__.py` file.
46
47 For more details, see the example hook in :ref:`event-listener`.
48
49 .. _Jenkins: http://jenkins-ci.org/
50 .. _HipChat: https://www.hipchat.com/
51 .. _Slack: https://slack.com/
52 .. _Redmine: http://www.redmine.org/
53 .. _Jira: https://www.atlassian.com/software/jira
@@ -0,0 +1,82 b''
1 .. _rhodecode-issue-trackers-ref:
2
3 Issue Tracker Integration
4 =========================
5
6 You can set an issue tracker connection in two ways with |RCE|.
7
8 * At instance level you can set a default issue tracker.
9 * At |repo| level you can configure an integration with a different issue
10 tracker.
11
12 To integrate |RCM| with an issue tracker you need to define a regular
13 expression that will fetch the issue ID stored in commit messages and replace
14 it with a URL. This enables |RCE| to generate a link matching each issue to the
15 target |repo|.
16
17 Default Issue Tracker Configuration
18 -----------------------------------
19
20 To integrate your issue tracker, use the following steps:
21
22 1. Open :menuselection:`Admin --> Settings --> Issue Tracker`.
23 2. In the new entry field, enter the following information:
24
25 * :guilabel:`Description`: A name for this set of rules.
26 * :guilabel:`Pattern`: The regular expression that will match issues
27 tagged in commit messages, or more see :ref:`issue-tr-eg-ref`.
28 * :guilabel:`URL`: The URL to your issue tracker.
29 * :guilabel:`Prefix`: The prefix with which you want to mark issues.
30
31 3. Select **Add** so save the rule to your issue tracker configuration.
32
33 Repository Issue Tracker Configuration
34 --------------------------------------
35
36 You can configure specific |repos| to use a different issue tracker if
37 you need to connect to a non-default one. See the instructions in
38 :ref:`repo-it`
39
40 .. _issue-tr-eg-ref:
41
42 Jira Integration
43 ----------------
44
45 * Regex = ``(?:^#|\s#)(\w+-\d+)``
46 * URL = ``https://myissueserver.com/issue/${id}``
47 * Issue Prefix = ``#``
48
49 Confluence (Wiki)
50 -----------------
51
52 * Regex = ``(?:conf-)([A-Z0-9]+)``
53 * URL = ``https://example.atlassian.net/display/wiki/${id}/${repo_name}``
54 * issue prefix = ``CONF-``
55
56 Redmine Integration
57 -------------------
58
59 * Regex = ``(issue-+\d+)``
60 * URL = ``https://myissueserver.com/redmine/issue/${id}``
61 * Issue Prefix = ``issue-``
62
63 Redmine (wiki)
64 --------------
65
66 * Regex = ``(?:wiki-)([a-zA-Z0-9]+)``
67 * URL = ``https://example.com/redmine/projects/wiki/${repo_name}``
68 * Issue prefix = ``Issue-``
69
70 Pivotal Tracker
71 ---------------
72
73 * Regex = ``(?:pivot-)(?<project_id>\d+)-(?<story>\d+)``
74 * URL = ``https://www.pivotaltracker.com/s/projects/${project_id}/stories/${story}``
75 * Issue prefix = ``Piv-``
76
77 Trello
78 ------
79
80 * Regex = ``(?:trello-)(?<card_id>[a-zA-Z0-9]+)``
81 * URL = ``https://trello.com/example.com/${card_id}``
82 * Issue prefix = ``Trello-``
@@ -0,0 +1,8 b''
1 .. _rhodecode-redmine-ref:
2
3 Redmine
4 -------
5
6 |RCE| tracke that issue!
7
8
@@ -0,0 +1,15 b''
1 .. _err-msg-ref:
2
3 Error Message Guide
4 ===================
5
6 Error Message
7 Error creating repository repo-name
8
9 Cause
10 As of |RCM| 3.0, a VCS Server is required to run backend operations.
11
12 Solution
13 Install a VCS Server. See the `Install a VCS Server`_ section of |RCC|
14
15 .. _Install a VCS Server: https://docs.rhodecode.com/RhodeCode-Control/tasks/upgrade-from-cli.html#install-a-vcs-server No newline at end of file
@@ -0,0 +1,88 b''
1 .. _known-issues:
2
3 Known Issues
4 ============
5
6 Subversion Issues
7 -----------------
8
9 Limited |svn| support has been achieved for this release,
10 |release|. The following known issues are in development for improvement.
11
12 * |svn| |repo| creation:
13 Terminating the VCS Server during remote importation of |svn| |repos| leaves
14 the the process still running in the background.
15
16 * |svn| |repo| checkin/checkout:
17 |svn| cloning support is not enabled by default. Please contact support if
18 you want it enabled.
19
20 Windows Upload
21 --------------
22
23 There can be an issue with uploading files from web interface on Windows,
24 and afterwards users cannot properly clone or synchronize with the repository.
25
26 Early testing shows that often uploading files via HTML forms on Windows
27 includes the full path of the file being uploaded and not the name of the file.
28
29 Old Format of Git Repositories
30 ------------------------------
31
32 There is an issue when trying to import old |git| format |repos| into recent
33 versions of |RCE|. This issue can occur when importing from external |git|
34 repositories or from older versions of |RCE| (<=2.2.7).
35
36 To convert the old version into a current version, clone the old
37 |repo| into a local machine using a recent |git| client, then push it to a new
38 |repo| inside |RCE|.
39
40 VCS Server Memory Consumption
41 -----------------------------
42
43 The VCS Server cache grows without limits if not configured correctly. This
44 applies to |RCE| versions prior to the 3.3.2 releases, as 3.3.2
45 shipped with the optimal configuration as default. See the
46 :ref:`vcs-server-maintain` section for details.
47
48 To fix this issue, upgrade to |RCE| 3.3.2 or greater, and if you discover
49 memory consumption issues check the VCS Server settings.
50
51 Fedora 23
52 ---------
53
54 |RCC| does not run perfectly on Fedora 23 due to a locale issue. This is a
55 known issue under investigation due to the Nix packaging of the product, see the
56 `Github issue here`_. |RCC| runs fine on Fedora 21.
57
58 To work around this problem, you need to point ``$LOCAL_ARCHIVE`` to the
59 workaround locale package.
60
61 1. Download this package:
62 http://lipa.ms.mff.cuni.cz/~cunav5am/nix/locale-archive
63
64 2. Point ``$LOCAL_ARCHIVE`` to the locale package.
65
66 .. code-block:: bash
67
68 $ export LOCALE_ARCHIVE=/home/VERSION/locale-archive # change to your path
69
70 If you happen to be running |RCC| from systemd, use the following
71 example to pass the correct locale information on boot.
72
73 .. code-block:: ini
74
75 [Unit]
76 Description=Rhodecode
77 After=network.target
78
79 [Service]
80 Type=forking
81 User=scm
82 Environment="LOCALE_ARCHIVE=/YOUR-PATH/locale-archive"
83 ExecStart=/YOUR-PATH/.rccontrol-profile/bin/rccontrol-self-init
84
85 [Install]
86 WantedBy=multi-user.target
87
88 .. _Github issue here: https://github.com/NixOS/nix/issues/599
@@ -0,0 +1,43 b''
1 Adding Custom Packages
2 ======================
3
4 If you wish to make additional Python modules available to use with
5 extensions that you have developed, use the following information.
6
7 Prerequisite
8 ------------
9
10 |RCC| manages the |RCE| environment using Supervisor. To add custom packages
11 you need to install your instance of |RCE| as a self managed
12 instance. This will let you to update the ``PYTHONPATH`` without |RCC|
13 overwriting it. You can then extend the ``PYTHONPATH`` to find packaged
14 outside of the |RCC| managed environment. To install |RCE| as a self-managed
15 service using |RCC|, see the
16 :ref:`Self-managed Instructions <control:set-self-managed-supervisor>`.
17
18 Adding Custom Packages
19 ----------------------
20
21 Once you have your instance configured as self-managed, use the following steps.
22
23 1. Add the modules to the |RCE| instance directory,
24 :file:`/home/{user}/.rccontrol/{instance-id}`.
25 2. Add this location to your ``PYTHONPATH`` environment variable. This is set
26 in the :file:`/home/{user}/.rccontrol/supervisor/supervisor.ini` file. For
27 more information about ``PYTHONPATH``, see the `PYTHONPATH documentation`_.
28
29 .. code-block:: ini
30
31 [program:enterprise-1_script]
32 numprocs = 1
33 redirect_stderr = true
34 environment = PYTHONPATH="",GIT_SSL_CAINFO="/home/user/.rccontrol-profile/etc/ca-bundle.crt"
35
36 3. Specify the hook for your added module on the
37 :menuselection:`Admin --> Settings --> Hooks` page. For
38 example, ``python:rcextensions/you.custom.hook``
39 4. Restart |RCE| using the ``rccontrol restart <instance-id>`` command.
40 For more information, see the :ref:`RhodeCode Control CLI <control:rcc-cli>`
41 documentation.
42
43 .. _PYTHONPATH documentation: https://docs.python.org/2/using/cmdline.html#envvar-PYTHONPATH
@@ -0,0 +1,10 b''
1 .. _system-pack:
2
3 System Packaging
4 ================
5
6 .. toctree::
7 :maxdepth: 1
8
9 nix
10 add-to-env
@@ -0,0 +1,31 b''
1 .. _rhodecode-nix-ref:
2
3 Nix Packaging
4 =============
5
6 |RCM| is installed using |Nix Package Manager|. The Nix environment provides
7 the following features for maintenance and deployment:
8
9 * Atomic upgrades and rollbacks
10 * Complete dependency management
11 * Garbage collection
12 * Binary patching
13 * Secure channel updates
14 * Nix works on Windows, Linux, and OSX
15
16 The complete list of dependencies can be found in
17 :file:`/opt/rhodecode/store/{unique-hash}`.
18
19 .. note::
20
21 No |RCE| data is stored in this location.
22
23 .. warning::
24
25 Never alter any of the packages in the store. Always use the
26 :ref:`RhodeCode Control CLI <control:rcc-cli>` update functions to keep
27 the packages and instances updated.
28
29 .. |Nix Package Manager| raw:: html
30
31 <a href="http://nixos.org/nix/" target="_blank">Nix</a>
@@ -0,0 +1,18 b''
1 |RCE| 1.6.0 |RNS|
2 -----------------
3
4 Release Date
5 ^^^^^^^^^^^^
6
7 * released 2013-05-12
8
9 Fixes
10 ^^^^^
11 * #818: Bookmarks Do Not Display on Changeset View.
12 * Fixed issue with forks form errors rendering.
13 * #819 review status is showed in the main changelog.
14 * Permission update function is idempotent, and doesn't override default permissions when doing upgrades.
15 * Fixed some unicode problems with git file path.
16 * Fixed broken handling of adding an htsts headers.
17 * Fixed redirection loop on changelog for empty repository.
18 * Fixed issue with web-editor that didn't preserve executable bit after editing files.
@@ -0,0 +1,36 b''
1 |RCE| 1.7.0 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2013-06-08
7
8 News
9 ^^^^
10 * Manage User's Groups(teams): create, delete, rename, add/remove users inside by delegated user group admins.
11 * Implemented simple Gist functionality.
12 * External authentication got special flag to control user activation.
13 * Created whitelist for API access. Each view can now be accessed by api_key if added to whitelist.
14 * Added dedicated file history page.
15 * Added compare option into bookmarks
16 * Improved diff display for binary files and renames.
17 * Archive downloading are now stored in main action journal.
18 * Switch gravatar to always use ssl.
19 * Implements #842 RhodeCode version disclosure.
20 * Allow underscore to be the optionally first character of username.
21
22 Fixes
23 ^^^^^
24 * #818: Bookmarks Do Not Display on Changeset View.
25 * Fixed default permissions population during upgrades.
26 * Fixed overwrite default user group permission flag.
27 * Fixed issue with h.person() function returned prematurly giving only email info from changeset metadata.
28 * get_changeset uses now mercurial revrange to filter out branches. Switch to branch it's around 20% faster this way.
29 * Fixed some issues with paginators on chrome.
30 * Forbid changing of repository type.
31 * Adde missing permission checks in list of forks in repository settings.
32 * Fixes #834 hooks error on remote pulling.
33 * Fixes issues #849. Web Commits functionality failed for non-ascii files.
34 * Fixed #850. Whoosh indexer should use the default revision when doing index.
35 * Fixed #851 and #563 make-index crashes on non-ascii files.
36 * Fixes #852, flash messages had issies with non-ascii messages No newline at end of file
@@ -0,0 +1,17 b''
1 |RCE| 1.7.1 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2013-06-13
7
8 News
9 ^^^^
10 * Apply to children flag on repository group also adds users to private repositories, this is now consistent with user groups. Private repos default permissions are not affected by apply to children flag.
11 * Removed unionrepo code as it's part of Mercurial 2.6
12 * RhodeCode accepts now read only paths for serving repositories.
13
14 Fixes
15 ^^^^^
16 * Fixed issues with how mysql handles float values. Caused gists with expiration dates not work properly on MySQL.
17 * Fixed issue with ldap enable/disable flag. No newline at end of file
@@ -0,0 +1,30 b''
1 |RCE| 1.7.2 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2013-07-18
7
8 News
9 ^^^^
10 * Added handling of copied files in diffs.
11 * Implemented issue #387 side-by-side diffs view.
12 * Added option to specify other than official bugtracker url to post issues with RhodeCode.
13 * Markdown renderer now uses github flavored syntax with a better newline handling
14 * Added User pre-create, create and delete hooks for rcextensions.
15 * Branch selectors: show closed branches too for Mercurial.
16 * Updated codemirror to latest version and added syntax coloring dropdown for various languages CodeMirror supports.
17 * Added --no-public-access / --public-access flags into setup-rhodecode command to enable setup without public access.
18 * Various small updates to pull requests.
19 * Bumped Mercurial version to latest.
20 * Diffs view doesn't show content of delete files anymore.
21
22 Fixes
23 ^^^^^
24 * Added missing __get_cs_or_redirect method for file history. Fixes issue with displaying a history of file that is not present at tip.
25 * Pull request: urlify description and fix javascript injection.
26 * Fixed some missing IP extraction for action logger.
27 * Fixed bug with log_delete hook didn't properly store user who triggered delete action.
28 * Fixed show as raw link for private gists.
29 * Fixes issue #860. IMC web commits poisoned caches when they failed with commit.
30 * Fixes issue #856 file upload >1000 bytes on windows throws exception. No newline at end of file
@@ -0,0 +1,28 b''
1 |RCE| 2.0.0 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2013-08-07
7 * First introduction as |RCE|
8
9 News
10 ^^^^
11 * Renamed to RhodeCode Enterprise.
12 * New UI based on font icons.
13 * Changed buttons to Twitter Bootstrap and Flat design.
14 * Only the most important button on a page is green.
15 * Capitalized labels.
16 * Pluggable Auth system.
17 * Extended API methods. Please check the latest docs for API changes.
18 * Only one most important button is green in a page.
19 * Reduced size of summary page info.
20 * Moved statistics to dedicated page for consistent summary view.
21 * New filtered and styled select fields using select2 widget. Select fields with bigger ammount of data are lazy loaded for performance.
22 * Implemented separate compare page for easy comparing changesets between revisions, tags and bookmarks.
23 * Repository, repository groups, users and users groups pages are now using same data_table rendered for consistency. All are now sortable with a special filter box.
24 * Small improvements on pull requests.
25
26 Fixes
27 ^^^^^
28 * No fixes No newline at end of file
@@ -0,0 +1,28 b''
1 |RCE| 2.0.1 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2013-08-14
7
8 News
9 ^^^^
10 * Create Pull-request button is visible for all logged in users, not only for those with a created repo permission set.
11 * New UI on repository groups, now consistent with other views.
12 * UI improvements on pull request reviewers.
13 * Repository admin can revoke reviewers from pull requests.
14 * Super admins can directly edit groups/users at permission box.
15 * Links in footer point to website and new support pages.
16
17 Fixes
18 ^^^^^
19 * Fixed download button size.
20 * Fixed empty dot occuring on page titles when no site customization was set.
21 * Fixed issue #893, some static resources were called without url() leading to bad address when used with proxy prefix.
22 * Fixed missing external values from user forms.
23 * Fixed one Git call in pygrack that defaulted to hardcoded 'git' instead of customized path from RhodeCode settings.
24 * Fixed issue with html on revoke buttons on pull request reviewers.
25 * Fixed all occurences of bad permission check that didn't allow repository admins to do certain actions. Only global admins could run them.
26 * Fixed gist url filtering for public gists.
27 * Newly registered users now default to 'rhodecode' as authentication type.
28 * Bumped Waitress version that allows setting `asyncore_use_poll` in settings to overcome 1024 open sockets limit with default `select()` implementation. No newline at end of file
@@ -0,0 +1,26 b''
1 |RCE| 2.0.2 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2013-08-27
7
8 News
9 ^^^^
10 * Completely new my account page.
11 * Added created_on field for repository groups.
12 * Users can now define extra email addresses in their account page.
13 * Updated codemirror to latest version with Nginx, Jade, Smartymixed modes.
14 * Better MIME-type detection of files with pygments to improve online editor syntax and mode detection.
15 * Added option to enable Captcha on registration page. It helps fight spam on open RhodeCode Enterprise instances.
16
17 Fixes
18 ^^^^^
19 * Many fixes for Internet Explorer 8 and newer.
20 * Fix largefiles user cache location by explicitly setting the location in RhodeCode database.
21 * Fixed "Remove Pull Request" button HTML on "my account" page.
22 * Allow admin flag control for external authentication accounts
23 * Changed landing_rev format to <rev_type>:<rev> to overcome issues with same names in different rev types like
24 bookmarks and branches.
25 * Add strip to attr_login for LDAP Auth plugin which is a very sensitive about whitespaces. Leaving whitespaces in
26 there causes hard to debug issues. No newline at end of file
@@ -0,0 +1,45 b''
1 |RCE| 2.1.0 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2013-09-25
7 * Pull requests work for Mercurial and Git
8 * New IP Whitelist inheritance
9 * Ability to check for new update of RhodeCode Enterprise
10 * Multiple API keys per user
11 * Strong performance improvements
12 * Shortcuts
13
14 News
15 ^^^^
16 * Added Git pull request functionality
17 * Multiple API keys and the option to add additional API keys for a user together with description and expiration.
18 * Users can now delete files via web interface.
19 * Moved Gravatar configuration from .ini files to web interface.
20 * Moved custom clone URL configuration from .ini files to web interface.
21 * Default IP whitelist is now inheritable by all users. This allows to setup system-wide IP restrictions for all users.
22 * Added intermediate waiting page for forks creation. After the fork is created the user is redirected to the forked
23 repo summary page.
24 * Next/prev links on changeset are now lazy calculated with onClick actions which can boost initial rendering speed
25 of pages by 2-3x.
26 * New repo switcher based on select2. Now with keyboard control and repository groups searching.Added basic keyboard
27 navigation shortcuts, simply call '?' to show them.
28 * Added check for update mechanism in web interface.
29 * All alerts and confirmations can be closed with an 'x' button in the corner.
30 * Updated Mercurial to 2.7.1
31 * Updated Waitress to 0.8.7
32
33 Fixes
34 ^^^^^
35 * Updated Google Noto Sans web font to fix issues for older IE versions
36 * Fixed Git backend calls to not use grep. Users are not required anymore to install it for Windows.
37 * Fixed sorting by revision in dashboard view.
38 * Container auth plugin preserves modified details after user is created and edited.
39 * Fixed issue with deleting notifications for some users.
40 * Fixed issue when external auth systems always regenerated tokens when user logged in (due to temp passwords on those
41 accounts)
42 * Fixed some JS errors on summary page.
43 * Fixed issue when external auth plugins wanted to create new users after the free limit is reached and failed with an
44 error.
45 * Removed broken prerender calls in pagination. No newline at end of file
@@ -0,0 +1,47 b''
1 |RCE| 2.2.0 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2013-10-23
7 * Gists are editable
8 * New keyboard shortcuts
9 * Improved permission management
10 * Speed improvements
11 * Security improvements
12
13 News
14 ^^^^
15 * Gists are editable.
16 * Gist URLs can take revisions as last parameter.
17 * New keyboard shortcuts 'gg' and 'gG' open private/public Gists page.
18 * New keyboard shortcut 'gF' opens files page with loaded files filter.
19 * New keyboard shortcut 'gO' opens repository permissions settings.
20 * 'Apply to children' becomes a 4-state radio button. It allows appling permissions to child objects of a repository group that are only repositories or only groups or both or none.
21 * New permission for controlling repository creation with write access on repository groups.
22 * Codemirror mode has added functionality of detection based on filename.
23 * Added get_user function to auth plugins base. Can be overriden to customize other than standard user extraction, like the one needed for container auth.
24 * API: added methods for permission managements for repo groups.
25 * API: get_nodes API function is now callable not only by users with admin permissions but also with at least read permissions to a given repo.
26 * Added stand-alone binary scripts for API, Gist, backup and extensions.
27 * Extensions has additional notification plugins. Builtin plugins hipchat (hipchat notification on push), push_post( POST data after push). Use 'rhodecode-extensions --plugins' to install them.
28 * Added captcha field to password_reset form.
29 * Removed mailto: links, for better anti-spam protection on open instances.
30 * Twice as fast page load of repository settings subpages.
31 * Added checkbox in Map & Scan Admin Setting to verify and install any missing Git hooks that RhodeCode uses.
32 * Bumped mako templates version to 0.9.0.
33 * Bumped dulwich version to 0.9.3
34 * Bumped mercurial version to 2.7.2.
35
36 Fixes
37 ^^^^^
38 * Fixed issue with container_auth tring to auth against non-container users.
39 * Fixed issues when authentication via container failed on Git/hg operations when using non standard (REMOTE_USER) headers.
40 * Fixed some JSON decode issue in Atlassian crowd auth plugin.
41 * Fixed Git-related issue that didn't allow to push a non-master branch on the first push to the server.
42 * Fixed issue on delete_user_group API call.
43 * Fixed styling of password reset and register forms.
44 * Fixed issue with Mercurial ui() object generation that caused certain extensions like hgsubversion to work incorrectly.
45 * Fixed issue with revoked access to repo group for admins of repos inside those groups. In that case editing of these repos no longer causes an error.
46 * Fixed sorting issues on tags/bookmarks/branches views.
47 * Fixed issue when performing 'git update-server-info' while importing existing Git repositories. It makes sure now that clients can clone it. No newline at end of file
@@ -0,0 +1,16 b''
1 |RCE| 2.2.1 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2013-10-25
7
8 News
9 ^^^^
10 * No news
11
12 Fixes
13 ^^^^^
14 * Fixed issue with forking.
15 * Fixed redirection to previous location which was lost via container auth login.
16 * API: removed urllib.unquote_plus on raw body. This caused a bug with '+' chars beeing stripped out of sent JSON BODY. No newline at end of file
@@ -0,0 +1,26 b''
1 |RCE| 2.2.2 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2013-11-19
7 * Push & pull up to 4x faster
8 * Security fixes
9
10 News
11 ^^^^
12 * Optimized the number of permission tree builds when doing push and pull operations which leads to a significant (up
13 to 4x) performance increase.
14
15 Fixes
16 ^^^^^
17 * Fixed issue with pygrack using os.cwd for working dir, that caused issues in some operating systems.
18 * Fixed dulwich parents function call used when building DAG graph.
19 * Fixed issue with revoke permissions on repository group when apply to children was set to 'none'. This call could
20 silently fail without proper notification to users.
21 * Fixed issues with Mercurial hooks when creating remote repositories.
22 * Strip passwords from clone urls for logging output.
23 * Fixed LDAP issues with unicode. LDAP bind does not support unicode passwords.
24 * Fixed admin UI which broke when using long names.
25 * Fixed rendering of READMEs that contained different line endings.
26 * Fixed issue with admin users of groups which could create repositories at top-level. No newline at end of file
@@ -0,0 +1,29 b''
1 |RCE| 2.2.3 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2013-11-27
7 * Asynchronous & more stable repo forking & creation
8 * Inheritable repository group permissions
9
10 News
11 ^^^^
12 * Bumped Mercurial to 2.8.0.
13 * Bumped Mergely to latest version.
14 * Permissions from a repository group can be inherited to child repositories.
15 * Added side-by-side diff link to compare files diff view.
16 * Forking and creation of repositories can be done asynchronously via Celery.
17 * Forking and creation of repositories is more stable in terms of concurrency and file system errors.
18 * Added new visual option for number of records on admin 'data grids'.
19 * Repository admins can add/delete repository extra fields.
20 * Improved validators of remote clone urls for Git and Mercurial.
21
22 Fixes
23 ^^^^^
24 * Fixed page links at Gists which lost filter settings on click.
25 * Fixed how auth plugins handle groups.
26 * Fixed issue on mismatch of repository fork VCS type (Git or Mercurial).
27 * Fixed admin UI forms which broke when using long names.
28 * Fixed LookupError exceptions when ambiguous identifier was given.
29 * Fixed issues which occured with Git under Windows.
@@ -0,0 +1,25 b''
1 |RCE| 2.2.4 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2013-12-30
7 * More secure output of a remote clone URL
8 * Extended API calls
9 * Support for latest Git versions
10
11 News
12 ^^^^
13 * Password in a remote clone URL are not displayed anymore.
14 * Better Windows support on server info page.
15 * Extended API: added permission delegation to grant/revoke calls.
16 * Extended API: added copy_permissions flag to create_repo_group.
17 * Extended API: added apply_to_children to grant/revoke methods of repo groups.
18
19 Fixes
20 ^^^^^
21 * Fixed forking into a repository group.
22 * Fixed detection of remote Git repositories.
23 * Fixed issue with API calls on repo names with groups.
24 * Fixed unescaped characters which broke Javascript in the 2-side diff view.
25 * Fixed git clone command by adding -q flag due to changes in the latest Git.
@@ -0,0 +1,20 b''
1 |RCE| 2.2.5 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * released 2014-02-13
7 * Improvements for larger setups
8 * Extended API calls
9
10 News
11 ^^^^
12 * Better support for larger enterprise hierarchies with more repository group levels.
13 * Added filters to permission boxes which makes managing of many thousand repo groups easier.
14 * The My Account page requires the old password for a password change.
15 * Removing of deprecated parts in .ini files.
16 * Extended API: added permission delegation on user groups calls.
17
18 Fixes
19 ^^^^^
20 * No fixes No newline at end of file
@@ -0,0 +1,27 b''
1 |RCE| 2.2.6 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * 2014-12-03
7
8 News
9 ^^^^
10 - Repository locking requires at least write permission to repository.
11 - API: added add/remove methods for extra fields
12 - New repositories/ repository groups should be created using 0755 mode not 0777
13 - Added editable owner field for repository groups
14 - Added editable owner field for user groups
15 - API: Permission delegation on grant/revoke user permission functions
16 - Auth plugin can create user creation state on first login
17 - New license logic
18
19 Fixes
20 ^^^^^
21 - Fix issue with unicode email addresses in custom gravatar template
22 - Protect against empty author string
23 - Fixed issue with multiprocess setup and cached global settings
24 - Fixed issues with IIS and proxied ports
25 - Fixed issue with mysql column size on installing RhodeCode
26 - Fixed issue with API call for update repo when a repo inside a group
27 was badly renamed when doing those calls No newline at end of file
@@ -0,0 +1,13 b''
1 |RCE| 2.2.7 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * 2015-02-03
7
8 Fixes
9 ^^^^^
10
11 * Security: fixed severe issue with leaking of auth_tokens(api_keys) on the
12 following API calls; ``get_repo``,
13 ``update_repo``, ``get_locks``, and ``get_user_groups``.
@@ -0,0 +1,12 b''
1 |RCE| 2.2.8 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * 2015-06-30
7
8 Fixes
9 ^^^^^
10
11 * Security: Apply the same permission checks for the API call `create_repo`
12 and the web interface to create a repository.
@@ -0,0 +1,166 b''
1 |RCE| 3.0.0 |RNS|
2 -----------------
3
4 As |RCM| 3.0 is a big release, the release notes have been split into the following sections:
5
6 * :ref:`general-rn-ref`
7 * :ref:`security-rn-ref`
8 * :ref:`api-rn-ref`
9 * :ref:`performance-rn-ref`
10 * :ref:`prs-rn-ref`
11 * :ref:`gists-rn-ref`
12 * :ref:`search-rn-ref`
13 * :ref:`fixes-rn-ref`
14
15 .. _general-rn-ref:
16
17 General
18 ^^^^^^^
19 * Released 2015-01-27
20 * Basic |svn| support added
21 * GPLv3 components removed
22 * Server/Client architecture for VCS systems created
23 * Python 2.5 and 2.6 support deprecated
24 * Server info pages now show gist/archive cache storage, and also CPU/Memory/Load information.
25 * Added new bulk commit (changeset) status comment form into compare view which enables bulk code-reviews without
26 opening a pull-request.
27 * License checks and limits now only apply to active users.
28 * Removed CLI command for |repo| scans as it can be done via an API call.
29 * VCS backends can be globally enabled/disabled from the :file:`rhodecode.ini` file.
30 * Added a UI option to set default rendering to rst or markdown.
31 * Added syntax highlighting to 2 way compare diff.
32 * Markup rendering can now render checkboxes for easy checklists generation.
33 * Gravatars are now retina ready.
34 * Admins can define custom CSS or JavaScript in the header or footer via new pre/post code options.
35 * Replaced ``graph.js`` with ``commits-graph.js`` html5 implementation.
36 * Added editable owner field for repository groups, and user group.
37 * Added an option to detach/delete user repositories when deleting users from the system.
38 * Added a Supervisor control page that shows status of processes.
39 * User admin grid can now filter by username OR email.
40 * Added personal |repo| group link for easier fork creation.
41 * Added support for using subdirectories when creating and uploading new files.
42 * Added option to rename a file from the web interface.
43 * Added arrow key navigation to file filter and fixed the back button behaviour.
44 * Added fuzzy matching to file filter.
45 * Added functionality to create folder structures along with files when adding content via the web interface.
46 * Separated default permissions UI into `global`, `user`, or `object` permissions management.
47 * Added an inheritance flag to object permissions which allows for explicit permissions which disregard global
48 permissions.
49 * Added post create repository group hook.
50 * Added trigger push hooks on online file editor.
51 * Added default title for pull request.
52 * More detailed logs during Authentication.
53 * More explicit logging when permission checks occur.
54 * Switched the implementation of |git| ``fetch clone pull checkout`` commands to pure |py| without any subprocess
55 calls.
56 * Introduced the ``rcserver`` command for custom development.
57 * Added the ability to force no cache archived via the ``GET no_cache`` flag
58
59 .. _security-rn-ref:
60
61 Security
62 ^^^^^^^^
63
64 * CSRF (Cross-Site Request Forgery) tokens now in all pages that use forms.
65 * The ``clone_url`` field is now AES encrypted inside the database.
66 * ACLs (Access Control Lists) are checked on the gist edit page for logged in users.
67 * New repository groups and repositories are created with 0755 permissions and not not 0777.
68 * Explicit RSS tokens are used for the RSS journal, when leaked, limits access to RSS only.
69 * Fixed XSS issues when rendering raw SVG files.
70 * Added force password reset option for users.
71 * IP list now accepts comma-separated values, and also ranges using `-` to specify multiple addresses.
72 * Added ``auth tokens``, these authentication tokens can be used as an alternative to passwords.
73 * Added roles (``http, api, rss, all, vcs``) into authentication tokens (previously called ``apikeys``).
74 * LDAP Group Support added.
75 * Added JASIG CAS auth plugin support.
76 * Added a plugin parameter that defines if a plugin can create new users on the fly.
77
78 .. _api-rn-ref:
79
80 API
81 ^^^
82 * Added permissions delegation when creating |repos| or |repo| groups.
83 * Added ``strip`` support for |hg| and |git| |repos|.
84 * Added comments API for commits.
85 * Added add/remove methods for extra fields in repositories.
86 * ``get_*`` calls now use ``permission()`` and ``permission_user_group()`` methods for unified permissions structure.
87 * ``get_repo_nodes`` information sending has changed and is no longer a boolean flag, it's now ``basic`` or ``full``.
88 * Due to configurable backends ``repo_type`` is now mandatory parameter for the ``create_repo`` call.
89
90 .. _performance-rn-ref:
91
92 Performance
93 ^^^^^^^^^^^
94
95 * Significant performance improvements across all application functions.
96 * HTTP Authentication performance enhancements.
97 * Added a ``scope`` variable to the permissions fetching function which improves building permission trees in large
98 amounts by a factor of 10.
99 * Implemented caching logic for all authentication plugins. The ``AUTH_CACHE_TTL = <int>`` property now allow you to
100 set the cache in seconds.
101
102 .. _prs-rn-ref:
103
104 Pull Requests
105 ^^^^^^^^^^^^^
106
107 * Pull requests can be now updated and merged from the web interface
108 * Fixed creating a Mercurial |pr| from a bookmark.
109 * Forbid closing pull requests when calculated status is different that the approved or rejected version.
110 * Properly display calculated pull request review status on listing page.
111 * Disable delete comment button if |pr| is closed.
112
113 .. _gists-rn-ref:
114
115 Gists
116 ^^^^^
117 * New UI based on grids with filtering.
118 * Super-admins can see all gists.
119 * Gists can now be created with a custom names.
120
121 .. _search-rn-ref:
122
123 Search
124 ^^^^^^
125
126 * New API based indexer.
127 * Added the ability to create size limits for indexed files.
128 * Added a new mapping configuration file which gives a very high level of flexibility when creating full text search.
129
130 .. _fixes-rn-ref:
131
132 Fixes
133 ^^^^^
134
135 * General: fixed issues with dependent objects, such as ``users`` in ``user groups``. Cleaning up these dependent
136 objects is now done in a safe way.
137 * General: deleting a ``user group`` from **settings > advanced** will use force removal and cleanup from all
138 associations.
139 * General: fixed issue with filter proxy middleware it's now more error prone.
140 * General: fixed issues with unable to create fork inside a group.
141 * General: fixed bad logic in ``ext_json`` lib, that checked bool on microseconds, in case it was 0 bool it returned False.
142 * General: authors in annotation mode shows authors of current source, not from all history (that is in normal mode)
143 * Permissions: fix issue when inherit flag for user group stopped working after initial permissions set.
144 * |git|: fixed shallow clones.
145 * |git|: added ``\n`` into the service line of |git| protocol. It is in the specifications and some python clients
146 require this.
147 * |hg|: fix thread safety for mercurial ``in-memory`` commits.
148 * Windows: fixed issue with shebang and env headers.
149 * MySQL: fixed database fields with 256 char length with added indexes. Mysql had problems with them.
150 * Database: fixed bad usage of matching using ``ILIKE``. Previously it could happen that if you had
151 ``marcin_1@rhodecode.com`` and ``marcin_2@rhodecode.com`` emails, using ``marcin_@rhodecode.com`` would match both.
152 * VCS: fixed issues with double new lines on the commit patches.
153 * VCS: repository locking now requires write permission to repository. If we allowed locking with read,
154 people can lock repository without an option to unlock it.
155 * Models: removed the ``isdigit`` call that can create issues when names are actually numbers on fetching objects.
156 * Files: Fix bug with show authors in annotate view.
157 * Hooks: truncate excessive commit lists on ``post_push`` hook.
158 * Hooks: in |git|, support added to set the default branch if it is not ``master``.
159 * Notifications: now can be marked as read when you are not admin.
160 * Notifications: marking all notifications as read will hide the counter.
161 * Frontend: fixed branch-tag switcher multiple ajax calls.
162 * Repository group: |repo| group owners can now change group settings even if they don't have access to top-level
163 permissions.
164 * Repositories: if you set ``Fork of`` in advanced repository settings it will now only show valid repositories
165 with the same type.
166
@@ -0,0 +1,22 b''
1 |RCE| 3.0.1 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * 2015-02-03
7
8 News
9 ^^^^
10
11 * Server info: added more details into server info page.
12
13 Fixes
14 ^^^^^
15
16 * Security: fixed severe issue with leaking of auth_tokens(api_keys) on
17 certain API calls.
18 * VCS Client: Improved reconnection logic.
19 * SVN: forbid certain actions like pull requests on svn repositories.
20 * Style: fixed comments with Markdown, and also multiple styling issues.
21 * Style: fixed re-captcha html issues.
22 * Style: fixed large inputs.
@@ -0,0 +1,31 b''
1 |RCE| 3.0.2 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * 2015-02-16
7
8 News
9 ^^^^
10
11 * Style: Overhaul of typography styling
12 * Consistent use of product name in application
13 * Action Parser: More robust handling of data
14 * Permissions: More consistent sorting of permissions
15 * Gists: Added a ``noindex`` flag for private Gists
16
17 Fixes
18 ^^^^^
19
20 * LDAP: renamed LDAP plugins for backwards compatibility. The original
21 plugin is called ``auth_ldap`` and group support is with the
22 ``auth_ldap_group`` plugin.
23 * |svn|: Support "0" to get the first commit via API from Subversion
24 repositories
25 * Style: fixed display issues with select boxes in IE
26 * Style: fixed highlighting of commits in compare view
27 * Style: Preserve new-line breaks in commit messages
28 * Style: fixed icons on code-block elements
29 * Style: fixed side-by-side diff header
30 * Style: fixed form-inputs on login pages
31 * Style: fixed multiple minor display issues in the diff display No newline at end of file
@@ -0,0 +1,49 b''
1 |RCE| 3.1.0 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * 2015-03-17
7
8 News
9 ^^^^
10
11 - API: extended the API regarding |prs|. Added the following operations to
12 support CI integrations.
13
14 * ``get_pull_request``
15 * ``get_pull_requests``
16 * ``merge_pull_request``
17 * ``close_pull_request``
18 * ``comment_pull_request``
19
20 - VCS Server: improved handling for the user in the event that no
21 VCS Server is enabled.
22 - VCS Server: Added the ``vcs.server.enable`` configuration option,
23 see :ref:`vcs-server`
24 - VCS Server: improved system stability if the VCS Server is not installed.
25 - Style: changed icon colors for the vcs back ends; Git,
26 Mercurial and Subversion.
27
28 Fixes
29 ^^^^^
30
31 - Security: fixed XSS vulnerability in files view.
32 - Pull Request: fixed dataTable integration for IE8 in Pull Request overview.
33 - Files: adding a new file via web form has been fixed.
34 - Diff: renames of files which have spaces in their file names are now displayed
35 correctly.
36 - Settings: Remove supervisor statistics page.
37 - Style: improved headers on all Pull Request related pages to make them more
38 consistent.
39 - Style: improved headers on all repository related pages to make them more
40 consistent.
41 - Style: updated icons.
42 - Style: removed border around checkboxes in IE10.
43 - Style: improved display of permission summaries in admin settings for all
44 browsers.
45 - Style: fixed alignment of form labels across all browsers.
46 - Style: improved title on the Changeset page.
47 - Style: fixed display of select widgets in IE8 and IE9.
48 - Style: fixed password input field for IE8.
49 - Style: fixed button positioning in inline comment forms of diffs for IE8.
@@ -0,0 +1,11 b''
1 |RCE| 3.1.1 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * 2015-03-27
7
8 fixes
9 ^^^^^
10
11 * Security: updated Dulwich due to CVE-2015-0838
@@ -0,0 +1,54 b''
1 |RCE| 3.2.0 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * 2015-04-08
7
8 News
9 ^^^^
10
11 - Administration: Improved the logging and rendering of tracebacks from the
12 VCS Server. The logging configuration in the INI file should be updated.
13 For information about these parts of |RCE|, see :ref:`vcs-server`, and
14 :ref:`debug-mode`.
15 - Administration: Added the ability to set a per user language.
16 - Gists: Added an option to restrict gists to logged in users only.
17 - Pull requests: Reviewer status is reset after after an update.
18 - Pull requests: Improved logging during an update.
19 - Pull requests: Added various hooks around the life-cycle and review status
20 changes of a |pr|.
21 - Security: Support added for `bcrypt`_ on Windows systems.
22 - Style: Added headers to tables which display commits, e.g. the changelog.
23 - Style: Redesigned the compare page for multiple commits.
24 - Style: Redesigned the error pages.
25 - Style: Redesigned the file details page.
26 - Style: Redesigned the summary pages of |repos|.
27 - Style: Improved the details form for managing authentication plugins.
28 - VCS Server: Robust push and pull operations if the VCSServer is restarted.
29
30 Fixes
31 ^^^^^
32
33 - Administration: :ref:`remap-rescan` could cause issues with empty |repo|
34 groups.
35 - Administration: Fix edit of an existing issue tracker entry.
36 - Comments: Allow to delete comments on regular commits.
37 - Comments: Fix batch comment functionality on the compare page.
38 - Diffs: Improve diff parser to better recognize special file names.
39 - |git|: Avoid errors when pushing into an empty |git| repository.
40 - File edit: Avoid internal server error for file edits on branches which are
41 not the default branch.
42 - Pull requests: Show initial pull request comment.
43 - Security: Escape repository description to avoid XSS like vulnerabilities.
44 - Setup: Allow to setup a new system even with expired trial license.
45 - Style: Fixed styling of repository extra fields.
46 - Style: Fixed display issues on the file page when a line is selected and the
47 history buttons are used to navigate back and forth.
48 - Style: Improve the display of the commit message on the file details page.
49 - Style: Improve :guilabel:`My Account` page for email addresses.
50 - Style: Improve :guilabel:`My Account` page for external user accounts, e.g. LDAP
51 - Style: Improve transition from file list to file details.
52 - Style: Remove light font face for improved readability on Windows.
53
54 .. _bcrypt: https://bcrypt.codeplex.com/ No newline at end of file
@@ -0,0 +1,18 b''
1 |RCE| 3.2.1 |RNS|
2 -----------------
3
4
5 General
6 ^^^^^^^
7
8 - 2015-04-20
9
10
11 fixes
12 ^^^^^
13
14 - Security: Fixed a potential XSS vulnerability in user names and user group
15 descriptions.
16
17 - Style: Fixed a form misalignment for the management of user group
18 permissions.
@@ -0,0 +1,14 b''
1 |RCE| 3.2.2 |RNS|
2 -----------------
3
4
5 General
6 ^^^^^^^
7
8 - 2015-04-22
9
10
11 fixes
12 ^^^^^
13
14 - API: Fix password handling in the API call `create_user`.
@@ -0,0 +1,14 b''
1 |RCE| 3.2.3 |RNS|
2 -----------------
3
4
5 General
6 ^^^^^^^
7
8 - 2015-04-27
9
10
11 fixes
12 ^^^^^
13
14 - Pull request: Fix Git based pull requests in the case of missing commits.
@@ -0,0 +1,70 b''
1 |RCE| 3.3.0 |RNS|
2 -----------------
3
4 General
5 ^^^^^^^
6 * 2015-05-18
7
8 News
9 ^^^^
10
11 - Administration: Clean up |repo| groups which have been deleted on the
12 file system.
13 - Docs: Overhaul the section about integrations and extensions.
14 - Docs: Document how to configure the file `.rhoderc`
15 - Docs: Extend the documentation about the usage of Gunicorn and horizontal
16 scaling.
17 - Docs: Document that we don't support the |git| dump protocol and provide a
18 workaround for very old servers.
19 - General: Decouple from external links to allow easier maintenance.
20 - Pull requests: Show a warning message if the commits are missing in the
21 source |repo| and suggest suitable next steps.
22 - Pull requests: New lab setting which enables the invalidation of inline
23 comments during an update; currently all comments are invalidated.
24 - Pull requests: Add keyboard shortcut `g p` to navigate to the |prs|
25 page of the current |repo|.
26 - Pull requests: Send notifications when a new reviewer is added to a |pr|.
27 - Pull requests: Show information about the target of a |pr|.
28 - Pull requests: Show progress after clicking the button "Update" on a |pr|.
29 - Pull requests: Show a more informative flash message after a successful
30 update of a |pr|.
31 - Style: Unify how gravatars are displayed for a more consistent look.
32 - Style: Better display of the |pr| page in smaller browser windows for
33 IE.
34 - Style: Better alignment of the status indicator in the list of reviewers of a
35 |pr|.
36 - UX: Add flash message if a |repo| has been deleted in the file system.
37 - UX: Consistent usage of |authtoken| in the settings section.
38 - UX: Better help message for the authentication plugins configuration.
39 - VCSServer: Add support for an external configuration file.
40
41
42
43 Fixes
44 ^^^^^
45
46
47 - API: Multiple fixes for the call `update_repo_group`, adjusting parent path
48 if a new parent is specified and allow to update the owner.
49 - API: Fix the handling of boolean values in the call `create_repo`.
50 - API: Fix usage of the parameter `password` in the call `create_user`.
51 - API: Make the call `strip` more robust.
52 - Auth: Better support for the parameter "Base DN" in the plugin
53 `auth_ldap_group`.
54 - Auth: Avoid concurrency issue when forking a |repo| and celery is
55 enabled.
56 - Compare: Avoid duplication of diff content in the case of commit range
57 comparison.
58 - DB: Improve `Pullrequest.revisions` to work even for empty |prs|.
59 - DB: Avoid extremely large varchar columns for MySQL and MariaDB
60 - Files: Fix an issue around "Compare to revision" for diffs which are bigger
61 than the per file limit.
62 - Files: Present submodules with an absolute URL as real links.
63 - |Repo| settings: Allow to rename |svn| |repos|.
64 - Search: |Repo| search allows to use uppercase characters in |repo|
65 names.
66 - Style: Gist header alignment issues fixed.
67 - Style: Line heights in side by side diff display improved.
68 - UX: Hide "Add comments" button if the comments form is already open.
69 - UX: Fix links of bookmarks and tags on the overview pages.
70 - VCSServer: More robust locale handling.
@@ -0,0 +1,16 b''
1 |RCE| 3.3.1 |RNS|
2 -----------------
3
4 Release Date
5 ^^^^^^^^^^^^
6
7 - 2015-05-27
8
9
10 fixes
11 ^^^^^
12
13 - Pull requests: Fix for the server side merge functionality for Mercurial
14 repositories.
15 - Repository: Fix for a problem with the remote import of repositories in
16 combination with celery based asynchronous task execution.
@@ -0,0 +1,25 b''
1 |RCE| 3.3.2 |RNS|
2 -----------------
3
4
5 Release Date
6 ^^^^^^^^^^^^
7
8 - 2015-06-05
9
10
11 security fixes
12 ^^^^^^^^^^^^^^
13
14 * Stored XSS attempts on user login fields, and other text input fields.
15 * DOM Based XSS attempts
16 * HTML Injection
17 * Cross frame scripting (XFS)
18 * Invalidation of concurrent sessions on password change.
19 * Downgrading of HTTPS connections.
20
21 fixes
22 ^^^^^
23
24 * Generation of URLs on system with custom URL prefixes.
25 * VCSServer: Improved memory management of the cache data used by the server.
@@ -0,0 +1,16 b''
1 |RCE| 3.3.3 |RNS|
2 -----------------
3
4
5 Release Date
6 ^^^^^^^^^^^^
7
8 - 2015-06-12
9
10
11 fixes
12 ^^^^^
13
14 * File system: Better handling of filenames with encoding other than utf-8
15 * Performance: Includes new cache based on LRU
16 * URLs: More robust URL generation in reverse proxy based setups
@@ -0,0 +1,16 b''
1 |RCE| 3.3.4 |RNS|
2 -----------------
3
4
5 Release Date
6 ^^^^^^^^^^^^
7
8 - 2015-06-25
9
10
11 fixes
12 ^^^^^
13
14 * References: Support for unicode characters.
15 * Gists: Fixes the problem with gists when |hg| is not in VCS backends list.
16 * Search: Improves search speed for super admin users.
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now