##// END OF EJS Templates
fixes #449 bad regex could get more than revisions from parsing history
marcink -
r2274:34eb00bd beta
parent child Browse files
Show More
@@ -1,660 +1,661 b''
1 .. _changelog:
1 .. _changelog:
2
2
3 =========
3 =========
4 Changelog
4 Changelog
5 =========
5 =========
6
6
7 1.4.0 (**2012-XX-XX**)
7 1.4.0 (**2012-XX-XX**)
8 ----------------------
8 ----------------------
9
9
10 :status: in-progress
10 :status: in-progress
11 :branch: beta
11 :branch: beta
12
12
13 news
13 news
14 ++++
14 ++++
15
15
16 fixes
16 fixes
17 +++++
17 +++++
18
18
19 1.3.6 (**2012-05-16**)
19 1.3.6 (**2012-05-16**)
20 ----------------------
20 ----------------------
21
21
22 news
22 news
23 ++++
23 ++++
24
24
25 - chinese traditional translation
25 - chinese traditional translation
26
26
27 fixes
27 fixes
28 +++++
28 +++++
29
29
30 - fixed no scm found warning
30 - fixed no scm found warning
31 - fixed __future__ import error on rcextensions
31 - fixed __future__ import error on rcextensions
32 - made simplejson required lib for speedup on JSON encoding
32 - made simplejson required lib for speedup on JSON encoding
33 - fixes #449 bad regex could get more than revisions from parsing history
33
34
34 1.3.5 (**2012-05-10**)
35 1.3.5 (**2012-05-10**)
35 ----------------------
36 ----------------------
36
37
37 news
38 news
38 ++++
39 ++++
39
40
40 - use ext_json for json module
41 - use ext_json for json module
41 - unified annotation view with file source view
42 - unified annotation view with file source view
42 - notification improvements, better inbox + css
43 - notification improvements, better inbox + css
43 - #419 don't strip passwords for login forms, make rhodecode
44 - #419 don't strip passwords for login forms, make rhodecode
44 more compatible with LDAP servers
45 more compatible with LDAP servers
45 - Added HTTP_X_FORWARDED_FOR as another method of extracting
46 - Added HTTP_X_FORWARDED_FOR as another method of extracting
46 IP for pull/push logs. - moved all to base controller
47 IP for pull/push logs. - moved all to base controller
47 - #415: Adding comment to changeset causes reload.
48 - #415: Adding comment to changeset causes reload.
48 Comments are now added via ajax and doesn't reload the page
49 Comments are now added via ajax and doesn't reload the page
49 - #374 LDAP config is discarded when LDAP can't be activated
50 - #374 LDAP config is discarded when LDAP can't be activated
50 - limited push/pull operations are now logged for git in the journal
51 - limited push/pull operations are now logged for git in the journal
51 - bumped mercurial to 2.2.X series
52 - bumped mercurial to 2.2.X series
52 - added support for displaying submodules in file-browser
53 - added support for displaying submodules in file-browser
53 - #421 added bookmarks in changelog view
54 - #421 added bookmarks in changelog view
54
55
55 fixes
56 fixes
56 +++++
57 +++++
57
58
58 - fixed dev-version marker for stable when served from source codes
59 - fixed dev-version marker for stable when served from source codes
59 - fixed missing permission checks on show forks page
60 - fixed missing permission checks on show forks page
60 - #418 cast to unicode fixes in notification objects
61 - #418 cast to unicode fixes in notification objects
61 - #426 fixed mention extracting regex
62 - #426 fixed mention extracting regex
62 - fixed remote-pulling for git remotes remopositories
63 - fixed remote-pulling for git remotes remopositories
63 - fixed #434: Error when accessing files or changesets of a git repository
64 - fixed #434: Error when accessing files or changesets of a git repository
64 with submodules
65 with submodules
65 - fixed issue with empty APIKEYS for users after registration ref. #438
66 - fixed issue with empty APIKEYS for users after registration ref. #438
66 - fixed issue with getting README files from git repositories
67 - fixed issue with getting README files from git repositories
67
68
68 1.3.4 (**2012-03-28**)
69 1.3.4 (**2012-03-28**)
69 ----------------------
70 ----------------------
70
71
71 news
72 news
72 ++++
73 ++++
73
74
74 - Whoosh logging is now controlled by the .ini files logging setup
75 - Whoosh logging is now controlled by the .ini files logging setup
75 - added clone-url into edit form on /settings page
76 - added clone-url into edit form on /settings page
76 - added help text into repo add/edit forms
77 - added help text into repo add/edit forms
77 - created rcextensions module with additional mappings (ref #322) and
78 - created rcextensions module with additional mappings (ref #322) and
78 post push/pull/create repo hooks callbacks
79 post push/pull/create repo hooks callbacks
79 - implemented #377 Users view for his own permissions on account page
80 - implemented #377 Users view for his own permissions on account page
80 - #399 added inheritance of permissions for users group on repos groups
81 - #399 added inheritance of permissions for users group on repos groups
81 - #401 repository group is automatically pre-selected when adding repos
82 - #401 repository group is automatically pre-selected when adding repos
82 inside a repository group
83 inside a repository group
83 - added alternative HTTP 403 response when client failed to authenticate. Helps
84 - added alternative HTTP 403 response when client failed to authenticate. Helps
84 solving issues with Mercurial and LDAP
85 solving issues with Mercurial and LDAP
85 - #402 removed group prefix from repository name when listing repositories
86 - #402 removed group prefix from repository name when listing repositories
86 inside a group
87 inside a group
87 - added gravatars into permission view and permissions autocomplete
88 - added gravatars into permission view and permissions autocomplete
88 - #347 when running multiple RhodeCode instances, properly invalidates cache
89 - #347 when running multiple RhodeCode instances, properly invalidates cache
89 for all registered servers
90 for all registered servers
90
91
91 fixes
92 fixes
92 +++++
93 +++++
93
94
94 - fixed #390 cache invalidation problems on repos inside group
95 - fixed #390 cache invalidation problems on repos inside group
95 - fixed #385 clone by ID url was loosing proxy prefix in URL
96 - fixed #385 clone by ID url was loosing proxy prefix in URL
96 - fixed some unicode problems with waitress
97 - fixed some unicode problems with waitress
97 - fixed issue with escaping < and > in changeset commits
98 - fixed issue with escaping < and > in changeset commits
98 - fixed error occurring during recursive group creation in API
99 - fixed error occurring during recursive group creation in API
99 create_repo function
100 create_repo function
100 - fixed #393 py2.5 fixes for routes url generator
101 - fixed #393 py2.5 fixes for routes url generator
101 - fixed #397 Private repository groups shows up before login
102 - fixed #397 Private repository groups shows up before login
102 - fixed #396 fixed problems with revoking users in nested groups
103 - fixed #396 fixed problems with revoking users in nested groups
103 - fixed mysql unicode issues + specified InnoDB as default engine with
104 - fixed mysql unicode issues + specified InnoDB as default engine with
104 utf8 charset
105 utf8 charset
105 - #406 trim long branch/tag names in changelog to not break UI
106 - #406 trim long branch/tag names in changelog to not break UI
106
107
107 1.3.3 (**2012-03-02**)
108 1.3.3 (**2012-03-02**)
108 ----------------------
109 ----------------------
109
110
110 news
111 news
111 ++++
112 ++++
112
113
113
114
114 fixes
115 fixes
115 +++++
116 +++++
116
117
117 - fixed some python2.5 compatibility issues
118 - fixed some python2.5 compatibility issues
118 - fixed issues with removed repos was accidentally added as groups, after
119 - fixed issues with removed repos was accidentally added as groups, after
119 full rescan of paths
120 full rescan of paths
120 - fixes #376 Cannot edit user (using container auth)
121 - fixes #376 Cannot edit user (using container auth)
121 - fixes #378 Invalid image urls on changeset screen with proxy-prefix
122 - fixes #378 Invalid image urls on changeset screen with proxy-prefix
122 configuration
123 configuration
123 - fixed initial sorting of repos inside repo group
124 - fixed initial sorting of repos inside repo group
124 - fixes issue when user tried to resubmit same permission into user/user_groups
125 - fixes issue when user tried to resubmit same permission into user/user_groups
125 - bumped beaker version that fixes #375 leap error bug
126 - bumped beaker version that fixes #375 leap error bug
126 - fixed raw_changeset for git. It was generated with hg patch headers
127 - fixed raw_changeset for git. It was generated with hg patch headers
127 - fixed vcs issue with last_changeset for filenodes
128 - fixed vcs issue with last_changeset for filenodes
128 - fixed missing commit after hook delete
129 - fixed missing commit after hook delete
129 - fixed #372 issues with git operation detection that caused a security issue
130 - fixed #372 issues with git operation detection that caused a security issue
130 for git repos
131 for git repos
131
132
132 1.3.2 (**2012-02-28**)
133 1.3.2 (**2012-02-28**)
133 ----------------------
134 ----------------------
134
135
135 news
136 news
136 ++++
137 ++++
137
138
138
139
139 fixes
140 fixes
140 +++++
141 +++++
141
142
142 - fixed git protocol issues with repos-groups
143 - fixed git protocol issues with repos-groups
143 - fixed git remote repos validator that prevented from cloning remote git repos
144 - fixed git remote repos validator that prevented from cloning remote git repos
144 - fixes #370 ending slashes fixes for repo and groups
145 - fixes #370 ending slashes fixes for repo and groups
145 - fixes #368 improved git-protocol detection to handle other clients
146 - fixes #368 improved git-protocol detection to handle other clients
146 - fixes #366 When Setting Repository Group To Blank Repo Group Wont Be
147 - fixes #366 When Setting Repository Group To Blank Repo Group Wont Be
147 Moved To Root
148 Moved To Root
148 - fixes #371 fixed issues with beaker/sqlalchemy and non-ascii cache keys
149 - fixes #371 fixed issues with beaker/sqlalchemy and non-ascii cache keys
149 - fixed #373 missing cascade drop on user_group_to_perm table
150 - fixed #373 missing cascade drop on user_group_to_perm table
150
151
151 1.3.1 (**2012-02-27**)
152 1.3.1 (**2012-02-27**)
152 ----------------------
153 ----------------------
153
154
154 news
155 news
155 ++++
156 ++++
156
157
157
158
158 fixes
159 fixes
159 +++++
160 +++++
160
161
161 - redirection loop occurs when remember-me wasn't checked during login
162 - redirection loop occurs when remember-me wasn't checked during login
162 - fixes issues with git blob history generation
163 - fixes issues with git blob history generation
163 - don't fetch branch for git in file history dropdown. Causes unneeded slowness
164 - don't fetch branch for git in file history dropdown. Causes unneeded slowness
164
165
165 1.3.0 (**2012-02-26**)
166 1.3.0 (**2012-02-26**)
166 ----------------------
167 ----------------------
167
168
168 news
169 news
169 ++++
170 ++++
170
171
171 - code review, inspired by github code-comments
172 - code review, inspired by github code-comments
172 - #215 rst and markdown README files support
173 - #215 rst and markdown README files support
173 - #252 Container-based and proxy pass-through authentication support
174 - #252 Container-based and proxy pass-through authentication support
174 - #44 branch browser. Filtering of changelog by branches
175 - #44 branch browser. Filtering of changelog by branches
175 - mercurial bookmarks support
176 - mercurial bookmarks support
176 - new hover top menu, optimized to add maximum size for important views
177 - new hover top menu, optimized to add maximum size for important views
177 - configurable clone url template with possibility to specify protocol like
178 - configurable clone url template with possibility to specify protocol like
178 ssh:// or http:// and also manually alter other parts of clone_url.
179 ssh:// or http:// and also manually alter other parts of clone_url.
179 - enabled largefiles extension by default
180 - enabled largefiles extension by default
180 - optimized summary file pages and saved a lot of unused space in them
181 - optimized summary file pages and saved a lot of unused space in them
181 - #239 option to manually mark repository as fork
182 - #239 option to manually mark repository as fork
182 - #320 mapping of commit authors to RhodeCode users
183 - #320 mapping of commit authors to RhodeCode users
183 - #304 hashes are displayed using monospace font
184 - #304 hashes are displayed using monospace font
184 - diff configuration, toggle white lines and context lines
185 - diff configuration, toggle white lines and context lines
185 - #307 configurable diffs, whitespace toggle, increasing context lines
186 - #307 configurable diffs, whitespace toggle, increasing context lines
186 - sorting on branches, tags and bookmarks using YUI datatable
187 - sorting on branches, tags and bookmarks using YUI datatable
187 - improved file filter on files page
188 - improved file filter on files page
188 - implements #330 api method for listing nodes ar particular revision
189 - implements #330 api method for listing nodes ar particular revision
189 - #73 added linking issues in commit messages to chosen issue tracker url
190 - #73 added linking issues in commit messages to chosen issue tracker url
190 based on user defined regular expression
191 based on user defined regular expression
191 - added linking of changesets in commit messages
192 - added linking of changesets in commit messages
192 - new compact changelog with expandable commit messages
193 - new compact changelog with expandable commit messages
193 - firstname and lastname are optional in user creation
194 - firstname and lastname are optional in user creation
194 - #348 added post-create repository hook
195 - #348 added post-create repository hook
195 - #212 global encoding settings is now configurable from .ini files
196 - #212 global encoding settings is now configurable from .ini files
196 - #227 added repository groups permissions
197 - #227 added repository groups permissions
197 - markdown gets codehilite extensions
198 - markdown gets codehilite extensions
198 - new API methods, delete_repositories, grante/revoke permissions for groups
199 - new API methods, delete_repositories, grante/revoke permissions for groups
199 and repos
200 and repos
200
201
201
202
202 fixes
203 fixes
203 +++++
204 +++++
204
205
205 - rewrote dbsession management for atomic operations, and better error handling
206 - rewrote dbsession management for atomic operations, and better error handling
206 - fixed sorting of repo tables
207 - fixed sorting of repo tables
207 - #326 escape of special html entities in diffs
208 - #326 escape of special html entities in diffs
208 - normalized user_name => username in api attributes
209 - normalized user_name => username in api attributes
209 - fixes #298 ldap created users with mixed case emails created conflicts
210 - fixes #298 ldap created users with mixed case emails created conflicts
210 on saving a form
211 on saving a form
211 - fixes issue when owner of a repo couldn't revoke permissions for users
212 - fixes issue when owner of a repo couldn't revoke permissions for users
212 and groups
213 and groups
213 - fixes #271 rare JSON serialization problem with statistics
214 - fixes #271 rare JSON serialization problem with statistics
214 - fixes #337 missing validation check for conflicting names of a group with a
215 - fixes #337 missing validation check for conflicting names of a group with a
215 repositories group
216 repositories group
216 - #340 fixed session problem for mysql and celery tasks
217 - #340 fixed session problem for mysql and celery tasks
217 - fixed #331 RhodeCode mangles repository names if the a repository group
218 - fixed #331 RhodeCode mangles repository names if the a repository group
218 contains the "full path" to the repositories
219 contains the "full path" to the repositories
219 - #355 RhodeCode doesn't store encrypted LDAP passwords
220 - #355 RhodeCode doesn't store encrypted LDAP passwords
220
221
221 1.2.5 (**2012-01-28**)
222 1.2.5 (**2012-01-28**)
222 ----------------------
223 ----------------------
223
224
224 news
225 news
225 ++++
226 ++++
226
227
227 fixes
228 fixes
228 +++++
229 +++++
229
230
230 - #340 Celery complains about MySQL server gone away, added session cleanup
231 - #340 Celery complains about MySQL server gone away, added session cleanup
231 for celery tasks
232 for celery tasks
232 - #341 "scanning for repositories in None" log message during Rescan was missing
233 - #341 "scanning for repositories in None" log message during Rescan was missing
233 a parameter
234 a parameter
234 - fixed creating archives with subrepos. Some hooks were triggered during that
235 - fixed creating archives with subrepos. Some hooks were triggered during that
235 operation leading to crash.
236 operation leading to crash.
236 - fixed missing email in account page.
237 - fixed missing email in account page.
237 - Reverted Mercurial to 2.0.1 for windows due to bug in Mercurial that makes
238 - Reverted Mercurial to 2.0.1 for windows due to bug in Mercurial that makes
238 forking on windows impossible
239 forking on windows impossible
239
240
240 1.2.4 (**2012-01-19**)
241 1.2.4 (**2012-01-19**)
241 ----------------------
242 ----------------------
242
243
243 news
244 news
244 ++++
245 ++++
245
246
246 - RhodeCode is bundled with mercurial series 2.0.X by default, with
247 - RhodeCode is bundled with mercurial series 2.0.X by default, with
247 full support to largefiles extension. Enabled by default in new installations
248 full support to largefiles extension. Enabled by default in new installations
248 - #329 Ability to Add/Remove Groups to/from a Repository via AP
249 - #329 Ability to Add/Remove Groups to/from a Repository via AP
249 - added requires.txt file with requirements
250 - added requires.txt file with requirements
250
251
251 fixes
252 fixes
252 +++++
253 +++++
253
254
254 - fixes db session issues with celery when emailing admins
255 - fixes db session issues with celery when emailing admins
255 - #331 RhodeCode mangles repository names if the a repository group
256 - #331 RhodeCode mangles repository names if the a repository group
256 contains the "full path" to the repositories
257 contains the "full path" to the repositories
257 - #298 Conflicting e-mail addresses for LDAP and RhodeCode users
258 - #298 Conflicting e-mail addresses for LDAP and RhodeCode users
258 - DB session cleanup after hg protocol operations, fixes issues with
259 - DB session cleanup after hg protocol operations, fixes issues with
259 `mysql has gone away` errors
260 `mysql has gone away` errors
260 - #333 doc fixes for get_repo api function
261 - #333 doc fixes for get_repo api function
261 - #271 rare JSON serialization problem with statistics enabled
262 - #271 rare JSON serialization problem with statistics enabled
262 - #337 Fixes issues with validation of repository name conflicting with
263 - #337 Fixes issues with validation of repository name conflicting with
263 a group name. A proper message is now displayed.
264 a group name. A proper message is now displayed.
264 - #292 made ldap_dn in user edit readonly, to get rid of confusion that field
265 - #292 made ldap_dn in user edit readonly, to get rid of confusion that field
265 doesn't work
266 doesn't work
266 - #316 fixes issues with web description in hgrc files
267 - #316 fixes issues with web description in hgrc files
267
268
268 1.2.3 (**2011-11-02**)
269 1.2.3 (**2011-11-02**)
269 ----------------------
270 ----------------------
270
271
271 news
272 news
272 ++++
273 ++++
273
274
274 - added option to manage repos group for non admin users
275 - added option to manage repos group for non admin users
275 - added following API methods for get_users, create_user, get_users_groups,
276 - added following API methods for get_users, create_user, get_users_groups,
276 get_users_group, create_users_group, add_user_to_users_groups, get_repos,
277 get_users_group, create_users_group, add_user_to_users_groups, get_repos,
277 get_repo, create_repo, add_user_to_repo
278 get_repo, create_repo, add_user_to_repo
278 - implements #237 added password confirmation for my account
279 - implements #237 added password confirmation for my account
279 and admin edit user.
280 and admin edit user.
280 - implements #291 email notification for global events are now sent to all
281 - implements #291 email notification for global events are now sent to all
281 administrator users, and global config email.
282 administrator users, and global config email.
282
283
283 fixes
284 fixes
284 +++++
285 +++++
285
286
286 - added option for passing auth method for smtp mailer
287 - added option for passing auth method for smtp mailer
287 - #276 issue with adding a single user with id>10 to usergroups
288 - #276 issue with adding a single user with id>10 to usergroups
288 - #277 fixes windows LDAP settings in which missing values breaks the ldap auth
289 - #277 fixes windows LDAP settings in which missing values breaks the ldap auth
289 - #288 fixes managing of repos in a group for non admin user
290 - #288 fixes managing of repos in a group for non admin user
290
291
291 1.2.2 (**2011-10-17**)
292 1.2.2 (**2011-10-17**)
292 ----------------------
293 ----------------------
293
294
294 news
295 news
295 ++++
296 ++++
296
297
297 - #226 repo groups are available by path instead of numerical id
298 - #226 repo groups are available by path instead of numerical id
298
299
299 fixes
300 fixes
300 +++++
301 +++++
301
302
302 - #259 Groups with the same name but with different parent group
303 - #259 Groups with the same name but with different parent group
303 - #260 Put repo in group, then move group to another group -> repo becomes unavailable
304 - #260 Put repo in group, then move group to another group -> repo becomes unavailable
304 - #258 RhodeCode 1.2 assumes egg folder is writable (lockfiles problems)
305 - #258 RhodeCode 1.2 assumes egg folder is writable (lockfiles problems)
305 - #265 ldap save fails sometimes on converting attributes to booleans,
306 - #265 ldap save fails sometimes on converting attributes to booleans,
306 added getter and setter into model that will prevent from this on db model level
307 added getter and setter into model that will prevent from this on db model level
307 - fixed problems with timestamps issues #251 and #213
308 - fixed problems with timestamps issues #251 and #213
308 - fixes #266 RhodeCode allows to create repo with the same name and in
309 - fixes #266 RhodeCode allows to create repo with the same name and in
309 the same parent as group
310 the same parent as group
310 - fixes #245 Rescan of the repositories on Windows
311 - fixes #245 Rescan of the repositories on Windows
311 - fixes #248 cannot edit repos inside a group on windows
312 - fixes #248 cannot edit repos inside a group on windows
312 - fixes #219 forking problems on windows
313 - fixes #219 forking problems on windows
313
314
314 1.2.1 (**2011-10-08**)
315 1.2.1 (**2011-10-08**)
315 ----------------------
316 ----------------------
316
317
317 news
318 news
318 ++++
319 ++++
319
320
320
321
321 fixes
322 fixes
322 +++++
323 +++++
323
324
324 - fixed problems with basic auth and push problems
325 - fixed problems with basic auth and push problems
325 - gui fixes
326 - gui fixes
326 - fixed logger
327 - fixed logger
327
328
328 1.2.0 (**2011-10-07**)
329 1.2.0 (**2011-10-07**)
329 ----------------------
330 ----------------------
330
331
331 news
332 news
332 ++++
333 ++++
333
334
334 - implemented #47 repository groups
335 - implemented #47 repository groups
335 - implemented #89 Can setup google analytics code from settings menu
336 - implemented #89 Can setup google analytics code from settings menu
336 - implemented #91 added nicer looking archive urls with more download options
337 - implemented #91 added nicer looking archive urls with more download options
337 like tags, branches
338 like tags, branches
338 - implemented #44 into file browsing, and added follow branch option
339 - implemented #44 into file browsing, and added follow branch option
339 - implemented #84 downloads can be enabled/disabled for each repository
340 - implemented #84 downloads can be enabled/disabled for each repository
340 - anonymous repository can be cloned without having to pass default:default
341 - anonymous repository can be cloned without having to pass default:default
341 into clone url
342 into clone url
342 - fixed #90 whoosh indexer can index chooses repositories passed in command
343 - fixed #90 whoosh indexer can index chooses repositories passed in command
343 line
344 line
344 - extended journal with day aggregates and paging
345 - extended journal with day aggregates and paging
345 - implemented #107 source code lines highlight ranges
346 - implemented #107 source code lines highlight ranges
346 - implemented #93 customizable changelog on combined revision ranges -
347 - implemented #93 customizable changelog on combined revision ranges -
347 equivalent of githubs compare view
348 equivalent of githubs compare view
348 - implemented #108 extended and more powerful LDAP configuration
349 - implemented #108 extended and more powerful LDAP configuration
349 - implemented #56 users groups
350 - implemented #56 users groups
350 - major code rewrites optimized codes for speed and memory usage
351 - major code rewrites optimized codes for speed and memory usage
351 - raw and diff downloads are now in git format
352 - raw and diff downloads are now in git format
352 - setup command checks for write access to given path
353 - setup command checks for write access to given path
353 - fixed many issues with international characters and unicode. It uses utf8
354 - fixed many issues with international characters and unicode. It uses utf8
354 decode with replace to provide less errors even with non utf8 encoded strings
355 decode with replace to provide less errors even with non utf8 encoded strings
355 - #125 added API KEY access to feeds
356 - #125 added API KEY access to feeds
356 - #109 Repository can be created from external Mercurial link (aka. remote
357 - #109 Repository can be created from external Mercurial link (aka. remote
357 repository, and manually updated (via pull) from admin panel
358 repository, and manually updated (via pull) from admin panel
358 - beta git support - push/pull server + basic view for git repos
359 - beta git support - push/pull server + basic view for git repos
359 - added followers page and forks page
360 - added followers page and forks page
360 - server side file creation (with binary file upload interface)
361 - server side file creation (with binary file upload interface)
361 and edition with commits powered by codemirror
362 and edition with commits powered by codemirror
362 - #111 file browser file finder, quick lookup files on whole file tree
363 - #111 file browser file finder, quick lookup files on whole file tree
363 - added quick login sliding menu into main page
364 - added quick login sliding menu into main page
364 - changelog uses lazy loading of affected files details, in some scenarios
365 - changelog uses lazy loading of affected files details, in some scenarios
365 this can improve speed of changelog page dramatically especially for
366 this can improve speed of changelog page dramatically especially for
366 larger repositories.
367 larger repositories.
367 - implements #214 added support for downloading subrepos in download menu.
368 - implements #214 added support for downloading subrepos in download menu.
368 - Added basic API for direct operations on rhodecode via JSON
369 - Added basic API for direct operations on rhodecode via JSON
369 - Implemented advanced hook management
370 - Implemented advanced hook management
370
371
371 fixes
372 fixes
372 +++++
373 +++++
373
374
374 - fixed file browser bug, when switching into given form revision the url was
375 - fixed file browser bug, when switching into given form revision the url was
375 not changing
376 not changing
376 - fixed propagation to error controller on simplehg and simplegit middlewares
377 - fixed propagation to error controller on simplehg and simplegit middlewares
377 - fixed error when trying to make a download on empty repository
378 - fixed error when trying to make a download on empty repository
378 - fixed problem with '[' chars in commit messages in journal
379 - fixed problem with '[' chars in commit messages in journal
379 - fixed #99 Unicode errors, on file node paths with non utf-8 characters
380 - fixed #99 Unicode errors, on file node paths with non utf-8 characters
380 - journal fork fixes
381 - journal fork fixes
381 - removed issue with space inside renamed repository after deletion
382 - removed issue with space inside renamed repository after deletion
382 - fixed strange issue on formencode imports
383 - fixed strange issue on formencode imports
383 - fixed #126 Deleting repository on Windows, rename used incompatible chars.
384 - fixed #126 Deleting repository on Windows, rename used incompatible chars.
384 - #150 fixes for errors on repositories mapped in db but corrupted in
385 - #150 fixes for errors on repositories mapped in db but corrupted in
385 filesystem
386 filesystem
386 - fixed problem with ascendant characters in realm #181
387 - fixed problem with ascendant characters in realm #181
387 - fixed problem with sqlite file based database connection pool
388 - fixed problem with sqlite file based database connection pool
388 - whoosh indexer and code stats share the same dynamic extensions map
389 - whoosh indexer and code stats share the same dynamic extensions map
389 - fixes #188 - relationship delete of repo_to_perm entry on user removal
390 - fixes #188 - relationship delete of repo_to_perm entry on user removal
390 - fixes issue #189 Trending source files shows "show more" when no more exist
391 - fixes issue #189 Trending source files shows "show more" when no more exist
391 - fixes issue #197 Relative paths for pidlocks
392 - fixes issue #197 Relative paths for pidlocks
392 - fixes issue #198 password will require only 3 chars now for login form
393 - fixes issue #198 password will require only 3 chars now for login form
393 - fixes issue #199 wrong redirection for non admin users after creating a repository
394 - fixes issue #199 wrong redirection for non admin users after creating a repository
394 - fixes issues #202, bad db constraint made impossible to attach same group
395 - fixes issues #202, bad db constraint made impossible to attach same group
395 more than one time. Affects only mysql/postgres
396 more than one time. Affects only mysql/postgres
396 - fixes #218 os.kill patch for windows was missing sig param
397 - fixes #218 os.kill patch for windows was missing sig param
397 - improved rendering of dag (they are not trimmed anymore when number of
398 - improved rendering of dag (they are not trimmed anymore when number of
398 heads exceeds 5)
399 heads exceeds 5)
399
400
400 1.1.8 (**2011-04-12**)
401 1.1.8 (**2011-04-12**)
401 ----------------------
402 ----------------------
402
403
403 news
404 news
404 ++++
405 ++++
405
406
406 - improved windows support
407 - improved windows support
407
408
408 fixes
409 fixes
409 +++++
410 +++++
410
411
411 - fixed #140 freeze of python dateutil library, since new version is python2.x
412 - fixed #140 freeze of python dateutil library, since new version is python2.x
412 incompatible
413 incompatible
413 - setup-app will check for write permission in given path
414 - setup-app will check for write permission in given path
414 - cleaned up license info issue #149
415 - cleaned up license info issue #149
415 - fixes for issues #137,#116 and problems with unicode and accented characters.
416 - fixes for issues #137,#116 and problems with unicode and accented characters.
416 - fixes crashes on gravatar, when passed in email as unicode
417 - fixes crashes on gravatar, when passed in email as unicode
417 - fixed tooltip flickering problems
418 - fixed tooltip flickering problems
418 - fixed came_from redirection on windows
419 - fixed came_from redirection on windows
419 - fixed logging modules, and sql formatters
420 - fixed logging modules, and sql formatters
420 - windows fixes for os.kill issue #133
421 - windows fixes for os.kill issue #133
421 - fixes path splitting for windows issues #148
422 - fixes path splitting for windows issues #148
422 - fixed issue #143 wrong import on migration to 1.1.X
423 - fixed issue #143 wrong import on migration to 1.1.X
423 - fixed problems with displaying binary files, thanks to Thomas Waldmann
424 - fixed problems with displaying binary files, thanks to Thomas Waldmann
424 - removed name from archive files since it's breaking ui for long repo names
425 - removed name from archive files since it's breaking ui for long repo names
425 - fixed issue with archive headers sent to browser, thanks to Thomas Waldmann
426 - fixed issue with archive headers sent to browser, thanks to Thomas Waldmann
426 - fixed compatibility for 1024px displays, and larger dpi settings, thanks to
427 - fixed compatibility for 1024px displays, and larger dpi settings, thanks to
427 Thomas Waldmann
428 Thomas Waldmann
428 - fixed issue #166 summary pager was skipping 10 revisions on second page
429 - fixed issue #166 summary pager was skipping 10 revisions on second page
429
430
430
431
431 1.1.7 (**2011-03-23**)
432 1.1.7 (**2011-03-23**)
432 ----------------------
433 ----------------------
433
434
434 news
435 news
435 ++++
436 ++++
436
437
437 fixes
438 fixes
438 +++++
439 +++++
439
440
440 - fixed (again) #136 installation support for FreeBSD
441 - fixed (again) #136 installation support for FreeBSD
441
442
442
443
443 1.1.6 (**2011-03-21**)
444 1.1.6 (**2011-03-21**)
444 ----------------------
445 ----------------------
445
446
446 news
447 news
447 ++++
448 ++++
448
449
449 fixes
450 fixes
450 +++++
451 +++++
451
452
452 - fixed #136 installation support for FreeBSD
453 - fixed #136 installation support for FreeBSD
453 - RhodeCode will check for python version during installation
454 - RhodeCode will check for python version during installation
454
455
455 1.1.5 (**2011-03-17**)
456 1.1.5 (**2011-03-17**)
456 ----------------------
457 ----------------------
457
458
458 news
459 news
459 ++++
460 ++++
460
461
461 - basic windows support, by exchanging pybcrypt into sha256 for windows only
462 - basic windows support, by exchanging pybcrypt into sha256 for windows only
462 highly inspired by idea of mantis406
463 highly inspired by idea of mantis406
463
464
464 fixes
465 fixes
465 +++++
466 +++++
466
467
467 - fixed sorting by author in main page
468 - fixed sorting by author in main page
468 - fixed crashes with diffs on binary files
469 - fixed crashes with diffs on binary files
469 - fixed #131 problem with boolean values for LDAP
470 - fixed #131 problem with boolean values for LDAP
470 - fixed #122 mysql problems thanks to striker69
471 - fixed #122 mysql problems thanks to striker69
471 - fixed problem with errors on calling raw/raw_files/annotate functions
472 - fixed problem with errors on calling raw/raw_files/annotate functions
472 with unknown revisions
473 with unknown revisions
473 - fixed returned rawfiles attachment names with international character
474 - fixed returned rawfiles attachment names with international character
474 - cleaned out docs, big thanks to Jason Harris
475 - cleaned out docs, big thanks to Jason Harris
475
476
476 1.1.4 (**2011-02-19**)
477 1.1.4 (**2011-02-19**)
477 ----------------------
478 ----------------------
478
479
479 news
480 news
480 ++++
481 ++++
481
482
482 fixes
483 fixes
483 +++++
484 +++++
484
485
485 - fixed formencode import problem on settings page, that caused server crash
486 - fixed formencode import problem on settings page, that caused server crash
486 when that page was accessed as first after server start
487 when that page was accessed as first after server start
487 - journal fixes
488 - journal fixes
488 - fixed option to access repository just by entering http://server/<repo_name>
489 - fixed option to access repository just by entering http://server/<repo_name>
489
490
490 1.1.3 (**2011-02-16**)
491 1.1.3 (**2011-02-16**)
491 ----------------------
492 ----------------------
492
493
493 news
494 news
494 ++++
495 ++++
495
496
496 - implemented #102 allowing the '.' character in username
497 - implemented #102 allowing the '.' character in username
497 - added option to access repository just by entering http://server/<repo_name>
498 - added option to access repository just by entering http://server/<repo_name>
498 - celery task ignores result for better performance
499 - celery task ignores result for better performance
499
500
500 fixes
501 fixes
501 +++++
502 +++++
502
503
503 - fixed ehlo command and non auth mail servers on smtp_lib. Thanks to
504 - fixed ehlo command and non auth mail servers on smtp_lib. Thanks to
504 apollo13 and Johan Walles
505 apollo13 and Johan Walles
505 - small fixes in journal
506 - small fixes in journal
506 - fixed problems with getting setting for celery from .ini files
507 - fixed problems with getting setting for celery from .ini files
507 - registration, password reset and login boxes share the same title as main
508 - registration, password reset and login boxes share the same title as main
508 application now
509 application now
509 - fixed #113: to high permissions to fork repository
510 - fixed #113: to high permissions to fork repository
510 - fixed problem with '[' chars in commit messages in journal
511 - fixed problem with '[' chars in commit messages in journal
511 - removed issue with space inside renamed repository after deletion
512 - removed issue with space inside renamed repository after deletion
512 - db transaction fixes when filesystem repository creation failed
513 - db transaction fixes when filesystem repository creation failed
513 - fixed #106 relation issues on databases different than sqlite
514 - fixed #106 relation issues on databases different than sqlite
514 - fixed static files paths links to use of url() method
515 - fixed static files paths links to use of url() method
515
516
516 1.1.2 (**2011-01-12**)
517 1.1.2 (**2011-01-12**)
517 ----------------------
518 ----------------------
518
519
519 news
520 news
520 ++++
521 ++++
521
522
522
523
523 fixes
524 fixes
524 +++++
525 +++++
525
526
526 - fixes #98 protection against float division of percentage stats
527 - fixes #98 protection against float division of percentage stats
527 - fixed graph bug
528 - fixed graph bug
528 - forced webhelpers version since it was making troubles during installation
529 - forced webhelpers version since it was making troubles during installation
529
530
530 1.1.1 (**2011-01-06**)
531 1.1.1 (**2011-01-06**)
531 ----------------------
532 ----------------------
532
533
533 news
534 news
534 ++++
535 ++++
535
536
536 - added force https option into ini files for easier https usage (no need to
537 - added force https option into ini files for easier https usage (no need to
537 set server headers with this options)
538 set server headers with this options)
538 - small css updates
539 - small css updates
539
540
540 fixes
541 fixes
541 +++++
542 +++++
542
543
543 - fixed #96 redirect loop on files view on repositories without changesets
544 - fixed #96 redirect loop on files view on repositories without changesets
544 - fixed #97 unicode string passed into server header in special cases (mod_wsgi)
545 - fixed #97 unicode string passed into server header in special cases (mod_wsgi)
545 and server crashed with errors
546 and server crashed with errors
546 - fixed large tooltips problems on main page
547 - fixed large tooltips problems on main page
547 - fixed #92 whoosh indexer is more error proof
548 - fixed #92 whoosh indexer is more error proof
548
549
549 1.1.0 (**2010-12-18**)
550 1.1.0 (**2010-12-18**)
550 ----------------------
551 ----------------------
551
552
552 news
553 news
553 ++++
554 ++++
554
555
555 - rewrite of internals for vcs >=0.1.10
556 - rewrite of internals for vcs >=0.1.10
556 - uses mercurial 1.7 with dotencode disabled for maintaining compatibility
557 - uses mercurial 1.7 with dotencode disabled for maintaining compatibility
557 with older clients
558 with older clients
558 - anonymous access, authentication via ldap
559 - anonymous access, authentication via ldap
559 - performance upgrade for cached repos list - each repository has its own
560 - performance upgrade for cached repos list - each repository has its own
560 cache that's invalidated when needed.
561 cache that's invalidated when needed.
561 - performance upgrades on repositories with large amount of commits (20K+)
562 - performance upgrades on repositories with large amount of commits (20K+)
562 - main page quick filter for filtering repositories
563 - main page quick filter for filtering repositories
563 - user dashboards with ability to follow chosen repositories actions
564 - user dashboards with ability to follow chosen repositories actions
564 - sends email to admin on new user registration
565 - sends email to admin on new user registration
565 - added cache/statistics reset options into repository settings
566 - added cache/statistics reset options into repository settings
566 - more detailed action logger (based on hooks) with pushed changesets lists
567 - more detailed action logger (based on hooks) with pushed changesets lists
567 and options to disable those hooks from admin panel
568 and options to disable those hooks from admin panel
568 - introduced new enhanced changelog for merges that shows more accurate results
569 - introduced new enhanced changelog for merges that shows more accurate results
569 - new improved and faster code stats (based on pygments lexers mapping tables,
570 - new improved and faster code stats (based on pygments lexers mapping tables,
570 showing up to 10 trending sources for each repository. Additionally stats
571 showing up to 10 trending sources for each repository. Additionally stats
571 can be disabled in repository settings.
572 can be disabled in repository settings.
572 - gui optimizations, fixed application width to 1024px
573 - gui optimizations, fixed application width to 1024px
573 - added cut off (for large files/changesets) limit into config files
574 - added cut off (for large files/changesets) limit into config files
574 - whoosh, celeryd, upgrade moved to paster command
575 - whoosh, celeryd, upgrade moved to paster command
575 - other than sqlite database backends can be used
576 - other than sqlite database backends can be used
576
577
577 fixes
578 fixes
578 +++++
579 +++++
579
580
580 - fixes #61 forked repo was showing only after cache expired
581 - fixes #61 forked repo was showing only after cache expired
581 - fixes #76 no confirmation on user deletes
582 - fixes #76 no confirmation on user deletes
582 - fixes #66 Name field misspelled
583 - fixes #66 Name field misspelled
583 - fixes #72 block user removal when he owns repositories
584 - fixes #72 block user removal when he owns repositories
584 - fixes #69 added password confirmation fields
585 - fixes #69 added password confirmation fields
585 - fixes #87 RhodeCode crashes occasionally on updating repository owner
586 - fixes #87 RhodeCode crashes occasionally on updating repository owner
586 - fixes #82 broken annotations on files with more than 1 blank line at the end
587 - fixes #82 broken annotations on files with more than 1 blank line at the end
587 - a lot of fixes and tweaks for file browser
588 - a lot of fixes and tweaks for file browser
588 - fixed detached session issues
589 - fixed detached session issues
589 - fixed when user had no repos he would see all repos listed in my account
590 - fixed when user had no repos he would see all repos listed in my account
590 - fixed ui() instance bug when global hgrc settings was loaded for server
591 - fixed ui() instance bug when global hgrc settings was loaded for server
591 instance and all hgrc options were merged with our db ui() object
592 instance and all hgrc options were merged with our db ui() object
592 - numerous small bugfixes
593 - numerous small bugfixes
593
594
594 (special thanks for TkSoh for detailed feedback)
595 (special thanks for TkSoh for detailed feedback)
595
596
596
597
597 1.0.2 (**2010-11-12**)
598 1.0.2 (**2010-11-12**)
598 ----------------------
599 ----------------------
599
600
600 news
601 news
601 ++++
602 ++++
602
603
603 - tested under python2.7
604 - tested under python2.7
604 - bumped sqlalchemy and celery versions
605 - bumped sqlalchemy and celery versions
605
606
606 fixes
607 fixes
607 +++++
608 +++++
608
609
609 - fixed #59 missing graph.js
610 - fixed #59 missing graph.js
610 - fixed repo_size crash when repository had broken symlinks
611 - fixed repo_size crash when repository had broken symlinks
611 - fixed python2.5 crashes.
612 - fixed python2.5 crashes.
612
613
613
614
614 1.0.1 (**2010-11-10**)
615 1.0.1 (**2010-11-10**)
615 ----------------------
616 ----------------------
616
617
617 news
618 news
618 ++++
619 ++++
619
620
620 - small css updated
621 - small css updated
621
622
622 fixes
623 fixes
623 +++++
624 +++++
624
625
625 - fixed #53 python2.5 incompatible enumerate calls
626 - fixed #53 python2.5 incompatible enumerate calls
626 - fixed #52 disable mercurial extension for web
627 - fixed #52 disable mercurial extension for web
627 - fixed #51 deleting repositories don't delete it's dependent objects
628 - fixed #51 deleting repositories don't delete it's dependent objects
628
629
629
630
630 1.0.0 (**2010-11-02**)
631 1.0.0 (**2010-11-02**)
631 ----------------------
632 ----------------------
632
633
633 - security bugfix simplehg wasn't checking for permissions on commands
634 - security bugfix simplehg wasn't checking for permissions on commands
634 other than pull or push.
635 other than pull or push.
635 - fixed doubled messages after push or pull in admin journal
636 - fixed doubled messages after push or pull in admin journal
636 - templating and css corrections, fixed repo switcher on chrome, updated titles
637 - templating and css corrections, fixed repo switcher on chrome, updated titles
637 - admin menu accessible from options menu on repository view
638 - admin menu accessible from options menu on repository view
638 - permissions cached queries
639 - permissions cached queries
639
640
640 1.0.0rc4 (**2010-10-12**)
641 1.0.0rc4 (**2010-10-12**)
641 --------------------------
642 --------------------------
642
643
643 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
644 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
644 - removed cache_manager settings from sqlalchemy meta
645 - removed cache_manager settings from sqlalchemy meta
645 - added sqlalchemy cache settings to ini files
646 - added sqlalchemy cache settings to ini files
646 - validated password length and added second try of failure on paster setup-app
647 - validated password length and added second try of failure on paster setup-app
647 - fixed setup database destroy prompt even when there was no db
648 - fixed setup database destroy prompt even when there was no db
648
649
649
650
650 1.0.0rc3 (**2010-10-11**)
651 1.0.0rc3 (**2010-10-11**)
651 -------------------------
652 -------------------------
652
653
653 - fixed i18n during installation.
654 - fixed i18n during installation.
654
655
655 1.0.0rc2 (**2010-10-11**)
656 1.0.0rc2 (**2010-10-11**)
656 -------------------------
657 -------------------------
657
658
658 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
659 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
659 occure. After vcs is fixed it'll be put back again.
660 occure. After vcs is fixed it'll be put back again.
660 - templating/css rewrites, optimized css. No newline at end of file
661 - templating/css rewrites, optimized css.
@@ -1,460 +1,460 b''
1 import re
1 import re
2 from itertools import chain
2 from itertools import chain
3 from dulwich import objects
3 from dulwich import objects
4 from subprocess import Popen, PIPE
4 from subprocess import Popen, PIPE
5 from rhodecode.lib.vcs.conf import settings
5 from rhodecode.lib.vcs.conf import settings
6 from rhodecode.lib.vcs.exceptions import RepositoryError
6 from rhodecode.lib.vcs.exceptions import RepositoryError
7 from rhodecode.lib.vcs.exceptions import ChangesetError
7 from rhodecode.lib.vcs.exceptions import ChangesetError
8 from rhodecode.lib.vcs.exceptions import NodeDoesNotExistError
8 from rhodecode.lib.vcs.exceptions import NodeDoesNotExistError
9 from rhodecode.lib.vcs.exceptions import VCSError
9 from rhodecode.lib.vcs.exceptions import VCSError
10 from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
10 from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
11 from rhodecode.lib.vcs.exceptions import ImproperArchiveTypeError
11 from rhodecode.lib.vcs.exceptions import ImproperArchiveTypeError
12 from rhodecode.lib.vcs.backends.base import BaseChangeset
12 from rhodecode.lib.vcs.backends.base import BaseChangeset
13 from rhodecode.lib.vcs.nodes import FileNode, DirNode, NodeKind, RootNode, \
13 from rhodecode.lib.vcs.nodes import FileNode, DirNode, NodeKind, RootNode, \
14 RemovedFileNode, SubModuleNode
14 RemovedFileNode, SubModuleNode
15 from rhodecode.lib.vcs.utils import safe_unicode
15 from rhodecode.lib.vcs.utils import safe_unicode
16 from rhodecode.lib.vcs.utils import date_fromtimestamp
16 from rhodecode.lib.vcs.utils import date_fromtimestamp
17 from rhodecode.lib.vcs.utils.lazy import LazyProperty
17 from rhodecode.lib.vcs.utils.lazy import LazyProperty
18
18
19
19
20 class GitChangeset(BaseChangeset):
20 class GitChangeset(BaseChangeset):
21 """
21 """
22 Represents state of the repository at single revision.
22 Represents state of the repository at single revision.
23 """
23 """
24
24
25 def __init__(self, repository, revision):
25 def __init__(self, repository, revision):
26 self._stat_modes = {}
26 self._stat_modes = {}
27 self.repository = repository
27 self.repository = repository
28 self.raw_id = revision
28 self.raw_id = revision
29 self.revision = repository.revisions.index(revision)
29 self.revision = repository.revisions.index(revision)
30
30
31 self.short_id = self.raw_id[:12]
31 self.short_id = self.raw_id[:12]
32 self.id = self.raw_id
32 self.id = self.raw_id
33 try:
33 try:
34 commit = self.repository._repo.get_object(self.raw_id)
34 commit = self.repository._repo.get_object(self.raw_id)
35 except KeyError:
35 except KeyError:
36 raise RepositoryError("Cannot get object with id %s" % self.raw_id)
36 raise RepositoryError("Cannot get object with id %s" % self.raw_id)
37 self._commit = commit
37 self._commit = commit
38 self._tree_id = commit.tree
38 self._tree_id = commit.tree
39
39
40 try:
40 try:
41 self.message = safe_unicode(commit.message[:-1])
41 self.message = safe_unicode(commit.message[:-1])
42 # Always strip last eol
42 # Always strip last eol
43 except UnicodeDecodeError:
43 except UnicodeDecodeError:
44 self.message = commit.message[:-1].decode(commit.encoding
44 self.message = commit.message[:-1].decode(commit.encoding
45 or 'utf-8')
45 or 'utf-8')
46 #self.branch = None
46 #self.branch = None
47 self.tags = []
47 self.tags = []
48 #tree = self.repository.get_object(self._tree_id)
48 #tree = self.repository.get_object(self._tree_id)
49 self.nodes = {}
49 self.nodes = {}
50 self._paths = {}
50 self._paths = {}
51
51
52 @LazyProperty
52 @LazyProperty
53 def author(self):
53 def author(self):
54 return safe_unicode(self._commit.committer)
54 return safe_unicode(self._commit.committer)
55
55
56 @LazyProperty
56 @LazyProperty
57 def date(self):
57 def date(self):
58 return date_fromtimestamp(self._commit.commit_time,
58 return date_fromtimestamp(self._commit.commit_time,
59 self._commit.commit_timezone)
59 self._commit.commit_timezone)
60
60
61 @LazyProperty
61 @LazyProperty
62 def status(self):
62 def status(self):
63 """
63 """
64 Returns modified, added, removed, deleted files for current changeset
64 Returns modified, added, removed, deleted files for current changeset
65 """
65 """
66 return self.changed, self.added, self.removed
66 return self.changed, self.added, self.removed
67
67
68 @LazyProperty
68 @LazyProperty
69 def branch(self):
69 def branch(self):
70
70
71 heads = self.repository._heads(reverse=False)
71 heads = self.repository._heads(reverse=False)
72
72
73 ref = heads.get(self.raw_id)
73 ref = heads.get(self.raw_id)
74 if ref:
74 if ref:
75 return safe_unicode(ref)
75 return safe_unicode(ref)
76
76
77 def _fix_path(self, path):
77 def _fix_path(self, path):
78 """
78 """
79 Paths are stored without trailing slash so we need to get rid off it if
79 Paths are stored without trailing slash so we need to get rid off it if
80 needed.
80 needed.
81 """
81 """
82 if path.endswith('/'):
82 if path.endswith('/'):
83 path = path.rstrip('/')
83 path = path.rstrip('/')
84 return path
84 return path
85
85
86 def _get_id_for_path(self, path):
86 def _get_id_for_path(self, path):
87
87
88 # FIXME: Please, spare a couple of minutes and make those codes cleaner;
88 # FIXME: Please, spare a couple of minutes and make those codes cleaner;
89 if not path in self._paths:
89 if not path in self._paths:
90 path = path.strip('/')
90 path = path.strip('/')
91 # set root tree
91 # set root tree
92 tree = self.repository._repo[self._commit.tree]
92 tree = self.repository._repo[self._commit.tree]
93 if path == '':
93 if path == '':
94 self._paths[''] = tree.id
94 self._paths[''] = tree.id
95 return tree.id
95 return tree.id
96 splitted = path.split('/')
96 splitted = path.split('/')
97 dirs, name = splitted[:-1], splitted[-1]
97 dirs, name = splitted[:-1], splitted[-1]
98 curdir = ''
98 curdir = ''
99
99
100 # initially extract things from root dir
100 # initially extract things from root dir
101 for item, stat, id in tree.iteritems():
101 for item, stat, id in tree.iteritems():
102 if curdir:
102 if curdir:
103 name = '/'.join((curdir, item))
103 name = '/'.join((curdir, item))
104 else:
104 else:
105 name = item
105 name = item
106 self._paths[name] = id
106 self._paths[name] = id
107 self._stat_modes[name] = stat
107 self._stat_modes[name] = stat
108
108
109 for dir in dirs:
109 for dir in dirs:
110 if curdir:
110 if curdir:
111 curdir = '/'.join((curdir, dir))
111 curdir = '/'.join((curdir, dir))
112 else:
112 else:
113 curdir = dir
113 curdir = dir
114 dir_id = None
114 dir_id = None
115 for item, stat, id in tree.iteritems():
115 for item, stat, id in tree.iteritems():
116 if dir == item:
116 if dir == item:
117 dir_id = id
117 dir_id = id
118 if dir_id:
118 if dir_id:
119 # Update tree
119 # Update tree
120 tree = self.repository._repo[dir_id]
120 tree = self.repository._repo[dir_id]
121 if not isinstance(tree, objects.Tree):
121 if not isinstance(tree, objects.Tree):
122 raise ChangesetError('%s is not a directory' % curdir)
122 raise ChangesetError('%s is not a directory' % curdir)
123 else:
123 else:
124 raise ChangesetError('%s have not been found' % curdir)
124 raise ChangesetError('%s have not been found' % curdir)
125
125
126 # cache all items from the given traversed tree
126 # cache all items from the given traversed tree
127 for item, stat, id in tree.iteritems():
127 for item, stat, id in tree.iteritems():
128 if curdir:
128 if curdir:
129 name = '/'.join((curdir, item))
129 name = '/'.join((curdir, item))
130 else:
130 else:
131 name = item
131 name = item
132 self._paths[name] = id
132 self._paths[name] = id
133 self._stat_modes[name] = stat
133 self._stat_modes[name] = stat
134 if not path in self._paths:
134 if not path in self._paths:
135 raise NodeDoesNotExistError("There is no file nor directory "
135 raise NodeDoesNotExistError("There is no file nor directory "
136 "at the given path %r at revision %r"
136 "at the given path %r at revision %r"
137 % (path, self.short_id))
137 % (path, self.short_id))
138 return self._paths[path]
138 return self._paths[path]
139
139
140 def _get_kind(self, path):
140 def _get_kind(self, path):
141 id = self._get_id_for_path(path)
141 id = self._get_id_for_path(path)
142 obj = self.repository._repo[id]
142 obj = self.repository._repo[id]
143 if isinstance(obj, objects.Blob):
143 if isinstance(obj, objects.Blob):
144 return NodeKind.FILE
144 return NodeKind.FILE
145 elif isinstance(obj, objects.Tree):
145 elif isinstance(obj, objects.Tree):
146 return NodeKind.DIR
146 return NodeKind.DIR
147
147
148 def _get_file_nodes(self):
148 def _get_file_nodes(self):
149 return chain(*(t[2] for t in self.walk()))
149 return chain(*(t[2] for t in self.walk()))
150
150
151 @LazyProperty
151 @LazyProperty
152 def parents(self):
152 def parents(self):
153 """
153 """
154 Returns list of parents changesets.
154 Returns list of parents changesets.
155 """
155 """
156 return [self.repository.get_changeset(parent)
156 return [self.repository.get_changeset(parent)
157 for parent in self._commit.parents]
157 for parent in self._commit.parents]
158
158
159 def next(self, branch=None):
159 def next(self, branch=None):
160
160
161 if branch and self.branch != branch:
161 if branch and self.branch != branch:
162 raise VCSError('Branch option used on changeset not belonging '
162 raise VCSError('Branch option used on changeset not belonging '
163 'to that branch')
163 'to that branch')
164
164
165 def _next(changeset, branch):
165 def _next(changeset, branch):
166 try:
166 try:
167 next_ = changeset.revision + 1
167 next_ = changeset.revision + 1
168 next_rev = changeset.repository.revisions[next_]
168 next_rev = changeset.repository.revisions[next_]
169 except IndexError:
169 except IndexError:
170 raise ChangesetDoesNotExistError
170 raise ChangesetDoesNotExistError
171 cs = changeset.repository.get_changeset(next_rev)
171 cs = changeset.repository.get_changeset(next_rev)
172
172
173 if branch and branch != cs.branch:
173 if branch and branch != cs.branch:
174 return _next(cs, branch)
174 return _next(cs, branch)
175
175
176 return cs
176 return cs
177
177
178 return _next(self, branch)
178 return _next(self, branch)
179
179
180 def prev(self, branch=None):
180 def prev(self, branch=None):
181 if branch and self.branch != branch:
181 if branch and self.branch != branch:
182 raise VCSError('Branch option used on changeset not belonging '
182 raise VCSError('Branch option used on changeset not belonging '
183 'to that branch')
183 'to that branch')
184
184
185 def _prev(changeset, branch):
185 def _prev(changeset, branch):
186 try:
186 try:
187 prev_ = changeset.revision - 1
187 prev_ = changeset.revision - 1
188 if prev_ < 0:
188 if prev_ < 0:
189 raise IndexError
189 raise IndexError
190 prev_rev = changeset.repository.revisions[prev_]
190 prev_rev = changeset.repository.revisions[prev_]
191 except IndexError:
191 except IndexError:
192 raise ChangesetDoesNotExistError
192 raise ChangesetDoesNotExistError
193
193
194 cs = changeset.repository.get_changeset(prev_rev)
194 cs = changeset.repository.get_changeset(prev_rev)
195
195
196 if branch and branch != cs.branch:
196 if branch and branch != cs.branch:
197 return _prev(cs, branch)
197 return _prev(cs, branch)
198
198
199 return cs
199 return cs
200
200
201 return _prev(self, branch)
201 return _prev(self, branch)
202
202
203 def get_file_mode(self, path):
203 def get_file_mode(self, path):
204 """
204 """
205 Returns stat mode of the file at the given ``path``.
205 Returns stat mode of the file at the given ``path``.
206 """
206 """
207 # ensure path is traversed
207 # ensure path is traversed
208 self._get_id_for_path(path)
208 self._get_id_for_path(path)
209 return self._stat_modes[path]
209 return self._stat_modes[path]
210
210
211 def get_file_content(self, path):
211 def get_file_content(self, path):
212 """
212 """
213 Returns content of the file at given ``path``.
213 Returns content of the file at given ``path``.
214 """
214 """
215 id = self._get_id_for_path(path)
215 id = self._get_id_for_path(path)
216 blob = self.repository._repo[id]
216 blob = self.repository._repo[id]
217 return blob.as_pretty_string()
217 return blob.as_pretty_string()
218
218
219 def get_file_size(self, path):
219 def get_file_size(self, path):
220 """
220 """
221 Returns size of the file at given ``path``.
221 Returns size of the file at given ``path``.
222 """
222 """
223 id = self._get_id_for_path(path)
223 id = self._get_id_for_path(path)
224 blob = self.repository._repo[id]
224 blob = self.repository._repo[id]
225 return blob.raw_length()
225 return blob.raw_length()
226
226
227 def get_file_changeset(self, path):
227 def get_file_changeset(self, path):
228 """
228 """
229 Returns last commit of the file at the given ``path``.
229 Returns last commit of the file at the given ``path``.
230 """
230 """
231 node = self.get_node(path)
231 node = self.get_node(path)
232 return node.history[0]
232 return node.history[0]
233
233
234 def get_file_history(self, path):
234 def get_file_history(self, path):
235 """
235 """
236 Returns history of file as reversed list of ``Changeset`` objects for
236 Returns history of file as reversed list of ``Changeset`` objects for
237 which file at given ``path`` has been modified.
237 which file at given ``path`` has been modified.
238
238
239 TODO: This function now uses os underlying 'git' and 'grep' commands
239 TODO: This function now uses os underlying 'git' and 'grep' commands
240 which is generally not good. Should be replaced with algorithm
240 which is generally not good. Should be replaced with algorithm
241 iterating commits.
241 iterating commits.
242 """
242 """
243 cmd = 'log --pretty="format: %%H" --name-status -p %s -- "%s"' % (
243 cmd = 'log --pretty="format: --%%H--" --name-status -p %s -- "%s"' % (
244 self.id, path
244 self.id, path
245 )
245 )
246 so, se = self.repository.run_git_command(cmd)
246 so, se = self.repository.run_git_command(cmd)
247 ids = re.findall(r'\w{40}', so)
247 ids = re.findall(r'(?:--)(\w{40})(?:--)', so)
248 return [self.repository.get_changeset(id) for id in ids]
248 return [self.repository.get_changeset(id) for id in ids]
249
249
250 def get_file_annotate(self, path):
250 def get_file_annotate(self, path):
251 """
251 """
252 Returns a list of three element tuples with lineno,changeset and line
252 Returns a list of three element tuples with lineno,changeset and line
253
253
254 TODO: This function now uses os underlying 'git' command which is
254 TODO: This function now uses os underlying 'git' command which is
255 generally not good. Should be replaced with algorithm iterating
255 generally not good. Should be replaced with algorithm iterating
256 commits.
256 commits.
257 """
257 """
258 cmd = 'blame -l --root -r %s -- "%s"' % (self.id, path)
258 cmd = 'blame -l --root -r %s -- "%s"' % (self.id, path)
259 # -l ==> outputs long shas (and we need all 40 characters)
259 # -l ==> outputs long shas (and we need all 40 characters)
260 # --root ==> doesn't put '^' character for bounderies
260 # --root ==> doesn't put '^' character for bounderies
261 # -r sha ==> blames for the given revision
261 # -r sha ==> blames for the given revision
262 so, se = self.repository.run_git_command(cmd)
262 so, se = self.repository.run_git_command(cmd)
263 annotate = []
263 annotate = []
264 for i, blame_line in enumerate(so.split('\n')[:-1]):
264 for i, blame_line in enumerate(so.split('\n')[:-1]):
265 ln_no = i + 1
265 ln_no = i + 1
266 id, line = re.split(r' \(.+?\) ', blame_line, 1)
266 id, line = re.split(r' \(.+?\) ', blame_line, 1)
267 annotate.append((ln_no, self.repository.get_changeset(id), line))
267 annotate.append((ln_no, self.repository.get_changeset(id), line))
268 return annotate
268 return annotate
269
269
270 def fill_archive(self, stream=None, kind='tgz', prefix=None,
270 def fill_archive(self, stream=None, kind='tgz', prefix=None,
271 subrepos=False):
271 subrepos=False):
272 """
272 """
273 Fills up given stream.
273 Fills up given stream.
274
274
275 :param stream: file like object.
275 :param stream: file like object.
276 :param kind: one of following: ``zip``, ``tgz`` or ``tbz2``.
276 :param kind: one of following: ``zip``, ``tgz`` or ``tbz2``.
277 Default: ``tgz``.
277 Default: ``tgz``.
278 :param prefix: name of root directory in archive.
278 :param prefix: name of root directory in archive.
279 Default is repository name and changeset's raw_id joined with dash
279 Default is repository name and changeset's raw_id joined with dash
280 (``repo-tip.<KIND>``).
280 (``repo-tip.<KIND>``).
281 :param subrepos: include subrepos in this archive.
281 :param subrepos: include subrepos in this archive.
282
282
283 :raise ImproperArchiveTypeError: If given kind is wrong.
283 :raise ImproperArchiveTypeError: If given kind is wrong.
284 :raise VcsError: If given stream is None
284 :raise VcsError: If given stream is None
285
285
286 """
286 """
287 allowed_kinds = settings.ARCHIVE_SPECS.keys()
287 allowed_kinds = settings.ARCHIVE_SPECS.keys()
288 if kind not in allowed_kinds:
288 if kind not in allowed_kinds:
289 raise ImproperArchiveTypeError('Archive kind not supported use one'
289 raise ImproperArchiveTypeError('Archive kind not supported use one'
290 'of %s', allowed_kinds)
290 'of %s', allowed_kinds)
291
291
292 if prefix is None:
292 if prefix is None:
293 prefix = '%s-%s' % (self.repository.name, self.short_id)
293 prefix = '%s-%s' % (self.repository.name, self.short_id)
294 elif prefix.startswith('/'):
294 elif prefix.startswith('/'):
295 raise VCSError("Prefix cannot start with leading slash")
295 raise VCSError("Prefix cannot start with leading slash")
296 elif prefix.strip() == '':
296 elif prefix.strip() == '':
297 raise VCSError("Prefix cannot be empty")
297 raise VCSError("Prefix cannot be empty")
298
298
299 if kind == 'zip':
299 if kind == 'zip':
300 frmt = 'zip'
300 frmt = 'zip'
301 else:
301 else:
302 frmt = 'tar'
302 frmt = 'tar'
303 cmd = 'git archive --format=%s --prefix=%s/ %s' % (frmt, prefix,
303 cmd = 'git archive --format=%s --prefix=%s/ %s' % (frmt, prefix,
304 self.raw_id)
304 self.raw_id)
305 if kind == 'tgz':
305 if kind == 'tgz':
306 cmd += ' | gzip -9'
306 cmd += ' | gzip -9'
307 elif kind == 'tbz2':
307 elif kind == 'tbz2':
308 cmd += ' | bzip2 -9'
308 cmd += ' | bzip2 -9'
309
309
310 if stream is None:
310 if stream is None:
311 raise VCSError('You need to pass in a valid stream for filling'
311 raise VCSError('You need to pass in a valid stream for filling'
312 ' with archival data')
312 ' with archival data')
313 popen = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True,
313 popen = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True,
314 cwd=self.repository.path)
314 cwd=self.repository.path)
315
315
316 buffer_size = 1024 * 8
316 buffer_size = 1024 * 8
317 chunk = popen.stdout.read(buffer_size)
317 chunk = popen.stdout.read(buffer_size)
318 while chunk:
318 while chunk:
319 stream.write(chunk)
319 stream.write(chunk)
320 chunk = popen.stdout.read(buffer_size)
320 chunk = popen.stdout.read(buffer_size)
321 # Make sure all descriptors would be read
321 # Make sure all descriptors would be read
322 popen.communicate()
322 popen.communicate()
323
323
324 def get_nodes(self, path):
324 def get_nodes(self, path):
325 if self._get_kind(path) != NodeKind.DIR:
325 if self._get_kind(path) != NodeKind.DIR:
326 raise ChangesetError("Directory does not exist for revision %r at "
326 raise ChangesetError("Directory does not exist for revision %r at "
327 " %r" % (self.revision, path))
327 " %r" % (self.revision, path))
328 path = self._fix_path(path)
328 path = self._fix_path(path)
329 id = self._get_id_for_path(path)
329 id = self._get_id_for_path(path)
330 tree = self.repository._repo[id]
330 tree = self.repository._repo[id]
331 dirnodes = []
331 dirnodes = []
332 filenodes = []
332 filenodes = []
333 als = self.repository.alias
333 als = self.repository.alias
334 for name, stat, id in tree.iteritems():
334 for name, stat, id in tree.iteritems():
335 if objects.S_ISGITLINK(stat):
335 if objects.S_ISGITLINK(stat):
336 dirnodes.append(SubModuleNode(name, url=None, changeset=id,
336 dirnodes.append(SubModuleNode(name, url=None, changeset=id,
337 alias=als))
337 alias=als))
338 continue
338 continue
339
339
340 obj = self.repository._repo.get_object(id)
340 obj = self.repository._repo.get_object(id)
341 if path != '':
341 if path != '':
342 obj_path = '/'.join((path, name))
342 obj_path = '/'.join((path, name))
343 else:
343 else:
344 obj_path = name
344 obj_path = name
345 if obj_path not in self._stat_modes:
345 if obj_path not in self._stat_modes:
346 self._stat_modes[obj_path] = stat
346 self._stat_modes[obj_path] = stat
347 if isinstance(obj, objects.Tree):
347 if isinstance(obj, objects.Tree):
348 dirnodes.append(DirNode(obj_path, changeset=self))
348 dirnodes.append(DirNode(obj_path, changeset=self))
349 elif isinstance(obj, objects.Blob):
349 elif isinstance(obj, objects.Blob):
350 filenodes.append(FileNode(obj_path, changeset=self, mode=stat))
350 filenodes.append(FileNode(obj_path, changeset=self, mode=stat))
351 else:
351 else:
352 raise ChangesetError("Requested object should be Tree "
352 raise ChangesetError("Requested object should be Tree "
353 "or Blob, is %r" % type(obj))
353 "or Blob, is %r" % type(obj))
354 nodes = dirnodes + filenodes
354 nodes = dirnodes + filenodes
355 for node in nodes:
355 for node in nodes:
356 if not node.path in self.nodes:
356 if not node.path in self.nodes:
357 self.nodes[node.path] = node
357 self.nodes[node.path] = node
358 nodes.sort()
358 nodes.sort()
359 return nodes
359 return nodes
360
360
361 def get_node(self, path):
361 def get_node(self, path):
362 if isinstance(path, unicode):
362 if isinstance(path, unicode):
363 path = path.encode('utf-8')
363 path = path.encode('utf-8')
364 path = self._fix_path(path)
364 path = self._fix_path(path)
365 if not path in self.nodes:
365 if not path in self.nodes:
366 try:
366 try:
367 id_ = self._get_id_for_path(path)
367 id_ = self._get_id_for_path(path)
368 except ChangesetError:
368 except ChangesetError:
369 raise NodeDoesNotExistError("Cannot find one of parents' "
369 raise NodeDoesNotExistError("Cannot find one of parents' "
370 "directories for a given path: %s" % path)
370 "directories for a given path: %s" % path)
371
371
372 als = self.repository.alias
372 als = self.repository.alias
373 _GL = lambda m: m and objects.S_ISGITLINK(m)
373 _GL = lambda m: m and objects.S_ISGITLINK(m)
374 if _GL(self._stat_modes.get(path)):
374 if _GL(self._stat_modes.get(path)):
375 node = SubModuleNode(path, url=None, changeset=id_, alias=als)
375 node = SubModuleNode(path, url=None, changeset=id_, alias=als)
376 else:
376 else:
377 obj = self.repository._repo.get_object(id_)
377 obj = self.repository._repo.get_object(id_)
378
378
379 if isinstance(obj, objects.Tree):
379 if isinstance(obj, objects.Tree):
380 if path == '':
380 if path == '':
381 node = RootNode(changeset=self)
381 node = RootNode(changeset=self)
382 else:
382 else:
383 node = DirNode(path, changeset=self)
383 node = DirNode(path, changeset=self)
384 node._tree = obj
384 node._tree = obj
385 elif isinstance(obj, objects.Blob):
385 elif isinstance(obj, objects.Blob):
386 node = FileNode(path, changeset=self)
386 node = FileNode(path, changeset=self)
387 node._blob = obj
387 node._blob = obj
388 else:
388 else:
389 raise NodeDoesNotExistError("There is no file nor directory "
389 raise NodeDoesNotExistError("There is no file nor directory "
390 "at the given path %r at revision %r"
390 "at the given path %r at revision %r"
391 % (path, self.short_id))
391 % (path, self.short_id))
392 # cache node
392 # cache node
393 self.nodes[path] = node
393 self.nodes[path] = node
394 return self.nodes[path]
394 return self.nodes[path]
395
395
396 @LazyProperty
396 @LazyProperty
397 def affected_files(self):
397 def affected_files(self):
398 """
398 """
399 Get's a fast accessible file changes for given changeset
399 Get's a fast accessible file changes for given changeset
400 """
400 """
401
401
402 return self.added + self.changed
402 return self.added + self.changed
403
403
404 @LazyProperty
404 @LazyProperty
405 def _diff_name_status(self):
405 def _diff_name_status(self):
406 output = []
406 output = []
407 for parent in self.parents:
407 for parent in self.parents:
408 cmd = 'diff --name-status %s %s --encoding=utf8' % (parent.raw_id, self.raw_id)
408 cmd = 'diff --name-status %s %s --encoding=utf8' % (parent.raw_id, self.raw_id)
409 so, se = self.repository.run_git_command(cmd)
409 so, se = self.repository.run_git_command(cmd)
410 output.append(so.strip())
410 output.append(so.strip())
411 return '\n'.join(output)
411 return '\n'.join(output)
412
412
413 def _get_paths_for_status(self, status):
413 def _get_paths_for_status(self, status):
414 """
414 """
415 Returns sorted list of paths for given ``status``.
415 Returns sorted list of paths for given ``status``.
416
416
417 :param status: one of: *added*, *modified* or *deleted*
417 :param status: one of: *added*, *modified* or *deleted*
418 """
418 """
419 paths = set()
419 paths = set()
420 char = status[0].upper()
420 char = status[0].upper()
421 for line in self._diff_name_status.splitlines():
421 for line in self._diff_name_status.splitlines():
422 if not line:
422 if not line:
423 continue
423 continue
424
424
425 if line.startswith(char):
425 if line.startswith(char):
426 splitted = line.split(char, 1)
426 splitted = line.split(char, 1)
427 if not len(splitted) == 2:
427 if not len(splitted) == 2:
428 raise VCSError("Couldn't parse diff result:\n%s\n\n and "
428 raise VCSError("Couldn't parse diff result:\n%s\n\n and "
429 "particularly that line: %s" % (self._diff_name_status,
429 "particularly that line: %s" % (self._diff_name_status,
430 line))
430 line))
431 _path = splitted[1].strip()
431 _path = splitted[1].strip()
432 paths.add(_path)
432 paths.add(_path)
433 return sorted(paths)
433 return sorted(paths)
434
434
435 @LazyProperty
435 @LazyProperty
436 def added(self):
436 def added(self):
437 """
437 """
438 Returns list of added ``FileNode`` objects.
438 Returns list of added ``FileNode`` objects.
439 """
439 """
440 if not self.parents:
440 if not self.parents:
441 return list(self._get_file_nodes())
441 return list(self._get_file_nodes())
442 return [self.get_node(path) for path in self._get_paths_for_status('added')]
442 return [self.get_node(path) for path in self._get_paths_for_status('added')]
443
443
444 @LazyProperty
444 @LazyProperty
445 def changed(self):
445 def changed(self):
446 """
446 """
447 Returns list of modified ``FileNode`` objects.
447 Returns list of modified ``FileNode`` objects.
448 """
448 """
449 if not self.parents:
449 if not self.parents:
450 return []
450 return []
451 return [self.get_node(path) for path in self._get_paths_for_status('modified')]
451 return [self.get_node(path) for path in self._get_paths_for_status('modified')]
452
452
453 @LazyProperty
453 @LazyProperty
454 def removed(self):
454 def removed(self):
455 """
455 """
456 Returns list of removed ``FileNode`` objects.
456 Returns list of removed ``FileNode`` objects.
457 """
457 """
458 if not self.parents:
458 if not self.parents:
459 return []
459 return []
460 return [RemovedFileNode(path) for path in self._get_paths_for_status('deleted')]
460 return [RemovedFileNode(path) for path in self._get_paths_for_status('deleted')]
General Comments 0
You need to be logged in to leave comments. Login now