webmat-git_remote_branch 0.2.1 → 0.2.2

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/README CHANGED
@@ -1,48 +1,56 @@
1
- Why git_remote_branch?
1
+ ==== Why git_remote_branch? ====
2
2
 
3
3
  The basic idea for git_remote_branch is to trivialize the interaction with
4
- remote branches in simple situations.
5
- Things we mean by 'simple situations':
6
- - The local and remote name are the same
4
+ remote branches in simple situations.
5
+
6
+ For now git_remote_branch assumes that the local and remote branches have the
7
+ same name. Multiple origins are supported.
7
8
 
8
9
  Another goal of git_remote_branch is to help teach the real underlying git
9
10
  commands. Each operation done on your behalf is displayed at the console.
10
11
 
11
12
 
12
13
 
13
- Installation
14
+ ==== Installation ====
15
+
16
+ sudo gem install webmat-git_remote_branch --source=http://gems.github.com
14
17
 
15
- (Not yet published as a gem)
16
- (gem install webmat-git_remote_branch --source=http://gems.github.com)
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.
17
22
 
18
23
 
19
24
 
20
- Usage
25
+ ==== Usage ====
21
26
 
22
27
  Notes:
23
28
  - parts between brackets are optional
24
29
  - When 'origin_server' is not specified, the name 'origin' is assumed.
25
30
 
26
- $ grb [-h] #=> Displays help
27
-
28
31
  Available commands (with aliases):
29
32
 
30
- create (alias: new)
31
- Create a new local branch as well as a corresponding remote branch.
33
+ == Help ==
34
+
35
+ $ grb [-h] #=> Displays help
36
+
37
+ == create (alias: new) ==
38
+ Create a new local branch as well as a corresponding remote branch from the
39
+ branch you are currently on.
32
40
  Automatically track the new remote branch (useful for pulling and merging).
33
41
  Switch to the new branch.
34
42
 
35
43
  $ grb create branch_name [origin_server]
36
44
 
37
45
 
38
- delete (aliases: destroy, kill)
46
+ == delete (aliases: destroy, kill) ==
39
47
  Delete the remote branch then delete the local branch.
40
48
  The local branch is not deleted if there are pending changes.
41
49
 
42
50
  $ grb delete branch_name [origin_server]
43
51
 
44
52
 
45
- track (aliases: follow grab)
53
+ == track (aliases: follow grab) ==
46
54
  Track an existing remote branch locally.
47
55
 
48
56
 
@@ -50,7 +58,7 @@ $ grb track branch_name [origin_server]
50
58
 
51
59
 
52
60
 
53
- History
61
+ ==== History ====
54
62
 
55
63
  This script was originally created by Carl Mercier and made public on his blog
56
64
  here:
@@ -58,12 +66,12 @@ here:
58
66
  No nonsense GIT, part 1: git-remote-branch
59
67
  http://blog.carlmercier.com/2008/01/25/no-nonsense-git-part-1-git-remote-branch/
60
68
 
61
- For now I just want to document the changes I make to it. I'm not sure if I'll
62
- keep this alive, it depends on if he wants to keep evolving it himself in a
63
- public repo.
69
+
70
+ I'm using it as a starting point to make it even easier to interact with remote
71
+ repositories.
64
72
 
65
73
 
74
+ === Contributors ===
66
75
 
67
- Contributors
68
76
  - Mathieu Martin webmat@gmail.com
69
77
  - Carl Mercier (Carl: want your email here?)
data/Rakefile CHANGED
@@ -43,6 +43,9 @@ namespace :gem do
43
43
 
44
44
  desc "Uninstall the .gem"
45
45
  task :uninstall do
46
- `#{SUDO} gem uninstall #{NAME}`
46
+ cmd = "#{SUDO} gem uninstall #{NAME}"
47
+ #TODO fix this crap
48
+ puts cmd, ' (Note: execute manually if more than one version is installed)'
49
+ `#{cmd}`
47
50
  end
48
51
  end
data/TODO CHANGED
@@ -1,8 +1,4 @@
1
- - Put in evidence the tutorial part of each grb action
2
- - colorize the git commands
3
- - Add 'explain' / 'show' command
4
1
  - tests :-)
5
- - re-architect the code a bit?
6
2
  - better exit status behavior
7
3
  - Add verification if remote delete didn't work
8
4
  - New functionality:
@@ -13,31 +9,11 @@
13
9
  git checkout master
14
10
  git branch --track -f branch_name origin/branch_name
