Skip to content

Instantly share code, notes, and snippets.

@Guaidaodl
Last active August 11, 2016 16:39
Show Gist options
  • Save Guaidaodl/8861d00bcea91e6edc9200c2964aeb06 to your computer and use it in GitHub Desktop.
Save Guaidaodl/8861d00bcea91e6edc9200c2964aeb06 to your computer and use it in GitHub Desktop.
快速查看repo的状态, 然后还加了没有用的 interactive 模式
#! /usr/bin/ruby
require 'colorize'
require 'optparse'
class FileStatus
attr_accessor :file_name, :status
def initialize(file_name, status)
@file_name = file_name
@status = status
end
def output
case @status
when :new
print "#{file_name}\n".green
when :mod
print "#{file_name}\n".yellow
when :del
print "#{file_name}\n".red
when :renamed
print "#{file_name}\n".blue
end
end
end
class Status
attr_accessor :untrack, :cached, :change
@@mod_pattern = /^\tmodified:\s+(.+)/
@@new_pattern = /^\tnew file:\s+(.+)/
@@del_pattern = /^\tdeleted:\s+(.+)/
@@renamed_pattern = /^\trenamed:\s+(.+)/
@@untrack_pattern = /^\t(.+)/
def initialize()
clear()
status = `git status`
parseStatus(status)
end
def clear
@cached = []
@change = []
@untrack = []
end
def update()
clear()
status = `git status`
parseStatus(status)
end
# 解析 git status 返回的信息
def parseStatus(status)
lines = status.split("\n")
untrack_part_start = false
## 当前的文件属于那个部分
currentPart = @cached
lines.each do |line|
if line.start_with?("Changes to be committed") then
currentPart = @cached
elsif line.start_with?("Changes not staged") then
currentPart = @change
elsif line.start_with?("Untracked") then
currentPart = @untrack
untrack_part_start = true
elsif untrack_part_start && line.start_with?("\t") then
m = @@untrack_pattern.match(line)
currentPart.push(FileStatus.new(m[1], :new))
end
parse_line(@@mod_pattern, :mod, line, currentPart) ||
parse_line(@@new_pattern, :new, line, currentPart) ||
parse_line(@@del_pattern, :del, line, currentPart) ||
parse_line(@@renamed_pattern, :renamed, line, currentPart)
end
end
def parse_line(pattern, file_status, line, part)
m = pattern.match(line)
if m then
part.push(FileStatus.new(m[1], file_status))
return true
else
return false
end
end
# 改变文件的状态
def change_status(index)
if index >= 0 && index < @cached.count then
`git reset HEAD #{@cached[index].file_name.gsub(" ", "\\ ")}`
elsif index < @cached.count + @change.count then
`git add #{@change[index - @cached.count].file_name.gsub(" ", "\\ ")}`
elsif index < @cached.count + @change.count + @untrack.count then
`git add #{@untrack[index - @cached.count - @change.count].file_name.gsub(" ", "\\ ")}`
end
end
def output()
index = print_file_status_array(@cached, "ADDED: ", 0)
print "-----------------------------------------------------------------\n".yellow
index = print_file_status_array(@change, "Change: ", index)
print "-----------------------------------------------------------------\n".red
index = print_file_status_array(@untrack, "UNTRACK: ", index)
end
# 输出状态数组
def print_file_status_array(fs, title, start_index)
index = start_index
if !fs.empty? then
print "#{title}\n"
fs.each do |f|
print "#{index}\t"
index = index + 1
f.output
end
print "\n"
end
index
end
end
# 解析参数
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: op.rb [options]"
opts.on("-i", "--interactive", "interactive") do |i|
options[:interactive] = i
end
end.parse!
# 获取 branch 的名称
branch_name = `git rev-parse --abbrev-ref HEAD`
if branch_name == "HEAD\n" then
short_version = `git rev-parse --short HEAD`
print "## " + short_version.red + "\n"
else
print "## " + branch_name.green + "\n"
end
s = Status.new()
s.output()
if options[:interactive] then
print "change file status:\n"
while true
c = gets
if c.start_with?("q") then
break
end
i = c.to_i
s.change_status(i)
print "=================================================================\n".green
s.update
s.output
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment