git_remote_branch 0.2.4 → 0.2.6

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.
data/CHANGELOG ADDED
@@ -0,0 +1,17 @@
1
+ * Release 0.2.6 *
2
+ Three new actual features
3
+ - grb rename, contributed by Caio Chassot (caiochassot.com)
4
+ - grb publish, to make available and track a local branch
5
+ - the --silent option, if you want to use grb in a script
6
+
7
+ And other stuff
8
+ - the grb bin file now works when symlinked (also thanks to Caio Chassot)
9
+ - Lots and lots of unit and functional tests
10
+ - bug fixes
11
+ - more flexibility for running grb outside of a git repository (e.g. for 'explain' or 'help')
12
+ - Now officially under the MIT license
13
+ - refactored a bunch of rake tasks
14
+
15
+
16
+ Versions lost in time:
17
+ 0.2.1, 0.2.2, 0.2.3, 0.2.4
data/COPYING ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2008 Mathieu Martin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to
5
+ deal in the Software without restriction, including without limitation the
6
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README CHANGED
@@ -13,12 +13,16 @@ commands. Each operation done on your behalf is displayed at the console.
13
13
 
14
14
  ==== Installation ====
15
15
 
16
- sudo gem install webmat-git_remote_branch --source=http://gems.github.com
16
+ sudo gem install grb
17
17
 
18
- Note: don't add gems.github.com as a permanent source for your gems. Check out
19
- http://gems.github.com for more information on the matter. If you've included
20
- it already and find yourself in trouble, check out
21
- http://chalain.livejournal.com/71260.html.
18
+
19
+ Or if you want the bleeding edge from GitHub
20
+ You may try
21
+ sudo gem install webmat-git_remote_branch --source=http://gems.github.com
22
+
23
+ But you're probably better off with
24
+ git clone git://github.com/webmat/git_remote_branch.git
25
+ rake install
22
26
 
23
27
 
24
28
 
@@ -30,9 +34,10 @@ Notes:
30
34
 
31
35
  Available commands (with aliases):
32
36
 
37
+
33
38
  == Help ==
34
39
 
35
- $ grb [-h] #=> Displays help
40
+ $ grb [-h|help] #=> Displays help
36
41
 
37
42
  == create (alias: new) ==
38
43
  Create a new local branch as well as a corresponding remote branch from the
@@ -43,6 +48,14 @@ Switch to the new branch.
43
48
  $ grb create branch_name [origin_server]
44
49
 
45
50
 
51
+ == publish (aliases: remotize) ==
52
+ Publish an existing local branch to the remote server.
53
+ Set up the local branch to track the new remote branch.
54
+ Switch to the new branch.
55
+
56
+ $ grb publish branch_name [origin_server]
57
+
58
+
46
59
  == delete (aliases: destroy, kill, remove) ==
47
60
  Delete the remote branch then delete the local branch.
48
61
  The local branch is not deleted if there are pending changes.
@@ -57,10 +70,10 @@ $ grb track branch_name [origin_server]
57
70
 
58
71
 
59
72
  == rename (aliases: rn, mv, move) ==
60
- Rename the remote branch by copying and deleting the old name.
61
- Checkout a new local tracking branch with the new name and delete the branch
62
- with the old name.
63
- branch_name is the new name, the old name is always the current branch's
73
+ To rename the branch you're currently on.
74
+ Rename the remote branch by copying then deleting the old name.
75
+ Checkout a new local tracking branch with the new name and delete the local
76
+ branch with the old name.
64
77
 
65
78
  $ grb rename branch_name [origin_server]
66
79
 
@@ -73,7 +86,7 @@ run to accomplish that goal.
73
86
  Examples:
74
87
 
75
88
  $ grb explain create
76
- git_remote_branch version 0.2.2
89
+ git_remote_branch version 0.2.6
77
90
 
78
91
  List of operations to do to create a new remote branch and track it locally:
79
92
 
