[yum] update to latest HEAD

James Antill james at fedoraproject.org
Tue Dec 17 22:54:06 UTC 2013


commit d1d5e4bada19cebfeb8b4f0b8be5bba3d4556322
Author: James Antill <james at and.org>
Date:   Tue Dec 17 17:54:11 2013 -0500

    update to latest HEAD
    
    - Again, lots of groups UI changes/fixes thanks to Adam.
    - Add "groups mark blacklist" command to get out of the upgrade problem.
    - Tell users how to mark install/remove groups without packages.
    - Show install groups as well as upgrading groups in transaction output.
    - Fix mark-convert-whitelist, and add mark-convert-blacklist (default).
    - Fix typo with simple groups compile of environment with only options.
    - Pass the ievgrp to groups for new installed envs., so they belong. BZ 1043231.
    - Don't confuse "group info" output by giving data for optional when it's off.

 yum-HEAD.patch |  519 ++++++++++++++++++++++++++++++++------------------------
 yum.spec       |   13 ++-
 2 files changed, 312 insertions(+), 220 deletions(-)
---
diff --git a/yum-HEAD.patch b/yum-HEAD.patch
index 43e006e..4e5f335 100644
--- a/yum-HEAD.patch
+++ b/yum-HEAD.patch
@@ -107,7 +107,7 @@ index 2f6154e..2e5a052 100644
 diff --git a/cli.py b/cli.py
 old mode 100644
 new mode 100755
-index 6056d38..be8c46f
+index 6056d38..c05a4cf
 --- a/cli.py
 +++ b/cli.py
 @@ -25,7 +25,7 @@ import sys
@@ -1361,7 +1361,7 @@ index 6056d38..be8c46f
              pkgcode, pkgresults = self.cleanPackages()
          if 'metadata' in userlist:
              self.logger.debug(_('Cleaning up xml metadata'))
-@@ -1228,138 +1698,273 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1228,159 +1698,336 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return code, []
  
      def returnGroupLists(self, userlist):
@@ -1690,7 +1690,7 @@ index 6056d38..be8c46f
 +                    txmbrs = self.selectEnvironment(group.environmentid,
 +                                                    upgrade=upgrade)
 +                except yum.Errors.GroupsError:
-+                    self.logger.critical(_('Warning: environment %s does not exist.'), group_string)
++                    self.logger.critical(_('Warning: Environment group %s does not exist.'), group_string)
 +                    continue
 +                else:
 +                    pkgs_used.extend(txmbrs)
@@ -1706,7 +1706,7 @@ index 6056d38..be8c46f
 +                    txmbrs = self.selectGroup(group.groupid, upgrade=upgrade)
                  except yum.Errors.GroupsError:
 -                    self.logger.critical(_('Warning: Group %s does not exist.'), group_string)
-+                    self.logger.critical(_('Warning: group %s does not exist.'), group_string)
++                    self.logger.critical(_('Warning: Package group %s does not exist.'), group_string)
                      continue
                  else:
                      pkgs_used.extend(txmbrs)
@@ -1717,7 +1717,10 @@ index 6056d38..be8c46f
                  continue
              
          if not pkgs_used:
-@@ -1368,17 +1973,55 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
++            if base.conf.group_command == 'objects':
++                self.logger.critical(_("Maybe run: yum groups mark install (see man yum)"))
+             return 0, [_('No packages in any requested group available to install or update')]
+         else:
              return 2, [P_('%d package to Install', '%d packages to Install', len(pkgs_used)) % len(pkgs_used)]
  
      def removeGroups(self, grouplist):
@@ -1780,8 +1783,12 @@ index 6056d38..be8c46f
 +                    pkgs_used.extend(txmbrs)
                  
          if not pkgs_used:
++            if base.conf.group_command == 'objects':
++                self.logger.critical(_("Maybe run: yum groups mark remove (see man yum)"))
              return 0, [_('No packages to remove from groups')]
-@@ -1389,7 +2032,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         else:
+             return 2, [P_('%d package to remove', '%d packages to remove', len(pkgs_used)) % len(pkgs_used)]
+@@ -1389,7 +2036,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
  
      def _promptWanted(self):
          # shortcut for the always-off/always-on options
@@ -1790,7 +1797,7 @@ index 6056d38..be8c46f
              return False
          if self.conf.alwaysprompt:
              return True
-@@ -1397,10 +2040,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1397,10 +2044,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          # prompt if:
          #  package was added to fill a dependency
          #  package is being removed
@@ -1802,7 +1809,7 @@ index 6056d38..be8c46f
                     txmbr.name not in self.extcmds:
                  return True
          
-@@ -1408,11 +2050,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1408,11 +2054,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return False
  
      def usage(self):
@@ -1816,7 +1823,7 @@ index 6056d38..be8c46f
          sys.stdout.write(self.optparser.get_usage())
      
      def _installable(self, pkg, ematch=False):
-@@ -1468,9 +2110,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1468,9 +2114,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return False
  
  class YumOptionParser(OptionParser):
@@ -1828,7 +1835,7 @@ index 6056d38..be8c46f
  
      def __init__(self,base, **kwargs):
          # check if this is called with a utils=True/False parameter
-@@ -1488,13 +2130,23 @@ class YumOptionParser(OptionParser):
+@@ -1488,13 +2134,23 @@ class YumOptionParser(OptionParser):
          self._addYumBasicOptions()
  
      def error(self, msg):
@@ -1854,7 +1861,7 @@ index 6056d38..be8c46f
          try:
              args = _filtercmdline(
                          ('--noplugins','--version','-q', '-v', "--quiet", "--verbose"), 
-@@ -1521,7 +2173,15 @@ class YumOptionParser(OptionParser):
+@@ -1521,7 +2177,15 @@ class YumOptionParser(OptionParser):
          return ret
          
      def setupYumConfig(self, args=None):
@@ -1871,7 +1878,7 @@ index 6056d38..be8c46f
          if not args:
              (opts, cmds) = self.parse_args()
          else:
-@@ -1533,16 +2193,30 @@ class YumOptionParser(OptionParser):
+@@ -1533,16 +2197,30 @@ class YumOptionParser(OptionParser):
          try:
              # config file is parsed and moving us forward
              # set some things in it.
@@ -1908,7 +1915,7 @@ index 6056d38..be8c46f
                  self.base.conf.cache = 1
  
              if opts.obsoletes:
-@@ -1574,11 +2248,8 @@ class YumOptionParser(OptionParser):
+@@ -1574,11 +2252,8 @@ class YumOptionParser(OptionParser):
                  if opts.color != 'auto':
                      self.base.term.reinit(color=opts.color)
  
@@ -1922,7 +1929,7 @@ index 6056d38..be8c46f
  
              for exclude in self._splitArg(opts.exclude):
                  try:
-@@ -1610,10 +2281,6 @@ class YumOptionParser(OptionParser):
+@@ -1610,10 +2285,6 @@ class YumOptionParser(OptionParser):
                      self.base.usage()
                      sys.exit(1)
  
@@ -1933,7 +1940,7 @@ index 6056d38..be8c46f
              # Disable all gpg key checking, if requested.
              if opts.nogpgcheck:
                  #  Altering the normal configs. doesn't work too well, esp. with
-@@ -1623,7 +2290,7 @@ class YumOptionParser(OptionParser):
+@@ -1623,7 +2294,7 @@ class YumOptionParser(OptionParser):
                      repo._override_sigchecks = True
                              
          except ValueError, e:
@@ -1942,7 +1949,7 @@ index 6056d38..be8c46f
              self.base.usage()
              sys.exit(1)
           
-@@ -1640,10 +2307,18 @@ class YumOptionParser(OptionParser):
+@@ -1640,10 +2311,18 @@ class YumOptionParser(OptionParser):
          sys.exit(1)
  
      def getRoot(self,opts):
@@ -1962,7 +1969,7 @@ index 6056d38..be8c46f
              if os.access(opts.installroot+'/'+opts.conffile, os.R_OK):
                  opts.conffile = opts.installroot+'/'+opts.conffile
              elif opts.conffile == '/etc/yum/yum.conf':
-@@ -1701,6 +2376,9 @@ class YumOptionParser(OptionParser):
+@@ -1701,6 +2380,9 @@ class YumOptionParser(OptionParser):
          group.add_option("--showduplicates", dest="showdupesfromrepos",
                          action="store_true",
                  help=_("show duplicates, in repos, in list/search commands"))
@@ -1972,7 +1979,7 @@ index 6056d38..be8c46f
          group.add_option("-e", "--errorlevel", dest="errorlevel", default=None,
                  help=_("error output level"), type='int',
                  metavar='[error level]')
-@@ -1713,6 +2391,10 @@ class YumOptionParser(OptionParser):
+@@ -1713,6 +2395,10 @@ class YumOptionParser(OptionParser):
                          help=_("verbose operation"))
          group.add_option("-y", "--assumeyes", dest="assumeyes",
                  action="store_true", help=_("answer yes for all questions"))
