git-utils 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +23 -0
- data/README.md +85 -0
- data/Rakefile +1 -0
- data/bin/git-amend +4 -0
- data/bin/git-anal +4 -0
- data/bin/git-cleanup +9 -0
- data/bin/git-delete-remote-branch +6 -0
- data/bin/git-merge-branch +11 -0
- data/bin/git-open +6 -0
- data/bin/git-polish +4 -0
- data/bin/git-pull-request +6 -0
- data/bin/git-push-branch +7 -0
- data/bin/git-switch +7 -0
- data/bin/git-sync +6 -0
- data/bin/git-undo +4 -0
- data/git-utils.gemspec +20 -0
- data/lib/git-utils.rb +10 -0
- data/lib/git-utils/command.rb +100 -0
- data/lib/git-utils/delete_remote_branch.rb +41 -0
- data/lib/git-utils/merge_branch.rb +35 -0
- data/lib/git-utils/open.rb +40 -0
- data/lib/git-utils/options.rb +39 -0
- data/lib/git-utils/pull_request.rb +46 -0
- data/lib/git-utils/push_branch.rb +20 -0
- data/lib/git-utils/switch.rb +33 -0
- data/lib/git-utils/sync.rb +22 -0
- data/lib/git-utils/version.rb +5 -0
- data/spec/commands/command_spec.rb +11 -0
- data/spec/commands/delete_remote_branch_spec.rb +18 -0
- data/spec/commands/merge_branch_spec.rb +38 -0
- data/spec/commands/open_spec.rb +37 -0
- data/spec/commands/pull_request_spec.rb +38 -0
- data/spec/commands/push_branch_spec.rb +17 -0
- data/spec/commands/switch_spec.rb +18 -0
- data/spec/commands/sync_spec.rb +19 -0
- data/spec/spec_helper.rb +12 -0
- data/test-open-pr.sh +71 -0
- metadata +114 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 2faeb0fba87e36f531addf4afed6971f1edf3aca
|
|
4
|
+
data.tar.gz: c74f6c8870f6f05b34976ebf29ce7803afebf1f4
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 2bb21163ca18e41b1695b00da352c8d259cd1f3b0e2db93feed285021ef44607c2b63f25063643cd601708356dbd140f651a92cbe9c4ad26da807c6acfe2541b
|
|
7
|
+
data.tar.gz: c0efe25871d671007427bf3cb2d28427f16a03d59b7086d768b046b2d513e1f7b0358a7be08d9847f8135b2927bcf22872f48f4a7597088701260e615fd18cb9
|
data/.gitignore
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
.bundle
|
|
4
|
+
.config
|
|
5
|
+
.yardoc
|
|
6
|
+
Gemfile.lock
|
|
7
|
+
InstalledFiles
|
|
8
|
+
_yardoc
|
|
9
|
+
coverage
|
|
10
|
+
doc/
|
|
11
|
+
lib/bundler/man
|
|
12
|
+
pkg
|
|
13
|
+
rdoc
|
|
14
|
+
spec/reports
|
|
15
|
+
test/tmp
|
|
16
|
+
test/version_tmp
|
|
17
|
+
tmp
|
|
18
|
+
.rvmrc
|
|
19
|
+
.DS_Store
|
|
20
|
+
.api_token
|
|
21
|
+
.project_id
|
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--color
|
data/.ruby-gemset
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pivotal-github
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ruby-2.0.0
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Copyright (c) 2013 Michael Hartl
|
|
2
|
+
Copyright (c) 2013 Aleksandar Simic
|
|
3
|
+
|
|
4
|
+
MIT License
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
7
|
+
a copy of this software and associated documentation files (the
|
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
12
|
+
the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be
|
|
15
|
+
included in all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Git utilities
|
|
2
|
+
|
|
3
|
+
This repo contains some Git utility scripts. The highlights are `git open`, `git pull-request`, `git push-branch`, and `git undo`, which you'll never understand how you did without.
|
|
4
|
+
|
|
5
|
+
The commands are especially useful when combined with [`pivotal-github`](https://github.com/mhartl/git-utils) gem (which, despite its name, also works with Bitbucket).
|
|
6
|
+
|
|
7
|
+
The `git-utils` used to be pure Bash scripts, but they are now available as a Ruby gem, both because Ruby is more powerful than bash and because now `git-utils` can be included more easily as a dependency for the [`pivotal-github`](https://github.com/mhartl/pivotal-github/) gem. As a result, installation is easy if you have RubyGems installed:
|
|
8
|
+
|
|
9
|
+
gem install git-utils
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
* `git amend`: alias for `git commit --amend`
|
|
14
|
+
* `git anal` (use with caution): makes a commit with the message "Make anal changes"
|
|
15
|
+
* `git cleanup`: deletes every branch already merged into current branch (apart from `master`, `staging`, and `development`)
|
|
16
|
+
* `git merge-branch [branch]`: merges current branch into given branch (defaults to `master`)
|
|
17
|
+
* `git open`: opens the remote page for the repo (OS X only)
|
|
18
|
+
* `git polish`: makes a commit with the message "Polish"
|
|
19
|
+
* `git pull-request`: opens the remote page for issuing a new a pull request (OS X only)
|
|
20
|
+
* `git push-branch`: pushes the current branch up to origin
|
|
21
|
+
* `git delete-remote-branch <branch>`: deletes the remote branch if it is safe to do so
|
|
22
|
+
* `git switch <pattern>`: switches to the first branch matching the given pattern
|
|
23
|
+
* `git sync`: syncs the local master with remote
|
|
24
|
+
* `git undo`: undoes the last commit
|
|
25
|
+
|
|
26
|
+
## Aliases
|
|
27
|
+
|
|
28
|
+
Here are some suggested aliases:
|
|
29
|
+
|
|
30
|
+
git config --global alias.mb merge-branch
|
|
31
|
+
git config --global alias.pr pull-request
|
|
32
|
+
git config --global alias.pb push-branch
|
|
33
|
+
|
|
34
|
+
## Further details
|
|
35
|
+
|
|
36
|
+
Some of these commands deserve further explanation.
|
|
37
|
+
|
|
38
|
+
### git merge-branch
|
|
39
|
+
|
|
40
|
+
`git merge-branch [target]` merges the current branch into the target branch (defaults to `master`). On a branch called `add-markdown-support`, `git merge-branch` is equivalent to the following:
|
|
41
|
+
|
|
42
|
+
$ git checkout master
|
|
43
|
+
$ git merge --no-ff --log add-markdown-support
|
|
44
|
+
|
|
45
|
+
Note that this effectively changes the default merge behavior from fast-forward to no-fast-forward, which makes it possible to use `git log` to see which of the commit objects together have implemented a feature on a particular branch. As noted in [A successful Git branching model](http://nvie.com/posts/a-successful-git-branching-model/),
|
|
46
|
+
|
|
47
|
+
> The `--no-ff` flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature… Yes, it will create a few more (empty) commit objects, but the gain is much bigger than that cost.
|
|
48
|
+
|
|
49
|
+
In addition, the `--log` option puts the commit messages from the individual commits in the merge message, which is especially useful for viewing the full diff represented by the commit.
|
|
50
|
+
|
|
51
|
+
These options can be overriden (and thus restored to their defaults) by passing the options `-ff` or `--no-log`. `git merge-branch` accepts any options valid for `git merge`.
|
|
52
|
+
|
|
53
|
+
### git push-branch
|
|
54
|
+
|
|
55
|
+
`git push-branch` creates a remote branch at `origin` with the name of the current branch:
|
|
56
|
+
|
|
57
|
+
$ git branch-push
|
|
58
|
+
* [new branch] add-markdown-support -> add-markdown-support
|
|
59
|
+
|
|
60
|
+
`git push-branch` accepts any options valid for `git push`.
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
### git sync
|
|
64
|
+
|
|
65
|
+
`git sync` syncs the local `master` with the remote `master`. On a branch called `add-markdown-support`, `git sync` is equivalent to the following:
|
|
66
|
+
|
|
67
|
+
$ git checkout master
|
|
68
|
+
$ git pull
|
|
69
|
+
$ git checkout add-markdown-support
|
|
70
|
+
|
|
71
|
+
The purpose of `git sync` is to prepare the current branch for rebasing against `master`:
|
|
72
|
+
|
|
73
|
+
$ git sync
|
|
74
|
+
$ git rebase master
|
|
75
|
+
|
|
76
|
+
(This is essentially equivalent to
|
|
77
|
+
|
|
78
|
+
$ git fetch
|
|
79
|
+
$ git rebase origin/master
|
|
80
|
+
|
|
81
|
+
but I don't like having `master` and `origin/master` be different since that means you have to remember to run `git pull` on `master` some time down the line.)
|
|
82
|
+
|
|
83
|
+
## Installation
|
|
84
|
+
|
|
85
|
+
gem install git-utils
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/git-amend
ADDED
data/bin/git-anal
ADDED
data/bin/git-cleanup
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# Deletes (almost) every branch already merged into current branch.
|
|
4
|
+
# Exceptions are `master`, `staging`, and `development`, and the current
|
|
5
|
+
# branch, which are preserved.
|
|
6
|
+
preserved = "(master|staging|development)"
|
|
7
|
+
cmd = %(git branch --merged | grep -v "\*" | egrep -v "#{preserved}" | )
|
|
8
|
+
cmd += 'xargs -n 1 git branch -d'
|
|
9
|
+
system cmd
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
|
3
|
+
require 'git-utils/merge_branch'
|
|
4
|
+
|
|
5
|
+
# Merges the current branch into the given branch (defaults to master).
|
|
6
|
+
# E.g., 'git merge-branch foobar' merges the current branch into foobar.
|
|
7
|
+
# 'git merge-branch', merges the current branch into master.
|
|
8
|
+
# git merge-branch uses the --no-ff --log options to ensure that the
|
|
9
|
+
# merge creates a new commit object and that the individual commits appear
|
|
10
|
+
# in the log file.
|
|
11
|
+
exit Command.run!(MergeBranch, ARGV.dup)
|
data/bin/git-open
ADDED
data/bin/git-polish
ADDED
data/bin/git-push-branch
ADDED
data/bin/git-switch
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
|
3
|
+
require 'git-utils/switch'
|
|
4
|
+
|
|
5
|
+
# Switches to the first branch matching the given pattern.
|
|
6
|
+
# E.g., 'git switch foobar' switches to 'the-foobar-branch'.
|
|
7
|
+
exit Command.run!(Switch, ARGV.dup)
|
data/bin/git-sync
ADDED
data/bin/git-undo
ADDED
data/git-utils.gemspec
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'git-utils/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |gem|
|
|
7
|
+
gem.name = "git-utils"
|
|
8
|
+
gem.version = Git::Utils::VERSION
|
|
9
|
+
gem.authors = ["Michael Hartl"]
|
|
10
|
+
gem.email = ["michael@michaelhartl.com"]
|
|
11
|
+
gem.description = %q{Add some Git utilities}
|
|
12
|
+
gem.summary = %q{See the README for full documentation}
|
|
13
|
+
gem.homepage = "https://github.com/mhartl/git-utils"
|
|
14
|
+
gem.license = "MIT"
|
|
15
|
+
|
|
16
|
+
gem.files = `git ls-files`.split($/)
|
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
gem.require_paths = ["lib"]
|
|
20
|
+
end
|
data/lib/git-utils.rb
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require "git-utils/version"
|
|
2
|
+
require "git-utils/options"
|
|
3
|
+
require "git-utils/command"
|
|
4
|
+
require "git-utils/merge_branch"
|
|
5
|
+
require "git-utils/open"
|
|
6
|
+
require "git-utils/delete_remote_branch"
|
|
7
|
+
require "git-utils/push_branch"
|
|
8
|
+
require "git-utils/switch"
|
|
9
|
+
require "git-utils/sync"
|
|
10
|
+
require "git-utils/pull_request"
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'optparse'
|
|
2
|
+
require 'ostruct'
|
|
3
|
+
require 'git-utils/options'
|
|
4
|
+
|
|
5
|
+
class Command
|
|
6
|
+
attr_accessor :args, :cmd, :options, :known_options, :unknown_options
|
|
7
|
+
|
|
8
|
+
def initialize(args = [])
|
|
9
|
+
self.args = args
|
|
10
|
+
self.options = OpenStruct.new
|
|
11
|
+
parse
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def parse
|
|
15
|
+
self.known_options = Options::known_options(parser, args)
|
|
16
|
+
self.unknown_options = Options::unknown_options(parser, args)
|
|
17
|
+
parser.parse!(known_options)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def parser
|
|
21
|
+
OptionParser.new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Returns the current Git branch.
|
|
25
|
+
def current_branch
|
|
26
|
+
@current_branch ||= `git rev-parse --abbrev-ref HEAD`.strip
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Returns the URL for the remote origin.
|
|
30
|
+
def origin_url
|
|
31
|
+
@origin_url ||= `git config --get remote.origin.url`.strip
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Returns the name of the repository service.
|
|
37
|
+
# It's currently GitHub, Bitbucket, or Stash.
|
|
38
|
+
# We return blank for an unknown service; the command will still
|
|
39
|
+
# often work in that case.
|
|
40
|
+
def service
|
|
41
|
+
if origin_url =~ /github/i
|
|
42
|
+
'github'
|
|
43
|
+
elsif origin_url =~ /bitbucket/i
|
|
44
|
+
'bitbucket'
|
|
45
|
+
elsif origin_url =~ /stash/i
|
|
46
|
+
'stash'
|
|
47
|
+
else
|
|
48
|
+
''
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Returns the protocol of the origin URL (defaults to ssh).
|
|
53
|
+
def protocol
|
|
54
|
+
if origin_url =~ /https?:\/\//
|
|
55
|
+
'http'
|
|
56
|
+
else
|
|
57
|
+
'ssh'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Runs a command.
|
|
62
|
+
# If the argument array contains '--debug', returns the command that would
|
|
63
|
+
# have been run.
|
|
64
|
+
def self.run!(command_class, args)
|
|
65
|
+
debug = args.delete('--debug')
|
|
66
|
+
command = command_class.new(args)
|
|
67
|
+
if debug
|
|
68
|
+
puts command.cmd
|
|
69
|
+
return 1
|
|
70
|
+
else
|
|
71
|
+
command.run!
|
|
72
|
+
return 0
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def run!
|
|
77
|
+
system cmd
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
# Returns an argument string based on given arguments.
|
|
83
|
+
# The main trick is to add in quotes for option
|
|
84
|
+
# arguments when necessary.
|
|
85
|
+
# For example, ['-a', '-m', 'foo bar'] becomes
|
|
86
|
+
# '-a -m "foo bar"'
|
|
87
|
+
def argument_string(args)
|
|
88
|
+
args.inject([]) do |opts, opt|
|
|
89
|
+
opts << (opt =~ /^-/ ? opt : opt.inspect)
|
|
90
|
+
end.join(' ')
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def finish?
|
|
94
|
+
options.finish
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def deliver?
|
|
98
|
+
options.deliver
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'git-utils/command'
|
|
2
|
+
|
|
3
|
+
class DeleteRemoteBranch < Command
|
|
4
|
+
|
|
5
|
+
def parser
|
|
6
|
+
OptionParser.new do |opts|
|
|
7
|
+
opts.banner = "Usage: git delete-remote-branch <branch>"
|
|
8
|
+
opts.on("-o", "--override", "override unsafe delete") do |opt|
|
|
9
|
+
self.options.override = opt
|
|
10
|
+
end
|
|
11
|
+
opts.on_tail("-h", "--help", "this usage guide") do
|
|
12
|
+
puts opts.to_s; exit 0
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def delete_safely?
|
|
18
|
+
command = "git log ..origin/#{target_branch} 2> /dev/null"
|
|
19
|
+
system(command) && !`#{command}`.strip.empty?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Returns a command appropriate for executing at the command line
|
|
23
|
+
def cmd
|
|
24
|
+
if delete_safely? || options.override
|
|
25
|
+
c = ["git push origin :#{target_branch}"]
|
|
26
|
+
c << argument_string(unknown_options) unless unknown_options.empty?
|
|
27
|
+
c.join("\n")
|
|
28
|
+
else
|
|
29
|
+
$stderr.puts "Target branch contains unmerged commits."
|
|
30
|
+
$stderr.puts "Please cherry-pick the commits or merge the branch again."
|
|
31
|
+
$stderr.puts "Use -o or --override to override."
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# Returns the name of the branch to be deleted.
|
|
38
|
+
def target_branch
|
|
39
|
+
self.known_options.first
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'git-utils/command'
|
|
2
|
+
|
|
3
|
+
class MergeBranch < Command
|
|
4
|
+
|
|
5
|
+
def parser
|
|
6
|
+
OptionParser.new do |opts|
|
|
7
|
+
opts.banner = "Usage: git merge-branch [branch] [options]"
|
|
8
|
+
opts.on_tail("-h", "--help", "this usage guide") do
|
|
9
|
+
puts opts.to_s; exit 0
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns a command appropriate for executing at the command line
|
|
15
|
+
# For example:
|
|
16
|
+
# git checkout master
|
|
17
|
+
# git merge --no-ff --log <branch>
|
|
18
|
+
def cmd
|
|
19
|
+
lines = ["git checkout #{target_branch}"]
|
|
20
|
+
c = ["git merge --no-ff --log"]
|
|
21
|
+
c << argument_string(unknown_options) unless unknown_options.empty?
|
|
22
|
+
c << current_branch
|
|
23
|
+
lines << c.join(' ')
|
|
24
|
+
lines.join("\n")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
# Returns the name of the branch to be merged into.
|
|
30
|
+
# If there is anything left in the known options after parsing,
|
|
31
|
+
# that's the merge branch. Otherwise, it's master.
|
|
32
|
+
def target_branch
|
|
33
|
+
self.known_options.first || 'master'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'git-utils/command'
|
|
2
|
+
|
|
3
|
+
class Open < Command
|
|
4
|
+
|
|
5
|
+
def parser
|
|
6
|
+
OptionParser.new do |opts|
|
|
7
|
+
opts.banner = "Usage: git open"
|
|
8
|
+
opts.on_tail("-h", "--help", "this usage guide") do
|
|
9
|
+
puts opts.to_s; exit 0
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns the URL for the repository page.
|
|
15
|
+
def page_url
|
|
16
|
+
if service == 'stash' && protocol == 'ssh'
|
|
17
|
+
pattern = /(.*)@([^:]*):?([^\/]*)\/([^\/]*)\/(.*)\.git/
|
|
18
|
+
replacement = 'https://\2/projects/\4/repos/\5/browse?at=' +
|
|
19
|
+
current_branch
|
|
20
|
+
elsif service == 'stash' && protocol == 'http'
|
|
21
|
+
pattern = /(.*)@([^:\/]*)(:?[^\/]*)\/(.*)scm\/([^\/]*)\/(.*)\.git/
|
|
22
|
+
replacement = 'https://\2\3/\4projects/\5/repos/\6/browse?at=' +
|
|
23
|
+
current_branch
|
|
24
|
+
elsif protocol == 'ssh'
|
|
25
|
+
pattern = /(.*)@(.*):(.*)\.git/
|
|
26
|
+
replacement = 'https://\2/\3/'
|
|
27
|
+
elsif protocol == 'http'
|
|
28
|
+
pattern = /https?\:\/\/(([^@]*)@)?(.*)\.git/
|
|
29
|
+
replacement = 'https://\3/'
|
|
30
|
+
end
|
|
31
|
+
origin_url.sub(pattern, replacement)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Returns a command appropriate for executing at the command line
|
|
35
|
+
def cmd
|
|
36
|
+
c = ["open #{page_url}"]
|
|
37
|
+
c << argument_string(unknown_options) unless unknown_options.empty?
|
|
38
|
+
c.join("\n")
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'optparse'
|
|
2
|
+
|
|
3
|
+
module Options
|
|
4
|
+
|
|
5
|
+
# Returns a list of options unknown to a particular options parser
|
|
6
|
+
# For example, if '-a' is a known option but '-b' and '-c' are not,
|
|
7
|
+
# unknown_options(parser, ['-a', '-b', '-c']) returns ['-b', '-c'].
|
|
8
|
+
# It also preserves arguments, so
|
|
9
|
+
# unknown_options(parser, ['-a', '-b', '-c', 'foo bar']) returns
|
|
10
|
+
# ['-b', '-c', 'foo bar'].
|
|
11
|
+
def self.unknown_options(parser, args)
|
|
12
|
+
unknown = []
|
|
13
|
+
recursive_parse = Proc.new do |arg_list|
|
|
14
|
+
begin
|
|
15
|
+
# Hack to handle an unknown '-ff' argument
|
|
16
|
+
# The issue here is that OptParse interprets '-ff' as a '-f' option
|
|
17
|
+
# applied twice. This is sort-of a feature, as it allows, e.g., '-am'
|
|
18
|
+
# to set both the '-a' and '-m' options, but it interacts badly
|
|
19
|
+
# with '-ff' (as used by 'git merge') when '-f' is one of the options.
|
|
20
|
+
unknown << arg_list.delete('-ff') if arg_list.include?('-ff')
|
|
21
|
+
parser.parse!(arg_list)
|
|
22
|
+
rescue OptionParser::InvalidOption => e
|
|
23
|
+
unknown.concat(e.args)
|
|
24
|
+
while !arg_list.empty? && arg_list.first[0] != "-"
|
|
25
|
+
unknown << arg_list.shift
|
|
26
|
+
end
|
|
27
|
+
recursive_parse.call(arg_list)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
recursive_parse.call(args.dup)
|
|
31
|
+
unknown
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Returns a list of options with unknown options removed
|
|
35
|
+
def self.known_options(parser, args)
|
|
36
|
+
unknown = unknown_options(parser, args)
|
|
37
|
+
args.reject { |arg| unknown.include?(arg) }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'git-utils/command'
|
|
2
|
+
|
|
3
|
+
class PullRequest < Command
|
|
4
|
+
|
|
5
|
+
def parser
|
|
6
|
+
OptionParser.new do |opts|
|
|
7
|
+
opts.banner = "Usage: git pull-request"
|
|
8
|
+
opts.on_tail("-h", "--help", "this usage guide") do
|
|
9
|
+
puts opts.to_s; exit 0
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns the URL for a new pull request.
|
|
15
|
+
def new_pr_url
|
|
16
|
+
if service == 'stash' && protocol == 'ssh'
|
|
17
|
+
pattern = /(.*)@([^:]*):?([^\/]*)\/([^\/]*)\/(.*)\.git/
|
|
18
|
+
replacement = 'https://\2/projects/\4/repos/\5/pull-requests?create&sourceBranch=' +
|
|
19
|
+
current_branch
|
|
20
|
+
elsif service == 'stash' && protocol == 'http'
|
|
21
|
+
pattern = /(.*)@([^:\/]*)(:?[^\/]*)\/(.*)scm\/([^\/]*)\/(.*)\.git/
|
|
22
|
+
replacement = 'https://\2\3/\4projects/\5/repos/\6/pull-requests?create&sourceBranch=' +
|
|
23
|
+
current_branch
|
|
24
|
+
elsif service == 'github' && protocol == 'ssh'
|
|
25
|
+
pattern = /(.*)@(.*):(.*)\.git/
|
|
26
|
+
replacement = 'https://\2/\3/pull/new/' + current_branch
|
|
27
|
+
elsif service == 'github' && protocol == 'http'
|
|
28
|
+
pattern = /https?\:\/\/(([^@]*)@)?(.*)\.git/
|
|
29
|
+
replacement = 'https://\3/pull/new/' + current_branch
|
|
30
|
+
elsif service == 'bitbucket' && protocol == 'ssh'
|
|
31
|
+
pattern = /(.*)@(.*):(.*)\.git/
|
|
32
|
+
replacement = 'https://\2/\3/pull-request/new/'
|
|
33
|
+
elsif service == 'bitbucket' && protocol == 'http'
|
|
34
|
+
pattern = /https?\:\/\/(([^@]*)@)?(.*)\.git/
|
|
35
|
+
replacement = 'https://\3/pull-request/new/'
|
|
36
|
+
end
|
|
37
|
+
origin_url.sub(pattern, replacement)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns a command appropriate for executing at the command line
|
|
41
|
+
def cmd
|
|
42
|
+
c = ["open #{new_pr_url}"]
|
|
43
|
+
c << argument_string(unknown_options) unless unknown_options.empty?
|
|
44
|
+
c.join("\n")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'git-utils/command'
|
|
2
|
+
|
|
3
|
+
class PushBranch < Command
|
|
4
|
+
|
|
5
|
+
def parser
|
|
6
|
+
OptionParser.new do |opts|
|
|
7
|
+
opts.banner = "Usage: git push-branch"
|
|
8
|
+
opts.on_tail("-h", "--help", "this usage guide") do
|
|
9
|
+
puts opts.to_s; exit 0
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns a command appropriate for executing at the command line
|
|
15
|
+
def cmd
|
|
16
|
+
c = ["git push origin #{current_branch}"]
|
|
17
|
+
c << argument_string(unknown_options) unless unknown_options.empty?
|
|
18
|
+
c.join("\n")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'git-utils/command'
|
|
2
|
+
|
|
3
|
+
class Switch < Command
|
|
4
|
+
|
|
5
|
+
def parser
|
|
6
|
+
OptionParser.new do |opts|
|
|
7
|
+
opts.banner = "Usage: git switch <pattern>"
|
|
8
|
+
opts.on_tail("-h", "--help", "this usage guide") do
|
|
9
|
+
puts opts.to_s; exit 0
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns the branch to switch to.
|
|
15
|
+
def other_branch
|
|
16
|
+
@other_branch ||= `git branch | grep #{pattern}`.strip
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns a command appropriate for executing at the command line
|
|
20
|
+
def cmd
|
|
21
|
+
c = ["git checkout #{other_branch}"]
|
|
22
|
+
c << argument_string(unknown_options) unless unknown_options.empty?
|
|
23
|
+
c.join("\n")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
# Returns the pattern of the branch to switch to.
|
|
29
|
+
def pattern
|
|
30
|
+
self.known_options.first
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'git-utils/command'
|
|
2
|
+
|
|
3
|
+
class Sync < Command
|
|
4
|
+
|
|
5
|
+
def parser
|
|
6
|
+
OptionParser.new do |opts|
|
|
7
|
+
opts.banner = "Usage: git sync"
|
|
8
|
+
opts.on_tail("-h", "--help", "this usage guide") do
|
|
9
|
+
puts opts.to_s; exit 0
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns a command appropriate for executing at the command line
|
|
15
|
+
def cmd
|
|
16
|
+
c = ["git checkout master"]
|
|
17
|
+
c << "git pull"
|
|
18
|
+
c << "git checkout #{current_branch}"
|
|
19
|
+
c << argument_string(unknown_options) unless unknown_options.empty?
|
|
20
|
+
c.join("\n")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe DeleteRemoteBranch do
|
|
4
|
+
|
|
5
|
+
let(:command) { DeleteRemoteBranch.new(['remote_branch']) }
|
|
6
|
+
before do
|
|
7
|
+
command.stub(:current_branch).and_return('test-br')
|
|
8
|
+
command.stub(:delete_safely?).and_return(true)
|
|
9
|
+
end
|
|
10
|
+
subject { command }
|
|
11
|
+
|
|
12
|
+
its(:cmd) { should match /git push origin :remote_branch/ }
|
|
13
|
+
|
|
14
|
+
describe "command-line command" do
|
|
15
|
+
subject { `bin/git-delete-remote-branch foobar -o --debug` }
|
|
16
|
+
it { should match /git push origin/ }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe MergeBranch do
|
|
4
|
+
|
|
5
|
+
let(:command) { MergeBranch.new }
|
|
6
|
+
before { command.stub(:current_branch).and_return('tau-manifesto') }
|
|
7
|
+
subject { command }
|
|
8
|
+
|
|
9
|
+
its(:cmd) { should match /git merge/ }
|
|
10
|
+
|
|
11
|
+
shared_examples "merge-branch with known options" do
|
|
12
|
+
subject { command }
|
|
13
|
+
it "should not raise an error" do
|
|
14
|
+
expect { command.parse }.not_to raise_error(OptionParser::InvalidOption)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "with no options" do
|
|
19
|
+
its(:cmd) { should match /git checkout master/ }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "with a custom development branch" do
|
|
23
|
+
let(:command) { MergeBranch.new(['development']) }
|
|
24
|
+
its(:cmd) { should match /git checkout development/ }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe "with some unknown options" do
|
|
28
|
+
let(:command) { MergeBranch.new(['dev', '-o', '-a', '-z', '--foo']) }
|
|
29
|
+
it_should_behave_like "merge-branch with known options"
|
|
30
|
+
its(:cmd) { should match /-a -z --foo/ }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "command-line command" do
|
|
34
|
+
subject { `bin/git-merge-branch --debug development` }
|
|
35
|
+
it { should match /git checkout development/ }
|
|
36
|
+
it { should match /git merge --no-ff --log/ }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Open do
|
|
4
|
+
|
|
5
|
+
let(:command) { Open.new }
|
|
6
|
+
before do
|
|
7
|
+
command.stub(:current_branch).and_return('test-br')
|
|
8
|
+
end
|
|
9
|
+
subject { command }
|
|
10
|
+
|
|
11
|
+
its(:cmd) { should match /open #{command.page_url}/ }
|
|
12
|
+
|
|
13
|
+
it "should have the right page URLs" do
|
|
14
|
+
urls = %w[
|
|
15
|
+
https://mwatson@bitbucket.org/atlassian/amps.git https://bitbucket.org/atlassian/amps
|
|
16
|
+
git@bitbucket.org:atlassian/amps.git https://bitbucket.org/atlassian/amps
|
|
17
|
+
git@github.com:mhartl/git-utils.git https://github.com/mhartl/git-utils
|
|
18
|
+
https://github.com/mhartl/git-utils.git https://github.com/mhartl/git-utils
|
|
19
|
+
ssh://git@stash.atlassian.com:7999/stash/stash.git https://stash.atlassian.com/projects/stash/repos/stash/browse?at=test-br
|
|
20
|
+
https://mwatson@stash.atlassian.com:7990/scm/stash/stash.git https://stash.atlassian.com:7990/projects/stash/repos/stash/browse?at=test-br
|
|
21
|
+
ssh://git@stash.atlassian.com/stash/stash.git https://stash.atlassian.com/projects/stash/repos/stash/browse?at=test-br
|
|
22
|
+
https://mwatson@stash.atlassian.com/scm/stash/stash.git https://stash.atlassian.com/projects/stash/repos/stash/browse?at=test-br
|
|
23
|
+
https://mwatson@stash.atlassian.com/stash/scm/stash/stash.git https://stash.atlassian.com/stash/projects/stash/repos/stash/browse?at=test-br
|
|
24
|
+
https://mwatson@stash.atlassian.com:7990/stash/scm/stash/stash.git https://stash.atlassian.com:7990/stash/projects/stash/repos/stash/browse?at=test-br
|
|
25
|
+
https://example.com/repos/foobar.git https://example.com/repos/foobar
|
|
26
|
+
]
|
|
27
|
+
urls.each_slice(2) do |origin_url, page_url|
|
|
28
|
+
command.stub(:origin_url).and_return(origin_url)
|
|
29
|
+
expect(command.page_url).to include page_url
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "command-line command" do
|
|
34
|
+
subject { `bin/git-open --debug` }
|
|
35
|
+
it { should match /open/ }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe PullRequest do
|
|
4
|
+
|
|
5
|
+
let(:command) { PullRequest.new }
|
|
6
|
+
before do
|
|
7
|
+
command.stub(:current_branch).and_return('test-br')
|
|
8
|
+
end
|
|
9
|
+
subject { command }
|
|
10
|
+
|
|
11
|
+
its(:cmd) { should match /open #{command.new_pr_url}/ }
|
|
12
|
+
|
|
13
|
+
it "should have the right pull request URLs" do
|
|
14
|
+
urls = %w[
|
|
15
|
+
https://mwatson@bitbucket.org/atlassian/amps.git https://bitbucket.org/atlassian/amps/pull-request/new
|
|
16
|
+
git@bitbucket.org:atlassian/amps.git https://bitbucket.org/atlassian/amps/pull-request/new
|
|
17
|
+
git@github.com:mhartl/git-utils.git https://github.com/mhartl/git-utils/pull/new/test-br
|
|
18
|
+
https://github.com/mhartl/git-utils.git https://github.com/mhartl/git-utils/pull/new/test-br
|
|
19
|
+
ssh://git@stash.atlassian.com:7999/stash/stash.git https://stash.atlassian.com/projects/stash/repos/stash/pull-requests?create&sourceBranch=test-br
|
|
20
|
+
https://mwatson@stash.atlassian.com:7990/scm/stash/stash.git https://stash.atlassian.com:7990/projects/stash/repos/stash/pull-requests?create&sourceBranch=test-br
|
|
21
|
+
ssh://git@stash.atlassian.com/stash/stash.git https://stash.atlassian.com/projects/stash/repos/stash/pull-requests?create&sourceBranch=test-br
|
|
22
|
+
https://mwatson@stash.atlassian.com/scm/stash/stash.git https://stash.atlassian.com/projects/stash/repos/stash/pull-requests?create&sourceBranch=test-br
|
|
23
|
+
https://mwatson@stash.atlassian.com/stash/scm/stash/stash.git https://stash.atlassian.com/stash/projects/stash/repos/stash/pull-requests?create&sourceBranch=test-br
|
|
24
|
+
https://mwatson@stash.atlassian.com:7990/stash/scm/stash/stash.git https://stash.atlassian.com:7990/stash/projects/stash/repos/stash/pull-requests?create&sourceBranch=test-br
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
urls.each_slice(2) do |origin_url, new_pr_url|
|
|
28
|
+
command.stub(:origin_url).and_return(origin_url)
|
|
29
|
+
expect(command.new_pr_url).to include new_pr_url
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
describe "command-line command" do
|
|
35
|
+
subject { `bin/git-pull-request --debug` }
|
|
36
|
+
it { should match /open/ }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe PushBranch do
|
|
4
|
+
|
|
5
|
+
let(:command) { PushBranch.new(['remote_branch']) }
|
|
6
|
+
before do
|
|
7
|
+
command.stub(:current_branch).and_return('test-br')
|
|
8
|
+
end
|
|
9
|
+
subject { command }
|
|
10
|
+
|
|
11
|
+
its(:cmd) { should match /git push origin #{command.current_branch}/ }
|
|
12
|
+
|
|
13
|
+
describe "command-line command" do
|
|
14
|
+
subject { `bin/git-push-branch --debug` }
|
|
15
|
+
it { should match /git push origin/ }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Switch do
|
|
4
|
+
|
|
5
|
+
let(:command) { Switch.new(['other-branch']) }
|
|
6
|
+
before do
|
|
7
|
+
command.stub(:current_branch).and_return('test-br')
|
|
8
|
+
command.stub(:other_branch).and_return('other-branch')
|
|
9
|
+
end
|
|
10
|
+
subject { command }
|
|
11
|
+
|
|
12
|
+
its(:cmd) { should match /git checkout #{command.other_branch}/ }
|
|
13
|
+
|
|
14
|
+
describe "command-line command" do
|
|
15
|
+
subject { `bin/git-push-branch --debug` }
|
|
16
|
+
it { should match /git push origin/ }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Sync do
|
|
4
|
+
|
|
5
|
+
let(:command) { Sync.new }
|
|
6
|
+
before do
|
|
7
|
+
command.stub(:current_branch).and_return('test-br')
|
|
8
|
+
end
|
|
9
|
+
subject { command }
|
|
10
|
+
|
|
11
|
+
its(:cmd) { should match /git checkout master/ }
|
|
12
|
+
its(:cmd) { should match /git pull/ }
|
|
13
|
+
its(:cmd) { should match /git checkout #{command.current_branch}/ }
|
|
14
|
+
|
|
15
|
+
describe "command-line command" do
|
|
16
|
+
subject { `bin/git-sync --debug` }
|
|
17
|
+
it { should match /git checkout master/ }
|
|
18
|
+
end
|
|
19
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'git-utils'
|
|
2
|
+
|
|
3
|
+
RSpec.configure do |config|
|
|
4
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
|
5
|
+
config.run_all_when_everything_filtered = true
|
|
6
|
+
config.filter_run :focus
|
|
7
|
+
|
|
8
|
+
# Disallow the old-style 'object.should' syntax.
|
|
9
|
+
config.expect_with :rspec do |c|
|
|
10
|
+
c.syntax = :expect
|
|
11
|
+
end
|
|
12
|
+
end
|
data/test-open-pr.sh
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
git init test-repo >/dev/null
|
|
4
|
+
cd test-repo
|
|
5
|
+
git checkout -b test-br 2>/dev/null
|
|
6
|
+
touch foo
|
|
7
|
+
git add foo
|
|
8
|
+
git commit -m "foo" >/dev/null
|
|
9
|
+
cat > open <<EOF
|
|
10
|
+
#!/usr/bin/env ruby
|
|
11
|
+
|
|
12
|
+
echo \$*
|
|
13
|
+
EOF
|
|
14
|
+
chmod +x open
|
|
15
|
+
cat > git-push-branch <<EOF
|
|
16
|
+
#!/usr/bin/env ruby
|
|
17
|
+
EOF
|
|
18
|
+
chmod +x git-push-branch
|
|
19
|
+
export PATH=`pwd`:$PATH
|
|
20
|
+
git remote add origin foo
|
|
21
|
+
|
|
22
|
+
test_open () {
|
|
23
|
+
REMOTE=$1
|
|
24
|
+
EXPECTED=$2
|
|
25
|
+
git remote set-url origin $REMOTE
|
|
26
|
+
RESULT=`../git-open`
|
|
27
|
+
if [ "$RESULT" = "$EXPECTED" ]
|
|
28
|
+
then
|
|
29
|
+
echo "passed: open $REMOTE"
|
|
30
|
+
else
|
|
31
|
+
echo "FAILED: open: Expected $EXPECTED (for origin $REMOTE) but got $RESULT"
|
|
32
|
+
fi
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
test_open https://mwatson@bitbucket.org/atlassian/amps.git https://bitbucket.org/atlassian/amps
|
|
36
|
+
test_open git@bitbucket.org:atlassian/amps.git https://bitbucket.org/atlassian/amps
|
|
37
|
+
test_open git@github.com:mhartl/git-utils.git https://github.com/mhartl/git-utils
|
|
38
|
+
test_open https://github.com/mhartl/git-utils.git https://github.com/mhartl/git-utils
|
|
39
|
+
test_open ssh://git@stash.atlassian.com:7999/stash/stash.git https://stash.atlassian.com/projects/stash/repos/stash/browse?at=test-br
|
|
40
|
+
test_open https://mwatson@stash.atlassian.com:7990/scm/stash/stash.git https://stash.atlassian.com:7990/projects/stash/repos/stash/browse?at=test-br
|
|
41
|
+
test_open ssh://git@stash.atlassian.com/stash/stash.git https://stash.atlassian.com/projects/stash/repos/stash/browse?at=test-br
|
|
42
|
+
test_open https://mwatson@stash.atlassian.com/scm/stash/stash.git https://stash.atlassian.com/projects/stash/repos/stash/browse?at=test-br
|
|
43
|
+
test_open https://mwatson@stash.atlassian.com/stash/scm/stash/stash.git https://stash.atlassian.com/stash/projects/stash/repos/stash/browse?at=test-br
|
|
44
|
+
test_open https://mwatson@stash.atlassian.com:7990/stash/scm/stash/stash.git https://stash.atlassian.com:7990/stash/projects/stash/repos/stash/browse?at=test-br
|
|
45
|
+
|
|
46
|
+
test_pr () {
|
|
47
|
+
REMOTE=$1
|
|
48
|
+
EXPECTED=$2
|
|
49
|
+
git remote set-url origin $REMOTE
|
|
50
|
+
RESULT=`../git-pull-request`
|
|
51
|
+
if [ "$RESULT" = "$EXPECTED" ]
|
|
52
|
+
then
|
|
53
|
+
echo "passed: pull-request $REMOTE"
|
|
54
|
+
else
|
|
55
|
+
echo "FAILED: pull-request: Expected $EXPECTED (for origin $REMOTE) but got $RESULT"
|
|
56
|
+
fi
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
test_pr https://mwatson@bitbucket.org/atlassian/amps.git https://bitbucket.org/atlassian/amps/pull-request/new
|
|
60
|
+
test_pr git@bitbucket.org:atlassian/amps.git https://bitbucket.org/atlassian/amps/pull-request/new
|
|
61
|
+
test_pr git@github.com:mhartl/git-utils.git https://github.com/mhartl/git-utils/pull/new/test-br
|
|
62
|
+
test_pr https://github.com/mhartl/git-utils.git https://github.com/mhartl/git-utils/pull/new/test-br
|
|
63
|
+
test_pr ssh://git@stash.atlassian.com:7999/stash/stash.git https://stash.atlassian.com/projects/stash/repos/stash/pull-requests?create\&sourceBranch=test-br
|
|
64
|
+
test_pr https://mwatson@stash.atlassian.com:7990/scm/stash/stash.git https://stash.atlassian.com:7990/projects/stash/repos/stash/pull-requests?create\&sourceBranch=test-br
|
|
65
|
+
test_pr ssh://git@stash.atlassian.com/stash/stash.git https://stash.atlassian.com/projects/stash/repos/stash/pull-requests?create\&sourceBranch=test-br
|
|
66
|
+
test_pr https://mwatson@stash.atlassian.com/scm/stash/stash.git https://stash.atlassian.com/projects/stash/repos/stash/pull-requests?create\&sourceBranch=test-br
|
|
67
|
+
test_pr https://mwatson@stash.atlassian.com/stash/scm/stash/stash.git https://stash.atlassian.com/stash/projects/stash/repos/stash/pull-requests?create\&sourceBranch=test-br
|
|
68
|
+
test_pr https://mwatson@stash.atlassian.com:7990/stash/scm/stash/stash.git https://stash.atlassian.com:7990/stash/projects/stash/repos/stash/pull-requests?create\&sourceBranch=test-br
|
|
69
|
+
|
|
70
|
+
cd ..
|
|
71
|
+
rm -rf test-repo
|
metadata
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: git-utils
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Michael Hartl
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2013-06-19 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Add some Git utilities
|
|
14
|
+
email:
|
|
15
|
+
- michael@michaelhartl.com
|
|
16
|
+
executables:
|
|
17
|
+
- git-amend
|
|
18
|
+
- git-anal
|
|
19
|
+
- git-cleanup
|
|
20
|
+
- git-delete-remote-branch
|
|
21
|
+
- git-merge-branch
|
|
22
|
+
- git-open
|
|
23
|
+
- git-polish
|
|
24
|
+
- git-pull-request
|
|
25
|
+
- git-push-branch
|
|
26
|
+
- git-switch
|
|
27
|
+
- git-sync
|
|
28
|
+
- git-undo
|
|
29
|
+
extensions: []
|
|
30
|
+
extra_rdoc_files: []
|
|
31
|
+
files:
|
|
32
|
+
- .DS_Store
|
|
33
|
+
- .gitignore
|
|
34
|
+
- .project_id
|
|
35
|
+
- .rspec
|
|
36
|
+
- .ruby-gemset
|
|
37
|
+
- .ruby-version
|
|
38
|
+
- Gemfile
|
|
39
|
+
- Gemfile.lock
|
|
40
|
+
- LICENSE.txt
|
|
41
|
+
- README.md
|
|
42
|
+
- Rakefile
|
|
43
|
+
- bin/git-amend
|
|
44
|
+
- bin/git-anal
|
|
45
|
+
- bin/git-cleanup
|
|
46
|
+
- bin/git-delete-remote-branch
|
|
47
|
+
- bin/git-merge-branch
|
|
48
|
+
- bin/git-open
|
|
49
|
+
- bin/git-polish
|
|
50
|
+
- bin/git-pull-request
|
|
51
|
+
- bin/git-push-branch
|
|
52
|
+
- bin/git-switch
|
|
53
|
+
- bin/git-sync
|
|
54
|
+
- bin/git-undo
|
|
55
|
+
- git-utils.gemspec
|
|
56
|
+
- lib/git-utils.rb
|
|
57
|
+
- lib/git-utils/command.rb
|
|
58
|
+
- lib/git-utils/delete_remote_branch.rb
|
|
59
|
+
- lib/git-utils/merge_branch.rb
|
|
60
|
+
- lib/git-utils/open.rb
|
|
61
|
+
- lib/git-utils/options.rb
|
|
62
|
+
- lib/git-utils/pull_request.rb
|
|
63
|
+
- lib/git-utils/push_branch.rb
|
|
64
|
+
- lib/git-utils/switch.rb
|
|
65
|
+
- lib/git-utils/sync.rb
|
|
66
|
+
- lib/git-utils/version.rb
|
|
67
|
+
- spec/.DS_Store
|
|
68
|
+
- spec/commands/.DS_Store
|
|
69
|
+
- spec/commands/command_spec.rb
|
|
70
|
+
- spec/commands/delete_remote_branch_spec.rb
|
|
71
|
+
- spec/commands/merge_branch_spec.rb
|
|
72
|
+
- spec/commands/open_spec.rb
|
|
73
|
+
- spec/commands/pull_request_spec.rb
|
|
74
|
+
- spec/commands/push_branch_spec.rb
|
|
75
|
+
- spec/commands/switch_spec.rb
|
|
76
|
+
- spec/commands/sync_spec.rb
|
|
77
|
+
- spec/spec_helper.rb
|
|
78
|
+
- test-open-pr.sh
|
|
79
|
+
homepage: https://github.com/mhartl/git-utils
|
|
80
|
+
licenses:
|
|
81
|
+
- MIT
|
|
82
|
+
metadata: {}
|
|
83
|
+
post_install_message:
|
|
84
|
+
rdoc_options: []
|
|
85
|
+
require_paths:
|
|
86
|
+
- lib
|
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
88
|
+
requirements:
|
|
89
|
+
- - '>='
|
|
90
|
+
- !ruby/object:Gem::Version
|
|
91
|
+
version: '0'
|
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - '>='
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
requirements: []
|
|
98
|
+
rubyforge_project:
|
|
99
|
+
rubygems_version: 2.0.3
|
|
100
|
+
signing_key:
|
|
101
|
+
specification_version: 4
|
|
102
|
+
summary: See the README for full documentation
|
|
103
|
+
test_files:
|
|
104
|
+
- spec/.DS_Store
|
|
105
|
+
- spec/commands/.DS_Store
|
|
106
|
+
- spec/commands/command_spec.rb
|
|
107
|
+
- spec/commands/delete_remote_branch_spec.rb
|
|
108
|
+
- spec/commands/merge_branch_spec.rb
|
|
109
|
+
- spec/commands/open_spec.rb
|
|
110
|
+
- spec/commands/pull_request_spec.rb
|
|
111
|
+
- spec/commands/push_branch_spec.rb
|
|
112
|
+
- spec/commands/switch_spec.rb
|
|
113
|
+
- spec/commands/sync_spec.rb
|
|
114
|
+
- spec/spec_helper.rb
|