@@ -84,7 +97,7 @@ git checkout branch_to_create
84
97
 
85
98
 
86
99
  $ grb explain create my_branch github
87
- git_remote_branch version 0.2.2
100
+ git_remote_branch version 0.2.6
88
101
 
89
102
  List of operations to do to create a new remote branch and track it locally:
90
103
 
@@ -94,6 +107,14 @@ git branch --track my_branch github/my_branch
94
107
  git checkout my_branch
95
108
 
96
109
 
110
+
111
+ ==== More on git_remote_branch ====
112
+
113
+ Site: http://github.com/webmat/git_remote_branch
114
+ Mailing list: http://groups.google.com/group/git_remote_branch
115
+
116
+
117
+
97
118
  ==== History ====
98
119
 
99
120
  This script was originally created by Carl Mercier and made public on his blog
@@ -107,8 +128,13 @@ I'm using it as a starting point to make it even easier to interact with remote
107
128
  repositories.
108
129
 
109
130
 
110
- === Contributors ===
131
+ == Contributors ==
111
132
 
112
133
  - Mathieu Martin webmat@gmail.com
113
134
  - Carl Mercier (Carl: want your email here?)
114
135
  - Caio Chassot dev@caiochassot.com
136
+
137
+
138
+ == Legalese ==
139
+
140
+ git_remote_branch is licensed under the MIT License. See the file COPYING for details.
data/Rakefile CHANGED
@@ -1,51 +1,12 @@
1
1
  require 'rubygems'
2
2
 
3
3
  require 'rake'
4
- require 'rake/testtask'
5
- require 'rake/gempackagetask'
6
4
 
7
5
  HERE = File.dirname(__FILE__)
8
-
9
- require "#{HERE}/lib/git_remote_branch"
10
-
11
-
12
- #Stuff gleaned from merb-core's Rakefile
13
- NAME = 'git_remote_branch'
14
6
  windows = (RUBY_PLATFORM =~ /win32|cygwin/) rescue nil
15
- install_home = ENV['GEM_HOME'] ? "-i #{ENV['GEM_HOME']}" : ""
16
7
  SUDO = windows ? "" : "sudo"
17
8
 
18
-
19
- Rake::TestTask.new(:test) do |t|
20
- t.pattern = 'test/**/*_test.rb'
21
- t.verbose = true
22
- end
9
+ require "#{HERE}/lib/git_remote_branch"
10
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
23
11
 
24
12
  task :default => :test
25
-
26
- gem_spec = eval(File.read("#{HERE}/git_remote_branch.gemspec"))
27
-
28
- namespace :gem do
29
- #Creates clobber_package, gem, package, repackage tasks
30
- #Note on clobber_package: fortunately, this will clobber the CODE package
31
- Rake::GemPackageTask.new(gem_spec) do |pkg|
32
- pkg.need_tar = true
33
- end
34
-
35
- #Tasks gleaned from merb-core's Rakefile
36
-
37
- desc "Run :gem and install the resulting .gem"
38
- task :install => :gem do
39
- cmd = "#{SUDO} gem install #{install_home} --local pkg/#{NAME}-#{GitRemoteBranch::VERSION}.gem --no-rdoc --no-ri"
40
- puts cmd
41
- `#{cmd}`
42
- end
43
-
44
- desc "Uninstall the .gem"
45
- task :uninstall do
46
- cmd = "#{SUDO} gem uninstall #{NAME} -x"
47
- #TODO fix this crap
48
- puts cmd, ' (Note: execute manually if more than one version is installed)'
49
- `#{cmd}`
50
- end
51
- end
data/TODO CHANGED
@@ -1,16 +1,7 @@
1
1
  - tests :-)
