webmat-git_remote_branch 0.2.1

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 ADDED
@@ -0,0 +1,69 @@
1
+ Why git_remote_branch?
2
+
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
7
+
8
+ Another goal of git_remote_branch is to help teach the real underlying git
9
+ commands. Each operation done on your behalf is displayed at the console.
10
+
11
+
12
+
13
+ Installation
14
+
15
+ (Not yet published as a gem)
16
+ (gem install webmat-git_remote_branch --source=http://gems.github.com)
17
+
18
+
19
+
20
+ Usage
21
+
22
+ Notes:
23
+ - parts between brackets are optional
24
+ - When 'origin_server' is not specified, the name 'origin' is assumed.
25
+
26
+ $ grb [-h] #=> Displays help
27
+
28
+ Available commands (with aliases):
29
+
30
+ create (alias: new)
31
+ Create a new local branch as well as a corresponding remote branch.
32
+ Automatically track the new remote branch (useful for pulling and merging).
33
+ Switch to the new branch.
34
+
35
+ $ grb create branch_name [origin_server]
36
+
37
+
38
+ delete (aliases: destroy, kill)
39
+ Delete the remote branch then delete the local branch.
40
+ The local branch is not deleted if there are pending changes.
41
+
42
+ $ grb delete branch_name [origin_server]
43
+
44
+
45
+ track (aliases: follow grab)
46
+ Track an existing remote branch locally.
47
+
48
+
49
+ $ grb track branch_name [origin_server]
50
+
51
+
52
+
53
+ History
54
+
55
+ This script was originally created by Carl Mercier and made public on his blog
56
+ here:
57
+
58
+ No nonsense GIT, part 1: git-remote-branch
59
+ http://blog.carlmercier.com/2008/01/25/no-nonsense-git-part-1-git-remote-branch/
60
+
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.
64
+
65
+
66
+
67
+ Contributors
68
+ - Mathieu Martin webmat@gmail.com
69
+ - Carl Mercier (Carl: want your email here?)
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ require 'rubygems'
2
+
3
+ require 'rake'
4
+ require 'rake/testtask'
5
+ require 'rake/gempackagetask'
6
+
7
+ 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
+ windows = (RUBY_PLATFORM =~ /win32|cygwin/) rescue nil
15
+ install_home = ENV['GEM_HOME'] ? "-i #{ENV['GEM_HOME']}" : ""
16
+ SUDO = windows ? "" : "sudo"
17
+
18
+
19
+ Rake::TestTask.new(:test) do |t|
20
+ t.pattern = 'test/**/*_test.rb'
21
+ t.verbose = true
22
+ end
23
+
24
+ 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
+ `#{SUDO} gem uninstall #{NAME}`
47
+ end
48
+ end
data/TODO ADDED
@@ -0,0 +1,43 @@
1
+ - Put in evidence the tutorial part of each grb action
2
+ - colorize the git commands
3
+ - Add 'explain' / 'show' command
4
+ - tests :-)
5
+ - re-architect the code a bit?
6
+ - better exit status behavior
7
+ - Add verification if remote delete didn't work
8
+ - New functionality:
9
+ - Remotize an existing local branch (aliases: publish share make_remote makeremote)
10
+ git push origin branch_name:refs/heads/branch_name
11
+ git fetch origin
12
+ (find a local branch other than the branch to remotize)
13
+ git checkout master
14
+ git branch --track -f branch_name origin/branch_name
15
+ (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
+
data/bin/grb ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Check out the README (or try grb -h) before you screw up your repos ;-)
4
+
5
+ require File.expand_path( File.join( [File.dirname(__FILE__)] + %w{ .. lib git_remote_branch } ) )
6
+ include GitRemoteBranch
7
+
8
+ print_welcome
9
+
10
+ p = read_params
11
+
12
+ if p[:action] == :help
13
+ print_usage
14
+ exit 0
15
+ end
16
+
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
33
+ end
@@ -0,0 +1,108 @@
1
+ module GitRemoteBranch
2
+ VERSION = '0.2.1'
3
+
4
+ CMD_ALIASES = {
5
+ :create => %w{create new},
6
+ :delete => %w{delete destroy kill remove},
7
+ :track => %w{track follow grab fetch},
8
+ }
9
+
10
+ def print_welcome
11
+ puts "git_remote_branch version #{VERSION}", '-' * 70, ''
12
+ end
13
+
14
+ def print_usage
15
+ puts <<-HELP
16
+ Usage:
17
+
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
25
+
26
+ 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 ") }
29
+ HELP
30
+ end
31
+
32
+ def execute_cmd(cmd)
33
+ res, out, err = steal_pipes do
34
+ `#{cmd}`
35
+ end
36
+ return res, out, err
37
+ end
38
+
39
+ def execute_cmds(*cmds)
40
+ cmds.flatten.each do |c|
41
+ puts "Executing: #{c}"
42
+ `#{c}`
43
+ puts ""
44
+ end
45
+ end
46
+
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)
54
+ end
55
+
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
73
+ end
74
+
75
+ puts "Couldn't identify the current local branch."
76
+ return nil
77
+ end
78
+
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}
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,57 @@
1
+ require 'fileutils'
2
+ require 'tmpdir'
3
+
4
+ # Instantiating a GitHelper object creates a temp directory containing 3 repos.
5
+ # 1 that's considered the remote repo and 2 peer local repos (local1 and local2).
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
8
+ # remote, local1 and local2.
9
+ class GitHelper
10
+ include FileUtils
11
+
12
+ @@WORK_DIR = 'repo_test'
13
+
14
+ attr_reader :remote, :local1, :local2
15
+
16
+ def initialize
17
+ @wd = get_temp_dir
18
+
19
+ @remote = init_repo(@wd, 'remote')
20
+ @local1 = clone_repo(@remote, @wd, 'local1')
21
+ @local2 = clone_repo(@remote, @wd, 'local2')
22
+ end
23
+
24
+ def cleanup
25
+ rm_rf @wd
26
+ end
27
+
28
+ protected
29
+ def get_temp_dir
30
+ #Note: it's NOT a good idea to do this stuff un a subdirectory of the
31
+ #git_remote_branch repo. Trust me :-)
32
+ wd = File.expand_path( File.join( Dir::tmpdir, @@WORK_DIR) )
33
+ Dir.mkdir wd unless File.exists? wd
34
+
35
+ #Create new subdir with a random name
36
+ new_dir=''
37
+ begin
38
+ new_dir = File.join( wd, "#{rand(10000)}" )
39
+ Dir.mkdir new_dir
40
+ rescue
41
+ retry
42
+ end
43
+
44
+ new_dir
45
+ end
46
+
47
+ def init_repo(path, name)
48
+ repo_dir = File.join(path, name)
49
+ `mkdir #{repo_dir}; cd $_; git init; touch file.txt; git add .; git commit -a -m "dummy file"`
50
+ repo_dir
51
+ end
52
+
53
+ def clone_repo(origin_path, clone_path, name)
54
+ `cd #{clone_path}; git clone #{File.join(origin_path, '.git')} #{name}`
55
+ return File.join(clone_path, name)
56
+ end
57
+ end
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ test_dir = File.dirname(__FILE__)
5
+
6
+ begin
7
+ require 'try_require'
8
+ rescue LoadError
9
+ require File.join( [test_dir] + %w{ .. vendor try_require try_require } )
10
+ end
11
+
12
+ try_require 'redgreen'
13
+ try_require 'ruby-debug'
14
+
15
+ require File.join(test_dir, 'git_helper')
16
+ require File.join( [test_dir] + %w{ .. lib git_remote_branch} )
17
+
18
+ class Test::Unit::TestCase
19
+ include GitRemoteBranch
20
+
21
+ # Passes assertion if condition is false
22
+ def assert_false(condition, message = nil)
23
+ message = "assert_false failed" unless message
24
+ assert condition == false, message
25
+ end
26
+
27
+ end
@@ -0,0 +1,30 @@
1
+ require File.join( File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class GitHelperTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ super
7
+ @g = GitHelper.new
8
+ @directories = [@g.remote, @g.local1, @g.local2]
9
+ end
10
+
11
+ def teardown
12
+ @g.cleanup
13
+ end
14
+
15
+ def test_init
16
+ @directories.each do |d|
17
+ assert File.exists?(@g.remote), 'Directory for repo must be created'
18
+ assert File.exists?( File.join(@g.remote, '.git') ), 'Repo must be created'
19
+ end
20
+ end
21
+
22
+ def test_cleanup
23
+ @g.cleanup
24
+
25
+ @directories.each do |d|
26
+ assert_false File.exists?(@g.remote), 'Each repo directory must be destroyed after cleanup'
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,60 @@
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
@@ -0,0 +1,18 @@
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
+
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: webmat-git_remote_branch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Mathieu Martin
8
+ - Carl Mercier
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2008-06-13 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: git_remote_branch is a learning tool to ease the interaction with remote branches in simple situations.
18
+ email: webmat@gmail.com
19
+ executables:
20
+ - grb
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - Rakefile
27
+ - README
28
+ - TODO
29
+ - bin/grb
30
+ - lib/git_remote_branch.rb
31
+ - vendor/try_require/try_require.rb
32
+ - vendor/capture_fu/capture_fu.rb
33
+ - test/git_helper.rb
34
+ - test/test_helper.rb
35
+ - test/unit/git_helper_test.rb
36
+ has_rdoc: false
37
+ homepage: http://github.com/webmat/git_remote_branch
38
+ post_install_message:
39
+ rdoc_options: []
40
+
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 1.0.1
59
+ signing_key:
60
+ specification_version: 2
61
+ summary: git_remote_branch eases the interaction with remote branches
62
+ test_files:
63
+ - test/git_helper.rb
64
+ - test/test_helper.rb
65
+ - test/unit/git_helper_test.rb