webmat-git_remote_branch 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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
-