2
- - displaying help shouldn't need grb to execute in a git working dir...
3
- - better exit status behavior
4
- - Add verification if remote delete didn't work
5
- - New functionality:
6
- - Remotize an existing local branch (aliases: publish share make_remote makeremote)
7
- git push origin branch_name:refs/heads/branch_name
8
- git fetch origin
9
- (find a local branch other than the branch to remotize)
10
- git checkout master
11
- git branch --track -f branch_name origin/branch_name
12
- (yay! we don't have to delete the local one...)
13
- - add support for different remote name (--remote-name)
2
+ - offer help when branch -d fails
3
+ - connect (new remote repo)
4
+ - Make remotize work when not specifying the local branch (and use this one by default)
14
5
  - avoid deleting local branches when tracking with the help of git-config ?
15
6
 
16
7
  - drop assumption that master can be treated differently than other branches (e.g. considered as a safe checkout)
@@ -18,3 +9,8 @@
18
9
  - is it even necessary to be on a branch per se? I think not...
19
10
  - survive checkouts with wrong case
20
11
  e.g.: branch "Bob" checked out branch 'bob'. git branch -l won't correctly flag branch Bob as current.
12
+
13
+ - better exit status behavior
14
+ - Add verification if remote delete didn't work
15
+ - add support for different remote name (--remote-name)
16
+
data/bin/grb CHANGED
@@ -7,12 +7,19 @@ require "#{File.dirname(THIS_FILE)}/../lib/git_remote_branch"
7
7
 
8
8
  include GitRemoteBranch
9
9
 
10
- print_welcome
10
+ begin
11
+ p = read_params(ARGV)
12
+ rescue InvalidBranchError => ex
13
+ puts ex.message
14
+ exit 1
15
+ end
16
+
17
+ $SILENT = p[:silent]
11
18
 
12
- p = read_params(ARGV)
19
+ whisper get_welcome
13
20
 
14
21
  if p[:action] == :help
15
- print_usage
22
+ whisper get_usage
16
23
  exit 0
17
24
  end
18
25
 
@@ -1,13 +1,18 @@
1
- grb_app_root = File.expand_path( File.dirname(__FILE__) + '/..' )
2
-
3
1
  require 'rubygems'
4
2
  require 'colored'
5
3
 
4
+ grb_app_root = File.expand_path( File.dirname(__FILE__) + '/..' )
5
+
6
+ $LOAD_PATH.unshift( grb_app_root + '/vendor' )
7
+ require 'capture_fu'
8
+
6
9
  $LOAD_PATH.unshift( grb_app_root + '/lib' )
7
10
  require 'param_reader'
11
+ require 'version'
8
12
 
9
13
  module GitRemoteBranch
10
- VERSION = '0.2.4'
14
+ class InvalidBranchError < RuntimeError; end
15
+ class NotOnGitRepositoryError < RuntimeError; end
11
16
 
12
17
  COMMANDS = {
13
18
  :create => {
@@ -21,9 +26,21 @@ module GitRemoteBranch
21
26
  ]
22
27
  },
23
28
 
29
+ :publish => {
30
+ :description => 'publish an exiting local branch',
31
+ :aliases => %w{publish remotize},
32
+ :commands => [
33
+ '"git push #{origin} #{branch_name}:refs/heads/#{branch_name}"',
34
+ '"git fetch #{origin}"',
35
+ '"git config branch.#{branch_name}.remote #{origin}"',
36
+ '"git config branch.#{branch_name}.merge refs/heads/#{branch_name}"',
37
+ '"git checkout #{branch_name}"'
38
+ ]
39
+ },
40
+
24
41
  :rename => {
25
42
  :description => 'rename a remote branch and its local tracking branch',
26
- :aliases => %w{ rn mv move },
43
+ :aliases => %w{rename rn mv move},
27
44
  :commands => [
28
45
  '"git push #{origin} #{current_branch}:refs/heads/#{branch_name}"',
29
46
  '"git fetch #{origin}"',
@@ -53,25 +70,39 @@ module GitRemoteBranch
53
70
  '"git branch --track #{branch_name} #{origin}/#{branch_name}"'
54
71
  ]
55
72
  }
56
- }
57
-
58
- def print_welcome
59
- puts "git_remote_branch version #{VERSION}", ''
73
+ } unless defined?(COMMANDS)
74
+
75
+ def self.get_reverse_map(commands)
76
+ h={}
77
+ commands.each_pair do |cmd, params|
78
+ params[:aliases].each do |alias_|
79
+ unless h[alias_]
80
+ h[alias_] = cmd
81
+ else
82
+ raise "Duplicate aliases: #{alias_.inspect} already defined for command #{h[alias_].inspect}"
83
+ end
84
+ end
85
+ end
86
+ h
87
+ end
88
+ ALIAS_REVERSE_MAP = get_reverse_map(COMMANDS) unless defined?(ALIAS_REVERSE_MAP)
89
+
90
+ def get_welcome
91
+ "git_remote_branch version #{VERSION::STRING}\n\n"
60
92
  end