@@ -1983,7 +1990,7 @@ index 6056d38..be8c46f
          group.add_option("--version", action="store_true", 
                  help=_("show Yum version and exit"))
          group.add_option("--installroot", help=_("set install root"), 
-@@ -1730,6 +2412,9 @@ class YumOptionParser(OptionParser):
+@@ -1730,6 +2416,9 @@ class YumOptionParser(OptionParser):
          group.add_option("", "--disableexcludes", default=[], action="append",
                  help=_("disable exclude from main, for a repo or for everything"),
                          metavar='[repo]')
@@ -1993,7 +2000,7 @@ index 6056d38..be8c46f
          group.add_option("--obsoletes", action="store_true", 
                  help=_("enable obsoletes processing during updates"))
          group.add_option("--noplugins", action="store_true", 
-@@ -1748,9 +2433,29 @@ class YumOptionParser(OptionParser):
+@@ -1748,9 +2437,29 @@ class YumOptionParser(OptionParser):
                  help=_("control whether color is used"))
          group.add_option("", "--releasever", dest="releasever", default=None, 
                  help=_("set value of $releasever in yum config and repo files"))
@@ -2789,7 +2796,7 @@ index 0000000..2af059d
 + the mailing list, yum at lists.baseurl.org, or consult bugzilla.
 +.fi
 diff --git a/docs/yum.8 b/docs/yum.8
-index 1a8202a..dff88af 100644
+index 1a8202a..0e211eb 100644
 --- a/docs/yum.8
 +++ b/docs/yum.8
 @@ -25,6 +25,8 @@ gnome\-packagekit application\&.
@@ -2957,7 +2964,7 @@ index 1a8202a..dff88af 100644
  
  "\fBgroup remove\fP" is used to remove all of the packages in a group, unlike "groupinstall" this
  will remove everything regardless of group_package_types. It is worth pointing
-@@ -224,23 +280,65 @@ to only remove packages which aren't required by something else.
+@@ -224,23 +280,79 @@ to only remove packages which aren't required by something else.
  
  "\fBgroup info\fP" is used to give the description and package list of a group (and which type
  those packages are marked as). Note that you can use the yum-filter-data and
@@ -3002,9 +3009,23 @@ index 1a8202a..dff88af 100644
 +"\fBgroup mark packages-force\fP" works like mark packages, but doesn't care if
 +the packages are already members of another group.
 +
-+"\fBgroup mark convert\fP" converts the automatic data you get without using
-+groups as objects into groups as objects data. This makes it much easier to
-+convert to groups as objects without having to reinstall.
++"\fBgroup mark blacklist\fP" will blacklist all packages marked to be installed
++for a group. After this command a "yum group upgrade" will not install any new
++packages as part of the group.
++
++"\fBgroup mark convert-blacklist\fP"
++
++"\fBgroup mark convert-whitelist\fP"
++
++"\fBgroup mark convert\fP" converts the automatic data you get
++without using groups as objects into groups as objects data, in other words
++this will make "yum --setopt=group_command=objects groups list" look as similar
++as possible to the current output of
++"yum --setopt=group_command=simple groups list". This makes it much
++easier to convert to groups as objects without having to reinstall. For groups
++that are installed the whitelist variant will mark all uninstalled packages for
++the group as to be installed on the next "yum group upgrade", the blacklist
++variant (current default) will mark them all as blacklisted.
 +
 +"\fBgroup unmark packages\fP" remove a package as a member from any groups.
  .IP
@@ -3027,7 +3048,7 @@ index 1a8202a..dff88af 100644
  reasons only.
  .IP
  .IP "\fBlocalupdate\fP"
-@@ -248,7 +346,7 @@ Is used to update the system by specifying local rpm files. Only the specified
+@@ -248,7 +360,7 @@ Is used to update the system by specifying local rpm files. Only the specified
  rpm files of which an older version is already installed will be installed,
  the remaining specified packages will be ignored.
  If required the enabled repositories will be used to resolve dependencies. Note
@@ -3036,7 +3057,7 @@ index 1a8202a..dff88af 100644
  legacy reasons only.
  .IP
  .IP "\fBreinstall\fP"
-@@ -260,10 +358,28 @@ on groups, files, provides and filelists just like the "install" command\&.
+@@ -260,10 +372,28 @@ on groups, files, provides and filelists just like the "install" command\&.
  Will try and downgrade a package from the version currently installed to the
  previously highest version (or the specified version).
  The depsolver will not necessarily work, but if you specify all the packages it
@@ -3066,7 +3087,7 @@ index 1a8202a..dff88af 100644
  .IP "\fBdeplist\fP"
  Produces a list of all dependencies and what packages provide those
  dependencies for the given packages. As of 3.2.30 it now just shows the latest
-@@ -271,18 +387,20 @@ version of each package that matches (this can be changed by
+@@ -271,18 +401,20 @@ version of each package that matches (this can be changed by
  using --showduplicates) and it only shows the newest providers (which can be
  changed by using --verbose).
  .IP
@@ -3093,7 +3114,7 @@ index 1a8202a..dff88af 100644
  last column will also display the number of packages in the repo. and (if there
  are any user specified excludes) the number of packages excluded.
  
-@@ -291,11 +409,66 @@ then yum will ignore any repo errors and output the information it can get
+@@ -291,11 +423,66 @@ then yum will ignore any repo errors and output the information it can get
  (Eg. "yum clean all; yum -C repolist" will output something, although the
  package counts/etc. will be zeroed out).
  .IP
@@ -3162,7 +3183,7 @@ index 1a8202a..dff88af 100644
  packages (in sorted order), and the checksum_type/checksum_data entries from
  the yumdb. Note that this rpmdb version is now also used significantly within
  yum (esp. in yum history).
-@@ -321,26 +494,33 @@ and so takes sub-commands:
+@@ -321,26 +508,33 @@ and so takes sub-commands:
  .IP "\fBhistory\fP"
  The history command allows the user to view what has happened in past
  transactions (assuming the history_record config. option is set). You can use
@@ -3202,7 +3223,7 @@ index 1a8202a..dff88af 100644
  A (if it is not still installed), and "rollback 1" will try to remove packages
  B and C. Note that after a "rollback 1" you will have a fourth transaction,
  although the ending rpmdb version (see: yum version) should be the same in
-@@ -349,13 +529,20 @@ transactions 1 and 4.
+@@ -349,13 +543,20 @@ transactions 1 and 4.
  The addon-info command takes a transaction ID, and the packages-list command
  takes a package (with wildcards).
  
@@ -3224,7 +3245,7 @@ index 1a8202a..dff88af 100644
  .I \fB>\fR - The rpmdb was changed, outside yum, after the transaction.
  .br
  .I \fB<\fR - The rpmdb was changed, outside yum, before the transaction.
-@@ -371,11 +558,156 @@ end of the package column in the packages-list command).
+@@ -371,11 +572,156 @@ end of the package column in the packages-list command).
  .I \fBs\fR - The transaction completed fine, but --skip-broken was enabled and had to skip some packages.
  .br
  
@@ -3383,7 +3404,7 @@ index 1a8202a..dff88af 100644
  
  The info command can also take ranges of transaction ids, of the form
  start..end, which will then display a merged history as if all the
-@@ -401,6 +733,11 @@ Assume yes; assume that the answer to any question which would be asked
+@@ -401,6 +747,11 @@ Assume yes; assume that the answer to any question which would be asked
  is yes\&.
  .br
  Configuration Option: \fBassumeyes\fP
@@ -3395,7 +3416,7 @@ index 1a8202a..dff88af 100644
  .IP "\fB\-c, \-\-config=[config file]\fP" 
  Specifies the config file location - can take HTTP and FTP URLs and local file
  paths\&.
-@@ -420,7 +757,7 @@ Sets the error level to [number] Practical range 0 \- 10. 0 means print only cri
+@@ -420,7 +771,7 @@ Sets the error level to [number] Practical range 0 \- 10. 0 means print only cri
  .br
  Configuration Option: \fBerrorlevel\fP
  .IP "\fB\-\-rpmverbosity=[name]\fP" 
@@ -3404,7 +3425,7 @@ index 1a8202a..dff88af 100644
  options are: 'critical', 'emergency', 'error', 'warn' and 'debug'.
  .br
  Configuration Option: \fBrpmverbosity\fP
-@@ -428,9 +765,7 @@ Configuration Option: \fBrpmverbosity\fP
+@@ -428,9 +779,7 @@ Configuration Option: \fBrpmverbosity\fP
  Sets the maximum amount of time yum will wait before performing a command \- it randomizes over the time.
  .IP "\fB\-C, \-\-cacheonly\fP" 
  Tells yum to run entirely from system cache - does not download or
@@ -3415,7 +3436,7 @@ index 1a8202a..dff88af 100644
  .IP "\fB\-\-version\fP" 
  Reports the \fByum\fP version number and installed package versions for
  everything in history_record_packages (can be added to by plugins).
-@@ -461,8 +796,13 @@ processing logic. For more information see the \fBupdate\fP command above.
+@@ -461,8 +810,13 @@ processing logic. For more information see the \fBupdate\fP command above.
  .br
  Configuration Option: \fBobsoletes\fP
  .IP "\fB\-x, \-\-exclude=package\fP"
@@ -3431,7 +3452,7 @@ index 1a8202a..dff88af 100644
  .br
  .IP "\fB\-\-color=[always|auto|never]\fP"
  Display colorized output automatically, depending on the output terminal,
-@@ -479,6 +819,13 @@ main == disable excludes defined in [main] in yum.conf
+@@ -479,6 +833,13 @@ main == disable excludes defined in [main] in yum.conf
  .br
  repoid == disable excludes defined for that repo
  .br
@@ -3445,7 +3466,7 @@ index 1a8202a..dff88af 100644
  .IP "\fB\-\-disableplugin=plugin\fP"
  Run with one or more plugins disabled, the argument is a comma separated list
  of wildcards to match against plugin names.