15
11
  (yay! we don't have to delete the local one...)
16
- - make into a gem?
17
- - that installs a grb command in the path?
18
-
19
- Fix that problem:
20
- mathieu@ml code (master)$ grbd follow aaron
21
- git_remote_branch version 0.2.1
22
- ----------------------------------------------------------------------
23
-
24
- Executing: git branch --track aaron origin/aaron
25
- fatal: Not a valid object name: 'origin/aaron'.
26
-
27
-
28
- mathieu@ml code (master)$ git fetch
29
- remote: Counting objects: 87, done.
30
- remote: Compressing objects: 100% (45/45), done.
31
- remote: Total 51 (delta 13), reused 40 (delta 5)
32
- Unpacking objects: 100% (51/51), done.
33
- From git@github.com:webmat/priv_repo
34
- * [new branch] aaron -> origin/aaron
35
-
36
- mathieu@ml code (master)$ grbd follow aaron
37
- git_remote_branch version 0.2.1
38
- ----------------------------------------------------------------------
39
-
40
- Executing: git branch --track aaron origin/aaron
41
-
42
-
43
-
12
+ - add support for different remote name (--remote-name)
13
+ - avoid deleting local branches when tracking with the help of git-config ?
14
+
15
+ - drop assumption that master can be treated differently than other branches (e.g. considered as a safe checkout)
16
+ - reliance on current_branch
17
+ - is it even necessary to be on a branch per se? I think not...
18
+ - survive checkouts with wrong case
19
+ e.g.: branch "Bob" checked out branch 'bob'. git branch -l won't correctly flag branch Bob as current.
data/bin/grb CHANGED
@@ -1,33 +1,22 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # Check out the README (or try grb -h) before you screw up your repos ;-)
3
+ # Check out the README (or try 'grb help') before you screw up your repos ;-)
4
+
5
+ require "#{File.dirname(__FILE__)}/../lib/git_remote_branch"
4
6
 
5
- require File.expand_path( File.join( [File.dirname(__FILE__)] + %w{ .. lib git_remote_branch } ) )
6
7
  include GitRemoteBranch
7
8
 
8
9
  print_welcome
9
10
 
10
- p = read_params
11
+ p = read_params(ARGV)
11
12
 
12
13
  if p[:action] == :help
13
14
  print_usage
14
15
  exit 0
15
16
  end
16
17
 
17
- if p[:current_branch].nil?
18
- puts 'You must specify a branch'
19
- print_usage
20
- exit 1
21
- end
22
-
23
- case p[:action]
24
- when :create
25
- create_branch(p[:branch], p[:origin], p[:current_branch])
26
- when :delete
27
- delete_branch(p[:branch], p[:origin], p[:current_branch])
28
- when :track
29
- track_branch(p[:branch], p[:origin])
30
- else
31
- print_usage
32
- exit 1
18
+ if p[:explain]
19
+ explain_action(p[:action], p[:branch], p[:origin], p[:current_branch])
20
+ else
21
+ execute_action(p[:action], p[:branch], p[:origin], p[:current_branch])
33
22
  end
@@ -1,108 +1,93 @@
1
+ grb_app_root = File.expand_path( File.dirname(__FILE__) + '/..' )
2
+
3
+ require 'rubygems'
4
+ require 'colored'
5
+
6
+ $LOAD_PATH.unshift( grb_app_root + '/lib' )
7
+ require 'param_reader'
8
+
1
9
  module GitRemoteBranch
2
- VERSION = '0.2.1'
10
+ VERSION = '0.2.2'
11
+
12
+ COMMANDS = {
13
+ :create => {
14
+ :description => 'create a new remote branch and track it locally',
15
+ :aliases => %w{create new},
16
+ :commands => [
17
+ '"git push #{origin} #{current_branch}:refs/heads/#{branch_name}"',
18
+ '"git fetch #{origin}"',
19
+ '"git branch --track #{branch_name} #{origin}/#{branch_name}"',
20
+ '"git checkout #{branch_name}"'
21
+ ]
22
+ },
3
23
 
4
- CMD_ALIASES = {
5
- :create => %w{create new},
6
- :delete => %w{delete destroy kill remove},
7
- :track => %w{track follow grab fetch},
24
+ :delete => {
25
+ :description => 'delete a local and a remote branch',
26
+ :aliases => %w{delete destroy kill remove},
27
+ :commands => [
28
+ '"git push #{origin} :refs/heads/#{branch_name}"',
29
+ '"git checkout master" if current_branch == branch_name',
30
+ '"git branch -d #{branch_name}"'
31
+ ]
32
+ },
33
+
34
+ :track => {
35
+ :description => 'track an existing remote branch',
36
+ :aliases => %w{track follow grab fetch},
37
+ :commands => [
38
+ '"git fetch #{origin}"',
39
+ '"git checkout master" if current_branch == branch_name',
40
+ '"git branch --track #{branch_name} #{origin}/#{branch_name}"'
41
+ ]
42
+ }
8
43
  }
9
44
 
10
45
  def print_welcome
11
- puts "git_remote_branch version #{VERSION}", '-' * 70, ''
46
+ puts "git_remote_branch version #{VERSION}", ''
12
47
  end
13
48
 
14
49
  def print_usage
15
50
  puts <<-HELP
16
51
  Usage:
17
52
 
18
- git_remote_branch create branch_name [origin_server]
19
- -or-
20
- git_remote_branch delete branch_name [origin_server]
21
- -or-
22
- git_remote_branch track branch_name [origin_server]
23
-
24
- If origin_server is not specified, the name 'origin' is assumed
53
+ grb create branch_name [origin_server]
54
+
55
+ grb delete branch_name [origin_server]
56
+
57
+ grb track branch_name [origin_server]
58
+
59
+ If origin_server is not specified, the name 'origin' is assumed (git's default)
25
60
 
26
61
  All commands also have aliases:
27
- #{ CMD_ALIASES.keys.map{|k| k.to_s}.sort.map {|k|
28
- "#{k}: #{CMD_ALIASES[k.to_sym].join(', ')}" }.join("\n ") }
62
+ #{ COMMANDS.keys.map{|k| k.to_s}.sort.map {|cmd|
63
+ "#{cmd}: #{COMMANDS[cmd.to_sym][:aliases].join(', ')}" }.join("\n ") }
29
64
  HELP
