You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildr.apache.org by vb...@apache.org on 2009/03/04 05:31:28 UTC

svn commit: r749897 - /buildr/trunk/doc/scripts/buildr-git.rb

Author: vborja
Date: Wed Mar  4 04:31:28 2009
New Revision: 749897

URL: http://svn.apache.org/viewvc?rev=749897&view=rev
Log:
Modified buildr-git to use GitFlow, so we can have git-like commands implemented in ruby.

Modified:
    buildr/trunk/doc/scripts/buildr-git.rb

Modified: buildr/trunk/doc/scripts/buildr-git.rb
URL: http://svn.apache.org/viewvc/buildr/trunk/doc/scripts/buildr-git.rb?rev=749897&r1=749896&r2=749897&view=diff
==============================================================================
--- buildr/trunk/doc/scripts/buildr-git.rb (original)
+++ buildr/trunk/doc/scripts/buildr-git.rb Wed Mar  4 04:31:28 2009
@@ -18,79 +18,299 @@
 # This script helps buildr developers to obtain their own git clone from
 # github, having a set of pre-defined aliases to work with Apache's SVN.
 #
-# You dont need to have a buildr copy to use it, just execute the buildr-git balloon:
+# You dont need to have a buildr copy to use it, just execute:
 #
-#   ruby -ropen-uri -e 'eval(open("http://svn.apache.org/viewvc/buildr/trunk/doc/scripts/buildr-git.rb?view=co").read)'
+#   ruby -ropen-uri -e 'eval(open("http://svn.apache.org/viewvc/buildr/trunk/doc/scripts/buildr-git.rb?view=co").read)' help
 
 require 'yaml'
-require 'optparse'
-require 'ostruct'
 require 'open-uri'
-require 'fileutils'
+if $0 == '-e' # invoked from open-uri
+  gitflow = "http://svn.apache.org/viewvc/buildr/trunk/doc/scripts/gitflow.rb?view=co"
+  eval(open(gitflow).read)
+else
+  require File.expand_path('gitflow', File.dirname(__FILE__))
+end
+
+GitFlow.program = 'buildr-git'
+
+module BuildrGit
 
-# Pager from http://nex-3.com/posts/73-git-style-automatic-paging-in-ruby
-def run_pager
-  return if RUBY_PLATFORM =~ /win32/
-  return unless STDOUT.tty?
-
-  read, write = IO.pipe
-
-  unless Kernel.fork # Child process
-    STDOUT.reopen(write)
-    STDERR.reopen(write) if STDERR.tty?
-    read.close
-    write.close
-    return
+  class UpdateUsersCommand < GitFlow/'update-users'
+
+    @help = "Update list of Apache SVN committers from Jukka's list."
+    @@url = 'http://people.apache.org/~jukka/authors.txt'
+
+    def self.authors_file
+      File.expand_path('.git/authors.txt', Dir.pwd)
+    end
+
+    def self.user_email(apache_login, authors_file = nil)
+      authors_file ||= self.authors_file
+      authors = YAML.load(File.read(authors_file).gsub!(/\s+=\s+/, ': '))
+      contact = authors[apache_login]
+      fail "You are not listed as apache commiter on #{authors_file}" unless contact
+      fail "Not a valid contact line: #{contact}" unless contact =~ /\s+<(.*)>/
+      [$`, $1]
+    end
+
+    def options(opts)
+      opts.url = @@url
+      opts.file = self.class.authors_file
+      [['-u', '--url URL', 
+        "From URL. defaults to: #{opts.url}", lambda { |url|
+          opts.url = url
+       }],
+       ['-f', '--file FILE', 
+        "Write to FILE, defaults to #{opts.file}", lambda { |path|
+          opts.file = path
+        }]
+      ]
+    end
+
+    def execute(opts, argv)
+      FileUtils.mkdir_p(File.dirname(opts.file))
+      content = open(opts.url).read
+      File.open(opts.file, "w") { |f| f.print content }
+    end
+  end
+
+  class CloneCommand < GitFlow/:clone
+    @help = "Create a clone from github.com/buildr repository."
+    
+    def options(opts)
+      opts.origin = 'git://github.com/buildr/buildr.git'
+      opts.svn_prefix = 'apache'
+      opts.project = 'buildr'
+      opts.local = expand_path(opts.project)
+      [['--prefix SVN_PREFIX', opts.svn_prefix, lambda { |p|
+          opts.svn_prefix = p }],
+       ['--origin GIT_ORIGIN', opts.origin, lambda { |o|
+          opts.origin = o }],
+       ['-d', '--dir DIR', opts.local, lambda { |d| opts.local = d }]
+      ]
+    end
+
+    def execute(opts, argv)
+      git 'clone', opts.origin, opts.local
+      Dir.chdir(opts.local) do 
+        run 'update-users'
+        run 'setup'
+      end
+    end
+  end
+
+  class SetupCommand < GitFlow/:setup
+    @help = "Setup your buildr clone to be used with git mirror."
+    def options(opt)
+      []
+    end
+    
+    def execute(opt, argv)
+      run 'setup', 'alias'
+      run 'setup', 'svn'
+    end
+  end
+
+  class SetupAliasCommand < SetupCommand/:alias
+    def execute(opt, argv)
+      me = expand_path('doc/scripts/buildr-git.rb')
+      git 'config', 'alias.apache', "!ruby #{me}"
+    end
+  end
+
+  class SetupSvnCommand < SetupCommand/:svn
+    @help = "Setup for getting changes from Apache SVN."
+
+    def options(opt)
+      opt.svn_prefix = 'apache'
+      opt.svn_project = 'buildr'
+      opt.townhall = 'origin'
+      [['--apache-login USER', 'Use Apache login to identify yourself', 
+        lambda { |e| opt.apache_login = e  }],
+       ['--svn-prefix PREFIX', 'The name of svn remote to use for project.',
+        "Defaults to #{opt.svn_prefix}", 
+        lambda{|p| opt.svn_prefix = p }],
+       ['--svn-uri URI', lambda {|p| opt.svn_uri = p  }],
+       ['--svn-rev REVISION', lambda {|p| opt.svn_rev = p  }],
+       ['--svn-project PATH', 'The path to append to svn-uri.',
+        "Defaults to #{opt.svn_project}", lambda {|p| opt.svn_project = p  }],
+       ['--townhall REMOTE', 'The name of remote you are using as town-hall repo.', 
+        "Defaults to #{opt.townhall}",
+        lambda {|p| opt.townhall = p }]
+      ]
+    end
+
+    def execute(opt, argv)
+      authors_file = UpdateUsersCommand.authors_file
+      git 'config', 'svn.authorsfile', authors_file
+      git 'config', 'apache.svn', opt.svn_prefix
+      git 'config', 'apache.git', opt.townhall
+      
+      if opt.apache_login
+        user, email = UpdateUsersCommand.user_email(opt.apache_login, authors_file)
+        puts "You claim to be #{user} <#{email}> with apache login: #{opt.apache_login}"
+        git('config', 'user.name', user)
+        git('config', 'user.email', email)
+      end
+      
+      if opt.svn_rev
+        revision = opt.svn_rev
+      else
+        location, revision = svn_loc_rev
+        revision = opt.svn_rev || revision
+      end
+      
+      if opt.svn_uri
+        repo = opt.svn_uri
+      else
+        fail "No #{opt.svn_project} directory on #{location}" unless
+          location =~ /\/#{opt.svn_project}/
+        repo = $`
+      end
+
+      # Tell git where the svn repository is 
+      git('config', "svn-remote.#{opt.svn_prefix}.url", repo)
+      git('config', "svn-remote.#{opt.svn_prefix}.fetch",
+          "#{opt.svn_project}/trunk:refs/remotes/#{opt.svn_prefix}/trunk")
+      git('config', "svn-remote.#{opt.svn_prefix}.branches", 
+          "#{opt.svn_project}/branches/*:refs/remotes/#{opt.svn_prefix}/*")
+      git('config', "svn-remote.#{opt.svn_prefix}.tags", 
+          "#{opt.svn_project}/tags/*:refs/remotes/#{opt.svn_prefix}/tags/*")
+
+      # Create the svn branch, do this instead of pulling the full svn history
+      git('update-ref', "refs/remotes/#{opt.svn_prefix}/trunk",
+          'refs/remotes/origin/master')
+      # create tags from git
+      git('tag').split.each do |tag|
+        git('update-ref', "refs/remotes/#{opt.svn_prefix}/tags/#{tag}",
+            "refs/tags/#{tag}")
+      end
+      # update svn metadata
+      mkdir_p(expand_path('.git/svn'))
+      svn_meta = expand_path('.git/svn/.metadata')
+      git('config', '--file', svn_meta, 
+          "svn-remote.#{opt.svn_prefix}.branches-maxRev", revision)
+      git('config', '--file', svn_meta, 
+          "svn-remote.#{opt.svn_prefix}.tags-maxRev", revision)
+    end
+
+    def svn_loc_rev
+      meta = sh('git log -n 10 | grep git-svn-id | head -n 1').chomp
+      fail "No svn metadata on last 10 commits" if meta.empty?
+      meta.split[1].split('@')
+    end
+  end
+
+  class FetchCommand < GitFlow/:fetch
+    @help = "Get changes from svn, creating tags, branches on townhall"
+    @documentation = <<-DOC
+This command can be used to fetch changes from Apache\'s SVN repo.
+
+GIT CONFIG VALUES:
+
+apache.svn  - The svn remote using to get changes from Apache SVN.
+              Set by setup-svn --svn-prefix.
+    DOC
+
+    def options(opt)
+      opt.apache_svn = git('config', '--get', 'apache.svn').chomp rescue nil
+      [['--apache-svn SVN_REMOTE', 'The SVN remote used to get changes from Apache',
+        "Current value: #{opt.apache_svn}",
+        lambda { |r| opt.apache_svn = r }]
+       ]
+    end
+
+    def execute(opt, argv)
+      fail "Missing apache.svn config value" unless opt.apache_svn
+      git('svn', 'fetch', opt.apache_svn)
+    end
+  end
+
+  class SyncCommand < GitFlow/:sync
+    @help = "Synchronizes between Apache svn and git townhall."
+    @documentation = <<-DOC
+This command will perform the following actions: 
+  * fetch changes from apache svn.
+  * rebase them on the current branch or on the one specified with --onto
+  * dcommit (this will push your changes to Apache trunk)
+
+GIT CONFIG VALUES:
+
+apache.svn  - The svn remote using to get changes from Apache SVN.
+              Set by setup-svn --svn-prefix.
+apache.git  - The git remote used as townhall repository.
+              Set by setup-svn --townhall.
+DOC
+
+    def options(opt)
+      git('branch').split.tap { |n| opt.branch = n[n.index('*')+1] }
+      opt.onto = opt.branch
+      opt.svn_branch = 'trunk'
+      opt.apache_git = git('config', '--get', 'apache.git').chomp rescue nil
+      opt.apache_svn = git('config', '--get', 'apache.svn').chomp rescue nil
+      [['--apache-svn SVN_REMOTE', 'The SVN remote used to get changes from Apache',
+        "Current value: #{opt.apache_svn}",
+        lambda { |r| opt.apache_svn = r }],
+       ['--apache-git REMOTE', 'The git remote used as town-hall repository.',
+        "Current value: #{opt.apache_git}",
+        lambda { |r| opt.apache_git = r }],
+       ['--from SVN_BRANCH', 'Specify the SVN branch to rebase changes from', 
+        "Defaults to: #{opt.svn_branch}", 
+        lambda { |b| opt.svn_branch = b }],
+       ['--onto BRANCH', 'Specify the local branch where to rebase apache changes',
+        "Current branch: #{opt.branch}",
+        lambda { |b| opt.onto = b }]
+      ]
+    end
+
+    def execute(opt, argv)
+      run('fetch', '--apache-svn', opt.apache_svn)
+      git('fetch', opt.apache_git, opt.onto)
+      git('rebase', '--onto', opt.onto, "#{opt.apache_svn}/#{opt.svn_branch}")
+      git('rebase', '--onto', opt.onto, "#{opt.apache_git}/#{opt.onto}")
+      git('dcommit', opt.apache_svn)
+    end
   end
 
-  # Parent process, become pager
-  STDIN.reopen(read)
-  read.close
-  write.close
-
-  ENV['LESS'] = 'FSRX' # Don't page if the input is short enough
-
-  Kernel.select [STDIN] # Wait until we have input before we start the pager
-  pager = ENV['PAGER'] || 'less'
-  exec pager rescue exec "/bin/sh", "-c", pager
-end
 
-def header
-  <<HEADER
+  # This one is displayed when the user executes this script using 
+  # open-uri -e
+  HEADER = <<HEADER
 
 Buildr official commit channel is Apache's svn repository, however some
 developers may prefer to use git while working on several features and
 merging other's changes.
 
-This script will configure a buildr-git copy on so you can commit to svn.
+This script will configure a gitflow copy on so you can commit to svn.
 
 Enter <-h> to see options, <-H> to see notes about configured aliases
 and recommended workflow, or any other option.
 
 Ctrl+D or an invalid option to abort
 HEADER
-end
-
-def notice
-  <<NOTICE
+  
+  # When fork is completed, we display the following notice on a 
+  # pager, giving the user a brief overview of git aliases used
+  # to keep the mirror in sync.
+  NOTICE = <<NOTICE
 ALIASES:
 
   Some git aliases have been created for developer convenience:
 
-    git apache-fetch    # get changes from apache/trunk without merging them
+    git apache fetch    # get changes from apache/trunk without merging them
                         # you can inspect what's happening on trunk without
                         # having to worry about merging conflicts.
                         # Inspect the remote branch with `git log apache/trunk`
                         # Or if you have a git-ui like `tig` you can use that.
 
-    git apache-merge    # Merge already fetched changes on the current branch
+    git apache merge    # Merge already fetched changes on the current branch
                         # Use this command to get up to date with trunk changes
                         # you can always cherry-pick from the apache/trunk 
                         # branch.
 
-    git apache-pull     # get apache-fetch && git apache-merge
+    git apache pull     # get apache-fetch && git apache-merge
    
-    git apache-push     # Push to Apache's SVN. Only staged changes (those 
+    git apache push     # Push to Apache's SVN. Only staged changes (those 
                         # recorded using `git commit`) will be sent to SVN. 
                         # You need not to be on the master branch.
                         # Actually you can work on a tiny-feature branch and
@@ -126,7 +346,7 @@
       git synchronize
 
    This command will synchronize both ways svn<->git to keep trunk upto date.
-   You need to be an Apache committer an have permissions on the SVN repo.
+   You need to be an Apache committer and have permissions on the SVN repo.
    
    It's VERY IMPORTANT for Buildr committers to remember that contributions from
    external entities wanting to be accepted will require them to sign the Apache ICLA.
@@ -147,7 +367,7 @@
    As all things git, you can always follow your own workflow and even create
    aliases on you .git/config file to avoid typing much. So, here they are:
 
-   1) get your buildr-git configured 
+   1) get your gitflow configured 
      (you have already do so, this was the most difficult part)
 
    2) create a topic branch to work on, say.. you want to add cool-feature:
