webmat-git_remote_branch 0.2.1

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