30
65
  end
31
66
 
32
- def execute_cmd(cmd)
33
- res, out, err = steal_pipes do
34
- `#{cmd}`
35
- end
36
- return res, out, err
67
+ def execute_action(action, branch_name, origin, current_branch)
68
+ cmds = COMMANDS[action][:commands].map{ |c| eval(c) }.compact
69
+ execute_cmds(cmds)
37
70
  end
38
71
 
39
- def execute_cmds(*cmds)
40
- cmds.flatten.each do |c|
41
- puts "Executing: #{c}"
42
- `#{c}`
43
- puts ""
44
- end
45
- end
72
+ def explain_action(action, branch_name, origin, current_branch)
73
+ cmds = COMMANDS[action][:commands].map{ |c| eval(c) }.compact
46
74
 
47
- def create_branch(branch_name, origin, current_branch)
48
- cmd = []
49
- cmd << "git push origin #{current_branch}:refs/heads/#{branch_name}"
50
- cmd << "git fetch #{origin}"
51
- cmd << "git branch --track #{branch_name} #{origin}/#{branch_name}"
52
- cmd << "git checkout #{branch_name}"
53
- execute_cmds(cmd)
75
+ puts "List of operations to do to #{COMMANDS[action][:description]}:", ''
76
+ puts_cmd cmds
77
+ puts ''
54
78
  end
55
79
 
56
- def delete_branch(branch_name, origin, current_branch)
57
- cmd = []
58
- cmd << "git push #{origin} :refs/heads/#{branch_name}"
59
- cmd << "git checkout master" if current_branch == branch_name
60
- cmd << "git branch -d #{branch_name}"
61
- execute_cmds(cmd)
62
- end
63
-
64
- def track_branch(branch_name, origin)
65
- cmd = ["git branch --track #{branch_name} #{origin}/#{branch_name}"]
66
- execute_cmds(cmd)
67
- end
68
-
69
- def get_current_branch
70
- x = `git branch -l`
71
- x.each_line do |l|
72
- return l.sub("*","").strip if l[0] == 42
80
+ def execute_cmds(*cmds)
81
+ cmds.flatten.each do |c|
82
+ puts_cmd c
83
+ `#{c}`
84
+ puts ''
73
85
  end
74
-
75
- puts "Couldn't identify the current local branch."
76
- return nil
77
86
  end
78
87
 
79
- def get_action
80
- a = ARGV[0].downcase
81
- return :create if CMD_ALIASES[:create].include?(a)
82
- return :delete if CMD_ALIASES[:delete].include?(a)
83
- return :track if CMD_ALIASES[:track].include?(a)
84
- return nil
85
- end
86
-
87
- def get_branch
88
- ARGV[1].downcase
89
- end
90
-
91
- def get_origin
92
- return ARGV[2] if ARGV.size > 2
93
- return "origin"
94
- end
95
-
96
- def read_params
97
- p={}
98
- begin
99
- p[:action] = get_action
100
- p[:branch] = get_branch
101
- p[:origin] = get_origin
102
- p[:current_branch] = get_current_branch
103
- p
104
- rescue
105
- {:action=>:help}
88
+ def puts_cmd(*cmds)
89
+ cmds.flatten.each do |c|
90
+ puts "#{c}".red
106
91
  end
107
92
  end
108
93
  end
