gitpusher 0.0.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/.gitignore +3 -0
- data/Gemfile +3 -0
- data/README.md +33 -0
- data/Rakefile +1 -0
- data/bin/gitpusher +23 -0
- data/config/git_to_bitbucket.yml +6 -0
- data/gitpusher.gemspec +23 -0
- data/lib/gitpusher/config.rb +10 -0
- data/lib/gitpusher/context.rb +7 -0
- data/lib/gitpusher/helper.rb +17 -0
- data/lib/gitpusher/repo/base.rb +8 -0
- data/lib/gitpusher/repo/bitbucket.rb +6 -0
- data/lib/gitpusher/repo/factory.rb +14 -0
- data/lib/gitpusher/repo/github.rb +36 -0
- data/lib/gitpusher/repo.rb +8 -0
- data/lib/gitpusher/runner.rb +64 -0
- data/lib/gitpusher/service/base.rb +8 -0
- data/lib/gitpusher/service/bitbucket.rb +63 -0
- data/lib/gitpusher/service/factory.rb +14 -0
- data/lib/gitpusher/service/github.rb +36 -0
- data/lib/gitpusher/version.rb +3 -0
- data/lib/gitpusher.rb +10 -0
- metadata +133 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# gitpusher
|
2
|
+
|
3
|
+
gitpusher is a command line tool for replicating git repositories from one service to another.
|
4
|
+
|
5
|
+
```
|
6
|
+
$ gitpusher -c default.yml
|
7
|
+
```
|
8
|
+
|
9
|
+
default.yaml is like this.
|
10
|
+
|
11
|
+
```
|
12
|
+
:base_dir: /var/repos
|
13
|
+
:src:
|
14
|
+
:type: github
|
15
|
+
:dest:
|
16
|
+
:type: bitbucket
|
17
|
+
```
|
18
|
+
|
19
|
+
With this settings, All of your repositories on GitHub will be replicated to BitBucket.
|
20
|
+
(User name and password of each service are asked when you run the command first.)
|
21
|
+
|
22
|
+
If you would like to replicate GitHub organization's repos instead of your own repos, settings are like this.
|
23
|
+
|
24
|
+
```
|
25
|
+
:base_dir: /var/repos
|
26
|
+
:src:
|
27
|
+
:type: github
|
28
|
+
:organization: github
|
29
|
+
:dest:
|
30
|
+
:type: bitbucket
|
31
|
+
```
|
32
|
+
|
33
|
+
Now this tool support only replicating from GitHub to BitBucket.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/gitpusher
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'gitpusher'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
op = OptionParser.new do |opts|
|
8
|
+
opts.on('-c', '--config FILE') do |file|
|
9
|
+
options[:config] = file
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
op.parse!
|
14
|
+
|
15
|
+
options[:config] ||= 'config/default.yml'
|
16
|
+
|
17
|
+
context = GitPusher::Context.instance
|
18
|
+
context.home = File.join(File.dirname(__FILE__), '..')
|
19
|
+
|
20
|
+
GitPusher::Config.load(options)
|
21
|
+
|
22
|
+
GitPusher::Runner.run
|
23
|
+
|
data/gitpusher.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "gitpusher/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "gitpusher"
|
7
|
+
s.version = GitPusher::VERSION
|
8
|
+
s.authors = ["Gosuke Miyashita"]
|
9
|
+
s.email = ["gosukenator@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/mizzy/gitpusher"
|
11
|
+
s.summary = %q{A command line tool for replicating git repositories from one service to another.}
|
12
|
+
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
|
18
|
+
# dependencies
|
19
|
+
s.add_dependency 'grit'
|
20
|
+
s.add_dependency 'octokit'
|
21
|
+
s.add_dependency 'pit'
|
22
|
+
s.add_dependency 'grit'
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module GitPusher
|
2
|
+
class Helper
|
3
|
+
|
4
|
+
=begin いらないかも
|
5
|
+
def self.git_config_value(name, trim = true)
|
6
|
+
res = `git config issue.#{name}`
|
7
|
+
trim ? res.strip : res
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.git_global_config_value(name)
|
11
|
+
res = `git config --global #{name}`
|
12
|
+
res.strip
|
13
|
+
end
|
14
|
+
=end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module GitPusher
|
2
|
+
module Repo
|
3
|
+
class Factory
|
4
|
+
def self.create(config)
|
5
|
+
case config[:type]
|
6
|
+
when /github/i then GitPusher::Repo::GitHub.new(config)
|
7
|
+
when /bitbucket/i then GitPusher::Repo::BitBucket.new(config)
|
8
|
+
else
|
9
|
+
raise "unknown issue tracker type : #{its_type}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'octokit'
|
2
|
+
require 'pit'
|
3
|
+
|
4
|
+
module GitPusher
|
5
|
+
module Repo
|
6
|
+
class GitHub < Base
|
7
|
+
attr :user, :password, :organization
|
8
|
+
|
9
|
+
def initialize(config)
|
10
|
+
super(config)
|
11
|
+
@user = Pit.get(
|
12
|
+
'github', :require => { 'user' => 'Your user name of GitHub' }
|
13
|
+
)['user']
|
14
|
+
@password = Pit.get(
|
15
|
+
'github', :require => { 'password' => 'Your user password of GitHub' }
|
16
|
+
)['password']
|
17
|
+
@organization = config[:organization]
|
18
|
+
end
|
19
|
+
|
20
|
+
def repos
|
21
|
+
repos = []
|
22
|
+
octokit.repos(self.organization||self.user).each do |repo|
|
23
|
+
p repo
|
24
|
+
break
|
25
|
+
end
|
26
|
+
repos
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def octokit
|
31
|
+
Octokit::Client.new(:login => self.user, :password => self.password)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'grit'
|
2
|
+
|
3
|
+
module GitPusher
|
4
|
+
class Runner
|
5
|
+
def self.run
|
6
|
+
context = GitPusher::Context.instance
|
7
|
+
|
8
|
+
src = GitPusher::Service::Factory.create(context.config[:src])
|
9
|
+
dest = GitPusher::Service::Factory.create(context.config[:dest])
|
10
|
+
|
11
|
+
base_dir = context.config[:base_dir]
|
12
|
+
src.repos.each do |src_repo|
|
13
|
+
puts "Cheking #{src_repo.url} ..."
|
14
|
+
repo_name = File.basename(src_repo.url).gsub(/.git$/, '')
|
15
|
+
repo_path = File.join(base_dir, repo_name)
|
16
|
+
unless File.exist?(repo_path)
|
17
|
+
Dir.chdir(base_dir) do
|
18
|
+
p src_repo.url
|
19
|
+
`git clone #{src_repo.url}`
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
local_repo = Grit::Repo.new(repo_path)
|
24
|
+
|
25
|
+
# local repo の git remote で mirror があるかどうかチェック
|
26
|
+
has_remote_mirror = false
|
27
|
+
local_repo.remote_list.each do |remote|
|
28
|
+
has_remote_mirror = true if remote === 'mirror'
|
29
|
+
end
|
30
|
+
|
31
|
+
unless has_remote_mirror
|
32
|
+
mirror_repo = dest.repo(repo_name) || dest.create_repo(repo_name)
|
33
|
+
local_repo.git.remote({}, 'add', 'mirror', mirror_repo.url)
|
34
|
+
end
|
35
|
+
|
36
|
+
local_repo.remotes.each do |remote|
|
37
|
+
next if remote.name == 'origin/HEAD'
|
38
|
+
next if remote.name =~ %r!mirror/.+!
|
39
|
+
branch = remote.name.gsub(%r!^origin/!, '')
|
40
|
+
|
41
|
+
matched = false
|
42
|
+
local_repo.branches.each do |x|
|
43
|
+
matched = true if x.name === branch
|
44
|
+
end
|
45
|
+
|
46
|
+
unless matched
|
47
|
+
local_repo.git.branch({}, branch, remote.name)
|
48
|
+
end
|
49
|
+
|
50
|
+
# pull する
|
51
|
+
puts "Pulling #{branch} ..."
|
52
|
+
local_repo.git.pull({}, 'origin', branch)
|
53
|
+
|
54
|
+
# git push mirror #{branch} する
|
55
|
+
puts "Pushing #{branch} ..."
|
56
|
+
local_repo.git.push({ :timeout => 300 }, 'mirror', branch)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
module GitPusher
|
5
|
+
module Service
|
6
|
+
class BitBucket < Base
|
7
|
+
|
8
|
+
def initialize(config)
|
9
|
+
super(config)
|
10
|
+
@user = Pit.get(
|
11
|
+
'bitbucket', :require => { 'user' => 'Your user name of BitBucket' }
|
12
|
+
)['user']
|
13
|
+
@password = Pit.get(
|
14
|
+
'bitbucket', :require => { 'password' => 'Your user password of BitBucket' }
|
15
|
+
)['password']
|
16
|
+
end
|
17
|
+
|
18
|
+
def repo(name)
|
19
|
+
url = sprintf 'https://api.bitbucket.org/1.0/repositories/%s/%s', @user, name
|
20
|
+
opt = {"Authorization" => "Basic " + Base64.encode64("#{@user}:#{@password}")}
|
21
|
+
opt[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE
|
22
|
+
begin
|
23
|
+
json = open(url, opt) {|io|
|
24
|
+
JSON.parse(io.read)
|
25
|
+
}
|
26
|
+
rescue OpenURI::HTTPError => e
|
27
|
+
if e.message === '404 NOT FOUND'
|
28
|
+
return nil
|
29
|
+
else
|
30
|
+
raise e
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
GitPusher::Repo.new(ssh_url(name))
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_repo(name)
|
38
|
+
puts "Creating repository #{name} on the mirror ..."
|
39
|
+
https = Net::HTTP.new('api.bitbucket.org', 443)
|
40
|
+
https.use_ssl = true
|
41
|
+
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
42
|
+
https.start{|http|
|
43
|
+
request = Net::HTTP::Post.new('/1.0/repositories/')
|
44
|
+
request.basic_auth @user, @password
|
45
|
+
request.set_form_data({
|
46
|
+
:name => name,
|
47
|
+
:scm => 'git',
|
48
|
+
:is_private => 'True',
|
49
|
+
})
|
50
|
+
response = http.request(request)
|
51
|
+
}
|
52
|
+
|
53
|
+
GitPusher::Repo.new(ssh_url(name))
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def ssh_url(name)
|
58
|
+
sprintf "git@bitbucket.org:%s/%s.git", @user, name
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module GitPusher
|
2
|
+
module Service
|
3
|
+
class Factory
|
4
|
+
def self.create(config)
|
5
|
+
case config[:type]
|
6
|
+
when /github/i then GitPusher::Service::GitHub.new(config)
|
7
|
+
when /bitbucket/i then GitPusher::Service::BitBucket.new(config)
|
8
|
+
else
|
9
|
+
raise "unknown issue tracker type : #{its_type}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'octokit'
|
2
|
+
require 'pit'
|
3
|
+
|
4
|
+
module GitPusher
|
5
|
+
module Service
|
6
|
+
class GitHub < Base
|
7
|
+
attr :user, :password, :organization
|
8
|
+
|
9
|
+
def initialize(config)
|
10
|
+
super(config)
|
11
|
+
@user = Pit.get(
|
12
|
+
'github', :require => { 'user' => 'Your user name of GitHub' }
|
13
|
+
)['user']
|
14
|
+
@password = Pit.get(
|
15
|
+
'github', :require => { 'password' => 'Your user password of GitHub' }
|
16
|
+
)['password']
|
17
|
+
@organization = config[:organization]
|
18
|
+
end
|
19
|
+
|
20
|
+
def repos
|
21
|
+
repos = []
|
22
|
+
github_repos = self.organization ? octokit.org_repos(self.organization) : octokit.repos(self.user)
|
23
|
+
github_repos.each do |repo|
|
24
|
+
repos << GitPusher::Repo.new(repo[:ssh_url])
|
25
|
+
end
|
26
|
+
repos
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def octokit
|
31
|
+
Octokit::Client.new(:login => self.user, :password => self.password)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/gitpusher.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'gitpusher/context'
|
3
|
+
require 'gitpusher/config'
|
4
|
+
require 'gitpusher/runner'
|
5
|
+
require 'gitpusher/helper'
|
6
|
+
require 'gitpusher/service/base'
|
7
|
+
require 'gitpusher/service/factory'
|
8
|
+
require 'gitpusher/service/github'
|
9
|
+
require 'gitpusher/service/bitbucket'
|
10
|
+
require 'gitpusher/repo'
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gitpusher
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Gosuke Miyashita
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: grit
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: octokit
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: pit
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: grit
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description:
|
79
|
+
email:
|
80
|
+
- gosukenator@gmail.com
|
81
|
+
executables:
|
82
|
+
- gitpusher
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- .gitignore
|
87
|
+
- Gemfile
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- bin/gitpusher
|
91
|
+
- config/git_to_bitbucket.yml
|
92
|
+
- gitpusher.gemspec
|
93
|
+
- lib/gitpusher.rb
|
94
|
+
- lib/gitpusher/config.rb
|
95
|
+
- lib/gitpusher/context.rb
|
96
|
+
- lib/gitpusher/helper.rb
|
97
|
+
- lib/gitpusher/repo.rb
|
98
|
+
- lib/gitpusher/repo/base.rb
|
99
|
+
- lib/gitpusher/repo/bitbucket.rb
|
100
|
+
- lib/gitpusher/repo/factory.rb
|
101
|
+
- lib/gitpusher/repo/github.rb
|
102
|
+
- lib/gitpusher/runner.rb
|
103
|
+
- lib/gitpusher/service/base.rb
|
104
|
+
- lib/gitpusher/service/bitbucket.rb
|
105
|
+
- lib/gitpusher/service/factory.rb
|
106
|
+
- lib/gitpusher/service/github.rb
|
107
|
+
- lib/gitpusher/version.rb
|
108
|
+
homepage: https://github.com/mizzy/gitpusher
|
109
|
+
licenses: []
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ! '>='
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
requirements: []
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 1.8.23
|
129
|
+
signing_key:
|
130
|
+
specification_version: 3
|
131
|
+
summary: A command line tool for replicating git repositories from one service to
|
132
|
+
another.
|
133
|
+
test_files: []
|