Changeset - 4839bc1d89fa
[Not reviewed]
beta
0 2 0
Marcin Kuzminski - 13 years ago 2013-04-07 19:09:52
marcin@python-works.com
small fixes backported from stable
2 files changed with 3 insertions and 3 deletions:
0 comments (0 inline, 0 general)
docs/usage/general.rst
Show inline comments
 
.. _general:
 

	
 
=======================
 
General RhodeCode usage
 
=======================
 

	
 

	
 
Repository deleting
 
-------------------
 

	
 
Currently when admin/owner deletes a repository, RhodeCode does not physically
 
delete a repository from filesystem, it renames it in a special way so it's
 
not possible to push,clone or access repository. It's worth a notice that,
 
even if someone will be given administrative access to RhodeCode and will
 
delete a repository You can easy restore such action by restoring `rm__<date>`
 
from the repository name, and internal repository storage (.hg/.git). There
 
is also a special command for cleaning such archived repos::
 

	
 
    paster cleanup-repos --older-than=30d production.ini
 

	
 
This command will scan for archived repositories that are older than 30d,
 
display them and ask if you want to delete them (there's a --dont-ask flag also)
 
If you host big amount of repositories with forks that are constantly deleted
 
it's recommended that you run such command via crontab.
 

	
 
Follow current branch in file view
 
----------------------------------
 

	
 
In file view when this checkbox is checked the << and >> arrows will jump
 
to changesets within the same branch currently viewing. So for example
 
if someone is viewing files at 'beta' branch and marks `follow current branch`
 
checkbox the << and >> buttons will only show him revisions for 'beta' branch
 

	
 

	
 
Compare view from changelog
 
---------------------------
 

	
 
Checkboxes in compare view allow users to view combined compare view. You can
 
only show the range between the first and last checkbox (no cherry pick).
 
Clicking more than one checkbox will activate a link in top saying
 
`Show selected changesets <from-rev> -> <to-rev>` clicking this will bring
 
compare view. In this view also it's possible to switch to combined compare.
 

	
 
Compare view is also available from the journal on pushes having more than
 
one changeset
 

	
 

	
 
Non changeable repository urls
 
------------------------------
 

	
 
Due to complicated nature of repository grouping, often urls of repositories
 
can change.
 

	
 
example::
 

	
 
  #before
 
  http://server.com/repo_name
 
  # after insertion to test_group group the url will be
 
  http://server.com/test_group/repo_name
 

	
 
This can be an issue for build systems and any other hardcoded scripts, moving
 
repository to a group leads to a need for changing external systems. To
 
overcome this RhodeCode introduces a non changable replacement url. It's
 
simply an repository ID prefixed with `_` above urls are also accessible as::
 

	
 
  http://server.com/_<ID>
 

	
 
Since ID are always the same moving the repository will not affect such url.
 
the _<ID> syntax can be used anywhere in the system so urls with repo_name
 
for changelogs, files and other can be exchanged with _<ID> syntax.
 

	
 

	
 
Mailing
 
-------
 

	
 
When administrator will fill up the mailing settings in .ini files
 
RhodeCode will send mails on user registration, or when RhodeCode errors occur
 
on errors the mails will have a detailed traceback of error.
 

	
 

	
 
Mails are also sent for code comments. If someone comments on a changeset
 
mail is sent to all participants, the person who commited the changeset
 
(if present in RhodeCode), and to all people mentioned with @mention system.
 

	
 

	
 
Trending source files
 
---------------------
 

	
 
Trending source files are calculated based on pre defined dict of known
 
types and extensions. If You miss some extension or Would like to scan some
 
custom files it's possible to add new types in `LANGUAGES_EXTENSIONS_MAP` dict
 
located in `/rhodecode/lib/celerylib/tasks.py`
 

	
 

	
 
Cloning remote repositories
 
---------------------------
 

	
 
RhodeCode has an ability to clone remote repos from given remote locations.
 
Currently it support following options:
 

	
 
- hg  -> hg clone
 
- svn -> hg clone
 
- git -> git clone
 

	
 

	
 
.. note::
 

	
 
    - *`svn -> hg` cloning requires `hgsubversion` library to be installed.*
 

	
 
If you need to clone repositories that are protected via basic auth, you
 
might pass the url with stored credentials inside eg.
 
`http://user:passw@remote.server/repo, RhodeCode will try to login and clone
 
`http://user:passw@remote.server/repo`, RhodeCode will try to login and clone
 
using given credentials. Please take a note that they will be stored as
 
plaintext inside the database. RhodeCode will remove auth info when showing the
 
clone url in summary page.
rhodecode/lib/paster_commands/cleanup.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    rhodecode.lib.paster_commands.make_rcextensions
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
    rhodecode.lib.paster_commands.cleanup
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    cleanup-repos paster command for RhodeCode
 

	
 

	
 
    :created_on: Jul 14, 2012
 
    :author: marcink
 
    :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
 
    :license: GPLv3, see COPYING for more details.
 
"""
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
from __future__ import with_statement
 

	
 
import os
 
import sys
 
import re
 
import shutil
 
import logging
 
import datetime
 

	
 
from os.path import dirname as dn, join as jn
 
#to get the rhodecode import
 
rc_path = dn(dn(dn(os.path.realpath(__file__))))
 
sys.path.append(rc_path)
 
from rhodecode.lib.utils import BasePasterCommand, ask_ok, REMOVED_REPO_PAT
 

	
 
from rhodecode.lib.utils2 import safe_str
 
from rhodecode.model.db import RhodeCodeUi
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class Command(BasePasterCommand):
 

	
 
    max_args = 1
 
    min_args = 1
 

	
 
    usage = "CONFIG_FILE"
 
    group_name = "RhodeCode"
 
    takes_config_file = -1
 
    parser = BasePasterCommand.standard_parser(verbose=True)
 
    summary = "Cleanup deleted repos"
 

	
 
    def _parse_older_than(self, val):
 
        regex = re.compile(r'((?P<days>\d+?)d)?((?P<hours>\d+?)h)?((?P<minutes>\d+?)m)?((?P<seconds>\d+?)s)?')
 
        parts = regex.match(val)
 
        if not parts:
 
            return
 
        parts = parts.groupdict()
 
        time_params = {}
 
        for (name, param) in parts.iteritems():
 
            if param:
 
                time_params[name] = int(param)
 
        return datetime.timedelta(**time_params)
 

	
 
    def _extract_date(self, name):
 
        """
 
        Extract the date part from rm__<date> pattern of removed repos,
 
        and convert it to datetime object
 

	
 
        :param name:
 
        """
 
        date_part = name[4:19]  # 4:19 since we don't parse milisecods
 
        return datetime.datetime.strptime(date_part, '%Y%m%d_%H%M%S')
 

	
 
    def command(self):
 
        #get SqlAlchemy session
 
        self._init_session()
 

	
 
        repos_location = RhodeCodeUi.get_repos_location()
 
        to_remove = []
 
        for dn, dirs, f in os.walk(safe_str(repos_location)):
 
            alldirs = list(dirs)
 
            del dirs[:]
 
            if ('.hg' in alldirs or
 
                'objects' in alldirs and ('refs' in alldirs or 'packed-refs' in f)):
 
                continue
 
            for loc in alldirs:
 
                if REMOVED_REPO_PAT.match(loc):
 
                    to_remove.append([os.path.join(dn, loc),
 
                                      self._extract_date(loc)])
 
                else:
 
                    dirs.append(loc)
 

	
 
        #filter older than (if present)!
 
        now = datetime.datetime.now()
 
        older_than = self.options.older_than
 
        if older_than:
 
            to_remove_filtered = []
 
            older_than_date = self._parse_older_than(older_than)
 
            for name, date_ in to_remove:
 
                repo_age = now - date_
 
                if repo_age > older_than_date:
 
                    to_remove_filtered.append([name, date_])
 

	
 
            to_remove = to_remove_filtered
 
            print >> sys.stdout, 'removing %s deleted repos older than %s (%s)' \
 
                % (len(to_remove), older_than, older_than_date)
 
        else:
 
            print >> sys.stdout, 'removing all [%s] deleted repos' \
 
                % len(to_remove)
 
        if self.options.dont_ask or not to_remove:
 
            # don't ask just remove !
 
            remove = True
 
        else:
 
            remove = ask_ok('the following repositories will be deleted completely:\n%s\n'
 
                            'are you sure you want to remove them [y/n]?'
 
                            % ', \n'.join(['%s removed on %s'
 
                    % (safe_str(x[0]), safe_str(x[1])) for x in to_remove]))
 

	
 
        if remove:
 
            for path, date_ in to_remove:
 
                print >> sys.stdout, 'removing repository %s' % path
 
                shutil.rmtree(path)
 
        else:
 
            print 'nothing done exiting...'
 
            sys.exit(0)
 

	
 
    def update_parser(self):
 
        self.parser.add_option(
 
            '--older-than',
 
            action='store',
 
            dest='older_than',
 
            help=("only remove repos that have been removed "
 
                 "at least given time ago. "
 
                 "The default is to remove all removed repositories. "
 
                 "Possible suffixes: "
 
                 "d (days), h (hours), m (minutes), s (seconds). "
 
                 "For example --older-than=30d deletes repositories "
 
                 "removed more than 30 days ago.")
 
            )
 

	
 
        self.parser.add_option(
 
            '--dont-ask',
 
            action="store_true",
 
            dest="dont_ask",
 
            help="remove repositories without asking for confirmation."
 
        )
0 comments (0 inline, 0 general)