@@ -0,0 +1,51 @@
1
+ module GitRemoteBranch
2
+ def read_params(argv)
3
+ 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
9
+
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]
12
+
13
+ #TODO Some validation on the params
14
+
15
+ p
16
+ end
17
+
18
+ def explain_mode!(argv)
19
+ if argv[0].to_s.downcase == 'explain'
20
+ argv.shift
21
+ true
22
+ else
23
+ false
24
+ end
25
+ end
26
+
27
+ 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 nil
33
+ end
34
+
35
+ def get_branch(branch)
36
+ branch
37
+ end
38
+
39
+ def get_origin(origin)
40
+ return origin || 'origin'
41
+ end
42
+
43
+ def get_current_branch
44
+ #This is sensitive to checkouts of branches specified with wrong case
45
+ x = `git branch -l`
46
+ x.each_line do |l|
47
+ return l.sub("*","").strip if l =~ /\A\*/ and not l =~ /\(no branch\)/
48
+ end
49
+ raise "Couldn't identify the current local branch."
50
+ end
51
+ end
data/test/git_helper.rb CHANGED
@@ -4,7 +4,7 @@ require 'tmpdir'
4
4
  # Instantiating a GitHelper object creates a temp directory containing 3 repos.
5
5
  # 1 that's considered the remote repo and 2 peer local repos (local1 and local2).
6
6
  # All 3 are synchronized with the same data (they contain a few dummy files).
7
- # Once instantiated you can access the 3 full repo locations with attribute readers
7
+ # Once instantiated you can access the 3 full repo locations through attribute readers
8
8
  # remote, local1 and local2.
9
9
  class GitHelper
10
10
  include FileUtils
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webmat-git_remote_branch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mathieu Martin
@@ -12,8 +12,16 @@ cert_chain: []
12
12
 
13
13
  date: 2008-06-13 00:00:00 -07:00
14
14
  default_executable:
15
- dependencies: []
16
-
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: colored
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "1.1"
24
+ version:
17
25
  description: git_remote_branch is a learning tool to ease the interaction with remote branches in simple situations.
18
26
  email: webmat@gmail.com
19
27
  executables:
@@ -28,8 +36,7 @@ files:
28
36
  - TODO
29
37
  - bin/grb
30
38
  - lib/git_remote_branch.rb
31
- - vendor/try_require/try_require.rb
32
- - vendor/capture_fu/capture_fu.rb
39
+ - lib/param_reader.rb
33
40
  - test/git_helper.rb
34
41
  - test/test_helper.rb
35
42
  - test/unit/git_helper_test.rb
@@ -1,60 +0,0 @@
1
- # This is a very early version of capture_fu.
2
- # See github.com/webmat/capture_fu for more info.
3
- module CaptureFu
4
- VERSION = '0.0.1'
5
-
6
- def capture_output(&block)
7
- real_out, real_err = $stdout, $stderr
8
- result = fake_out = fake_err = nil
9
- begin
10
- fake_out, fake_err = Helpers::PipeStealer.new, Helpers::PipeStealer.new
11
- $stdout, $stderr = fake_out, fake_err
12
- result = yield
13
- ensure
14
- $stdout, $stderr = real_out, real_err
15
- end
16
- return result, fake_out.captured, fake_err.captured
17
- end
18
-
19
- # This first implementation is only intended for batch executions.
20
- # You can't pipe stuff programmatically to the child process.
21
- def capture_process_output(command)
22
-
23
- #capture stderr in the same stream
24
- command << ' 2>&1' unless Helpers.stderr_already_redirected(command)
25
-
26
- out = `#{command}`
27
- return $?.exitstatus, out
28
- end
29
-
30
-
31
- private
32
-
33
- module Helpers
34
-
35
- def self.stderr_already_redirected(command)
36
- #Already redirected to stdout (valid for Windows)
37
- return true if command =~ /2>&1\s*\Z/
38
-
39
- #Redirected to /dev/null (this is clearly POSIX-dependent)
40
- return true if command =~ /2>\/dev\/null\s*\Z/
41
-
42
- return false
43
- end
44
-
45
- class PipeStealer < File
46
- attr_reader :captured
47
- def initialize
48
- @captured = ''
49
- end
50
- def write(s)
51
- @captured << s
52
- end
53
- def captured
54
- return nil if @captured.empty?
55
- @captured.dup
56
- end
57
- end
58
-
59
- end #Helper module
60
- end
@@ -1,18 +0,0 @@
1
- # This is a very early version of try_require.
2
- # See github.com/webmat/try_require for more info.
3
- def try_require(what, &block)
4
- loaded, require_result = false, nil
5
-
6
- begin
7
- require_result = require what
8
- loaded = true
9
-
10
- rescue LoadError => ex
11
- puts "Unable to require '#{what}'", "#{ex.class}: #{ex.message}"
12
- end
13
-
14
- yield if loaded and block_given?
15
-
16
- require_result
17
- end
18
-