-@@ -506,7 +853,14 @@ option will corrupt your cache (and you can use $releasever in your cachedir
+@@ -506,7 +867,14 @@ option will corrupt your cache (and you can use $releasever in your cachedir
  configuration to stop this).
  .PP 
  .IP "\fB\-t, \-\-tolerant\fP"
@@ -3461,7 +3482,7 @@ index 1a8202a..dff88af 100644
  .br
  .IP "\fB\-\-setopt=option=value\fP"
  Set any config option in yum config or repo files. For options in the global 
-@@ -523,7 +877,7 @@ version of the package\&.
+@@ -523,7 +891,7 @@ version of the package\&.
  
  The format of the output of yum list is:
  
@@ -3470,7 +3491,7 @@ index 1a8202a..dff88af 100644
  
  .IP "\fByum list [all | glob_exp1] [glob_exp2] [\&.\&.\&.]\fP"
  List all available and installed packages\&.
-@@ -542,6 +896,10 @@ shell\-style glob and any matches are printed\&.
+@@ -542,6 +910,10 @@ shell\-style glob and any matches are printed\&.
  List the packages installed on the system that are not available in any yum
  repository listed in the config file.
  .IP
@@ -3481,7 +3502,7 @@ index 1a8202a..dff88af 100644
  .IP "\fByum list obsoletes [glob_exp1] [\&.\&.\&.]\fP"
  List the packages installed on the system that are obsoleted by packages
  in any yum repository listed in the config file.
-@@ -658,7 +1016,7 @@ configuration options.
+@@ -658,7 +1030,7 @@ configuration options.
  .I yum-complete-transaction (1)
  .I yumdownloader (1)
  .I yum-utils (1)
@@ -5035,7 +5056,7 @@ index f1e06e8..16d096c 100644
  complete -F _yum -o filenames yum yummain.py
  
 diff --git a/output.py b/output.py
-index b6aa277..041910c 100755
+index b6aa277..38045e9 100755
 --- a/output.py
 +++ b/output.py
 @@ -1,6 +1,6 @@
@@ -5705,7 +5726,7 @@ index b6aa277..041910c 100755
                      continue
                  for (apkg, ipkg) in sorted(pkg_names2pkgs[item],
                                             key=lambda x: x[1] or x[0]):
-@@ -770,18 +1094,38 @@ class YumOutput:
+@@ -770,45 +1094,145 @@ class YumOutput:
                      else:
                          highlight = False
                      self.simpleEnvraList(ipkg or apkg, ui_overflow=True,
@@ -5748,7 +5769,21 @@ index b6aa277..041910c 100755
          if group.ui_description:
              print _(' Description: %s') % to_unicode(group.ui_description)
          if group.langonly:
-@@ -795,7 +1139,8 @@ class YumOutput:
+             print _(' Language: %s') % group.langonly
+ 
+-        sections = ((_(' Mandatory Packages:'),   group.mandatory_packages),
+-                    (_(' Default Packages:'),     group.default_packages),
+-                    (_(' Optional Packages:'),    group.optional_packages),
+-                    (_(' Conditional Packages:'), group.conditional_packages))
++        sections = (('mandatory', _(' Mandatory Packages:'),
++                     group.mandatory_packages),
++                    ('default',  _(' Default Packages:'),
++                     group.default_packages),
++                    ('optional', _(' Optional Packages:'),
++                     group.optional_packages),
++                    (None, _(' Conditional Packages:'),
++                     group.conditional_packages))
+         columns = None
          if verb:
              data = {'envra' : {}, 'rid' : {}}
              for (section_name, pkg_names) in sections:
@@ -5758,13 +5793,24 @@ index b6aa277..041910c 100755
              data = [data['envra'], data['rid']]
              columns = self.calcColumns(data)
              columns = (-columns[0], -columns[1])
-@@ -804,11 +1149,77 @@ class YumOutput:
+ 
+-        for (section_name, pkg_names) in sections:
++        for (section_type, section_name, pkg_names) in sections:
++            #  Only display igroup data for things that we'll actually try to
++            # install.
++            if section_type is None:
++                tigroup_data = igroup_data
++            elif section_type in self.conf.group_package_types:
++                tigroup_data = igroup_data
++            else:
++                tigroup_data = None
++
              if len(pkg_names) > 0:
                  print section_name
                  self._displayPkgsFromNames(pkg_names, verb, pkg_names2pkgs,
 -                                           columns=columns)
 +                                           columns=columns,
-+                                           igroup_data=igroup_data)
++                                           igroup_data=tigroup_data)
 +        if igrp_only:
 +            print _(' Installed Packages:')
 +            self._displayPkgsFromNames(igrp_only, verb, pkg_names2pkgs,
@@ -5839,7 +5885,7 @@ index b6aa277..041910c 100755
          verb = self.verbose_logger.isEnabledFor(logginglevels.DEBUG_3)
          for pkg in sorted(results):
              print _("package: %s") % pkg.compactPrint()
-@@ -832,7 +1243,18 @@ class YumOutput:
+@@ -832,7 +1256,18 @@ class YumOutput:
                      print "   provider: %s" % po.compactPrint()
  
      def format_number(self, number, SI=0, space=' '):
@@ -5859,7 +5905,7 @@ index b6aa277..041910c 100755
          symbols = [ ' ', # (none)
                      'k', # kilo
                      'M', # mega
-@@ -870,16 +1292,31 @@ class YumOutput:
+@@ -870,16 +1305,31 @@ class YumOutput:
  
      @staticmethod
      def format_time(seconds, use_hours=0):
@@ -5897,7 +5943,7 @@ index b6aa277..041910c 100755
          if self.conf.showdupesfromrepos:
              msg = '%s : ' % po
          else:
-@@ -923,7 +1360,15 @@ class YumOutput:
+@@ -923,7 +1373,15 @@ class YumOutput:
                  item = self._enc(item)
                  can_overflow = False
              else:
@@ -5914,7 +5960,7 @@ index b6aa277..041910c 100755
  
              if matchfor:
                  item = self._sub_highlight(item, highlight, matchfor,
-@@ -935,14 +1380,34 @@ class YumOutput:
+@@ -935,14 +1393,34 @@ class YumOutput:
          print '\n\n'
  
      def matchcallback_verbose(self, po, values, matchfor=None):
@@ -5950,7 +5996,7 @@ index b6aa277..041910c 100755
          for pkg in packages:
              # Just to be on the safe side, if for some reason getting
              # the package size fails, log the error and don't report download
-@@ -971,18 +1436,18 @@ class YumOutput:
+@@ -971,18 +1449,18 @@ class YumOutput:
  
          if (not error):
              if locsize:
@@ -5977,7 +6023,7 @@ index b6aa277..041910c 100755
          totsize = 0
          error = False
          for pkg in packages:
-@@ -997,13 +1462,19 @@ class YumOutput:
+@@ -997,13 +1475,19 @@ class YumOutput:
                  self.logger.error(_('There was an error calculating installed size'))
                  break
          if (not error):
@@ -6002,7 +6048,7 @@ index b6aa277..041910c 100755
          self.tsInfo.makelists(True, True)
          pkglist_lines = []
          data  = {'n' : {}, 'v' : {}, 'r' : {}}
-@@ -1032,11 +1503,33 @@ class YumOutput:
+@@ -1032,11 +1516,43 @@ class YumOutput:
              for (d, v) in (("n",len(n)), ("v",len(evr)), ("r",len(repoid))):
                  data[d].setdefault(v, 0)
                  data[d][v] += 1
@@ -6018,16 +6064,26 @@ index b6aa277..041910c 100755
 +            # Show new pkgs. that are installed via. a group.
 +            ninstalled = []
 +            for txmbr in self.tsInfo.installed:
-+                if not hasattr(txmbr, '_ugroup_member'):
++                if hasattr(txmbr, '_igroup_member'):
++                    key = ('i', txmbr._igroup_member)
++                    if key not in ginstalled:
++                        ginstalled[key] = []
++                    ginstalled[key].append(txmbr)
++                elif hasattr(txmbr, '_ugroup_member'):
++                    key = ('u', txmbr._ugroup_member)
++                    if key not in ginstalled:
++                        ginstalled[key] = []
++                    ginstalled[key].append(txmbr)
++                else:
 +                    ninstalled.append(txmbr)
-+                    continue
-+                if txmbr._ugroup_member not in ginstalled:
-+                    ginstalled[txmbr._ugroup_member] = []
-+                ginstalled[txmbr._ugroup_member].append(txmbr)
 +
-+        for grp in sorted(ginstalled, key=lambda x: x.ui_name):
-+            action = _('Installing for group upgrade "%s"') % grp.ui_name
-+            pkglist = ginstalled[grp]
++        for (T, grp) in sorted(ginstalled, key=lambda x: x[1].ui_name):
++            if T == 'u':
++                msg = _('Installing for group upgrade "%s"')
++            else:
++                msg = _('Installing for group install "%s"')
++            action = msg % grp.ui_name
++            pkglist = ginstalled[(T, grp)]
 +
 +            lines = []
 +            for txmbr in pkglist:
@@ -6039,7 +6095,7 @@ index b6aa277..041910c 100755
                              (_('Updating'), self.tsInfo.updated),
                              (_('Removing'), self.tsInfo.removed),
                              (_('Reinstalling'), self.tsInfo.reinstalled),
-@@ -1102,19 +1595,72 @@ class YumOutput:
+@@ -1102,19 +1618,72 @@ class YumOutput:
  Transaction Summary
  %s
  """) % ('=' * self.term.columns))
@@ -6122,7 +6178,7 @@ index b6aa277..041910c 100755
          out = ''
          
          self.tsInfo.makelists()
-@@ -1179,17 +1725,19 @@ Transaction Summary
+@@ -1179,17 +1748,19 @@ Transaction Summary
          return out
  
      def setupProgressCallbacks(self):
@@ -6145,7 +6201,7 @@ index b6aa277..041910c 100755
              callback = CacheProgressCallback()
  
          # setup our failure report for failover
-@@ -1200,13 +1748,14 @@ Transaction Summary
+@@ -1200,13 +1771,14 @@ Transaction Summary
          interrupt_callback = self.interrupt_callback
          if hasattr(self, 'prerepoconf'):
              self.prerepoconf.progressbar = progressbar
@@ -6161,7 +6217,7 @@ index b6aa277..041910c 100755
              self.repos.callback = callback
              self.repos.setFailureCallback(failure_callback)
              self.repos.setInterruptCallback(interrupt_callback)
-@@ -1216,10 +1765,12 @@ Transaction Summary
+@@ -1216,10 +1788,12 @@ Transaction Summary
          self.dsCallback = dscb
      
      def setupProgessCallbacks(self):
@@ -6175,27 +6231,27 @@ index b6aa277..041910c 100755
          confirm_func = self._cli_confirm_gpg_key_import
          gpg_import_func = self.getKeyForRepo
          gpgca_import_func = self.getCAKeyForRepo
-@@ -1233,14 +1784,12 @@ Transaction Summary
+@@ -1233,14 +1807,12 @@ Transaction Summary
              self.repos.gpgca_import_func = gpgca_import_func
  
      def interrupt_callback(self, cbobj):
 -        '''Handle CTRL-C's during downloads
+-
+-        If a CTRL-C occurs a URLGrabError will be raised to push the download
+-        onto the next mirror.  
+-        
+-        If two CTRL-C's occur in quick succession then yum will exit.
 +        '''Handle CTRL-C's during downloads.  If a CTRL-C occurs a
 +        URLGrabError will be raised to push the download onto the next
 +        mirror.  If two CTRL-C's occur in quick succession then yum
 +        will exit.
  
--        If a CTRL-C occurs a URLGrabError will be raised to push the download
--        onto the next mirror.  
--        
--        If two CTRL-C's occur in quick succession then yum will exit.
--
 -        @param cbobj: urlgrabber callback obj
 +        :param cbobj: :class:`urlgrabber.grabber.CallbackObject`
          '''
          delta_exit_chk = 2.0      # Delta between C-c's so we treat as exit
          delta_exit_str = _("two") # Human readable version of above
-@@ -1253,7 +1802,7 @@ Transaction Summary
+@@ -1253,7 +1825,7 @@ Transaction Summary
              # For translators: This is output like:
  #  Current download cancelled, interrupt (ctrl-c) again within two seconds
  # to exit.
@@ -6204,7 +6260,7 @@ index b6aa277..041910c 100755
              msg = _("""
   Current download cancelled, %sinterrupt (ctrl-c) again%s within %s%s%s seconds
  to exit.
-@@ -1269,6 +1818,14 @@ to exit.
+@@ -1269,6 +1841,14 @@ to exit.
  
      def download_callback_total_cb(self, remote_pkgs, remote_size,
                                     download_start_timestamp):
@@ -6219,7 +6275,7 @@ index b6aa277..041910c 100755
          if len(remote_pkgs) <= 1:
              return
          if not hasattr(urlgrabber.progress, 'TerminalLine'):
-@@ -1280,7 +1837,7 @@ to exit.
+@@ -1280,7 +1860,7 @@ to exit.
          if dl_time <= 0: # This stops divide by zero, among other problems
              dl_time = 0.01
          ui_size = tl.add(' | %5sB' % self.format_number(remote_size))
@@ -6228,19 +6284,19 @@ index b6aa277..041910c 100755
          ui_end  = tl.add(' ' * 5)
          ui_bs   = tl.add(' %5sB/s' % self.format_number(remote_size / dl_time))
          msg = "%s%s%s%s%s" % (utf8_width_fill(_("Total"), tl.rest(), tl.rest()),
-@@ -1434,10 +1991,21 @@ to exit.
+@@ -1434,10 +2014,21 @@ to exit.
          return tids, printall
  
      def historyListCmd(self, extcmds):
 -        """ Shows the user a list of data about the history. """
 +        """Output a list of information about the history of yum
 +        transactions.
-+
+ 
 +        :param extcmds: list of extra command line arguments
 +        :return: (exit_code, [errors])
 +
 +        exit_code is::
- 
++
 +            0 = we're done, exit
 +            1 = we've errored, exit with error string
 +        """
@@ -6251,7 +6307,7 @@ index b6aa277..041910c 100755
              return 1, ['Failed history list']
  
          limit = 20
-@@ -1564,6 +2132,16 @@ to exit.
+@@ -1564,6 +2155,16 @@ to exit.
          return old[0]
  
      def historyInfoCmd(self, extcmds):
@@ -6268,7 +6324,7 @@ index b6aa277..041910c 100755
          def str2int(x):
              try:
                  return int(x)
-@@ -1656,6 +2234,9 @@ to exit.
+@@ -1656,6 +2257,9 @@ to exit.
      def _hpkg2from_repo(self, hpkg):
          """ Given a pkg, find the ipkg.ui_from_repo ... if none, then
              get an apkg. ... and put a ? in there. """
@@ -6278,7 +6334,7 @@ index b6aa277..041910c 100755
          ipkgs = self.rpmdb.searchPkgTuple(hpkg.pkgtup)
          if not ipkgs:
              apkgs = self.pkgSack.searchPkgTuple(hpkg.pkgtup)
-@@ -1672,13 +2253,12 @@ to exit.
+@@ -1672,13 +2276,12 @@ to exit.
                                   'o' : _('Updated'), 'n' : _('Downgraded')}
          _pkg_states_available = {'i' : _('Installed'), 'e' : _('Not installed'),
                                   'o' : _('Older'), 'n' : _('Newer')}
@@ -6295,7 +6351,7 @@ index b6aa277..041910c 100755
              prefix = " " * prefix_len
              if was_installed:
                  _pkg_states = _pkg_states_installed
-@@ -1702,9 +2282,11 @@ to exit.
+@@ -1702,9 +2305,11 @@ to exit.
              else:
                  (hibeg, hiend) = self._highlight('normal')
              state = utf8_width_fill(state, _pkg_states['maxlen'])
@@ -6309,7 +6365,7 @@ index b6aa277..041910c 100755
  
          if type(old.tid) == type([]):
              print _("Transaction ID :"), "%u..%u" % (old.tid[0], old.tid[-1])
-@@ -1778,8 +2360,8 @@ to exit.
+@@ -1778,8 +2383,8 @@ to exit.
              default_addons = set(['config-main', 'config-repos', 'saved_tx'])
              non_default = set(addon_info).difference(default_addons)
              if len(non_default) > 0:
@@ -6320,7 +6376,7 @@ index b6aa277..041910c 100755
  
          if old.trans_with:
              # This is _possible_, but not common
-@@ -1794,7 +2376,9 @@ to exit.
+@@ -1794,7 +2399,9 @@ to exit.
              print _("Packages Skipped:")
              pkg_max_len = max((len(str(hpkg)) for hpkg in old.trans_skip))
          for hpkg in old.trans_skip:
@@ -6331,7 +6387,7 @@ index b6aa277..041910c 100755
  
          if old.rpmdb_problems:
              print _("Rpmdb Problems:")
-@@ -1833,6 +2417,13 @@ to exit.
+@@ -1833,6 +2440,13 @@ to exit.
                                'Updated'      : _('Updated'),
                                }
      def historyInfoCmdPkgsAltered(self, old, pats=[]):
@@ -6345,7 +6401,7 @@ index b6aa277..041910c 100755
          last = None
          #  Note that these don't use _simple_pkg() because we are showing what
          # happened to them in the transaction ... not the difference between the
-@@ -1886,6 +2477,10 @@ to exit.
+@@ -1886,6 +2500,10 @@ to exit.
                                          self._hpkg2from_repo(hpkg))
  
      def historySummaryCmd(self, extcmds):
@@ -6356,7 +6412,7 @@ index b6aa277..041910c 100755
          tids, printall = self._history_list_transactions(extcmds)
          if tids is None:
              return 1, ['Failed history info']
-@@ -1946,6 +2541,10 @@ to exit.
+@@ -1946,6 +2564,10 @@ to exit.
                               utf8_width_fill(uiacts, 16, 16), count)
  
      def historyAddonInfoCmd(self, extcmds):
