mavenlink-git-scripts 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2a793b24f0f684d1cc498443ac36dce26a51c13d
4
+ data.tar.gz: 0c3b8bca0d67edeaa31cc67e13fa246cfa176128
5
+ SHA512:
6
+ metadata.gz: ecd299a5ffbe08de9c5bc84bcef12a635551827822ff45c9f615caf516c709ab876d3afe630509c6311aeb7a798f8692e034f8cb18f415b43d6a65f214d215de
7
+ data.tar.gz: d0b70f876ca927b7a5d70397b06b6f4e49d397719cb792bc087a6d4bb911d140abb75b86efd7a49f9dd073f848e64ba8933ef2305b766dc75fada76433cfe123
@@ -0,0 +1,5 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ spec/tmp
5
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.1
4
+ - 2.2.5
5
+ - 2.1.9
6
+ - 2.0.0-p648
7
+ # Fix weird issues from this Travis build:
8
+ # https://travis-ci.org/pivotal/git_scripts/jobs/5501358
9
+ # https://git.wiki.kernel.org/index.php/Git_FAQ#Git_commit_is_dying_telling_me_.22fatal:_empty_ident_.3Cuser.40myhost.3E_not_allowed.22.2C_what.27s_wrong.3F
10
+ env:
11
+ global:
12
+ - GIT_AUTHOR_NAME="Travis CI"
13
+ before_script:
14
+ - git config --global user.email "travis-ci@example.com"
15
+ - git config --global user.name "Travis CI"
@@ -0,0 +1,26 @@
1
+ # CHANGELOG
2
+
3
+ ## 1.4.0 - released 2015-01-15
4
+
5
+ ### `git pair-commit` explicitly sets the author name
6
+
7
+ Before this change, git's user.name setting would override. In
8
+ repositories where the user had previously run `git duet`, this meant
9
+ that after a `git pair --global ...` the email was set correctly by `git
10
+ pair-commit`, but the author name was not.
11
+
12
+ [#62606550]
13
+
14
+ ### `git pair-commit` sets committer name and email
15
+
16
+ [Finishes #62606550]
17
+
18
+ ### Add ability to use a custom email address per user
19
+
20
+ # include the following section to set custom email addresses for users
21
+ email_addresses:
22
+ zr: zach.robinson@example.com
23
+
24
+ ### Include the $HOME directory if it's not in the list of pwd ancestors.
25
+
26
+ This fixes the actual behavior to match the documentation, which states that the `.pairs` file may be in the user's home directory.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Pivotal Labs
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,125 @@
1
+ # Git Scripts
2
+
3
+ These scripts are helpers for managing developer workflow when using git repositories hosted on GitHub. Install as a RubyGem and they can be run as standard git commands, eg: `git about`.
4
+
5
+ [![Build Status](https://img.shields.io/travis/pivotal/git_scripts.svg)](https://travis-ci.org/pivotal/git_scripts)
6
+
7
+ ## Gem Installation
8
+
9
+ ```shell
10
+ gem install pivotal_git_scripts
11
+ ```
12
+
13
+ ## System Wide Installation
14
+
15
+ ```shell
16
+ cd /usr/local/bin && curl -L http://github.com/pivotal/git_scripts/tarball/master | gunzip | tar xvf - --strip=2
17
+ ```
18
+
19
+ ## git-about
20
+
21
+ `git about` shows settings set by `git pair` and `git project`
22
+
23
+ ## git-pair
24
+
25
+ Configures git authors when pair programming.
26
+
27
+ ```shell
28
+ $ git pair sp js
29
+ user.name=Josh Susser & Sam Pierson
30
+ user.email=pair+jsusser+sam@pivotallabs.com
31
+ ```
32
+
33
+ Create a `.pairs` config file in project root or your home folder.
34
+
35
+ ```yaml
36
+ # .pairs - configuration for 'git pair'
37
+ pairs:
38
+ # <initials>: <Firstname> <Lastname>[; <email-id>]
39
+ eh: Edward Hieatt
40
+ js: Josh Susser; jsusser
41
+ sf: Serguei Filimonov; serguei
42
+ email:
43
+ prefix: pair
44
+ domain: pivotallabs.com
45
+ no_solo_prefix: true
46
+ global: false # Set to true for git-pair to change git configuration for all your projects
47
+ ```
48
+
49
+
50
+ By default this affects the current project (`.git/config`).
51
+ Use the `--global` option or add `global: true` to your `.pairs` file to set the global git configuration for all projects (`~/.gitconfig`).
52
+
53
+ Options are:
54
+
55
+ -g, --global Modify global git options instead of local
56
+ -v, --version Show Version
57
+ -h, --help Show this.
58
+
59
+ When you're done pairing, change git's configuration to use your personal details.
60
+
61
+ ```shell
62
+ git pair <your-initials>
63
+ ```
64
+
65
+ ## git-pair-commit
66
+
67
+ Makes a git commit as normal, but chooses one of the pair members randomly to get credit for the commit on github (by setting the author email to that member's email address). The author name on the commit will list all members of the pair, as usual.
68
+
69
+ If pair members have email addresses on different domains, you can specify them separately in the optional `email_addresses:` key in your `.pairs` file.
70
+
71
+ If pair members would like to sign commits with a GPG key, you can specifiy them in the optional `gpg_keys:` sections in your `.pairs` file.
72
+
73
+ ```yaml
74
+ pairs:
75
+ jd: Jane Doe
76
+ fb: Frances Bar
77
+ email_addresses:
78
+ jd: jane@awesome.local
79
+ fb: frances@foo.bar
80
+ gpg_keys:
81
+ jd: A1B2C3D4
82
+ fb: E5F6G7H8
83
+ ```
84
+
85
+ ### Using git-pair-commit in RubyMine
86
+ RubyMine already supports pointing at a custom location for your git executable in the Preferences -> Version Control -> Git
87
+ ![RubyMine Git Configuration](http://i.imgur.com/hTHkdeA.png)
88
+ The trick then is that `pair-commit` doesn't encompass all git functionality, so you can't just point RubyMine directly at it, you need something in the middle that will use `pair-commit` if the first arg is `commit`, otherwise just pass through. Here's a ruby script to do just that:
89
+
90
+ ```ruby
91
+ #!/usr/bin/env ruby
92
+
93
+ exit_code = if ARGV[1] == "commit"
94
+ system "git pair-commit #{ARGV[1..-1].join(" ")}"
95
+ else
96
+ system "git #{ARGV.join(" ")}"
97
+ end
98
+
99
+ exit exit_code
100
+ ```
101
+
102
+ Make sure it's executable.
103
+
104
+
105
+ ## git-project
106
+
107
+ ```shell
108
+ git project pivots
109
+ ```
110
+
111
+ This script sets the user account you will use to access repos hosted on github.com. It creates a symlink from `id_github_current` to `id_github_pivotal<project>`, which switches the SSH key you are currently using to access GitHub repos. Make sure you have the following lines in your .ssh/config file:
112
+
113
+ Host github.com
114
+ User git
115
+ IdentityFile /Users/pivotal/.ssh/id_github_current
116
+
117
+ Authors
118
+ ====
119
+ Copyright (c) 2010 [Pivotal Labs](http://pivotallabs.com). This software is licensed under the MIT License.
120
+
121
+ ### [Contributors](https://github.com/pivotal/git_scripts/contributors)
122
+ - git-pair original author [Bryan Helmkamp](http://brynary.com)
123
+ - lots of pivots :)
124
+ - [James Sanders](https://github.com/jsanders)
125
+ - [Todd Persen](https://github.com/toddboom)
@@ -0,0 +1,22 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :default do
4
+ sh "bundle exec rspec spec"
5
+ end
6
+
7
+ # extracted from https://github.com/grosser/project_template
8
+ rule /^version:bump:.*/ do |t|
9
+ sh "git status | grep 'nothing to commit'" # ensure we are not dirty
10
+ index = ['major', 'minor','patch'].index(t.name.split(':').last)
11
+ file = 'lib/pivotal_git_scripts/version.rb'
12
+
13
+ version_file = File.read(file)
14
+ old_version, *version_parts = version_file.match(/(\d+)\.(\d+)\.(\d+)/).to_a
15
+ version_parts[index] = version_parts[index].to_i + 1
16
+ version_parts[2] = 0 if index < 2 # remove patch for minor
17
+ version_parts[1] = 0 if index < 1 # remove minor for major
18
+ new_version = version_parts * '.'
19
+ File.open(file,'w'){|f| f.write(version_file.sub(old_version, new_version)) }
20
+
21
+ sh "bundle && git add #{file} Gemfile.lock && git commit -m 'bump version to #{new_version}'"
22
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ user_name = `git config --get user.name`
3
+ user_name = "NONE" if user_name.strip.empty?
4
+
5
+ user_email = `git config --get user.email`
6
+ user_email = "NONE" if user_email.strip.empty?
7
+
8
+ begin
9
+ key_file = File.readlink(File.expand_path("~/.ssh/id_github_current"))
10
+ project = (key_file =~ %r{id_github_(\w+)} ? $1 : "NONE")
11
+ rescue Errno::ENOENT
12
+ project = "NONE"
13
+ end
14
+
15
+ puts "git user: #{user_name}"
16
+ puts "git email: #{user_email}"
17
+ puts "GitHub project: #{project}"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__)) # this is required when running from /usr/local/bin
3
+ require 'pivotal_git_scripts/git_pair'
4
+
5
+ PivotalGitScripts::GitPair.main(ARGV)
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__)) # this is required when running from /usr/local/bin
3
+ require 'pivotal_git_scripts/git_pair'
4
+
5
+ PivotalGitScripts::GitPair.commit(ARGV)
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+ require 'socket'
3
+
4
+ def check_ssh_config
5
+ if `grep -c id_github_current config`.to_i == 0
6
+ puts <<-WARNING
7
+ You must edit your .ssh/config file to include:
8
+ Host github.com
9
+ User git
10
+ IdentityFile /Users/pivotal/.ssh/id_github_current
11
+ WARNING
12
+ end
13
+ end
14
+
15
+ project = ARGV[0] || Dir.pwd.split('/').last
16
+ hostname = Socket.gethostname.split('.').first
17
+ possible_id_files = [
18
+ "id_#{hostname}_github_pivotal#{project}",
19
+ "id_github_pivotal#{project}",
20
+ "id_github_#{project}"
21
+ ]
22
+
23
+ Dir.chdir(File.expand_path('~/.ssh')) do
24
+ possible_id_files.each do |id_file|
25
+ if File.exists?(id_file)
26
+ `ln -sf #{id_file} id_github_current`
27
+ puts "Now using key #{id_file}"
28
+ check_ssh_config
29
+ exit 0
30
+ end
31
+ end
32
+ puts "Key not found. You must create a ssh key in ~/.ssh/ called " +
33
+ possible_id_files[0..-2].join(", ") +
34
+ " or #{possible_id_files[-1]}"
35
+ end
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ git pull && git submodule init && git submodule update
@@ -0,0 +1,271 @@
1
+ require "pivotal_git_scripts/version"
2
+ require 'yaml'
3
+ require 'optparse'
4
+ require 'pathname'
5
+
6
+ module PivotalGitScripts
7
+ module GitPair
8
+ def self.main(argv)
9
+ runner = Runner.new
10
+ runner.main(argv)
11
+ end
12
+
13
+ def self.commit(argv)
14
+ runner = Runner.new
15
+ runner.commit(argv)
16
+ end
17
+
18
+ class GitPairException < Exception; end
19
+
20
+ class Runner
21
+ def main(argv)
22
+ git_dir = `git rev-parse --git-dir`.chomp
23
+ exit 1 if git_dir.empty?
24
+
25
+ options = parse_cli_options(argv)
26
+ initials = argv
27
+ config = read_pairs_config
28
+ global = !!(options[:global] || config["global"])
29
+
30
+ if initials.any?
31
+ author_names, email_ids = extract_author_names_and_email_ids_from_config(config, initials)
32
+ authors = pair_names(author_names)
33
+ git_config = {:name => authors, :initials => initials.sort.join(" ")}
34
+ git_config[:email] = build_email(email_ids, config["email"]) unless no_email(config)
35
+ set_git_config global, git_config
36
+ else
37
+ git_config = {:name => nil, :initials => nil}
38
+ git_config[:email] = nil unless no_email(config)
39
+ set_git_config global, git_config
40
+ puts "Unset#{' global' if global} user.name, #{'user.email, ' unless no_email(config)}user.initials"
41
+ end
42
+
43
+ [:name, :email, :initials].each do |key|
44
+ report_git_settings(git_dir, key)
45
+ end
46
+ rescue GitPairException => e
47
+ puts e.message
48
+ exit 1
49
+ end
50
+
51
+ def commit(argv)
52
+ if argv[0] == '-h'
53
+ puts 'Usage: git pair-commit [options_for_git_commit]'
54
+ puts ''
55
+ puts 'Commits changes to the repository using `git commit`, but randomly chooses the author email from the'
56
+ puts 'members of the pair. In order for GitHub to assign credit for the commit activity, the user\'s email'
57
+ puts 'must be linked in their GitHub account.'
58
+ exit 0
59
+ end
60
+
61
+ config = read_pairs_config
62
+ author_details = extract_author_details_from_config(config, current_pair_initials)
63
+ author_names = author_details.keys.map { |i| author_details[i][:name] }
64
+ authors = pair_names(author_names)
65
+ author_details = random_author_details(author_details)
66
+ author_email = author_details[:email]
67
+ author_key = author_details[:key]
68
+ env_variables = "GIT_AUTHOR_NAME='#{authors}' GIT_AUTHOR_EMAIL='#{author_email}' GIT_COMMITTER_NAME='#{authors}' GIT_COMMITTER_EMAIL='#{author_email}'"
69
+
70
+ puts "Committing under #{author_email}"
71
+
72
+ unless author_key.nil?
73
+ argv << "--gpg-sign=#{author_key}"
74
+ puts "Signing with key #{author_key}"
75
+ end
76
+
77
+ args = argv.map{|arg| "'#{arg}'"}.join(' ')
78
+
79
+ system "#{env_variables} git commit #{args}"
80
+ rescue GitPairException => e
81
+ puts e.message
82
+ exit 1
83
+ end
84
+
85
+ def current_pair_initials
86
+ initials = `git config user.initials`.strip.split(' ')
87
+ raise GitPairException, 'Error: No pair set. Please set your pair with `git pair ...`' if initials.empty?
88
+ initials
89
+ end
90
+
91
+ def parse_cli_options(argv)
92
+ options = {}
93
+ OptionParser.new do |opts|
94
+ # copy-paste from readme
95
+ opts.banner = <<BANNER.sub('<br/>','')
96
+ Configures git authors when pair programming.
97
+
98
+ git pair sp js
99
+ user.name=Josh Susser and Sam Pierson
100
+ user.email=pair+jsusser+sam@pivotallabs.com
101
+
102
+
103
+ Create a `.pairs` config file in project root or your home folder.
104
+
105
+ # .pairs - configuration for 'git pair'
106
+ pairs:
107
+ # <initials>: <Firstname> <Lastname>[; <email-id>]
108
+ eh: Edward Hieatt
109
+ js: Josh Susser; jsusser
110
+ sf: Serguei Filimonov; serguei
111
+ # if email section is present, email will be set
112
+ # if you leave out the email config section, email will not be set
113
+ email:
114
+ prefix: pair
115
+ domain: pivotallabs.com
116
+ # no_solo_prefix: true
117
+ #global: true
118
+ # include the following section to set custom email addresses for users
119
+ #email_addresses:
120
+ # zr: zach.robinson@example.com
121
+ #gpg_keys:
122
+ # zr: 1A2B3C4D
123
+
124
+
125
+ By default this affects the current project (.git/config).<br/>
126
+ Use the `--global` option or add `global: true` to your `.pairs` file to set the global git configuration for all projects (~/.gitconfig).
127
+
128
+ Options are:
129
+ BANNER
130
+ opts.on("-g", "--global", "Modify global git options instead of local") { options[:global] = true }
131
+ opts.on("-v", "--version", "Show Version") do
132
+ puts PivotalGitScripts::VERSION
133
+ exit
134
+ end
135
+ opts.on("-h", "--help", "Show this.") { puts opts; exit }
136
+ end.parse!(argv)
137
+
138
+ options
139
+ end
140
+
141
+ def read_pairs_config
142
+ pairs_file_name = '.pairs'
143
+
144
+ directory = File.absolute_path(Dir.pwd)
145
+ candidate_directories = [directory]
146
+ while ! Pathname.new(directory).root? do
147
+ directory = File.absolute_path(File.join(directory, ".."))
148
+ candidate_directories << directory
149
+ end
150
+ home = File.absolute_path(ENV["HOME"])
151
+ candidate_directories << home unless candidate_directories.include? home
152
+
153
+ pairs_file_path = candidate_directories.
154
+ map { |d| File.join(d, ".pairs") }.
155
+ find { |f| File.exists? f }
156
+
157
+ unless pairs_file_path
158
+ raise GitPairException, <<-INSTRUCTIONS
159
+ Could not find a .pairs file. Create a YAML file in your project or home directory.
160
+ Format: <initials>: <name>[; <email>]
161
+ Example:
162
+ # .pairs - configuration for 'git pair'
163
+ # place in project or home directory
164
+ pairs:
165
+ eh: Edward Hieatt
166
+ js: Josh Susser; jsusser
167
+ sf: Serguei Filimonov; serguei
168
+ email:
169
+ prefix: pair
170
+ domain: pivotallabs.com
171
+ INSTRUCTIONS
172
+ end
173
+
174
+ YAML.load_file(pairs_file_path)
175
+ end
176
+
177
+ def read_author_info_from_config(config, initials_ary)
178
+ initials_ary.map do |initials|
179
+ config['pairs'][initials.downcase] or
180
+ raise GitPairException, "Couldn't find author name for initials: #{initials}. Add this person to the .pairs file in your project or home directory."
181
+ end
182
+ end
183
+
184
+ def build_email(emails, config)
185
+ if config.is_a?(Hash)
186
+ prefix = config['prefix'] if !config['no_solo_prefix'] or emails.size > 1
187
+ "#{([prefix] + emails).compact.join('+')}@#{config['domain']}"
188
+ else
189
+ config
190
+ end
191
+ end
192
+
193
+ def random_author_details(author_details)
194
+ author_id = author_details.keys.sample
195
+ author_details[author_id]
196
+ end
197
+
198
+ def set_git_config(global, options)
199
+ options.each do |key,value|
200
+ config_key = "user.#{key}"
201
+ arg = value ? %Q{#{config_key} "#{value}"} : "--unset #{config_key}"
202
+ system(%Q{git config#{' --global' if global} #{arg}})
203
+ end
204
+ end
205
+
206
+ def report_git_settings(git_dir, key)
207
+ global = `git config --global --get-regexp '^user\.#{key}'`
208
+ local = `git config -f #{git_dir}/config --get-regexp '^user\.#{key}'`
209
+ if global.length > 0 && local.length > 0
210
+ puts "NOTE: Overriding global user.#{key} setting with local."
211
+ end
212
+ puts "global: #{global}" if global.length > 0
213
+ puts "local: #{local}" if local.length > 0
214
+ end
215
+
216
+ def extract_author_names_and_email_ids_from_config(config, initials)
217
+ authors = read_author_info_from_config(config, initials)
218
+ authors.sort!.uniq! # FIXME
219
+ authors.map do |a|
220
+ full_name, email_id = a.split(";").map(&:strip)
221
+ email_id ||= full_name.split(' ').first.downcase
222
+ [full_name, email_id]
223
+ end.transpose
224
+ end
225
+
226
+ def no_email(config)
227
+ !config.key? 'email'
228
+ end
229
+
230
+ def extract_author_details_from_config(config, initials)
231
+ details = {}
232
+
233
+ initials.each do |i|
234
+ info = read_author_info_from_config(config, [i]).first
235
+
236
+ full_name, email_id = info.split(";").map(&:strip)
237
+ email_id ||= full_name.split(' ').first.downcase
238
+
239
+ email = read_custom_email_address_from_config(config, i)
240
+ email ||= "#{email_id}@#{config['email']['domain']}"
241
+
242
+ key = read_gpg_keys_from_config(config, i)
243
+
244
+ details[i] = {
245
+ :name => full_name,
246
+ :email => email,
247
+ :key => key
248
+ }
249
+ end
250
+
251
+ details
252
+ end
253
+
254
+ def read_custom_email_address_from_config(config, initial)
255
+ return nil unless config['email_addresses']
256
+ return config['email_addresses'][initial.downcase]
257
+ end
258
+
259
+ def read_gpg_keys_from_config(config, initial)
260
+ return nil unless config['gpg_keys']
261
+ return config['gpg_keys'][initial.downcase]
262
+ end
263
+
264
+ private
265
+
266
+ def pair_names(author_names)
267
+ [author_names[0..-2].join(", "), author_names.last].reject(&:empty?).join(" and ")
268
+ end
269
+ end
270
+ end
271
+ end