diff --git a/bin/is b/bin/is
index 286eec57cb4723a1caad6257f594432a5c2ebd3b..9c88288cdf4c02f3c84e640b7f4fe534bb7699d4 100755
--- a/bin/is
+++ b/bin/is
@@ -24,7 +24,7 @@ from installsystems.repository import RepositoryConfig
 from installsystems.image import PackageImage, SourceImage
 from installsystems.config import MainConfigFile, RepoConfigFile
 
-def load_repositories(args):
+def load_repositories(args, force_offline=False):
     '''
     Load repositories on a repository manager
     '''
@@ -37,10 +37,10 @@ def load_repositories(args):
     # load repo configs from command line
     if args.repo_path is not None:
         repoman.register(RepositoryConfig(istools.smd5sum(args.repo_path)[:8],
-                                          path=args.repo_path), temp=True)
+                                          path=args.repo_path), temp=True, offline=force_offline)
     # load repo configs from config
     for repoconf in RepoConfigFile(args.repo_config).repos:
-        repoman.register(repoconf)
+        repoman.register(repoconf, offline=force_offline)
     return repoman
 
 def select_image(name, repoman, best=False):
@@ -255,7 +255,7 @@ def c_list(parser, args):
     repoman = load_repositories(args)
     if len(args.object) == 0:
         arrow("Repositories")
-        repoman.show(verbose=args.verbose)
+        repoman.show('*', url=args.verbose)
     else:
         for o in args.object:
             repos = fnmatch.filter(repoman.onlines, o)
@@ -296,6 +296,18 @@ def c_new(parser, args):
     '''
     SourceImage.create(args.path, args.force)
 
+def c_repo(parser, args):
+    '''
+    Get information about repositories
+    '''
+    # List available repositories
+    repoman = load_repositories(args, force_offline=args.local)
+    # if len(args.repository) == 0:
+    #     args.repository = ['*']
+    for pattern in args.repository:
+        repoman.show(pattern, online=not args.offline,
+                     offline=not args.online, url=args.verbose, state=not args.no_state)
+
 def c_search(parser, args):
     '''
     Search in repository
@@ -517,6 +529,23 @@ p_new.add_argument("-f", "--force", action="store_true", default=False,
 p_new.add_argument("path", help="new image directory path")
 p_new.set_defaults(func=c_new)
 
+# repo command parser
+p_repo = subparsers.add_parser("repo", help=c_repo.__doc__.lower())
+p_repo.add_argument("-v", "--verbose", action="store_true", default=False,
+                    help="verbose output")
+p_repo.add_argument("-o", "--online", action="store_true", default=False,
+                    help="list only online repository")
+p_repo.add_argument("-O", "--offline", action="store_true", default=False,
+                    help="list only offline repository")
+p_repo.add_argument("-l", "--local", action="store_true", default=False,
+                    help="force repository to be offline. This just list repository name without connection")
+p_repo.add_argument("-S", "--no-state", action="store_true", default=False,
+                    help="doesn't display repository state (online/offline)")
+
+p_repo.add_argument("repository", nargs='*', default=["*"], help="repository pattern")
+p_repo.set_defaults(func=c_repo)
+
+
 # search command parser
 p_search = subparsers.add_parser("search", help=c_search.__doc__.lower())
 p_search.add_argument("pattern", help="pattern to search in repositories")
diff --git a/completion/bash/is b/completion/bash/is
index d15bc1d9ff4cce756d75fc5778a2bfdc7a462708..0dacac0bde46bdb1bd34dbce7b4a2f7b841cd959 100644
--- a/completion/bash/is
+++ b/completion/bash/is
@@ -2,7 +2,7 @@
 
 # list local repositories
 _repo() {
-    COMPREPLY=("${COMPREPLY[@]}" $(compgen -W "$(is -q --no-color list | grep -v '\[offline\]')"  -- "$cur"))
+    COMPREPLY=("${COMPREPLY[@]}" $(compgen -W "$(is --no-color repo -lS)"  -- "$cur"))
 }
 
 # list all images available in any online repositories
@@ -23,7 +23,7 @@ _is() {
     _get_comp_words_by_ref cur prev cword
     _get_first_arg
     cmds=('add' 'build' 'cat' 'changelog' 'check' 'chroot' 'clean' 'copy' 'del'
-	'extract' 'get' 'help' 'info' 'init' 'install' 'list' 'move' 'new' 'search' 'version' 'diff')
+	'extract' 'get' 'help' 'info' 'init' 'install' 'list' 'move' 'new' 'repo' 'search' 'version' 'diff')
     opts=('-h'  '--help'
 	'-V'  '--version'
 	'-d'  '--debug'
@@ -128,6 +128,10 @@ _is() {
 	    [[ "$cur" == -* ]] && _opt '-h --help -f --force' && return 0
             _filedir -d
             ;;
+	repo)
+            [[ "$cur" == -* ]] && _opt '-h --help -v --verbose -o --online -O --offline -l --local -S --no-state' && return 0
+	    _repo
+	    ;;
 	search)
 	    [[ "$cur" == -* ]] && _opt '-h --help' && return 0
             ;;
diff --git a/installsystems/repository.py b/installsystems/repository.py
index 066f9d64f486aee02de2263935e62a2fcc0455bb..92165ba40e59d7470b206f4f971c2efb6f662754 100644
--- a/installsystems/repository.py
+++ b/installsystems/repository.py
@@ -505,17 +505,21 @@ class RepositoryManager(object):
                 return True
         return False
 
-    def register(self, config, temp=False):
+    def register(self, config, temp=False, offline=False):
         '''
         Register a repository from its config
+        temp: repository is stored in a temporary location
+        offline: repository is marked offline
         '''
         # check filter on name
         if self.filter is not None:
             if not fnmatch.fnmatch(config.name, self.filter):
                 return
         # repository is offline
-        if config.offline:
+        if config.offline or offline:
             debug("Registering offline repository %s (%s)" % (config.path, config.name))
+            # we must force offline in cast of argument offline
+            config.offline = True
             self.repos.append(Repository(config))
         # if path is local, no needs to create a cache
         elif istools.isfile(config.path):
@@ -627,15 +631,23 @@ class RepositoryManager(object):
                 return repo.get(name, version), repo
         raise Exception("Unable to find image %s v%s" % (name, version))
 
-    def show(self, verbose=False):
+    def show(self, pattern, online=True, offline=True, url=False, state=True):
         '''
         Show repository inside manager
-        '''
-        for repo in self.repos:
+        online: list online repository
+        offline: list offline repository
+        verbose: display path
+        '''
+        for reponame in fnmatch.filter(self.names, pattern):
+            repo = self[reponame]
+            if repo.config.offline and not offline:
+                continue
+            if not repo.config.offline and not online:
+                continue
             s = "#light##blue#%s#reset#"% repo.config.name
-            if verbose:
+            if url:
                 s += " (%s)" % repo.config.path
-            if repo.config.offline:
+            if state and repo.config.offline:
                 s +=  " #light##red#[offline]#reset#"
             out(s)
 
@@ -660,7 +672,7 @@ class RepositoryConfig(object):
         Raise exception is repository name is invalid
         '''
         if re.match("^[-_\w]+$", name) is None:
-            raise Exception("Invalid repository name %s" % buf)
+            raise Exception("Invalid repository name %s" % name)
         return name
 
     def __init__(self, name, **kwargs):