@@ -6367,7 +6423,7 @@ index b6aa277..041910c 100755
          tid = None
          if len(extcmds) > 1:
              tid = extcmds[1]
-@@ -1983,16 +2582,19 @@ to exit.
+@@ -1983,16 +2605,19 @@ to exit.
          
          for item in extcmds[2:]:
              if item in addon_info:
@@ -6393,7 +6449,7 @@ index b6aa277..041910c 100755
          tids = self.history.search(extcmds)
          limit = None
          if extcmds and not tids:
-@@ -2078,9 +2680,94 @@ to exit.
+@@ -2078,9 +2703,94 @@ to exit.
              if lastdbv.end_rpmdbversion != rpmdbv:
                  self._rpmdb_warn_checks()
  
@@ -6489,7 +6545,7 @@ index b6aa277..041910c 100755
      
      def __init__(self, ayum=None):
          """requires yum-cli log and errorlog functions as arguments"""
-@@ -2089,6 +2776,25 @@ class DepSolveProgressCallBack:
+@@ -2089,6 +2799,25 @@ class DepSolveProgressCallBack:
          self.ayum = ayum
  
      def pkgAdded(self, pkgtup, mode):
@@ -6515,7 +6571,7 @@ index b6aa277..041910c 100755
          modedict = { 'i': _('installed'),
                       'u': _('an update'),
                       'e': _('erased'),
-@@ -2104,43 +2810,86 @@ class DepSolveProgressCallBack:
+@@ -2104,43 +2833,86 @@ class DepSolveProgressCallBack:
              modeterm)
          
      def start(self):
@@ -6606,7 +6662,7 @@ index b6aa277..041910c 100755
          needname, needflags, needversion = reqTup
  
          yb = self.ayum
-@@ -2164,6 +2913,18 @@ class DepSolveProgressCallBack:
+@@ -2164,6 +2936,18 @@ class DepSolveProgressCallBack:
                  done = True
                  msg += _('\n        %s') % yum.misc.prco_tuple_to_string(pkgtup)
              if not done:
@@ -6625,7 +6681,7 @@ index b6aa277..041910c 100755
                  msg += _('\n        Not found')
              return msg
  
-@@ -2225,46 +2986,106 @@ class DepSolveProgressCallBack:
+@@ -2225,46 +3009,106 @@ class DepSolveProgressCallBack:
          return msg
      
      def procConflict(self, name, confname):