@@ -202,7 +422,7 @@
         git rebase --onto origin/master master master
 
    10) Unconditionally, Go to step 2 ;)
-       Share your buildr-git workflow, git tips, etc.
+       Share your gitflow workflow, git tips, etc.
 
 RESOURCES:
 
@@ -211,239 +431,37 @@
    http://groups.google.com/group/git-users/web/git-references
 
 NOTICE
-end # notice method
+  #' for emacs
 
-def optparse(options = OpenStruct.new, argv = ARGV)
-  opt = OptionParser.new do |opt|
-    
-    if `git status 2>/dev/null`.chomp.empty?
-      options.local = File.expand_path('buildr', Dir.pwd)
-    else
-      puts "Current directory is a git repo: #{Dir.pwd}"
-      options.local = Dir.pwd 
-    end
-
-    options.svn_prefix = "apache"
-    options.origin = "git://github.com/buildr/buildr.git"
-    options.member = false
-
-    opt.banner = "Usage: buildr-git.rb [options]"
-    opt.separator ""
-    opt.separator "OPTIONS:"
-
-    opt.on('-a', "--anon", "Use git://github.com/buildr/buildr.git as origin") do 
-      options.origin = "git://github.com/buildr/buildr.git"
-    end
-    opt.on('-A', "--auth", "Use git@github.com:buildr/buildr.git as origin") do
-      options.origin = "git@github.com:buildr/buildr.git"
-    end
-    opt.on("-o", "--origin GIT_URL", "Clone from GIT_URL origin") do |value|
-      options.origin = value
-    end
-    opt.on('-l', "--local DIRECTORY", "Create local git clone on DIRECTORY") do |value|
-      options.local = value
-    end
-    opt.on('-p', "--prefix GIT_SVN_PREFIX", 
-           "Set the name for svn branch instead of apache") do |value|
-      options.svn_prefix = value
-    end
-    opt.on('-e', "--email EMAIL", 
-           "Configure git to use EMAIL for commits") do |value|
-      options.email = value
-    end
-    opt.on('-n', "--name USER_NAME", 
-           "Configure your USER_NAME for git commits") do |value|
-      options.user_name = value
-    end
-    opt.on('-u', "--update-users", 
-           "Just update svn-authors from jukka's list") do
-      get_authors(File.expand_path('.git/authors.txt', Dir.pwd))
-      throw :exit
-    end
-    opt.on('-h', "--help", "Show buildr-git help") do 
-      puts opt
-      throw :exit
-    end
-    opt.on('-H', "--notice", "Show notice about aliases and git workflow") do
-      run_pager
-      puts notice
-      throw :exit
-    end
-  end
-  opt.parse!(argv)
-  options
-end # optparse method
-
-
-def main
-  catch :exit do
-    options = optparse
-    puts header
-    puts 
-    print '> '
-    if input = gets
-      options = optparse(options, input.split)
-    end
-    if input.nil? || (input != "\n" && input.empty?)
-      puts "Aborting."
-      return
-    end
-    perform(options)
-  end  
-end
 
