0
+local = Dir.pwd if File.directory?(File.join('.git', Dir.pwd))
0
+local ||= ARGV.shift || File.expand_path('buildr', File.dirname(__FILE__))
0
+origin = ARGV.shift || 'git@github.com:vic/buildr.git'
0
+svn_branch = "apache/trunk"
0
+puts "Buildr official commit channel is Apache's svn repository, however some"
0
+puts "developers may prefer to use git while working on several features and"
0
+puts "merging other's changes. "
0
+puts "This script will configure a buildr-git copy on so you can commit to svn."
0
+puts "Local git copy: #{local}"
0
+puts "Press RETURN to continue or anything else to abort"
0
+unless gets.chomp.empty?
0
+`git clone #{origin} #{local} 1>&2` unless File.directory?(File.join('.git', origin))
0
+ # Load the list of git-svn committers
0
+ svn_authors_file = File.expand_path('etc/git-svn-authors', local)
0
+ svn_authors = File.read(svn_authors_file)
0
+ svn_authors.gsub!(/\s+=\s+/, ': ')
0
+ svn_authors = YAML.load(svn_authors)
0
+ # set the git-svn-authors file
0
+ `git config svn.authorsfile "#{svn_authors_file}"`
0
+ # Check that git is configured for the git developer
0
+ email = `git config --get user.email`.chomp
0
+ puts "Enter your email as listed on #{svn_authors_file}"
0
+ # Check user lis listed
0
+ svn_user, git_contact = *svn_authors.find { |entry| /#{email}/i === entry.join(' ') }
0
+ fail "You need to be a buildr commmitter listed on #{svn_authors_file}"+
0
+ "\nPerhaps you need to set user.email, user.name on .git/config" unless git_contact
0
+ if /\s*(.*?)\s+\<(.+)\>\s*/ === git_contact
0
+ user_name, user_email = $1, $2
0
+ fail "Invalid contact string for #{svn_user}: #{git_contact.inspect}"
0
+ # Configure user name and email for git sake (and github's gravatar)
0
+ puts "You claim to be #{user_name} <#{user_email}> with apache-svn user: #{svn_user}"
0
+ `git config user.name "#{user_name}"`
0
+ `git config user.email "#{user_email}"`
0
+ # Ok, now obtain the last svn commit from history
0
+ last_svn_log = `git log -n 10 | grep git-svn-id | head -n 1`
0
+ fail "No svn metadata on last 10 commits" unless last_svn_log =~ /git-svn-id/
0
+ svn_repo, svn_prev = last_svn_log.split[1].split("@")
0
+ # Tell git where the svn repository is.
0
+ `git config svn-remote.#{svn_branch}.url #{svn_repo}`
0
+ `git config svn-remote.#{svn_branch}.fetch :refs/remotes/#{svn_branch}`
0
+ # Create the svn branch, do this instead of pulling the full svn history
0
+ `git push --force . refs/remotes/origin/master:refs/remotes/#{svn_branch}`
0
+ # Create apache aliases for developers git-workflow.
0
+ `git config alias.apache-fetch "!git-svn fetch #{svn_branch}"`
0
+ `git config alias.apache-merge "!git merge #{svn_branch}"`
0
+ `git config alias.apache-pull "!git apache-fetch && git apache-merge"`
0
+ `git config alias.apache-push "!git-svn dcommit --username #{svn_user}"`
0
+ # Create github origin aliases
0
+ `git config alias.get "!git apache-fetch && git fetch origin"`
0
+ `git config alias.mrg "!git apache-merge && git merge origin"`
0
+ `git config alias.put "!git apache-push && git push origin"`
0
+ # This is Victor's cronjob
0
+ `git config alias.synchronize "!git get && git mrg && git put"`
0
+ Your git repo #{local} has been configured, please review the .git/config file.
0
+ Some git aliases have been created for developer's convenience:
0
+ git apache-fetch # get changes from apache/trunk without merging them
0
+ # you can inspect what's happening on trunk without
0
+ # having to worry about merging conflicts.
0
+ # Inspect the remote branch with `git log apache/trunk`
0
+ # Or if you have a git-ui like `tig` you can use that.
0
+ git apache-merge # Merge already fetched changes on the current branch
0
+ # Use this command to get up to date with trunk changes
0
+ # you can always cherry-pick from the apache/trunk branch.
0
+ git apache-pull # get apache-fetch && git apache-merge
0
+ git apache-push # Push to Apache's SVN. Only staged changed (commited patches)
0
+ # will be sent to SVN. You need not to be on the master branch.
0
+ # Actually you can work on a tiny-feature branch and commit
0
+ # Missing commits on Apache's SVN will be sent using
0
+ # your #{svn_user} svn account. This means that you can make
0
+ # some commits on behalf of others (like user-contributed patches
0
+ # from JIRA). Review the .git/config if you want to change login-name.
0
+ # See the recommended workflow to avoid commiting other developers' changes,
0
+ # and the notes on github mirror.
0
+ Buildr has an unofficial git mirror on github, maintained by Victor: http://github.com/vic/buildr
0
+ Actually it's not Victor who manually updates it, he has a cron-job on his server, that only runs
0
+ A command you also have configured on your .git/config file.
0
+ However there are some limitations due that git-svn cannot commit as multiple authors (unless all
0
+ of them provided their passwords to Victor, yet he doesn't want to take over the world.)
0
+ This means that if a commit "A" is pushed to vic/buildr/master and has not already been pushed
0
+ by #{svn_user} using `git apache-push` your change will be commited to apache/trunk having Victor as the
0
+ author (that's how he gains meritocratic points on Apache :P).
0
+ So, it's very important - if you care about meritocracy - to follow or at least that you get an
0
+ idea of the recommended workflow.
0
+ So now that you have your local buildr copy you can create topic branches to work on
0
+ independent features, and still merge easily with head changes.
0
+ They may seem lots of things to consider, but it's all for Buildr's healt. As all things git,
0
+ you can always follow your own workflow and even create aliases on you .git/config file to
0
+ avoid typing much. So, here here they are:
0
+ 1) get your buildr-git configured (you have already do so, this was the most difficult part)
0
+ 2) create a topic branch to work on, say.. you want to add cool-feature:
0
+ git checkout -b cool-feature master
0
+ # now on branch cool-feature
0
+ 3) hack hack hack.. use the source luke.
0
+ every time you feel you have something important (added failing spec, added part of feature)
0
+ you can commit your changes. If you want to be selective, use: git commit --interactive
0
+ 3) review your changes, get ALL specs passing, repeat step 3 as needed
0
+ 4) let's see what are they doing on trunk
0
+ # You can inspect the upstream changes without having to merge them
0
+ git log apache/trunk # what are they doing!!
0
+ 5) integrate mainstream changes to your cool-feature branch (you can always use cherry-pick)
0
+ git merge apache/trunk cool-feature
0
+ 6) Go to 3 unless ALL specs are passing.
0
+ 7) Now you have everyhing on stage area (git commit) and merged important changes from
0
+ apache/trunk. It's time to commit them to Apache's SVN.
0
+ Now your changes are on Apache SVN, you can wait for them to get synched to vic/buildr/master
0
+ or push them yourself. You need Victor to add you as member, just ask for it.
0
+ git rebase --into origin/master master
0
+ git push origin master:master
0
+ 9) Pull changes from origin frequently.
0
+ git rebase --onto origin/master master master
0
+ 10) Unconditionally, Go to step 2 ;) or share your buildr-git workflow, tips, etc.
Comments
No one has commented yet.