github-merge 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/.autotest ADDED
@@ -0,0 +1,25 @@
1
+ # -*- ruby -*-
2
+
3
+ require "autotest/restart"
4
+
5
+ # Autotest.add_hook :initialize do |at|
6
+ # at.testlib = "minitest/unit"
7
+ #
8
+ # at.extra_files << "../some/external/dependency.rb"
9
+ #
10
+ # at.libs << ":../some/external"
11
+ #
12
+ # at.add_exception "vendor"
13
+ #
14
+ # at.add_mapping(/dependency.rb/) do |f, _|
15
+ # at.files_matching(/test_.*rb$/)
16
+ # end
17
+ #
18
+ # %w(TestA TestB).each do |klass|
19
+ # at.extra_class_map[klass] = "test/test_misc.rb"
20
+ # end
21
+ # end
22
+
23
+ # Autotest.add_hook :run_command do |at|
24
+ # system "rake build"
25
+ # end
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org/"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,54 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ github-merge (1.0.0)
5
+ github_api (~> 0.9.4)
6
+ thor (~> 0.18.1)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ diff-lcs (1.2.2)
12
+ faraday (0.8.7)
13
+ multipart-post (~> 1.1)
14
+ github_api (0.9.6)
15
+ faraday (~> 0.8.1)
16
+ hashie (>= 1.2)
17
+ multi_json (~> 1.4)
18
+ nokogiri (~> 1.5.2)
19
+ oauth2
20
+ hashie (2.0.3)
21
+ httpauth (0.2.0)
22
+ jwt (0.1.8)
23
+ multi_json (>= 1.5)
24
+ multi_json (1.7.2)
25
+ multi_xml (0.5.3)
26
+ multipart-post (1.2.0)
27
+ nokogiri (1.5.9)
28
+ oauth2 (0.9.1)
29
+ faraday (~> 0.8)
30
+ httpauth (~> 0.1)
31
+ jwt (~> 0.1.4)
32
+ multi_json (~> 1.0)
33
+ multi_xml (~> 0.5)
34
+ rack (~> 1.2)
35
+ rack (1.5.2)
36
+ rake (10.0.4)
37
+ rspec (2.13.0)
38
+ rspec-core (~> 2.13.0)
39
+ rspec-expectations (~> 2.13.0)
40
+ rspec-mocks (~> 2.13.0)
41
+ rspec-core (2.13.1)
42
+ rspec-expectations (2.13.0)
43
+ diff-lcs (>= 1.1.3, < 2.0)
44
+ rspec-mocks (2.13.1)
45
+ thor (0.18.1)
46
+
47
+ PLATFORMS
48
+ ruby
49
+
50
+ DEPENDENCIES
51
+ bundler (~> 1.3)
52
+ github-merge!
53
+ rake
54
+ rspec
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2013-03-31
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Arthur Maltson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,10 @@
1
+ .autotest
2
+ History.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ bin/github-merge
7
+ lib/github_merge/merge.rb
8
+ lib/github_merge/cli.rb
9
+ lib/github_merge.rb
10
+ test/test_merge.rb
data/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # github-merge
2
+
3
+ Script that merges multiple GitHub repositories into a new, single repository.
4
+
5
+ ## Installation
6
+
7
+ This is a CLI app, so you'll have to:
8
+
9
+ ```
10
+ $ gem install github-merge
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ `github-merge` uses a YAML based configuration that lists the
16
+ repositories to merge and the name (and optionally organization) of the
17
+ new combined repository. A sample configuration file:
18
+
19
+ ```yaml
20
+ merged organization: acme
21
+ merged repository: sinatra-templates
22
+ repositories:
23
+ - url: https://github.com/rkh/sinatra-template.git
24
+ sub directory: sinatra-base-template
25
+ - url: https://github.com/sinatra/heroku-sinatra-app.git
26
+ sub directory: sinatra-heroku-template
27
+ ```
28
+
29
+ You'd then merge the repositories:
30
+
31
+ ```
32
+ $ github-merge local sinatra-templates.yml
33
+ ```
34
+
35
+ ### Options
36
+
37
+ *[--all-svn]*
38
+
39
+ Pass this argument if the repositories being merged started their life
40
+ in Subversion and were subsequently migrated to Git. This is required
41
+ because the merge has to skip the initial commit because of a weird
42
+ git-svn issue that causes the `git filter-branch` to bomb (don't ask
43
+ me, it was on Stackoverflow and it works).
44
+
45
+ ### Technical Details
46
+
47
+ The merge process is done in the following steps
48
+
49
+ 1. Clone repositories.
50
+ 2. For each repository to be merged, execute a `git filter-branch` to
51
+ move the entire repository contents into the specified subdirectory.
52
+ 3. Create a new empty Git repository.
53
+ 4. Add each repository to be merged as a remote repository.
54
+ 5. Fetch and `git merge --no-edit <remote>/master` for each repository.
55
+
56
+ Note: a `git merge` is used to preserve the branching history of each
57
+ repository being merged.
58
+
59
+ ### Limitations
60
+
61
+ The following are limitations of github-merge that may, or may not, be
62
+ addressed in the future.
63
+
64
+ * Does not carry over tags
65
+ * Does not carry over active (unmerged) branches
66
+ * Does not merge repositories with only 1 commit
67
+
68
+ ## Contributing
69
+
70
+ 1. Fork it
71
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
72
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
73
+ 4. Push to the branch (`git push origin my-new-feature`)
74
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = FileList['spec/**/*_spec.rb']
8
+ end
9
+
10
+ task :default => [:spec]
data/bin/github-merge ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/github_merge/cli'
4
+
5
+ MergeCli.start(ARGV)
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'github_merge'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "github-merge"
8
+ spec.version = Merge::VERSION
9
+ spec.authors = ["Arthur Maltson"]
10
+ spec.email = ["arthur.kalm@gmail.com"]
11
+ spec.description = %q{Script that merges multiple GitHub repositories into a new, single repository.}
12
+ spec.summary = %q{Split your project into lots of small Git repos and finding yourself creating cross repo Pull Requests? This is the gem for you.}
13
+ spec.homepage = "https://github.com/amaltson/github-merge"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "github_api", "~>0.9.4"
22
+ spec.add_dependency "thor", "~>0.18.1"
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rspec"
26
+ end
@@ -0,0 +1 @@
1
+ require 'github_merge/merge.rb'
@@ -0,0 +1,10 @@
1
+ require 'thor'
2
+ require_relative 'merge'
3
+
4
+ class MergeCli < Thor
5
+ desc 'local file.yml', %q{Locally merge GitHub repositories as specified in YAML file.}
6
+ option :all_svn, :type => :boolean
7
+ def local(file)
8
+ Merge.new(file, options).local!
9
+ end
10
+ end
@@ -0,0 +1,89 @@
1
+ class LocalMerge
2
+
3
+ OUT_DIR = "#{Dir.pwd}/merged"
4
+
5
+ def initialize(config, options)
6
+ @config = config
7
+ @options = options
8
+ end
9
+
10
+ def merge!
11
+ FileUtils.mkdir_p OUT_DIR
12
+ Dir.chdir OUT_DIR do
13
+ clone_repos
14
+ move_repos_to_subdir
15
+ create_empty_merged_repo
16
+ merge_repositories
17
+ end
18
+ end
19
+
20
+ def clone_repos
21
+ @config["repositories"].each do |repo|
22
+ `git clone #{repo["url"]} #{repo["sub directory"]}`
23
+ end
24
+ end
25
+
26
+ def move_repos_to_subdir
27
+ @config["repositories"].each do |repo|
28
+ git_filter_branch_move(repo["sub directory"])
29
+ end
30
+ end
31
+
32
+ def create_empty_merged_repo
33
+ puts 'Creating merged repository'
34
+ `git init #{merge_repo_name}`
35
+ end
36
+
37
+ def merge_repositories
38
+ Dir.chdir merge_repo_name do
39
+ @config["repositories"].each_with_index do |repo, index|
40
+ repo_name = repo["sub directory"]
41
+ `git remote add #{repo_name} ../#{repo_name}`
42
+ `git fetch #{repo_name}`
43
+ `git merge --no-edit #{repo_name}/master`
44
+ end
45
+ end
46
+ end
47
+
48
+ def git_filter_branch_move(subdir)
49
+ puts "Moving repository #{subdir} to subdirectory #{subdir}..."
50
+
51
+ sed = sed_command_to_use
52
+ Dir.chdir subdir do
53
+ %x[git filter-branch --index-filter \
54
+ 'git ls-files -s | #{sed} "s@\t@&#{subdir}/@" |
55
+ GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
56
+ git update-index --index-info &&
57
+ mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' #{beginning_sha}..HEAD]
58
+ end
59
+ end
60
+
61
+ def beginning_sha
62
+ if @options.all_svn?
63
+ `git log --pretty=format:%H --reverse`.split("\n")[1]
64
+ else
65
+ `git log --pretty=format:%H --reverse`.split("\n").first
66
+ end
67
+ end
68
+
69
+ def sed_command_to_use
70
+ if RbConfig::CONFIG['host_os'] =~ /darwin/
71
+ 'gsed'
72
+ else
73
+ 'sed'
74
+ end
75
+ end
76
+
77
+ def merge_repo_name
78
+ @config["merged repository"]
79
+ end
80
+
81
+ def merged?
82
+ merge_repo_dir = "#{OUT_DIR}/#{merge_repo_name}"
83
+ return false unless Dir.exist? merge_repo_dir
84
+ Dir.chdir merge_repo_dir do
85
+ return false unless Dir.exists? '.git'
86
+ return `git log`.split("\n").size > 0
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,27 @@
1
+ require 'yaml'
2
+ require 'rbconfig'
3
+ require 'fileutils'
4
+ require_relative 'local'
5
+ require_relative 'push'
6
+
7
+ class Merge
8
+ VERSION = "0.0.1"
9
+ MOVE_TREE_SCRIPT_PATH = "#{Dir.pwd}/lib/github_merge"
10
+
11
+ def initialize(file, options)
12
+ @file = file
13
+ @options = options
14
+ @config = YAML.load_file @file
15
+ @local_merge = LocalMerge.new(@config, @options)
16
+ @push_merge = PushMerge.new(@config, @options)
17
+ end
18
+
19
+ def local!
20
+ @local_merge.merge!
21
+ end
22
+
23
+ def push!
24
+ @local_merge.merge! unless @local_merge.merged?
25
+ @push_merge.push!
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ class PushMerge
2
+
3
+ def initialize(config, options)
4
+ @config = config
5
+ @options = options
6
+ end
7
+
8
+ def push!
9
+ github = initialize_github
10
+ end
11
+
12
+ def initialize_github
13
+ api_endpoint = config["host"] || "https://api.github.com"
14
+ oauth_token = config["oauth"]
15
+
16
+ Github.new do |config|
17
+ config.endpoint = api_endpoint
18
+ config.oauth_token = oauth_token
19
+ config.adapter = :net_http
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,41 @@
1
+ require 'rspec'
2
+ require 'github_merge/merge'
3
+ require 'fileutils'
4
+
5
+ describe Merge do
6
+ before :each do
7
+ options = double()
8
+ options.stub(:all_svn? => false)
9
+ @merge = Merge.new 'spec/sample-merge-config.yml', options
10
+ end
11
+
12
+ after :each do
13
+ FileUtils.rm_rf(LocalMerge::OUT_DIR)
14
+ end
15
+
16
+ it "shouldn't be merged by default" do
17
+ @merge.instance_variable_get("@local_merge").merged?.should be_false
18
+ end
19
+
20
+ it "should merge locally" do
21
+ @merge.local!
22
+
23
+ # Check clone and rename worked
24
+ %w{github-merge github}.each do |repo|
25
+ Dir.exists?("#{LocalMerge::OUT_DIR}/#{repo}").should be_true
26
+ Dir.exists?("#{LocalMerge::OUT_DIR}/#{repo}/#{repo}").should be_true
27
+ end
28
+
29
+ # check that the merge was successful
30
+ merged_dir = "#{LocalMerge::OUT_DIR}/merge-test"
31
+ Dir.exists?(merged_dir).should be_true
32
+ %w{github-merge github}.each do |repo|
33
+ Dir.exists?("#{merged_dir}/#{repo}").should be_true
34
+ end
35
+
36
+ @merge.instance_variable_get("@local_merge").merged?.should be_true
37
+ end
38
+
39
+ it "should merge local when pushing" do
40
+ end
41
+ end
@@ -0,0 +1,9 @@
1
+ host: https://api.github.com
2
+ oauth: oauth_token_here
3
+ merged organization: org
4
+ merged repository: merge-test
5
+ repositories:
6
+ - url: https://github.com/amaltson/github-merge.git
7
+ sub directory: github-merge
8
+ - url: https://github.com/amaltson/github-merge.git
9
+ sub directory: github
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: github-merge
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Arthur Maltson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: github_api
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.9.4
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.9.4
30
+ - !ruby/object:Gem::Dependency
31
+ name: thor
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.18.1
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.18.1
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
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
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: Script that merges multiple GitHub repositories into a new, single repository.
95
+ email:
96
+ - arthur.kalm@gmail.com
97
+ executables:
98
+ - github-merge
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - .autotest
103
+ - .gitignore
104
+ - Gemfile
105
+ - Gemfile.lock
106
+ - History.txt
107
+ - LICENSE.txt
108
+ - Manifest.txt
109
+ - README.md
110
+ - Rakefile
111
+ - bin/github-merge
112
+ - github-merge.gemspec
113
+ - lib/github_merge.rb
114
+ - lib/github_merge/cli.rb
115
+ - lib/github_merge/local.rb
116
+ - lib/github_merge/merge.rb
117
+ - lib/github_merge/push.rb
118
+ - spec/merge_spec.rb
119
+ - spec/sample-merge-config.yml
120
+ homepage: https://github.com/amaltson/github-merge
121
+ licenses:
122
+ - MIT
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - ! '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 1.8.23
142
+ signing_key:
143
+ specification_version: 3
144
+ summary: Split your project into lots of small Git repos and finding yourself creating
145
+ cross repo Pull Requests? This is the gem for you.
146
+ test_files:
147
+ - spec/merge_spec.rb
148
+ - spec/sample-merge-config.yml