git-up-portertech 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +30 -0
  3. data/bin/git-up +6 -0
  4. data/lib/git-up.rb +223 -0
  5. data/lib/git-up/version.rb +3 -0
  6. metadata +97 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Aanand Prasad
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,30 @@
1
+ git-up
2
+ ======
3
+
4
+ So `git pull` merges by default, when it [should really rebase](http://www.gitready.com/advanced/2009/02/11/pull-with-rebase.html). You can [ask it to rebase instead](http://d.strelau.net/post/47338904/git-pull-rebase-by-default), but it still won't touch anything other than the currently checked-out branch. If you're tracking a bunch of remote branches, you'll get non-fast-forward complaints next time you push.
5
+
6
+ Solve it once and for all:
7
+
8
+ ![gem install git-up](http://dl.dropbox.com/u/166030/nonsense/git-up.png)
9
+
10
+ although
11
+ --------
12
+
13
+ `git-up` might mess up your branches, or set your chest hair on fire, or be racist to your cat, I don't know. It works for me.
14
+
15
+ configuration
16
+ -------------
17
+
18
+ `git-up` can check your app for any new bundled gems and suggest a `bundle install` if necessary.
19
+
20
+ It slows the process down slightly, and is therefore enabled by setting `git-up.bundler.check` to `true` in your git config, either globally or per-project. To set it globally, run this command anywhere:
21
+
22
+ git config --global git-up.bundler.check true
23
+
24
+ To set it within a project, run this command inside that project's directory:
25
+
26
+ git config git-up.bundler.check true
27
+
28
+ Replace 'true' with 'false' to disable checking.
29
+
30
+ If you're even lazier, you can tell `git-up` to run `bundle install` for you if it finds missing gems. Simply set `git-up.bundler.autoinstall` to `true`, in the same manner. As above, it works globally or per-project, but make sure `git-up.bundler.check` is also set to `true` or it won't do anything.
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'git-up'
4
+
5
+ GitUp.new.run
6
+
@@ -0,0 +1,223 @@
1
+ require 'colored'
2
+ require 'grit'
3
+
4
+ class GitUp
5
+ def run
6
+ system('git', 'fetch', '--multiple', *remotes)
7
+ raise GitError, "`git fetch` failed" unless $? == 0
8
+ @remote_map = nil # flush cache after fetch
9
+
10
+ with_stash do
11
+ returning_to_current_branch do
12
+ col_width = branches.map { |b| b.name.length }.max + 1
13
+
14
+ branches.each do |branch|
15
+ remote = remote_map[branch.name]
16
+
17
+ print branch.name.ljust(col_width)
18
+
19
+ if remote.commit.sha == branch.commit.sha
20
+ puts "up to date".green
21
+ next
22
+ end
23
+
24
+ base = merge_base(branch.name, remote.name)
25
+
26
+ if base == remote.commit.sha
27
+ puts "ahead of upstream".blue
28
+ next
29
+ end
30
+
31
+ if base == branch.commit.sha
32
+ puts "fast-forwarding...".yellow
33
+ checkout(branch.name)
34
+ rebase(remote)
35
+ else
36
+ puts "diverged".red
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+
43
+ check_bundler
44
+ rescue GitError => e
45
+ puts e.message
46
+ exit 1
47
+ end
48
+
49
+ def repo
50
+ @repo ||= get_repo
51
+ end
52
+
53
+ def get_repo
54
+ git_dir = `git rev-parse --git-dir`
55
+
56
+ if $? == 0
57
+ @repo = Grit::Repo.new(File.dirname(git_dir))
58
+ else
59
+ raise GitError, "We don't seem to be in a git repository."
60
+ end
61
+ end
62
+
63
+ def branches
64
+ @branches ||= repo.branches.select { |b| remote_map.has_key?(b.name) }
65
+ end
66
+
67
+ def remotes
68
+ @remotes ||= remote_map.values.map { |r| r.name.split('/', 2).first }.uniq
69
+ end
70
+
71
+ def remote_map
72
+ @remote_map ||= repo.branches.inject({}) { |map, branch|
73
+ if remote = remote_for_branch(branch)
74
+ map[branch.name] = remote
75
+ end
76
+
77
+ map
78
+ }
79
+ end
80
+
81
+ def remote_for_branch(branch)
82
+ remote_name = repo.config["branch.#{branch.name}.remote"] || "origin"
83
+ remote_branch = repo.config["branch.#{branch.name}.merge"] || branch.name
84
+ remote_branch.sub!(%r{^refs/heads/}, '')
85
+ repo.remotes.find { |r| r.name == "#{remote_name}/#{remote_branch}" }
86
+ end
87
+
88
+ def with_stash
89
+ stashed = false
90
+
91
+ status = repo.status
92
+ change_count = status.added.length + status.changed.length + status.deleted.length
93
+
94
+ if change_count > 0
95
+ puts "stashing #{change_count} changes".magenta
96
+ repo.git.stash
97
+ stashed = true
98
+ end
99
+
100
+ yield
101
+
102
+ if stashed
103
+ puts "unstashing".magenta
104
+ repo.git.stash({}, "pop")
105
+ end
106
+ end
107
+
108
+ def returning_to_current_branch
109
+ unless repo.head.respond_to?(:name)
110
+ puts "You're not currently on a branch. I'm exiting in case you're in the middle of something.".red
111
+ return
112
+ end
113
+
114
+ branch_name = repo.head.name
115
+
116
+ yield
117
+
118
+ unless on_branch?(branch_name)
119
+ puts "returning to #{branch_name}".magenta
120
+ checkout(branch_name)
121
+ end
122
+ end
123
+
124
+ def checkout(branch_name)
125
+ output = repo.git.checkout({}, branch_name)
126
+
127
+ unless on_branch?(branch_name)
128
+ raise GitError.new("Failed to checkout #{branch_name}", output)
129
+ end
130
+ end
131
+
132
+ def rebase(target_branch)
133
+ current_branch = repo.head
134
+
135
+ output, err = repo.git.sh("#{Grit::Git.git_binary} rebase #{target_branch.name}")
136
+
137
+ unless on_branch?(current_branch.name) and is_fast_forward?(current_branch, target_branch)
138
+ raise GitError.new("Failed to rebase #{current_branch.name} onto #{target_branch.name}", output+err)
139
+ end
140
+ end
141
+
142
+ def check_bundler
143
+ return unless use_bundler?
144
+
145
+ begin
146
+ require 'bundler'
147
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('Gemfile')
148
+ Bundler.setup
149
+ rescue Bundler::GemNotFound, Bundler::GitError
150
+ puts
151
+ print 'Gems are missing. '.yellow
152
+
153
+ if config("bundler.autoinstall") == 'true'
154
+ puts "Running `bundle install`.".yellow
155
+ system "bundle", "install"
156
+ else
157
+ puts "You should `bundle install`.".yellow
158
+ end
159
+ end
160
+ end
161
+
162
+ def is_fast_forward?(a, b)
163
+ merge_base(a.name, b.name) == b.commit.sha
164
+ end
165
+
166
+ def merge_base(a, b)
167
+ repo.git.send("merge-base", {}, a, b).strip
168
+ end
169
+
170
+ def on_branch?(branch_name=nil)
171
+ repo.head.respond_to?(:name) and repo.head.name == branch_name
172
+ end
173
+
174
+ class GitError < StandardError
175
+ def initialize(message, output=nil)
176
+ @msg = "#{message.red}"
177
+
178
+ if output
179
+ @msg << "\n"
180
+ @msg << "Here's what Git said:".red
181
+ @msg << "\n"
182
+ @msg << output
183
+ end
184
+ end
185
+
186
+ def message
187
+ @msg
188
+ end
189
+ end
190
+
191
+ private
192
+
193
+ def use_bundler?
194
+ use_bundler_config? and File.exists? 'Gemfile'
195
+ end
196
+
197
+ def use_bundler_config?
198
+ if ENV.has_key?('GIT_UP_BUNDLER_CHECK')
199
+ puts <<-EOS.yellow
200
+ The GIT_UP_BUNDLER_CHECK environment variable is deprecated.
201
+ You can now tell git-up to check (or not check) for missing
202
+ gems on a per-project basis using git's config system. To
203
+ set it globally, run this command anywhere:
204
+
205
+ git config --global git-up.bundler.check true
206
+
207
+ To set it within a project, run this command inside that
208
+ project's directory:
209
+
210
+ git config git-up.bundler.check true
211
+
212
+ Replace 'true' with 'false' to disable checking.
213
+ EOS
214
+ end
215
+
216
+ config("bundler.check") == 'true' || ENV['GIT_UP_BUNDLER_CHECK'] == 'true'
217
+ end
218
+
219
+ def config(key)
220
+ repo.config["git-up.#{key}"]
221
+ end
222
+ end
223
+
@@ -0,0 +1,3 @@
1
+ class GitUp
2
+ VERSION = "0.5.0"
3
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git-up-portertech
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.5.0
6
+ platform: ruby
7
+ authors:
8
+ - Aanand Prasad
9
+ - Elliot Crosby-McCullough
10
+ - Adrian Irving-Beer
11
+ - Joshua Wehner
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2011-07-13 00:00:00 -07:00
17
+ default_executable:
18
+ dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ name: thoughtbot-shoulda
21
+ prerelease: false
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: "0"
28
+ type: :development
29
+ version_requirements: *id001
30
+ - !ruby/object:Gem::Dependency
31
+ name: colored
32
+ prerelease: false
33
+ requirement: &id002 !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: "1.2"
39
+ type: :runtime
40
+ version_requirements: *id002
41
+ - !ruby/object:Gem::Dependency
42
+ name: grit
43
+ prerelease: false
44
+ requirement: &id003 !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ type: :runtime
51
+ version_requirements: *id003
52
+ description:
53
+ email:
54
+ - aanand.prasad@gmail.com
55
+ - elliot.cm@gmail.com
56
+ executables:
57
+ - git-up
58
+ extensions: []
59
+
60
+ extra_rdoc_files: []
61
+
62
+ files:
63
+ - bin/git-up
64
+ - lib/git-up/version.rb
65
+ - lib/git-up.rb
66
+ - LICENSE
67
+ - README.md
68
+ has_rdoc: true
69
+ homepage: http://github.com/aanand/git-up
70
+ licenses: []
71
+
72
+ post_install_message:
73
+ rdoc_options: []
74
+
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ requirements: []
90
+
91
+ rubyforge_project:
92
+ rubygems_version: 1.6.2
93
+ signing_key:
94
+ specification_version: 3
95
+ summary: git command to fetch and rebase all branches
96
+ test_files: []
97
+