@@ -6737,7 +6793,7 @@ index b6aa277..041910c 100755
  
  def _pkgname_ui(ayum, pkgname, ts_states=None):
      """ Get more information on a simple pkgname, if we can. We need to search
-@@ -2316,10 +3137,7 @@ def _pkgname_ui(ayum, pkgname, ts_states=None):
+@@ -2316,10 +3160,7 @@ def _pkgname_ui(ayum, pkgname, ts_states=None):
      return pkgname
  
  class YumCliRPMCallBack(RPMBaseCallback):
@@ -6749,7 +6805,7 @@ index b6aa277..041910c 100755
  
      width = property(lambda x: _term_width())
  
-@@ -2337,21 +3155,34 @@ class YumCliRPMCallBack(RPMBaseCallback):
+@@ -2337,21 +3178,34 @@ class YumCliRPMCallBack(RPMBaseCallback):
      #  Installing things have pkg objects passed to the events, so only need to
      # lookup for erased/obsoleted.
      def pkgname_ui(self, pkgname, ts_states=('e', 'od', 'ud', None)):
@@ -6794,7 +6850,7 @@ index b6aa277..041910c 100755
          
          if type(package) not in types.StringTypes:
              pkgname = str(package)
-@@ -2363,9 +3194,25 @@ class YumCliRPMCallBack(RPMBaseCallback):
+@@ -2363,9 +3217,25 @@ class YumCliRPMCallBack(RPMBaseCallback):
              percent = 0
          else:
              percent = (te_current*100L)/te_total
@@ -6821,7 +6877,7 @@ index b6aa277..041910c 100755
                                                pkgname=pkgname, wid1=wid1)
              msg = fmt % (utf8_width_fill(process, wid1, wid1),
                           utf8_width_fill(pkgname, wid2, wid2))
-@@ -2377,6 +3224,11 @@ class YumCliRPMCallBack(RPMBaseCallback):
+@@ -2377,6 +3247,11 @@ class YumCliRPMCallBack(RPMBaseCallback):
                  print " "
  
      def scriptout(self, package, msgs):
@@ -6833,7 +6889,7 @@ index b6aa277..041910c 100755
          if msgs:
              sys.stdout.write(to_unicode(msgs))
              sys.stdout.flush()
-@@ -2396,7 +3248,7 @@ class YumCliRPMCallBack(RPMBaseCallback):
+@@ -2396,7 +3271,7 @@ class YumCliRPMCallBack(RPMBaseCallback):
              pnl = utf8_width(pkgname)
  
          overhead  = (2 * l) + 2 # Length of done, above
@@ -6842,7 +6898,7 @@ index b6aa277..041910c 100755
          overhead +=  1          # Space between pn and done
          overhead +=  2          # Ends for progress
          overhead +=  1          # Space for end
-@@ -2429,8 +3281,30 @@ class YumCliRPMCallBack(RPMBaseCallback):
+@@ -2429,8 +3304,30 @@ class YumCliRPMCallBack(RPMBaseCallback):
              wid2 = pnl
          return fmt, wid1, wid2
  
@@ -186543,7 +186599,7 @@ index c1af4ad..70de539 100644
      pass
      
 diff --git a/yum/__init__.py b/yum/__init__.py
-index 99039e0..b7eedf4 100644
+index 99039e0..41c932c 100644
 --- a/yum/__init__.py
 +++ b/yum/__init__.py
 @@ -21,6 +21,7 @@ The Yum RPM software updater.
@@ -188935,7 +188991,7 @@ index 99039e0..b7eedf4 100644
              pkgs = []
              if 'mandatory' in package_types:
                  pkgs.extend(thisgroup.mandatory_packages)
-@@ -2934,12 +3801,54 @@ class YumBase(depsolve.Depsolve):
+@@ -2934,12 +3801,56 @@ class YumBase(depsolve.Depsolve):
              if 'optional' in package_types:
                  pkgs.extend(thisgroup.optional_packages)
  
@@ -188988,10 +189044,12 @@ index 99039e0..b7eedf4 100644
 +                            txmbr.group_member = thisgroup.groupid
 +                            if lupgrade: # For list transaction.
 +                                txmbr._ugroup_member = thisgroup
++                            else:
++                                txmbr._igroup_member = thisgroup
                  except Errors.InstallError, e:
                      self.verbose_logger.debug(_('No package named %s available to be installed'),
                          pkg)
-@@ -2953,7 +3862,9 @@ class YumBase(depsolve.Depsolve):
+@@ -2953,7 +3864,9 @@ class YumBase(depsolve.Depsolve):
                  group_conditionals = enable_group_conditionals
  
              count_cond_test = 0
@@ -189002,7 +189060,7 @@ index 99039e0..b7eedf4 100644
                  for condreq, cond in thisgroup.conditional_packages.iteritems():
                      if self.isPackageInstalled(cond):
                          try:
-@@ -2990,17 +3901,23 @@ class YumBase(depsolve.Depsolve):
+@@ -2990,17 +3903,23 @@ class YumBase(depsolve.Depsolve):
                          if cond not in self.tsInfo.conditionals:
                              self.tsInfo.conditionals[cond] = []
                          self.tsInfo.conditionals[cond].extend(pkgs)
@@ -189033,7 +189091,7 @@ index 99039e0..b7eedf4 100644
          
          if not self.comps.has_group(grpid):
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -3008,7 +3925,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3008,7 +3927,8 @@ class YumBase(depsolve.Depsolve):
          thesegroups = self.comps.return_groups(grpid)
          if not thesegroups:
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
@@ -189043,7 +189101,7 @@ index 99039e0..b7eedf4 100644
          for thisgroup in thesegroups:
              thisgroup.selected = False
              
-@@ -3034,13 +3952,114 @@ class YumBase(depsolve.Depsolve):
+@@ -3034,13 +3954,114 @@ class YumBase(depsolve.Depsolve):
                          for pkg in self.tsInfo.conditionals.get(txmbr.name, []):
                              self.tsInfo.remove(pkg.pkgtup)
          
@@ -189107,8 +189165,8 @@ index 99039e0..b7eedf4 100644
 +                            continue
 +                        grps.add(grp_name)
 +                else:
-+                    self.igroups.add_environment(evgrp.environmentid,
-+                                                 evgrp.allgroups)
++                    ievgrp = self.igroups.add_environment(evgrp.environmentid,
++                                                          evgrp.allgroups)
 +                grps = ",".join(sorted(grps))
 +
 +            try:
@@ -189164,7 +189222,7 @@ index 99039e0..b7eedf4 100644
          # look it up in the self.localPackages first:
          for po in self.localPackages:
              if po.pkgtup == pkgtup:
-@@ -3049,7 +4068,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3049,7 +4070,7 @@ class YumBase(depsolve.Depsolve):
          pkgs = self.pkgSack.searchPkgTuple(pkgtup)
  
          if len(pkgs) == 0:
@@ -189173,7 +189231,7 @@ index 99039e0..b7eedf4 100644
              if allow_missing: #  This can happen due to excludes after .up has
                  return None   # happened.
              raise Errors.DepError, _('Package tuple %s could not be found in packagesack') % str(pkgtup)
-@@ -3065,13 +4084,21 @@ class YumBase(depsolve.Depsolve):
+@@ -3065,13 +4086,21 @@ class YumBase(depsolve.Depsolve):
          return result
  
      def getInstalledPackageObject(self, pkgtup):
@@ -189200,7 +189258,7 @@ index 99039e0..b7eedf4 100644
              raise Errors.RpmDBError, _('Package tuple %s could not be found in rpmdb') % str(pkgtup)
  
          # Dito. FIXME from getPackageObject() for len() > 1 ... :)
-@@ -3079,9 +4106,11 @@ class YumBase(depsolve.Depsolve):
+@@ -3079,9 +4108,11 @@ class YumBase(depsolve.Depsolve):
          return po
          
      def gpgKeyCheck(self):
@@ -189214,7 +189272,7 @@ index 99039e0..b7eedf4 100644
          gpgkeyschecked = self.conf.cachedir + '/.gpgkeyschecked.yum'
          if os.path.exists(gpgkeyschecked):
              return 1
-@@ -3106,9 +4135,13 @@ class YumBase(depsolve.Depsolve):
+@@ -3106,9 +4137,13 @@ class YumBase(depsolve.Depsolve):
              return 1
  
      def returnPackagesByDep(self, depstring):
@@ -189230,7 +189288,7 @@ index 99039e0..b7eedf4 100644
          if not depstring:
              return []
  
-@@ -3132,12 +4165,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3132,12 +4167,23 @@ class YumBase(depsolve.Depsolve):
                          raise Errors.YumBaseError, _('Invalid version flag from: %s') % str(depstring)
                      depflags = SYMBOLFLAGS[flagsymbol]
  
@@ -189257,7 +189315,7 @@ index 99039e0..b7eedf4 100644
          # we get all sorts of randomness here
          errstring = depstring
          if type(depstring) not in types.StringTypes:
-@@ -3149,16 +4193,22 @@ class YumBase(depsolve.Depsolve):
+@@ -3149,16 +4195,22 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError, _('No Package found for %s') % errstring
          
          ps = ListPackageSack(pkglist)
@@ -189284,7 +189342,7 @@ index 99039e0..b7eedf4 100644
          if not depstring:
              return []
  
-@@ -3182,14 +4232,53 @@ class YumBase(depsolve.Depsolve):
+@@ -3182,14 +4234,53 @@ class YumBase(depsolve.Depsolve):
                          raise Errors.YumBaseError, _('Invalid version flag from: %s') % str(depstring)
                      depflags = SYMBOLFLAGS[flagsymbol]
  
@@ -189340,7 +189398,7 @@ index 99039e0..b7eedf4 100644
          
          
          if len(pkglist) == 0:
-@@ -3198,14 +4287,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3198,14 +4289,23 @@ class YumBase(depsolve.Depsolve):
          if len(pkglist) == 1:
              return pkglist[0]
  
@@ -189370,7 +189428,7 @@ index 99039e0..b7eedf4 100644
          returnlist = []
          compatArchList = self.arch.get_arch_list(arch)
          multiLib = []
-@@ -3222,9 +4320,9 @@ class YumBase(depsolve.Depsolve):
+@@ -3222,9 +4322,9 @@ class YumBase(depsolve.Depsolve):
                  singleLib.append(po)
                  
          # we now have three lists.  find the best package(s) of each
@@ -189383,7 +189441,7 @@ index 99039e0..b7eedf4 100644
  
          if single_name and multi and single and multi.name != single.name:
              # Sinlge _must_ match multi, if we want a single package name
-@@ -3238,7 +4336,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3238,7 +4338,7 @@ class YumBase(depsolve.Depsolve):
          # if there's a noarch and it's newer than the multilib, we want
          # just the noarch.  otherwise, we want multi + single
          elif multi:
@@ -189392,7 +189450,7 @@ index 99039e0..b7eedf4 100644
              if best.arch == "noarch":
                  returnlist.append(no)
              else:
-@@ -3246,7 +4344,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3246,7 +4346,7 @@ class YumBase(depsolve.Depsolve):
                  if single: returnlist.append(single)
          # similar for the non-multilib case
          elif single:
@@ -189401,7 +189459,7 @@ index 99039e0..b7eedf4 100644
              if best.arch == "noarch":
                  returnlist.append(no)
              else:
-@@ -3350,28 +4448,76 @@ class YumBase(depsolve.Depsolve):
+@@ -3350,28 +4450,76 @@ class YumBase(depsolve.Depsolve):
              done = True
  
              slow = next_func(slow)
@@ -189455,7 +189513,7 @@ index 99039e0..b7eedf4 100644
 +                assert False, "Checked in for loop."
                  continue
 +        if not found:
-+            self.logger.error(_('Warning: group %s does not exist.'),
++            self.logger.error(_('Warning: Package group %s does not exist.'),
 +                              group_string)
 +
          return tx_return
@@ -189485,7 +189543,7 @@ index 99039e0..b7eedf4 100644
          try:
              txmbrs = self.groupRemove(group_string)
          except yum.Errors.GroupsError:
-@@ -3387,6 +4533,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3387,6 +4535,8 @@ class YumBase(depsolve.Depsolve):
          assert pattern[0] == '@'
          grpid = pattern[1:]
  
@@ -189494,7 +189552,7 @@ index 99039e0..b7eedf4 100644
          thesegroups = self.comps.return_groups(grpid)
          if not thesegroups:
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -3398,7 +4546,11 @@ class YumBase(depsolve.Depsolve):
+@@ -3398,7 +4548,11 @@ class YumBase(depsolve.Depsolve):
      def _minus_deselect(self, pattern):
          """ Remove things from the transaction, like kickstart. """
          assert pattern[0] == '-'
@@ -189507,7 +189565,7 @@ index 99039e0..b7eedf4 100644
  
          if pat and pat[0] == '@':
              pat = pat[1:]
-@@ -3437,14 +4589,87 @@ class YumBase(depsolve.Depsolve):
+@@ -3437,14 +4591,87 @@ class YumBase(depsolve.Depsolve):
              if flag not in self.tsInfo.probFilterFlags:
                  self.tsInfo.probFilterFlags.append(flag)
  
@@ -189601,7 +189659,7 @@ index 99039e0..b7eedf4 100644
          pkgs = []
          was_pattern = False
          if po:
-@@ -3464,9 +4689,14 @@ class YumBase(depsolve.Depsolve):
+@@ -3464,9 +4691,14 @@ class YumBase(depsolve.Depsolve):
                  if kwargs['pattern'] and kwargs['pattern'][0] == '@':
                      return self._at_groupinstall(kwargs['pattern'])
  
@@ -189616,7 +189674,7 @@ index 99039e0..b7eedf4 100644
                                                        ignore_case=False)
                  pkgs.extend(mypkgs)
                  # if we have anything left unmatched, let's take a look for it
-@@ -3477,20 +4707,12 @@ class YumBase(depsolve.Depsolve):
+@@ -3477,20 +4709,12 @@ class YumBase(depsolve.Depsolve):
                      self.verbose_logger.debug(_('Checking for virtual provide or file-provide for %s'), 
                          arg)
  
@@ -189643,7 +189701,7 @@ index 99039e0..b7eedf4 100644
              else:
                  nevra_dict = self._nevra_kwarg_parse(kwargs)
  
-@@ -3499,6 +4721,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3499,6 +4723,8 @@ class YumBase(depsolve.Depsolve):
                       ver=nevra_dict['version'], rel=nevra_dict['release'])
                  self._add_not_found_a(pkgs, nevra_dict)
                  
@@ -189652,7 +189710,7 @@ index 99039e0..b7eedf4 100644
              if pkgs:
                  # if was_pattern or nevra-dict['arch'] is none, take the list
                  # of arches based on our multilib_compat config and 
-@@ -3577,17 +4801,21 @@ class YumBase(depsolve.Depsolve):
+@@ -3577,17 +4803,21 @@ class YumBase(depsolve.Depsolve):
                      continue
              
              # make sure this shouldn't be passed to update:
@@ -189678,7 +189736,7 @@ index 99039e0..b7eedf4 100644
                  obsoleting_pkg = self._test_loop(po, self._pkg2obspkg)
              if obsoleting_pkg is not None:
                  # this is not a definitive check but it'll make sure we don't
-@@ -3600,23 +4828,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3600,23 +4830,23 @@ class YumBase(depsolve.Depsolve):
                      already_obs = pkgs[0]
  
                  if already_obs:
@@ -189709,7 +189767,7 @@ index 99039e0..b7eedf4 100644
                      continue
  
              # make sure we don't have a name.arch of this already installed
-@@ -3630,8 +4858,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3630,8 +4860,8 @@ class YumBase(depsolve.Depsolve):
                          found = True
                          break
                  if not found:
@@ -189720,7 +189778,7 @@ index 99039e0..b7eedf4 100644
                      tx_return.extend(txmbrs)
                      continue
  
-@@ -3719,19 +4947,47 @@ class YumBase(depsolve.Depsolve):
+@@ -3719,19 +4949,47 @@ class YumBase(depsolve.Depsolve):
          return txmbr
  
      def update(self, po=None, requiringPo=None, update_to=False, **kwargs):
@@ -189775,7 +189833,7 @@ index 99039e0..b7eedf4 100644
          tx_return = []
          if not po and not kwargs: # update everything (the easy case)
              self.verbose_logger.log(logginglevels.DEBUG_2, _('Updating Everything'))
-@@ -3765,7 +5021,15 @@ class YumBase(depsolve.Depsolve):
+@@ -3765,7 +5023,15 @@ class YumBase(depsolve.Depsolve):
                      if new is None:
                          continue
                      tx_return.extend(self.update(po=new))
@@ -189792,7 +189850,7 @@ index 99039e0..b7eedf4 100644
              return tx_return
  
          # complications
-@@ -3787,13 +5051,16 @@ class YumBase(depsolve.Depsolve):
+@@ -3787,13 +5053,16 @@ class YumBase(depsolve.Depsolve):
                  return self._minus_deselect(kwargs['pattern'])
  
              if kwargs['pattern'] and kwargs['pattern'][0] == '@':
@@ -189811,7 +189869,7 @@ index 99039e0..b7eedf4 100644
  
              if not instpkgs and not availpkgs:
                  depmatches = []
-@@ -3805,6 +5072,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3805,6 +5074,8 @@ class YumBase(depsolve.Depsolve):
                  except yum.Errors.YumBaseError, e:
                      self.logger.critical(_('%s') % e)
  
@@ -189820,7 +189878,7 @@ index 99039e0..b7eedf4 100644
                  if update_to:
                      availpkgs.extend(depmatches)
                  else:
-@@ -3816,9 +5085,12 @@ class YumBase(depsolve.Depsolve):
+@@ -3816,9 +5087,12 @@ class YumBase(depsolve.Depsolve):
              try:
                  if update_to:
                      m = []
@@ -189834,7 +189892,7 @@ index 99039e0..b7eedf4 100644
                      m = self.pkgSack.returnNewestByNameArch(patterns=pats)
              except Errors.PackageSackError:
                  m = []
-@@ -3843,7 +5115,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3843,7 +5117,7 @@ class YumBase(depsolve.Depsolve):
                      availpkgs = self._compare_providers(availpkgs, requiringPo)
                      availpkgs = map(lambda x: x[0], availpkgs)
                  elif not availpkgs:
@@ -189843,7 +189901,7 @@ index 99039e0..b7eedf4 100644
         
          # for any thing specified
          # get the list of available pkgs matching it (or take the po)
-@@ -3879,6 +5151,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3879,6 +5153,7 @@ class YumBase(depsolve.Depsolve):
                      if obsoleting_pkg is None:
                          continue
                      obs_pkgs.append(obsoleting_pkg)
@@ -189851,7 +189909,7 @@ index 99039e0..b7eedf4 100644
                  for obsoleting_pkg in packagesNewestByName(obs_pkgs):
                      tx_return.extend(self.install(po=obsoleting_pkg))
              for available_pkg in availpkgs:
-@@ -3920,11 +5193,29 @@ class YumBase(depsolve.Depsolve):
+@@ -3920,11 +5195,29 @@ class YumBase(depsolve.Depsolve):
                      tx_return.append(txmbr)
                          
          for available_pkg in availpkgs:
@@ -189881,7 +189939,7 @@ index 99039e0..b7eedf4 100644
                  self.verbose_logger.log(logginglevels.DEBUG_2, _('Not Updating Package that is obsoleted: %s'), available_pkg)
                  tx_return.extend(self.update(po=obsoleting_pkg))
                  continue
-@@ -3985,11 +5276,18 @@ class YumBase(depsolve.Depsolve):
+@@ -3985,11 +5278,18 @@ class YumBase(depsolve.Depsolve):
          return tx_return
          
      def remove(self, po=None, **kwargs):
@@ -189905,7 +189963,7 @@ index 99039e0..b7eedf4 100644
          if not po and not kwargs:
              raise Errors.RemoveError, 'Nothing specified to remove'
          
-@@ -4008,6 +5306,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4008,6 +5308,10 @@ class YumBase(depsolve.Depsolve):
                      return self._at_groupremove(kwargs['pattern'])
  
                  (e,m,u) = self.rpmdb.matchPackageNames([kwargs['pattern']])
@@ -189916,7 +189974,7 @@ index 99039e0..b7eedf4 100644
                  pkgs.extend(e)
                  pkgs.extend(m)
                  if u:
-@@ -4018,6 +5320,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4018,6 +5322,10 @@ class YumBase(depsolve.Depsolve):
                      except yum.Errors.YumBaseError, e:
                          self.logger.critical(_('%s') % e)
                      
@@ -189927,7 +189985,7 @@ index 99039e0..b7eedf4 100644
                      if not depmatches:
                          arg = to_unicode(arg)
                          self.logger.critical(_('No Match for argument: %s') % to_unicode(arg))
-@@ -4055,17 +5361,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4055,17 +5363,19 @@ class YumBase(depsolve.Depsolve):
          return tx_return
  
      def installLocal(self, pkg, po=None, updateonly=False):
@@ -189957,7 +190015,7 @@ index 99039e0..b7eedf4 100644
          # read in the package into a YumLocalPackage Object
          # append it to self.localPackages
          # check if it can be installed or updated based on nevra versus rpmdb
-@@ -4183,16 +5491,15 @@ class YumBase(depsolve.Depsolve):
+@@ -4183,16 +5493,15 @@ class YumBase(depsolve.Depsolve):
          return tx_return
  
      def reinstallLocal(self, pkg, po=None):
@@ -189982,7 +190040,7 @@ index 99039e0..b7eedf4 100644
          if not po:
              try:
                  po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg,
-@@ -4215,13 +5522,29 @@ class YumBase(depsolve.Depsolve):
+@@ -4215,13 +5524,29 @@ class YumBase(depsolve.Depsolve):
          return self.reinstall(po=po)
  
      def reinstall(self, po=None, **kwargs):
@@ -190015,7 +190073,7 @@ index 99039e0..b7eedf4 100644
          tx_mbrs = []
          if po: # The po, is the "available" po ... we want the installed po
              tx_mbrs.extend(self.remove(pkgtup=po.pkgtup))
-@@ -4240,10 +5563,11 @@ class YumBase(depsolve.Depsolve):
+@@ -4240,10 +5565,11 @@ class YumBase(depsolve.Depsolve):
              # pkgs that are obsolete.
              old_conf_obs = self.conf.obsoletes
              self.conf.obsoletes = False
@@ -190029,7 +190087,7 @@ index 99039e0..b7eedf4 100644
              self.conf.obsoletes = old_conf_obs
              if len(members) == 0:
                  self.tsInfo.remove(item.pkgtup)
-@@ -4259,16 +5583,15 @@ class YumBase(depsolve.Depsolve):
+@@ -4259,16 +5585,15 @@ class YumBase(depsolve.Depsolve):
          return tx_mbrs
          
      def downgradeLocal(self, pkg, po=None):
@@ -190054,7 +190112,7 @@ index 99039e0..b7eedf4 100644
          if not po:
              try:
                  po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg,
-@@ -4309,13 +5632,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4309,13 +5634,19 @@ class YumBase(depsolve.Depsolve):
          return False
          
      def downgrade(self, po=None, **kwargs):
@@ -190081,7 +190139,7 @@ index 99039e0..b7eedf4 100644
          if not po and not kwargs:
              raise Errors.DowngradeError, 'Nothing specified to downgrade'
  
-@@ -4397,6 +5726,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4397,6 +5728,10 @@ class YumBase(depsolve.Depsolve):
          # installed version. Indexed fromn the latest installed pkgtup.
          downgrade_apkgs = {}
          for pkg in sorted(apkgs):
@@ -190092,7 +190150,7 @@ index 99039e0..b7eedf4 100644
              na  = (pkg.name, pkg.arch)
  
              # Here we allow downgrades from .i386 => .noarch, or .i586 => .i386
-@@ -4421,6 +5754,9 @@ class YumBase(depsolve.Depsolve):
+@@ -4421,6 +5756,9 @@ class YumBase(depsolve.Depsolve):
                  warned_nas.add(na)
                  continue
  
@@ -190102,7 +190160,7 @@ index 99039e0..b7eedf4 100644
              if pkg.verGE(lipkg):
                  if na not in warned_nas:
                      msg = _('Only Upgrade available on package: %s') % pkg
-@@ -4457,7 +5793,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4457,7 +5795,7 @@ class YumBase(depsolve.Depsolve):
          if e and v and r:
              evr = '%s:%s-%s' % (e, v, r)
          elif v and r:
@@ -190111,7 +190169,7 @@ index 99039e0..b7eedf4 100644
          elif e and v:
              evr = '%s:%s' % (e, v)
          elif v: # e and r etc. is just too weird to print
-@@ -4500,12 +5836,24 @@ class YumBase(depsolve.Depsolve):
+@@ -4500,12 +5838,24 @@ class YumBase(depsolve.Depsolve):
  
          return returndict
  
@@ -190139,7 +190197,7 @@ index 99039e0..b7eedf4 100644
          old_conf_obs = self.conf.obsoletes
          self.conf.obsoletes = False
          done = False
-@@ -4515,19 +5863,46 @@ class YumBase(depsolve.Depsolve):
+@@ -4515,19 +5865,46 @@ class YumBase(depsolve.Depsolve):
                      done = True
          for pkg in transaction.trans_data:
              if pkg.state == 'Downgrade':
@@ -190186,7 +190244,7 @@ index 99039e0..b7eedf4 100644
                  if self.install(pkgtup=pkg.pkgtup):
                      done = True
          for pkg in transaction.trans_data:
-@@ -4538,8 +5913,14 @@ class YumBase(depsolve.Depsolve):
+@@ -4538,8 +5915,14 @@ class YumBase(depsolve.Depsolve):
          return done
  
      def history_undo(self, transaction):
@@ -190203,7 +190261,7 @@ index 99039e0..b7eedf4 100644
          # NOTE: This is somewhat basic atm. ... for instance we don't check
          #       that we are going from the old new version. However it's still
          #       better than the RHN rollback code, and people pay for that :).
-@@ -4616,7 +5997,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4616,7 +5999,7 @@ class YumBase(depsolve.Depsolve):
  
          except urlgrabber.grabber.URLGrabError, e:
              raise Errors.YumBaseError(_('GPG key retrieval failed: ') +
@@ -190212,7 +190270,7 @@ index 99039e0..b7eedf4 100644
                                        
          # check for a .asc file accompanying it - that's our gpg sig on the key
          # suck it down and do the check
-@@ -4649,7 +6030,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4649,7 +6032,7 @@ class YumBase(depsolve.Depsolve):
              keys_info = misc.getgpgkeyinfo(rawkey, multiple=True)
          except ValueError, e:
              raise Errors.YumBaseError(_('Invalid GPG Key from %s: %s') % 
@@ -190221,7 +190279,7 @@ index 99039e0..b7eedf4 100644
          keys = []
          for keyinfo in keys_info:
              thiskey = {}
-@@ -4674,39 +6055,49 @@ class YumBase(depsolve.Depsolve):
+@@ -4674,39 +6057,49 @@ class YumBase(depsolve.Depsolve):
              if pkgs:
                  pkgs = sorted(pkgs)[-1]
                  msg = (_('Importing %s key 0x%s:\n'
@@ -190289,7 +190347,7 @@ index 99039e0..b7eedf4 100644
          user_cb_fail = False
          for keyurl in keyurls:
              keys = self._retrievePublicKey(keyurl, repo)
-@@ -4725,7 +6116,9 @@ class YumBase(depsolve.Depsolve):
+@@ -4725,7 +6118,9 @@ class YumBase(depsolve.Depsolve):
                      # Try installing/updating GPG key
                      self._getKeyImportMessage(info, keyurl)
                      rc = False
@@ -190300,7 +190358,7 @@ index 99039e0..b7eedf4 100644
                          rc = True
                          
                      # grab the .sig/.asc for the keyurl, if it exists
-@@ -4751,8 +6144,8 @@ class YumBase(depsolve.Depsolve):
+@@ -4751,8 +6146,8 @@ class YumBase(depsolve.Depsolve):
                  ts = self.rpmdb.readOnlyTS()
                  result = ts.pgpImportPubkey(misc.procgpgkey(info['raw_key']))
                  if result != 0:
@@ -190311,7 +190369,7 @@ index 99039e0..b7eedf4 100644
                  self.logger.info(_('Key imported successfully'))
                  key_installed = True
  
-@@ -4760,18 +6153,20 @@ class YumBase(depsolve.Depsolve):
+@@ -4760,18 +6155,20 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError, _("Didn't install any keys")
  
          if not key_installed:
@@ -190337,7 +190395,7 @@ index 99039e0..b7eedf4 100644
      
      def _getAnyKeyForRepo(self, repo, destdir, keyurl_list, is_cakey=False, callback=None):
          """
