Class: GitUp
- Inherits:
-
Object
- Object
- GitUp
- Defined in:
- lib/git-up.rb,
lib/git-up/version.rb
Defined Under Namespace
Classes: GitError
Constant Summary collapse
- VERSION =
"0.5.0"
Instance Method Summary collapse
- #branches ⇒ Object
- #check_bundler ⇒ Object
- #checkout(branch_name) ⇒ Object
- #get_repo ⇒ Object
- #is_fast_forward?(a, b) ⇒ Boolean
- #merge_base(a, b) ⇒ Object
- #on_branch?(branch_name = nil) ⇒ Boolean
- #rebase(target_branch) ⇒ Object
- #remote_for_branch(branch) ⇒ Object
- #remote_map ⇒ Object
- #remotes ⇒ Object
- #repo ⇒ Object
- #returning_to_current_branch ⇒ Object
- #run ⇒ Object
- #with_stash ⇒ Object
Instance Method Details
#branches ⇒ Object
63 64 65 |
# File 'lib/git-up.rb', line 63 def branches @branches ||= repo.branches.select { |b| remote_map.has_key?(b.name) } end |
#check_bundler ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/git-up.rb', line 142 def check_bundler return unless use_bundler? begin require 'bundler' ENV['BUNDLE_GEMFILE'] ||= File.('Gemfile') Bundler.setup rescue Bundler::GemNotFound, Bundler::GitError puts print 'Gems are missing. '.yellow if config("bundler.autoinstall") == 'true' puts "Running `bundle install`.".yellow system "bundle", "install" else puts "You should `bundle install`.".yellow end end end |
#checkout(branch_name) ⇒ Object
124 125 126 127 128 129 130 |
# File 'lib/git-up.rb', line 124 def 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 |
#get_repo ⇒ Object
53 54 55 56 57 58 59 60 61 |
# File 'lib/git-up.rb', line 53 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 |
#is_fast_forward?(a, b) ⇒ Boolean
162 163 164 |
# File 'lib/git-up.rb', line 162 def is_fast_forward?(a, b) merge_base(a.name, b.name) == b.commit.sha end |
#merge_base(a, b) ⇒ Object
166 167 168 |
# File 'lib/git-up.rb', line 166 def merge_base(a, b) repo.git.send("merge-base", {}, a, b).strip end |
#on_branch?(branch_name = nil) ⇒ Boolean
170 171 172 |
# File 'lib/git-up.rb', line 170 def on_branch?(branch_name=nil) repo.head.respond_to?(:name) and repo.head.name == branch_name end |
#rebase(target_branch) ⇒ Object
132 133 134 135 136 137 138 139 140 |
# File 'lib/git-up.rb', line 132 def rebase(target_branch) current_branch = repo.head 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 |
#remote_for_branch(branch) ⇒ Object
81 82 83 84 85 86 |
# File 'lib/git-up.rb', line 81 def remote_for_branch(branch) 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 |
#remote_map ⇒ Object
71 72 73 74 75 76 77 78 79 |
# File 'lib/git-up.rb', line 71 def remote_map @remote_map ||= repo.branches.inject({}) { |map, branch| if remote = remote_for_branch(branch) map[branch.name] = remote end map } end |
#remotes ⇒ Object
67 68 69 |
# File 'lib/git-up.rb', line 67 def remotes @remotes ||= remote_map.values.map { |r| r.name.split('/', 2).first }.uniq end |
#repo ⇒ Object
49 50 51 |
# File 'lib/git-up.rb', line 49 def repo @repo ||= get_repo end |
#returning_to_current_branch ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/git-up.rb', line 108 def returning_to_current_branch 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 yield unless on_branch?(branch_name) puts "returning to #{branch_name}".magenta checkout(branch_name) end end |
#run ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/git-up.rb', line 5 def run system('git', 'fetch', '--multiple', *remotes) raise GitError, "`git fetch` failed" unless $? == 0 @remote_map = nil # flush cache after fetch with_stash do returning_to_current_branch do col_width = branches.map { |b| b.name.length }.max + 1 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 next end base = merge_base(branch.name, remote.name) if base == remote.commit.sha puts "ahead of upstream".blue next end if base == branch.commit.sha puts "fast-forwarding...".yellow checkout(branch.name) rebase(remote) else puts "diverged".red end end end end check_bundler rescue GitError => e puts e. exit 1 end |
#with_stash ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/git-up.rb', line 88 def with_stash stashed = false 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 stashed = true end yield if stashed puts "unstashing".magenta repo.git.stash({}, "pop") end end |