-def get_authors(svn_authors_file, svn_authors_uri = "http://people.apache.org/~jukka/authors.txt")
-  File.open(svn_authors_file, "w") { |f| f.print open(svn_authors_uri).read }
-end
 
-def perform(options)
-  origin = options.origin
-  member = origin =~ /@/
-  local = options.local
-  svn_prefix = options.svn_prefix
-  user_email = options.email
-  user_name = options.user_name
-  project = 'buildr'
-  
-  `git clone #{origin} #{local} 1>&2` unless File.directory?(File.join('.git', origin))
-  
-  puts
-  puts "Entering #{local} directory"
-  puts
-  Dir.chdir(local) do
-    
-    # Load the list of git-svn committers
-    # Use Jukka's auto-updated list of apache commiters.
-    # It is VERY important for git-svn to use the correct author name/email
-    # else you will end with duplicate commit history on git.
-    svn_authors_file = File.expand_path('.git/authors.txt', Dir.pwd)
-    get_authors(svn_authors_file)
-
-    svn_authors = File.read(svn_authors_file)
-    svn_authors.gsub!(/\s+=\s+/, ': ')
-    svn_authors = YAML.load(svn_authors)
-
-    # set the git-svn-authors file
-    `git config svn.authorsfile "#{svn_authors_file}"`
-
-    # Check that git is configured for the developer
-    user_email ||= `git config --get user.email`.chomp
-    if user_email.empty?
-      if member
-        puts "Enter your email as listed on #{svn_authors_file}"
-        print "> "
-        user_email = gets.chomp
-      else
-        puts "Provide an email address for git usage:"
-        user_email = gets.chomp
-      end
-    end
-
-    # Check user is listed
-    unless user_email.empty?
-      svn_user, git_contact = *svn_authors.find { |entry| /#{user_email}/ === entry.join(' ') }
-    end
-
-    if member 
-      if git_contact.nil? # if using the authenticated git, he must be listed
-        puts <<-NOTICE
-          You need to be a buildr commmitter listed on #{svn_authors_file}. 
-          Perhaps you need to add yourself to it, commit it using SVN, and 
-          and run this script again.
-          Also checks your git global values for user.email and user.name
-        NOTICE
-        return
-      elsif /\s*(.*?)\s+\<(.+)\>\s*/ === git_contact
-        user_name, user_email = $1, $2
+  def old
+      # Create apache aliases for developers git-workflow.
+      `git config alias.apache-fetch "!git-svn fetch #{svn_prefix}"`
+      `git config alias.apache-merge "!git merge #{svn_prefix}"`
+      `git config alias.apache-pull  "!git apache-fetch && git apache-merge"`
+      if svn_user
+        `git config alias.apache-push  "!git-svn dcommit --username #{svn_user}"`
       else
-        puts "Invalid contact string for #{svn_user}: #{git_contact.inspect}"
-        return
+        `git config alias.apache-push  "!git-svn dcommit"`
       end
-    elsif user_email =~ /^\s*$/
-      puts "User email shall not include spaces: #{user_email.inspect}"
-      return
-    end
-    
-    user_name ||= `git config --get user.name`.chomp
-    if git_contact.nil? && user_name.empty?
-      puts "Provide a developer name for git usage:"
-      user_name = gets.chomp
-    end
-    
-    # Start the pager
-    run_pager
-    puts
-
-
-    old_origin = `git config --get remote.origin.url`.chomp
-    if member && old_origin !~ /@/
-      puts "Switching to authenticated origin #{origin}", ""
-      `git config remote.origin.url "#{origin}"`
-    elsif !member && old_origin =~ /@/
-      puts "Switching to anonymous origin #{origin}", ""
-      `git config remote.origin.url "#{origin}"`
-    end
-    
-    # Configure user name and email for git sake (and github's gravatar)
-    puts "You claim to be #{user_name.inspect} <#{user_email}> "
-    puts "with apache-svn user: #{svn_user}" if svn_user
-    puts
-    `git config user.name  "#{user_name}"`
-    `git config user.email "#{user_email}"`
-    
-    # Ok, now obtain the last svn commit from history
-    last_svn_log = `git log -n 10 | grep git-svn-id | head -n 1`
-    fail "No svn metadata on last 10 commits" unless last_svn_log =~ /git-svn-id/
-    svn_repo, svn_prev = last_svn_log.split[1].split("@")
-    fail "No #{project} directory on #{svn_repo}" unless svn_repo =~ /\/#{project}/
-    svn_repo = $`
-
-    
-    # Tell git where the svn repository is.
-    `git config svn-remote.#{svn_prefix}.url #{svn_repo}`
-    `git config svn-remote.#{svn_prefix}.fetch #{project}/trunk:refs/remotes/#{svn_prefix}/trunk`
-    `git config svn-remote.#{svn_prefix}.branches #{project}/branches/*:refs/remotes/#{svn_prefix}/*`
-    `git config svn-remote.#{svn_prefix}.tags #{project}/tags/*:refs/remotes/#{svn_prefix}/tags/*`
-    
-    # Create the svn branch, do this instead of pulling the full svn history
-    `git update-ref refs/remotes/#{svn_prefix}/trunk refs/remotes/origin/master`
-    `git tag`.split.each do |tag| 
-      `git update-ref refs/remotes/#{svn_prefix}/tags/#{tag} refs/tags/#{tag}`
-    end
-
-    puts "Updating svn metatada"
-    svn_meta = File.expand_path('.git/svn/.metadata', Dir.pwd)
-    FileUtils.mkdir_p(File.dirname(svn_meta))
-    `git config --file "#{svn_meta}" svn-remote.#{svn_prefix}.branches-maxRev #{svn_prev}`
-    `git config --file "#{svn_meta}" svn-remote.#{svn_prefix}.tags-maxRev #{svn_prev}`
-    
-    # Create apache aliases for developers git-workflow.
-    `git config alias.apache-fetch "!git-svn fetch #{svn_prefix}"`
-    `git config alias.apache-merge "!git merge #{svn_prefix}"`
-    `git config alias.apache-pull  "!git apache-fetch && git apache-merge"`
-    if svn_user
-      `git config alias.apache-push  "!git-svn dcommit --username #{svn_user}"`
-    else
-      `git config alias.apache-push  "!git-svn dcommit"`
-    end
-    
-    # Create github origin aliases
-    `git config alias.get "!git apache-fetch && git fetch origin"`
-    `git config alias.mrg "!git apache-merge && git merge origin"`
-    `git config alias.rbs "!git rebase --onto #{svn_prefix} origin/master master"`
-    `git config alias.put "!git apache-push && git push origin"`
-    
-    # This is Victor's cronjob
-    `git config alias.synchronize "!git get && git rbs && git put"`
-    
-    # Final notices.
-    puts <<-NOTICE + notice
+      
+      # Create github origin aliases
+      `git config alias.get "!git apache-fetch && git fetch origin"`
+      `git config alias.mrg "!git apache-merge && git merge origin"`
+      `git config alias.rbs "!git rebase --onto #{svn_prefix} origin/master master"`
+      `git config alias.put "!git apache-push && git push origin"`
+      
+      # This is Victor's cronjob
+      `git config alias.synchronize "!git get && git rbs && git put"`
+      
+      # Final notices.
+      puts <<-NOTICE + NOTICE
 
     Your git repo #{local} has been configured, please review the 
        #{File.join(local, '.git/config')} file.
 
     NOTICE
-  end  
-end # perform method
-
-main
+  end # perform method
+  
+end