-@@ -4788,6 +6183,18 @@ class YumBase(depsolve.Depsolve):
+@@ -4788,6 +6185,18 @@ class YumBase(depsolve.Depsolve):
          """
  
          key_installed = False
@@ -190356,7 +190414,7 @@ index 99039e0..b7eedf4 100644
          user_cb_fail = False
          for keyurl in keyurl_list:
              keys = self._retrievePublicKey(keyurl, repo, getSig=not is_cakey)
-@@ -4819,8 +6226,11 @@ class YumBase(depsolve.Depsolve):
+@@ -4819,8 +6228,11 @@ class YumBase(depsolve.Depsolve):
                  if not key_installed:
                      self._getKeyImportMessage(info, keyurl, keytype)
                      rc = False
@@ -190369,7 +190427,7 @@ index 99039e0..b7eedf4 100644
                      elif callback:
                          rc = callback({"repo": repo, "userid": info['userid'],
                                          "hexkeyid": info['hexkeyid'], "keyurl": keyurl,
-@@ -4835,7 +6245,8 @@ class YumBase(depsolve.Depsolve):
+@@ -4835,7 +6247,8 @@ class YumBase(depsolve.Depsolve):
                  # Import the key
                  result = misc.import_key_to_pubring(info['raw_key'], info['hexkeyid'], gpgdir=destdir)
                  if not result:
@@ -190379,7 +190437,7 @@ index 99039e0..b7eedf4 100644
                  self.logger.info(_('Key imported successfully'))
                  key_installed = True
                  # write out the key id to imported_cakeys in the repos basedir
-@@ -4851,36 +6262,35 @@ class YumBase(depsolve.Depsolve):
+@@ -4851,36 +6264,35 @@ class YumBase(depsolve.Depsolve):
                              pass
  
          if not key_installed and user_cb_fail:
@@ -190432,7 +190490,7 @@ index 99039e0..b7eedf4 100644
          self._getAnyKeyForRepo(repo, repo.gpgcadir, repo.gpgcakey, is_cakey=True, callback=callback)
  
      def _limit_installonly_pkgs(self):
-@@ -4889,7 +6299,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4889,7 +6301,7 @@ class YumBase(depsolve.Depsolve):
              New in 3.2.24: Obey yumdb_info.installonly data. """
  
          def _sort_and_filter_installonly(pkgs):
@@ -190441,7 +190499,7 @@ index 99039e0..b7eedf4 100644
                  using the yumdb. """
              ret_beg = []
              ret_mid = []
-@@ -4917,6 +6327,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4917,6 +6329,10 @@ class YumBase(depsolve.Depsolve):
  
          if self.conf.installonly_limit < 1 :
              return 
@@ -190452,7 +190510,7 @@ index 99039e0..b7eedf4 100644
              
          toremove = []
          #  We "probably" want to use either self.ts or self.rpmdb.ts if either
-@@ -4926,23 +6340,30 @@ class YumBase(depsolve.Depsolve):
+@@ -4926,23 +6342,30 @@ class YumBase(depsolve.Depsolve):
          # so self.rpmdb.ts should be valid.
          ts = self.rpmdb.readOnlyTS()
          (cur_kernel_v, cur_kernel_r) = misc.get_running_kernel_version_release(ts)
@@ -190491,7 +190549,7 @@ index 99039e0..b7eedf4 100644
              for po in installed:
                  if (po.version, po.release) == (cur_kernel_v, cur_kernel_r): 
                      # don't remove running
-@@ -4959,19 +6380,22 @@ class YumBase(depsolve.Depsolve):
+@@ -4959,19 +6382,22 @@ class YumBase(depsolve.Depsolve):
              txmbr.depends_on.append(rel)
  
      def processTransaction(self, callback=None,rpmTestDisplay=None, rpmDisplay=None):
@@ -190527,7 +190585,7 @@ index 99039e0..b7eedf4 100644
          
          if not callback:
              callback = callbacks.ProcessTransNoOutputCallback()
-@@ -5062,8 +6486,8 @@ class YumBase(depsolve.Depsolve):
+@@ -5062,8 +6488,8 @@ class YumBase(depsolve.Depsolve):
                  raise Errors.YumRPMCheckError, retmsgs
              retmsgs = [_('ERROR with transaction check vs depsolve:')]
              retmsgs.extend(msgs) 
@@ -190538,7 +190596,7 @@ index 99039e0..b7eedf4 100644
              raise Errors.YumRPMCheckError,retmsgs
          
          tsConf = {}
-@@ -5114,13 +6538,19 @@ class YumBase(depsolve.Depsolve):
+@@ -5114,13 +6540,19 @@ class YumBase(depsolve.Depsolve):
          return results
  
      def add_enable_repo(self, repoid, baseurls=[], mirrorlist=None, **kwargs):
@@ -190565,7 +190623,7 @@ index 99039e0..b7eedf4 100644
          # out of place fixme - maybe we should make this the default repo addition
          # routine and use it from getReposFromConfigFile(), etc.
          newrepo = yumRepo.YumRepository(repoid)
-@@ -5167,9 +6597,15 @@ class YumBase(depsolve.Depsolve):
+@@ -5167,9 +6599,15 @@ class YumBase(depsolve.Depsolve):
  
      def setCacheDir(self, force=False, tmpdir=None, reuse=True,
                      suffix='/$basearch/$releasever'):
@@ -190584,7 +190642,7 @@ index 99039e0..b7eedf4 100644
          if not force and os.geteuid() == 0:
              return True # We are root, not forced, so happy with the global dir.
          if tmpdir is None:
-@@ -5179,7 +6615,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5179,7 +6617,7 @@ class YumBase(depsolve.Depsolve):
          try:
              cachedir = misc.getCacheDir(tmpdir, reuse)
          except (IOError, OSError), e:
@@ -190593,7 +190651,7 @@ index 99039e0..b7eedf4 100644
              cachedir = None
              
          if cachedir is None:
-@@ -5190,6 +6626,8 @@ class YumBase(depsolve.Depsolve):
+@@ -5190,6 +6628,8 @@ class YumBase(depsolve.Depsolve):
              self.prerepoconf.cachedir = cachedir
          else:
              self.repos.setCacheDir(cachedir)
@@ -190602,7 +190660,7 @@ index 99039e0..b7eedf4 100644
          self.conf.cachedir = cachedir
          return True # We got a new cache dir
  
-@@ -5220,13 +6658,24 @@ class YumBase(depsolve.Depsolve):
+@@ -5220,13 +6660,24 @@ class YumBase(depsolve.Depsolve):
          self.history.write_addon_data('config-repos', myrepos)
          
      def verify_plugins_cb(self, verify_package):
@@ -190630,7 +190688,7 @@ index 99039e0..b7eedf4 100644
          if self.tsInfo._unresolvedMembers:
              if auto:
                  self.logger.critical(_("Dependencies not solved. Will not save unresolved transaction."))
-@@ -5234,7 +6683,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5234,7 +6685,7 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError(_("Dependencies not solved. Will not save unresolved transaction."))
          
          if not filename:
@@ -190639,7 +190697,7 @@ index 99039e0..b7eedf4 100644
              fd,filename = tempfile.mkstemp(suffix='.yumtx', prefix=prefix)
              f = os.fdopen(fd, 'w')
          else:
-@@ -5244,13 +6693,17 @@ class YumBase(depsolve.Depsolve):
+@@ -5244,13 +6695,17 @@ class YumBase(depsolve.Depsolve):
          
          msg = "%s\n" % self.rpmdb.simpleVersion(main_only=True)[0]
          msg += "%s\n" % self.ts.getTsFlags()
@@ -190660,7 +190718,7 @@ index 99039e0..b7eedf4 100644
          msg += "%s\n" % len(self.tsInfo.getMembers())
          for txmbr in self.tsInfo.getMembers():
              msg += txmbr._dump()
-@@ -5260,42 +6713,84 @@ class YumBase(depsolve.Depsolve):
+@@ -5260,42 +6715,84 @@ class YumBase(depsolve.Depsolve):
          except (IOError, OSError), e:
              self._ts_save_file = None
              if auto:
@@ -190757,7 +190815,7 @@ index 99039e0..b7eedf4 100644
              if ignorerpm:
                  msg += _(" ignoring, as requested.")
                  self.logger.critical(_(msg))
-@@ -5318,8 +6813,17 @@ class YumBase(depsolve.Depsolve):
+@@ -5318,8 +6815,17 @@ class YumBase(depsolve.Depsolve):
          numrepos = int(data[2].strip())
          repos = []
          rindex=3+numrepos
@@ -190776,7 +190834,7 @@ index 99039e0..b7eedf4 100644
  
          # pkgs/txmbrs
          numpkgs = int(data[rindex].strip())
-@@ -5329,6 +6833,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5329,6 +6835,7 @@ class YumBase(depsolve.Depsolve):
          pkgcount = 0
          pkgprob = False
          curpkg = None
@@ -190784,7 +190842,7 @@ index 99039e0..b7eedf4 100644
          for l in data[pkgstart:]:
              l = l.rstrip()
              # our main txmbrs
-@@ -5356,6 +6861,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5356,6 +6863,7 @@ class YumBase(depsolve.Depsolve):
                      if not ignoremissing:
                          raise Errors.YumBaseError(msg)
                      else:
@@ -190792,7 +190850,7 @@ index 99039e0..b7eedf4 100644
                          self.logger.critical(msg)
                  else:
                      pkgcount += 1
-@@ -5432,12 +6938,18 @@ class YumBase(depsolve.Depsolve):
+@@ -5432,12 +6940,18 @@ class YumBase(depsolve.Depsolve):
          if pkgprob:
              msg = _("Transaction members, relations are missing or ts has been modified,")
              if ignoremissing:
@@ -190811,7 +190869,7 @@ index 99039e0..b7eedf4 100644
          return self.tsInfo.getMembers()
  
      def _remove_old_deps(self):
-@@ -5470,18 +6982,6 @@ class YumBase(depsolve.Depsolve):
+@@ -5470,18 +6984,6 @@ class YumBase(depsolve.Depsolve):
                      if requiring == required: # if they are self-requiring skip them
                          continue
                          
@@ -190830,7 +190888,7 @@ index 99039e0..b7eedf4 100644
                      #for tbi_pkg in self.tsInfo.getMembersWithState(output_states=TS_INSTALL_STATES):
                      #   for reqtuple in tbi_pkg.po.requires:
                      #        if required.provides_for(reqtuple):
-@@ -5533,7 +7033,24 @@ class YumBase(depsolve.Depsolve):
+@@ -5533,7 +7035,24 @@ class YumBase(depsolve.Depsolve):
                      # Debugging output
                      self.verbose_logger.log(logginglevels.DEBUG_2, _("%s has revdep %s which was user-installed."), pkg, curpkg)
                      ok_to_remove[pkg] = False
@@ -190855,7 +190913,7 @@ index 99039e0..b7eedf4 100644
                  visited[curpkg] = True
              all_leaves_visited = True
              leaves = curpkg.requiring_packages()
-@@ -5547,4 +7064,3 @@ class YumBase(depsolve.Depsolve):
+@@ -5547,4 +7066,3 @@ class YumBase(depsolve.Depsolve):
          # Debugging output
          self.verbose_logger.log(logginglevels.DEBUG_2, _("%s has no user-installed revdeps."), pkg)
          return False
@@ -191008,7 +191066,7 @@ index 7ad25ce..a9a8e53 100644
          pass
          
 diff --git a/yum/comps.py b/yum/comps.py
-index 65f6d5e..706e2a4 100755
+index 65f6d5e..92e87ba 100755
 --- a/yum/comps.py
 +++ b/yum/comps.py
 @@ -16,14 +16,14 @@
@@ -191462,7 +191520,7 @@ index 65f6d5e..706e2a4 100755
 +                        break
 +            else:
 +                evgroup.installed = False
-+                for grpname in evgroup.optional:
++                for grpname in evgroup.options:
 +                    if grpname in inst_grp_names:
 +                        evgroup.installed = True
 +                        break
@@ -199700,7 +199758,7 @@ index e5e9ece..35359e2 100644
          fo = None
  
 diff --git a/yumcommands.py b/yumcommands.py
-index 4dcbea7..e01c96d 100644
+index 4dcbea7..291eae5 100644
 --- a/yumcommands.py
 +++ b/yumcommands.py
 @@ -13,6 +13,7 @@
@@ -200580,7 +200638,7 @@ index 4dcbea7..e01c96d 100644
          remap = {'update' : 'upgrade',
                   'erase' : 'remove',
                   'mark-erase' : 'mark-remove',
-@@ -479,32 +950,83 @@ class GroupsCommand(YumCommand):
+@@ -479,32 +950,86 @@ class GroupsCommand(YumCommand):
          return cmd, extcmds
  
      def doCheck(self, base, basecmd, extcmds):
@@ -200603,6 +200661,7 @@ index 4dcbea7..e01c96d 100644
 +        ocmds_arg = []
 +        if base.conf.group_command == 'objects':
 +            ocmds_arg = ('mark-install', 'mark-remove',
++                         'mark-blacklist',
 +                         'mark-packages', 'mark-packages-force',
 +                         'unmark-packages',
 +                         'mark-packages-sync', 'mark-packages-sync-force',
@@ -200611,6 +200670,8 @@ index 4dcbea7..e01c96d 100644
 +                         'mark-groups-sync', 'mark-groups-sync-force')
 +
 +            ocmds_all = ('mark-install', 'mark-remove', 'mark-convert',
++                         'mark-convert-whitelist', 'mark-convert-blacklist',
++                         'mark-blacklist',
 +                         'mark-packages', 'mark-packages-force',
 +                         'unmark-packages',
 +                         'mark-packages-sync', 'mark-packages-sync-force',
@@ -200646,13 +200707,13 @@ index 4dcbea7..e01c96d 100644
 +            pass
 +        elif not os.path.exists(os.path.dirname(base.igroups.filename)):
 +            base.logger.critical(_("There is no installed groups file."))
-+            base.logger.critical(_("Maybe run: yum groups mark convert"))
++            base.logger.critical(_("Maybe run: yum groups mark convert (see man yum)"))
 +        elif not os.access(os.path.dirname(base.igroups.filename), os.R_OK):
 +            base.logger.critical(_("You don't have access to the groups DBs."))
 +            raise cli.CliError
 +        elif not os.path.exists(base.igroups.filename):
 +            base.logger.critical(_("There is no installed groups file."))
-+            base.logger.critical(_("Maybe run: yum groups mark convert"))
++            base.logger.critical(_("Maybe run: yum groups mark convert (see man yum)"))
 +        elif not os.access(base.igroups.filename, os.R_OK):
 +            base.logger.critical(_("You don't have access to the groups DB."))
 +            raise cli.CliError
@@ -200674,7 +200735,7 @@ index 4dcbea7..e01c96d 100644
          cmd, extcmds = self._grp_cmd(basecmd, extcmds)
  
          self._grp_setup_doCommand(base)
-@@ -514,140 +1036,551 @@ class GroupsCommand(YumCommand):
+@@ -514,140 +1039,573 @@ class GroupsCommand(YumCommand):
          if cmd == 'list':
              return base.returnGroupLists(extcmds)
  
@@ -200708,6 +200769,24 @@ index 4dcbea7..e01c96d 100644
 +                base.igroups.save()
 +                return 0, ['Marked install: ' + ','.join(extcmds)]
 +
++            if cmd == 'mark-blacklist':
++                gRG = base._groupReturnGroups(extcmds,ignore_case=False)
++                igrps, grps, ievgrps, evgrps = gRG
++                for ievgrp in ievgrps:
++                    evgrp = base.comps.return_environment(igrp.evgid)
++                    if not evgrp:
++                        continue
++                    base.igroups.changed = True
++                    ievgrp.grp_names.update(grp.groups)
++                for igrp in igrps:
++                    grp = base.comps.return_group(igrp.gid)
++                    if not grp:
++                        continue
++                    base.igroups.changed = True
++                    igrp.pkg_names.update(grp.packages)
++                base.igroups.save()
++                return 0, ['Marked upgrade blacklist: ' + ','.join(extcmds)]
++
 +            if cmd in ('mark-packages', 'mark-packages-force'):
 +                if len(extcmds) < 2:
 +                    return 1, ['No group or package given']
@@ -200803,14 +200882,15 @@ index 4dcbea7..e01c96d 100644
 +                    return 0, ['Marked groups-sync: ' + ','.join(extcmds)]
 +
 +            # FIXME: This doesn't do environment groups atm.
-+            if cmd == 'mark-convert':
++            if cmd in ('mark-convert',
++                       'mark-convert-whitelist', 'mark-convert-blacklist'):
 +                # Convert old style info. into groups as objects.
 +
 +                def _convert_grp(grp):
 +                    if not grp.installed:
 +                        return
 +                    pkg_names = []
-+                    for pkg in base.rpmdb.searchNames(pkg_names):
++                    for pkg in base.rpmdb.searchNames(grp.packages):
 +                        if 'group_member' in pkg.yumdb_info:
 +                            continue
 +                        pkg.yumdb_info.group_member = grp.groupid
@@ -200819,7 +200899,10 @@ index 4dcbea7..e01c96d 100644
 +                    #  We only mark the packages installed as a known part of
 +                    # the group. This way "group update" will work and install
 +                    # any remaining packages, as it would before the conversion.
-+                    base.igroups.add_group(grp.groupid, pkg_names)
++                    if cmd == 'mark-convert-whitelist':
++                        base.igroups.add_group(grp.groupid, pkg_names)
++                    else:
++                        base.igroups.add_group(grp.groupid, grp.packages)
 +
 +                # Blank everything.
 +                for gid in base.igroups.groups.keys():
@@ -201101,9 +201184,6 @@ index 4dcbea7..e01c96d 100644
 +        """
          return False
  