61
93
 
62
- def print_usage
63
- puts <<-HELP
94
+ def get_usage
95
+ return <<-HELP
64
96
  Usage:
65
97
 
66
- grb create branch_name [origin_server]
67
-
68
- grb delete branch_name [origin_server]
69
-
70
- grb rename branch_name [origin_server]
71
-
72
- grb track branch_name [origin_server]
73
-
74
- If origin_server is not specified, the name 'origin' is assumed (git's default)
98
+ #{[:create, :publish, :rename, :delete, :track].map{|action|
99
+ " grb #{action} branch_name [origin_server] \n\n"
100
+ }
101
+ }
102
+
103
+ Notes:
104
+ - If origin_server is not specified, the name 'origin' is assumed (git's default)
105
+ - The rename functionality renames the current branch
75
106
 
76
107
  The explain meta-command: you can also prepend any command with the keyword 'explain'. Instead of executing the command, git_remote_branch will simply output the list of commands you need to run to accomplish that goal.
77
108
  Example:
@@ -92,22 +123,29 @@ module GitRemoteBranch
92
123
  def explain_action(action, branch_name, origin, current_branch)
93
124
  cmds = COMMANDS[action][:commands].map{ |c| eval(c) }.compact
94
125
 
95
- puts "List of operations to do to #{COMMANDS[action][:description]}:", ''
126
+ whisper "List of operations to do to #{COMMANDS[action][:description]}:", ''
96
127
  puts_cmd cmds
97
- puts ''
128
+ whisper ''
98
129
  end
99
130
 
100
131
  def execute_cmds(*cmds)
132
+ silencer = $SILENT ? ' 2>&1' : ''
101
133
  cmds.flatten.each do |c|
102
134
  puts_cmd c
103
- `#{c}`
104
- puts ''
135
+ `#{c}#{silencer}`
136
+ whisper ''
105
137
  end
106
138
  end
107
139
 
108
140
  def puts_cmd(*cmds)
109
141
  cmds.flatten.each do |c|
110
- puts "#{c}".red
142
+ whisper "#{c}".red
143
+ end
144
+ end
145
+
146
+ def whisper(*msgs)
147
+ unless $SILENT
148
+ msgs.flatten ? msgs.flatten.each{|m| puts m} : puts
111
149
  end
112
150
  end
113
151
  end
data/lib/param_reader.rb CHANGED
@@ -1,18 +1,40 @@
1
1
  module GitRemoteBranch
2
+ include ::CaptureFu
3
+
4
+ private
5
+ HELP_PARAMS = {:action => :help}
6
+
7
+ public
2
8
  def read_params(argv)
9
+ #TODO Some validation on the params
10
+
3
11
  p={}
4
- p[:explain] = explain_mode!(argv)
5
- p[:action] = get_action(argv[0]) || :help
6
- p[:branch] = get_branch(argv[1])
7
- p[:origin] = get_origin(argv[2])
8
- p[:current_branch] = get_current_branch
12
+ p[:silent] = silent!(argv)
13
+ p[:explain] = explain_mode!(argv)
14
+
15
+ p[:action] = get_action(argv[0]) or return HELP_PARAMS
9
16
 
10
- #If in explain mode, the user doesn't have to specify a branch to get the explanation
11
- p[:branch] ||= "branch_to_#{p[:action]}" if p[:explain]
17
+ return HELP_PARAMS if p[:action] == :help
12
18
 
13
- #TODO Some validation on the params
19
+ p[:branch] = get_branch(argv[1])
20
+ p[:origin] = get_origin(argv[2])
21
+
22
+ # If in explain mode, the user doesn't have to specify a branch or be on in
23
+ # actual repo to get the explanation.
24
+ # Of course if he is, the explanation will be made better by using contextual info.
25
+ if p[:explain]
26
+ p[:branch] ||= "branch_to_#{p[:action]}"
27
+ p[:current_branch] = begin
28
+ get_current_branch
29
+ rescue NotOnGitRepositoryError, InvalidBranchError
30
+ 'current_branch'
31
+ end
14
32
 
15
- p
33
+ else
34
+ return HELP_PARAMS unless p[:branch]
35
+ p[:current_branch] = get_current_branch
36
+ end
37
+ return p
16
38
  end
17
39
 
18
40
  def explain_mode!(argv)
@@ -23,14 +45,13 @@ module GitRemoteBranch
23
45
  false
24
46
  end
25
47
  end
48
+
49
+ def silent!(argv)
50
+ !!argv.delete('--silent')
51
+ end
26
52
 
27
53
  def get_action(action)
28
- a = action.to_s.downcase
29
- return :create if COMMANDS[:create][:aliases].include?(a)
30
- return :delete if COMMANDS[:delete][:aliases].include?(a)
31
- return :track if COMMANDS[:track][:aliases].include?(a)
32
- return :rename if COMMANDS[:rename][:aliases].include?(a)
33
- return nil
54
+ ALIAS_REVERSE_MAP[action.to_s.downcase]
34
55
  end
35
56
 
36
57
  def get_branch(branch)
@@ -41,12 +62,23 @@ module GitRemoteBranch
41
62
  return origin || 'origin'
42
63
  end
43
64
 
44
- def get_current_branch
45
- #This is sensitive to checkouts of branches specified with wrong case
46
- x = `git branch -l`
47
- x.each_line do |l|
48
- return l.sub("*","").strip if l =~ /\A\*/ and not l =~ /\(no branch\)/
65
+ private
66
+ BRANCH_LISTING_COMMAND = 'git branch -l'.freeze
67
+
68
+ public
69
+ def get_current_branch
70
+ #This is sensitive to checkouts of branches specified with wrong case
71
+
72
+ listing = capture_process_output("#{BRANCH_LISTING_COMMAND}")[1]
73
+ raise(NotOnGitRepositoryError, listing.chomp) if listing =~ /Not a git repository/i
74
+
75
+ current_branch = listing.scan(/^\*\s+(.+)/).flatten.first
76
+
77
+ if current_branch =~ /\(no branch\)/
78
+ raise InvalidBranchError, ["Couldn't identify the current local branch. The branch listing was:",
79
+ BRANCH_LISTING_COMMAND.red,
80
+ listing].join("\n")
81
+ end
82
+ current_branch.strip
49
83
  end
50
- raise "Couldn't identify the current local branch."
51
- end
52
84
  end
data/lib/version.rb ADDED
@@ -0,0 +1,14 @@
1
+ module GitRemoteBranch
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 2
5
+ TINY = 6
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.').freeze
8
+ end
9
+
10
+ NAME = 'git_remote_branch'.freeze
11
+ COMPLETE_NAME = "#{NAME} #{VERSION::STRING}".freeze
12
+ COMMAND_NAME = 'grb'.freeze
13
+ SHORT_NAME = COMMAND_NAME
14
+ end
data/tasks/gem.rake ADDED
@@ -0,0 +1,73 @@
1
+ require 'yaml'
2
+
3
+ require 'rake/gempackagetask'
4
+
5
+ task :clean => :clobber_package
6
+
7
+ spec = Gem::Specification.new do |s|
8
+ s.name = GitRemoteBranch::NAME
9
+ s.version = GitRemoteBranch::VERSION::STRING
10
+ s.summary = "git_remote_branch eases the interaction with remote branches"
11
+ s.description = "git_remote_branch is a learning tool to ease the interaction with " +
12
+ "remote branches in simple situations."
13
+
14
+ s.authors = ['Mathieu Martin', 'Carl Mercier']
15
+ s.email = "webmat@gmail.com"
16
+ s.homepage = "http://github.com/webmat/git_remote_branch"
17
+ s.rubyforge_project = 'grb'
18
+
19
+ s.has_rdoc = false
20
+
21
+ s.test_files = Dir['test/**/*']
22
+ s.files = Dir['**/*'].reject{|f| f =~ /\Apkg|\Acoverage|\.gemspec\Z/}
23
+
24
+ s.executable = 'grb'
25
+ s.bindir = "bin"
26
+ s.require_path = "lib"
27
+
28
+ s.add_dependency( 'colored', '>= 1.1' )
29
+ end
30
+
31
+ #Creates clobber_package, gem, package and repackage tasks
32
+ #Note on clobber_package: fortunately, this will clobber the CODE package
33
+ Rake::GemPackageTask.new(spec) do |p|
34
+ p.gem_spec = spec
35
+ end
36
+
37
+ TAG_COMMAND = "git tag -m 'Tagging version #{GitRemoteBranch::VERSION::STRING}' -a v#{GitRemoteBranch::VERSION::STRING}"
38
+ task :tag_warn do
39
+ puts "*" * 40,
40
+ "Don't forget to tag the release:",
41
+ '',
42
+ " " + TAG_COMMAND,
43
+ '',
44
+ "or run rake tag",
45
+ "*" * 40
46
+ end
47
+ task :tag do
48
+ sh TAG_COMMAND
49
+ end
50
+ task :gem => :tag_warn
51
+
52
+ namespace :gem do
53
+ desc "Update the gemspec for GitHub's gem server"
54
+ task :github do
55
+ File.open("#{GitRemoteBranch::NAME}.gemspec", 'w'){|f| f.puts YAML::dump(spec) }
56
+ puts "gemspec generated here: #{GitRemoteBranch::NAME}.gemspec"
57
+ end
58
+
59
+ desc 'Upload gem to rubyforge.org'
60
+ task :rubyforge => :gem do
61
+ sh 'rubyforge login'
62
+ sh "rubyforge add_release grb grb 'release #{GitRemoteBranch::VERSION::STRING}' pkg/#{spec.full_name}.gem"
63
+ sh "rubyforge add_file grb grb #{GitRemoteBranch::VERSION::STRING} pkg/#{spec.full_name}.gem"
64
+ end
65
+ end
66
+
67
+ task :install => [:clean, :gem] do
68
+ sh "#{SUDO} gem install pkg/#{spec.full_name}.gem"
69
+ end
70
+
71
+ task :uninstall do
72
+ sh "#{SUDO} gem uninstall -v #{GitRemoteBranch::VERSION::STRING} -x #{GitRemoteBranch::NAME}"
73
+ end
data/tasks/test.rake ADDED
@@ -0,0 +1,21 @@
1
+ require 'rake/testtask'
2
+
3
+ desc "Run all tests"
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.pattern = 'test/**/*_test.rb'
6
+ t.verbose = true
7
+ end
8
+
9
+ namespace :test do
10
+ desc "Run functional tests"
11
+ Rake::TestTask.new(:functional) do |t|
12
+ t.pattern = 'test/functional/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc "Run unit tests"
17
+ Rake::TestTask.new(:unit) do |t|
18
+ t.pattern = 'test/unit/**/*_test.rb'
19
+ t.verbose = true
20
+ end
21
+ end