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 +27 -19
- data/Rakefile +4 -1
- data/TODO +8 -32
- data/bin/grb +8 -19
- data/lib/git_remote_branch.rb +66 -81
- data/lib/param_reader.rb +51 -0
- data/test/git_helper.rb +1 -1
- metadata +12 -5
- data/vendor/capture_fu/capture_fu.rb +0 -60
- data/vendor/try_require/try_require.rb +0 -18
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
|
-
|
6
|
-
|
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
|
-
|
16
|
-
|
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
|
-
|
31
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
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
|
-
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
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[:
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
data/lib/git_remote_branch.rb
CHANGED
@@ -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.
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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}", '
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
#{
|
28
|
-
"#{
|
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
|
33
|
-
|
34
|
-
|
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
|
40
|
-
cmds.
|
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
|
-
|
48
|
-
|
49
|
-
|
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
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|
80
|
-
|
81
|
-
|
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
|
data/lib/param_reader.rb
ADDED
@@ -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
|
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.
|
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
|
-
-
|
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
|
-
|