--class ProvidesCommand(YumCommand):
--    def getNames(self):
--        return ['provides', 'whatprovides']
 +    def cacheRequirement(self, base, basecmd, extcmds):
 +        """Return the cache requirements for the remote repos.
 +
@@ -201115,18 +201195,18 @@ index 4dcbea7..e01c96d 100644
 +        return 'read-only:past'
 +
 +
-+class ProvidesCommand(YumCommand):
+ class ProvidesCommand(YumCommand):
 +    """A class containing methods needed by the cli to execute the
 +    provides command.
 +    """
 +
-+    def getNames(self):
+     def getNames(self):
 +        """Return a list containing the names of this command.  This
 +        command can be called from the command line by using any of these names.
 +
 +        :return: a list containing the names of this command
 +        """
-+        return ['provides', 'whatprovides']
+         return ['provides', 'whatprovides']
  
      def getUsage(self):
 +        """Return a usage string for this command.
@@ -201254,7 +201334,7 @@ index 4dcbea7..e01c96d 100644
                  ypl.obsoletes = typl.obsoletes
                  ypl.obsoletesTuples = typl.obsoletesTuples
  
-@@ -673,164 +1606,474 @@ class CheckUpdateCommand(YumCommand):
+@@ -673,164 +1631,474 @@ class CheckUpdateCommand(YumCommand):
                  for obtup in sorted(ypl.obsoletesTuples,
                                      key=operator.itemgetter(0)):
                      base.updatesObsoletesList(obtup, 'obsoletes',
@@ -201760,7 +201840,7 @@ index 4dcbea7..e01c96d 100644
          def _repo_size(repo):
              ret = 0
              for pkg in repo.sack.returnPackages():
-@@ -838,12 +2081,9 @@ class RepoListCommand(YumCommand):
+@@ -838,12 +2106,9 @@ class RepoListCommand(YumCommand):
              return base.format_number(ret)
  
          def _repo_match(repo, patterns):
@@ -201775,7 +201855,7 @@ index 4dcbea7..e01c96d 100644
                      return True
              return False
  
-@@ -857,7 +2097,10 @@ class RepoListCommand(YumCommand):
+@@ -857,7 +2122,10 @@ class RepoListCommand(YumCommand):
              arg = 'enabled'
          extcmds = map(lambda x: x.lower(), extcmds)
  
@@ -201787,7 +201867,7 @@ index 4dcbea7..e01c96d 100644
          if arg != 'disabled' or extcmds:
              try:
                  # Setup so len(repo.sack) is correct
-@@ -866,6 +2109,13 @@ class RepoListCommand(YumCommand):
+@@ -866,6 +2134,13 @@ class RepoListCommand(YumCommand):
              except yum.Errors.RepoError:
                  if verbose:
                      raise
@@ -201801,7 +201881,7 @@ index 4dcbea7..e01c96d 100644
  
          repos = base.repos.repos.values()
          repos.sort()
-@@ -924,111 +2174,113 @@ class RepoListCommand(YumCommand):
+@@ -924,111 +2199,113 @@ class RepoListCommand(YumCommand):
                  ui_enabled = dhibeg + _('disabled') + hiend
                  ui_endis_wid = utf8_width(_('disabled'))
  
@@ -202011,7 +202091,7 @@ index 4dcbea7..e01c96d 100644
  
          if not verbose and cols:
              #  Work out the first (id) and last (enabled/disalbed/count),
-@@ -1088,21 +2340,64 @@ class RepoListCommand(YumCommand):
+@@ -1088,21 +2365,64 @@ class RepoListCommand(YumCommand):
          return 0, ['repolist: ' +to_unicode(locale.format("%d", tot_num, True))]
  
      def needTs(self, base, basecmd, extcmds):
@@ -202076,7 +202156,7 @@ index 4dcbea7..e01c96d 100644
          if len(extcmds) == 0:
              base.usage()
              raise cli.CliError
-@@ -1147,82 +2442,230 @@ class HelpCommand(YumCommand):
+@@ -1147,82 +2467,230 @@ class HelpCommand(YumCommand):
          return help_output
  
      def doCommand(self, base, basecmd, extcmds):
@@ -202289,6 +202369,7 @@ index 4dcbea7..e01c96d 100644
          return _("Display a version for the machine and/or available repos.")
  
      def doCommand(self, base, basecmd, extcmds):
+-        vcmd = 'installed'
 +        """Execute this command.
 +
 +        :param base: a :class:`yum.Yumbase` object
@@ -202302,7 +202383,7 @@ index 4dcbea7..e01c96d 100644
 +            1 = we've errored, exit with error string
 +            2 = we've got work yet to do, onto the next stage
 +        """
-         vcmd = 'installed'
++        vcmd = 'installed'
          if extcmds:
              vcmd = extcmds[0]
 +        if vcmd in ('grouplist', 'groupinfo',
@@ -202316,7 +202397,7 @@ index 4dcbea7..e01c96d 100644
  
          def _append_repos(cols, repo_data):
              for repoid in sorted(repo_data):
-@@ -1264,7 +2707,7 @@ class VersionCommand(YumCommand):
+@@ -1264,7 +2732,7 @@ class VersionCommand(YumCommand):
  
          if vcmd == 'groupinfo':
              for group in groups:
@@ -202325,7 +202406,7 @@ index 4dcbea7..e01c96d 100644
                      continue
                  print _(" Group   :"), group
                  print _(" Packages:")
-@@ -1284,11 +2727,35 @@ class VersionCommand(YumCommand):
+@@ -1284,11 +2752,35 @@ class VersionCommand(YumCommand):
  
              return 0, ['version groupinfo']
  
@@ -202362,7 +202443,7 @@ index 4dcbea7..e01c96d 100644
                  data = base.rpmdb.simpleVersion(not verbose, groups=groups)
                  lastdbv = base.history.last()
                  if lastdbv is not None:
-@@ -1302,15 +2769,14 @@ class VersionCommand(YumCommand):
+@@ -1302,15 +2794,14 @@ class VersionCommand(YumCommand):
                  if groups:
                      for grp in sorted(data[2]):
                          if (vcmd.startswith("group-") and
@@ -202381,7 +202462,7 @@ index 4dcbea7..e01c96d 100644
                  data = base.pkgSack.simpleVersion(not verbose, groups=groups)
                  if vcmd not in ('group-available', 'group-all'):
                      cols.append(("%s %s/%s" % (_("Available:"), rel, ba),
-@@ -1320,14 +2786,12 @@ class VersionCommand(YumCommand):
+@@ -1320,14 +2811,12 @@ class VersionCommand(YumCommand):
                  if groups:
                      for grp in sorted(data[2]):
                          if (vcmd.startswith("group-") and
@@ -202397,7 +202478,7 @@ index 4dcbea7..e01c96d 100644
  
          data = {'rid' : {}, 'ver' : {}}
          for (rid, ver) in cols:
-@@ -1344,6 +2808,14 @@ class VersionCommand(YumCommand):
+@@ -1344,6 +2833,14 @@ class VersionCommand(YumCommand):
          return 0, ['version']
  
      def needTs(self, base, basecmd, extcmds):
@@ -202412,7 +202493,7 @@ index 4dcbea7..e01c96d 100644
          vcmd = 'installed'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1352,25 +2824,74 @@ class VersionCommand(YumCommand):
+@@ -1352,25 +2849,74 @@ class VersionCommand(YumCommand):
              return True
          return vcmd in ('available', 'all', 'group-available', 'group-all')
  
@@ -202488,7 +202569,7 @@ index 4dcbea7..e01c96d 100644
              return 2, ["Repeating transaction %u" % (old.tid,)]
  
      def _hcmd_undo(self, base, extcmds):
-@@ -1426,12 +2947,57 @@ class HistoryCommand(YumCommand):
+@@ -1426,12 +2972,57 @@ class HistoryCommand(YumCommand):
      def _hcmd_new(self, base, extcmds):
          base.history._create_db_file()
  
@@ -202547,7 +202628,7 @@ index 4dcbea7..e01c96d 100644
          if extcmds and extcmds[0] not in cmds:
              base.logger.critical(_('Invalid history sub-command, use: %s.'),
                                   ", ".join(cmds))
-@@ -1444,6 +3010,19 @@ class HistoryCommand(YumCommand):
+@@ -1444,6 +3035,19 @@ class HistoryCommand(YumCommand):
              raise cli.CliError
  
      def doCommand(self, base, basecmd, extcmds):
@@ -202567,7 +202648,7 @@ index 4dcbea7..e01c96d 100644
          vcmd = 'list'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1468,29 +3047,88 @@ class HistoryCommand(YumCommand):
+@@ -1468,29 +3072,88 @@ class HistoryCommand(YumCommand):
              ret = self._hcmd_rollback(base, extcmds)
          elif vcmd == 'new':
              ret = self._hcmd_new(base, extcmds)
@@ -202656,7 +202737,7 @@ index 4dcbea7..e01c96d 100644
          chkcmd = 'all'
          if extcmds:
              chkcmd = extcmds
-@@ -1505,33 +3143,1123 @@ class CheckRpmdbCommand(YumCommand):
+@@ -1505,33 +3168,1123 @@ class CheckRpmdbCommand(YumCommand):
          return rc, ['%s %s' % (basecmd, chkcmd)]
  
      def needTs(self, base, basecmd, extcmds):
@@ -202850,8 +202931,8 @@ index 4dcbea7..e01c96d 100644
 +        if not extcmds or os.path.isdir(extcmds[0]):
 +            return False
 +
-+        return True
-+
+         return True
+ 
 +    def cacheRequirement(self, base, basecmd, extcmds):
 +        """Return the cache requirements for the remote repos.
 +
@@ -203244,8 +203325,8 @@ index 4dcbea7..e01c96d 100644
 +        if cmd in ('info', 'list'):
 +            return InfoCommand().needTs(base, cmd, extcmds[2:])
 +
-         return True
- 
++        return True
++
 +    def cacheRequirement(self, base, basecmd, extcmds):
 +        """Return the cache requirements for the remote repos.
 +
diff --git a/yum.spec b/yum.spec
index 9abd5db..95d7dd5 100644
--- a/yum.spec
+++ b/yum.spec
@@ -60,7 +60,7 @@ BuildRequires: bash-completion
 Summary: RPM package installer/updater/manager
 Name: yum
 Version: 3.4.3
-Release: 124%{?dist}
+Release: 125%{?dist}
 License: GPLv2+
 Group: System Environment/Base
 Source0: http://yum.baseurl.org/download/3.4/%{name}-%{version}.tar.gz
@@ -444,6 +444,17 @@ exit 0
 %endif
 
 %changelog
+* Tue Dec 17 2013 James Antill <james at fedoraproject.org> - 3.4.3-125
+- update to latest HEAD
+- Again, lots of groups UI changes/fixes thanks to Adam.
+- Add "groups mark blacklist" command to get out of the upgrade problem.
+- Tell users how to mark install/remove groups without packages.
+- Show install groups as well as upgrading groups in transaction output.
+- Fix mark-convert-whitelist, and add mark-convert-blacklist (default).
+- Fix typo with simple groups compile of environment with only options.
+- Pass the ievgrp to groups for new installed envs., so they belong. BZ 1043231.
+- Don't confuse "group info" output by giving data for optional when it's off.
+
 * Tue Dec 17 2013 James Antill <james at fedoraproject.org> - 3.4.3-124
 - update to latest HEAD
 - Fix group update not trying to install all optional groups of evgrp.


More information about the scm-commits mailing list