My friend Jesse and I were trying to figure out a way to make the process of working with new GIT repositories easier. We wanted to create a new GIT repository locally, creating a new remote repository and adding the remote to the local so that you can push your development changes out for others to collaborate with. This involves a number of commands locally, then logging into your server, creating folders and git repositories there, then adding the remote repository to your local copy. Here is our current workflow:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#locally git init git add . git commit -m "initial import" #remote server cd /var/git mkdir newproject.git && cd newproject.git git --bare init #locally git remote add origin ssh://user@domain.com:35432/var/git/newproject.git git push origin master |
That isn't a ton of work but it is a repetitive task that could be simplified. We started with some ideas of shell scripts and I ended up creating a script in Ruby that handles everything. It is called GNR which represented GIT - New - Repository when we came up with the concept. The script does all the commands above for you. Lets look at an example.
1 2 3 |
rails newproj #create a new dummy rails project gnr newproj ssh://user@domain.com:35432/var/git/newproj.git |
That's it. Now we can CD into the newproj directory and start working. There are a couple assumptions that this script makes though:
1. You are using public/private RSA keys to login to your SSH server without passwords
2. Your user in the remote repo URL string (user@domain.com) has privileges to be able to write to the directory where your repositories are stored (/var/git in this example)
So here is the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
#!/usr/bin/env ruby # == Synopsis # This script streamlines the creation of GIT repositories # and the adding of the repository to a remote GIT server. # With one command you can create a new repository, add # it to your GIT server and start working. # # == Examples # This command just creates a new GIT repositor, but doesn't # add it to a remote origin server # gnr . # gnr /path/to/project # # Other examples: # gnr . ssh://[user]@[domain]:[port]/[root_repo_path]/[new_repo_name] # gnr . ssh://user@domain.com:29876/var/git/repo.git # # == Usage # gnr [options] local_project_folder remote_repository_path # # For help use: gnr -h # # == Options # -h, --help Displays help message # -v, --version Display the version, then exit # -q, --quiet Output as little as possible, overrides verbose # -V, --verbose Verbose output # # # == Author # Brian Webb <brian@parkersmithsoftware.com> # # == Copyright # Copyright (c) 2008 Parker Smith. Licensed under the MIT License: # http://www.opensource.org/licenses/mit-license.php require 'optparse' require 'rdoc/usage' require 'ostruct' require 'date' class App VERSION = '0.0.1' attr_reader :options def initialize(arguments, stdin) @arguments = arguments @stdin = stdin # Set defaults @options = OpenStruct.new @options.verbose = false @options.quiet = false @local_exists = false @remote_exists = false end #end initialize # Parse options, check arguments, then process the command def run if parsed_options? && arguments_valid? puts "Start at #{DateTime.now}\n\n" if @options.verbose output_options if @options.verbose # [Optional] process_arguments process_command puts "\nFinished at #{DateTime.now}" if @options.verbose else output_usage end end protected def parsed_options? # Specify options opts = OptionParser.new opts.on('-v', '--version') { output_version ; exit 0 } opts.on('-h', '--help') { output_help } opts.on('-V', '--verbose') { @options.verbose = true } opts.on('-q', '--quiet') { @options.quiet = true } opts.parse!(@arguments) rescue return false process_options true end # Performs post-parse processing on options def process_options @options.verbose = false if @options.quiet end def output_options puts "Options:\n" @options.marshal_dump.each do |name, val| puts " #{name} = #{val}" end end # True if required arguments were provided def arguments_valid? true if @arguments.length >= 1 end # Setup the arguments def process_arguments @project_folder = @arguments[0] @repo = @arguments[1] ? @arguments[1] : nil end def output_help output_version RDoc::usage() #exits app end def output_usage RDoc::usage('usage') # gets usage from comments above end def output_version puts "#{File.basename(__FILE__)} version #{VERSION}" end def process_command FileUtils.cd(@project_folder, :verbose => @options.verbose) do begin FileUtils.cd(".git", :verbose => @options.verbose) do @local_exists = true puts "Local repository already exists" unless @options.quiet config = File.new("config").read @remote_exists = true if config =~ /remote "origin"/ end rescue %x[git init] %x[git add .] %x[git commit -m "Created initial local repo"] #ssh to server and make new repo.git if @repo #get the repo string into usable vars user = @repo.gsub("ssh://","").split("@")[0] domain = @repo.gsub("ssh://","").split("@")[1].split(":")[0] port = @repo.gsub("ssh://", "").split(":")[1].split("/")[0] remote_repo = @repo.gsub("ssh://", "").split(":")[1][@repo.gsub("ssh://", "").split(":")[1].index("/"), @repo.gsub("ssh://", "").split(":")[1].length] root_folder = remote_repo[0,remote_repo.rindex("/")] repo_folder = remote_repo[remote_repo.rindex("/")+1, remote_repo.length] repo_string = %(ssh://#{user}@#{domain}:#{port}#{root_folder}/#{repo_folder}) commands = ["cd #{root_folder}", "mkdir #{repo_folder}", "cd #{repo_folder}", "git --bare init"] #ssh into the server and create the remote repo ssh_string = %(ssh -fCT #{user}@#{domain} -p #{port} "#{commands.join(" && ")}") Kernel.system "#{ssh_string}" #add the remote repo to the local repo Kernel.system "git remote add origin #{repo_string}" #push the local to the remote %x[git push origin master] end #end if @repo end #end rescue end #end FileUtils.cd end #end process_command end #end App Class # Create and run the application app = App.new(ARGV, STDIN) app.run |