lib/git-up.rb in git-up-0.4.1 vs lib/git-up.rb in git-up-0.4.2
- old
+ new
@@ -1,24 +1,19 @@
require 'colored'
require 'grit'
class GitUp
- def initialize(args)
- end
-
def run
- get_repo
-
- system "git fetch"
+ system "git", "fetch", "--all"
raise GitError, "`git fetch` failed" unless $? == 0
with_stash do
returning_to_current_branch do
- col_width = @repo.branches.map { |b| b.name.length }.max + 1
+ col_width = branches.map { |b| b.name.length }.max + 1
- @repo.branches.each do |branch|
- next unless remote = remote_for_branch(branch)
+ branches.each do |branch|
+ remote = remote_map[branch.name]
print branch.name.ljust(col_width)
if remote.commit.sha == branch.commit.sha
puts "up to date".green
@@ -48,73 +43,93 @@
rescue GitError => e
puts e.message
exit 1
end
+ def repo
+ @repo ||= get_repo
+ end
+
def get_repo
git_dir = `git rev-parse --git-dir`
if $? == 0
@repo = Grit::Repo.new(File.dirname(git_dir))
else
raise GitError, "We don't seem to be in a git repository."
end
end
+ def branches
+ @branches ||= repo.branches.select { |b| remote_map.has_key?(b.name) }
+ end
+
+ def remote_map
+ @remote_map ||= repo.branches.inject({}) { |map, branch|
+ if remote = remote_for_branch(branch)
+ map[branch.name] = remote
+ end
+
+ map
+ }
+ end
+
def remote_for_branch(branch)
- remote_name = @repo.config["branch.#{branch.name}.remote"] || "origin"
- @repo.remotes.find { |r| r.name == "#{remote_name}/#{branch.name}" }
+ remote_name = repo.config["branch.#{branch.name}.remote"] || "origin"
+ remote_branch = repo.config["branch.#{branch.name}.merge"] || branch.name
+ remote_branch.sub!(%r{^refs/heads/}, '')
+ repo.remotes.find { |r| r.name == "#{remote_name}/#{remote_branch}" }
end
def with_stash
stashed = false
- status = @repo.status
+ status = repo.status
change_count = status.added.length + status.changed.length + status.deleted.length
if change_count > 0
puts "stashing #{change_count} changes".magenta
- @repo.git.stash
+ repo.git.stash
stashed = true
end
yield
if stashed
puts "unstashing".magenta
- @repo.git.stash({}, "pop")
+ repo.git.stash({}, "pop")
end
end
def returning_to_current_branch
- unless @repo.head.respond_to?(:name)
+ unless repo.head.respond_to?(:name)
puts "You're not currently on a branch. I'm exiting in case you're in the middle of something.".red
return
end
- branch_name = @repo.head.name
+ branch_name = repo.head.name
yield
unless on_branch?(branch_name)
puts "returning to #{branch_name}".magenta
checkout(branch_name)
end
end
def checkout(branch_name)
- output = @repo.git.checkout({}, branch_name)
+ output = repo.git.checkout({}, branch_name)
unless on_branch?(branch_name)
raise GitError.new("Failed to checkout #{branch_name}", output)
end
end
def rebase(target_branch)
- current_branch = @repo.head
+ current_branch = repo.head
- output, err = @repo.git.sh("#{Grit::Git.git_binary} rebase #{target_branch.name}")
+ output, err = repo.git.sh("#{Grit::Git.git_binary} rebase #{target_branch.name}")
unless on_branch?(current_branch.name) and is_fast_forward?(current_branch, target_branch)
raise GitError.new("Failed to rebase #{current_branch.name} onto #{target_branch.name}", output+err)
end
end
@@ -124,24 +139,24 @@
begin
require 'bundler'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('Gemfile')
Bundler.setup
- rescue Bundler::GemNotFound
+ rescue Bundler::GemNotFound, Bundler::GitError
puts 'Gems are missing. You should `bundle install`.'.yellow
end
end
def is_fast_forward?(a, b)
merge_base(a.name, b.name) == b.commit.sha
end
def merge_base(a, b)
- @repo.git.send("merge-base", {}, a, b).strip
+ repo.git.send("merge-base", {}, a, b).strip
end
def on_branch?(branch_name=nil)
- @repo.head.respond_to?(:name) and @repo.head.name == branch_name
+ repo.head.respond_to?(:name) and repo.head.name == branch_name
end
class GitError < StandardError
def initialize(message, output=nil)
@msg = "#{message.red}"