git-hack 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ doc
6
+ tmp_git_hack_test
7
+ .idea
8
+ TAGS
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://ruby.taobao.org"
2
+
3
+ gem 'colorize'
4
+ gem 'git'
5
+ gem 'awesome_print'
6
+
7
+ group :development,:test do
8
+ gem 'rspec'
9
+ gem 'guard'
10
+ gem 'guard-rspec'
11
+ #gem 'libnotify' gname3的notify不太好用,先去掉
12
+ gem 'rspec-mocks'
13
+ end
@@ -0,0 +1,15 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :cli=>"--color",:version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch(%r{^lib/commands/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
8
+ watch(%r{^lib/git-hack/(.+)\.rb$}) { |m| ["spec/#{m[1]}_spec.rb",
9
+ "*.rb"] }
10
+ watch(%r{^lib/core_ext/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+
12
+ watch('spec/spec_helper.rb') { "spec" }
13
+
14
+ end
15
+
@@ -0,0 +1,26 @@
1
+ # git-hack
2
+
3
+ I don't known why logic of git is sooooo horrible!! And I make this tools for people to say "WOW,This is git !!!"
4
+
5
+ 0. git-save git-redo git-undo git-backto They look easy to understand? Wow,This is git.
6
+ 1.
7
+
8
+
9
+ ## Installing
10
+
11
+ All you need to do is grab the gem:
12
+
13
+ gem install git-hack
14
+
15
+
16
+ ### save
17
+
18
+ ### undo
19
+
20
+ ### redo
21
+
22
+ ### backto
23
+
24
+ ## Copyright
25
+
26
+ Copyright (c) 2012 weizhao mailto: azhao.1981@gmail.com
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require (File.expand_path('../../lib/git-hack', __FILE__))
4
+
5
+ GitHack::GitRepo.new(".").git_save(ARGV.first)
@@ -0,0 +1 @@
1
+ test for commit
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "git-hack/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "git-hack"
7
+ s.version = GitHack::VERSION
8
+ s.authors = ["weizhao"]
9
+ s.email = ["azhao.1981@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Facade of git. Make git easy to use.}
12
+ s.description = %q{A more smart tools of git. Come from git-smart}
13
+
14
+ s.rubyforge_project = "git-hack"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.executables = `git ls-files -- bin`.split("\n").map{|f| File.basename(f) }
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ # specify any dependencies here; for example:
23
+ # s.add_development_dependency "rspec"
24
+ # s.add_runtime_dependency "rest-client"
25
+ s.add_runtime_dependency "colorize"
26
+ s.add_runtime_dependency "git"
27
+ end
@@ -0,0 +1,27 @@
1
+ #
2
+ # ruby-git 库有一些错误,这是补丁
3
+ #
4
+
5
+
6
+ module Git
7
+ class Lib
8
+ def full_log_commits(opts = {})
9
+ arr_opts = ['--pretty=raw']
10
+ arr_opts << "-#{opts[:count]}" if opts[:count]
11
+ arr_opts << "--skip=#{opts[:skip]}" if opts[:skip]
12
+ arr_opts << "--since=#{opts[:since]}" if opts[:since].is_a? String
13
+ arr_opts << "--until=#{opts[:until]}" if opts[:until].is_a? String
14
+ arr_opts << "--grep=#{opts[:grep]}" if opts[:grep].is_a? String
15
+ arr_opts << "--author=#{opts[:author]}" if opts[:author].is_a? String
16
+ arr_opts << "#{opts[:between][0].to_s}..#{opts[:between][1].to_s}" if (opts[:between] && opts[:between].size == 2)
17
+ arr_opts << opts[:object] if opts[:object].is_a? String
18
+ arr_opts << '--' << opts[:path_limiter] if opts[:path_limiter].is_a? String
19
+ puts arr_opts.to_s_s
20
+
21
+ full_log = command_lines('log', arr_opts, true)
22
+ # modify by weizhao. commit must be specify
23
+ # putsrocess_commit_data(full_log)
24
+ process_commit_data(full_log,"commit")
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,32 @@
1
+ #
2
+ # 把文本转化成对象的Build模式
3
+ #
4
+ #
5
+ class LineBuilder
6
+ attr_accessor :data,:index,:object
7
+ def initialize(data,index=0)
8
+ @data = data
9
+ @index = index
10
+ @object = nil
11
+ end
12
+ def parse
13
+ begin
14
+ next unless in?
15
+ process_line
16
+ end until ( out? )
17
+ @object
18
+ end
19
+ # 行处理函数,必须被重写
20
+ def process_line
21
+ line = @data[@index]
22
+ @object = line
23
+ end
24
+ # 进入条件,默认直接进入
25
+ def in?
26
+ true
27
+ end
28
+ # 退出条件,默认为读完本行直接退出,重写要设置@index的新值
29
+ def out?
30
+ @index += 1
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'pathname'
3
+
4
+ module PathCommon
5
+ # 给定相对项目根目录路径,返回绝对路径
6
+ def project_file(path)
7
+ join(project_dir,path)
8
+ end
9
+ # 返回项目绝对目录
10
+ def project_dir
11
+ absolute_path("#{File.dirname(__FILE__)}/../../")
12
+ end
13
+ def absolute_path(path,dir=Dir.pwd)
14
+ Pathname.new(path).relative? ? File.expand_path(path,dir) : File.expand_path(path,"/")
15
+ end
16
+ # require file from project dir
17
+ def require_p(path)
18
+ require join(project_dir,path)
19
+ end
20
+ def join(path,file=".")
21
+ File.join(path,file)
22
+ end
23
+ end
24
+
@@ -0,0 +1,25 @@
1
+ require "git-hack/version"
2
+ Dir["#{File.dirname(__FILE__)}/**/*.rb"].each { |f| require f }
3
+ require "git"
4
+
5
+ module GitHack
6
+ def self.current
7
+ @current || get_dir('.')
8
+ end
9
+ def self.commit
10
+ current.commit
11
+ end
12
+ private
13
+ # get_dir(path) 检查给定目录是否在git受控目录中
14
+ # 本身是git目录返回 GitProject
15
+ # 本身不是,但上层是返回GitProject,并设置dir
16
+ # 本身不是,上层也不是则返回RawDir
17
+ def self.get_dir(path)
18
+ return GitRepo.new(path) if is_git(path)
19
+ return get_dir(File.join(path,"/../"))
20
+ end
21
+ def self.is_git(path)
22
+ File.directory?(File.join(path,"/.git"))
23
+ end
24
+ end
25
+
@@ -0,0 +1,11 @@
1
+
2
+ require_relative "../git-hack"
3
+
4
+
5
+ module GitHack
6
+ class Commit
7
+ attr_accessor :message,:sha
8
+ end
9
+ end
10
+
11
+
@@ -0,0 +1,35 @@
1
+
2
+ require_relative "../git-hack"
3
+
4
+
5
+ module GitHack
6
+ class CommitLineBuilder < LineBuilder
7
+ def initialize(data,index)
8
+ super(data,index)
9
+ @is_message = false
10
+ @commit = { 'masseg' => '', parent => []}
11
+ end
12
+ def process_line
13
+ @is_message
14
+ line = @data[@index]
15
+ line = line.chomp
16
+ if line = ""
17
+ @is_message = !@is_message
18
+ elsif is_message
19
+ @commit.message << line+"\n"
20
+ else
21
+ data = line.split
22
+ key = data.shift
23
+ value = data.join(" ")
24
+ if key == 'commit'
25
+ @commit['sha'] = value
26
+ end
27
+ if key == 'parent'
28
+ @commit[key] << value
29
+ else
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+
@@ -0,0 +1,98 @@
1
+ require "git"
2
+ require 'logger'
3
+ require 'colorize'
4
+ require "ap"
5
+
6
+ require_relative "../core_ext/path"
7
+
8
+ module GitHack
9
+ # GitRepo类拥有git的所有
10
+ # 包括.git文件下所有的文件的功能的@git ,GitHack::Git类
11
+ # work,即工作目录及文件 GitHack::WorkingDirectory类
12
+ # remote,对应远程库信息 GitHack::Remote类
13
+ #
14
+ class GitRepo < Git::Path
15
+ include PathCommon
16
+ attr_accessor :git,:commits,:work,:remote
17
+ def initialize(path)
18
+ @workingdirectory = get_gitdir(path)
19
+ @commits = []
20
+ end
21
+ def git
22
+ @git ||= Git.open(@workingdirectory ,:log => Logger.new(STDOUT))
23
+ end
24
+ def commits
25
+ @commits if !@commits.empty?
26
+ @commits = git.log
27
+ end
28
+ # 得到本身或是上层目录中.git文件的路经
29
+ def get_gitdir(path)
30
+ git_path = absolute_path(path)
31
+ return nil if git_path == "/"
32
+ return git_path if is_gitdir?(git_path)
33
+ return get_gitdir(join(git_path,"/../"))
34
+ end
35
+ def is_gitdir?(path)
36
+ File.directory?(join(path,".git")) ? true : false
37
+ end
38
+ # 把工作目录的文件添加到git仓库并提交
39
+ def git_save(msg,options={})
40
+ ready_to_execute
41
+ return self if not_git_directory?
42
+ add_workingdirectory
43
+ commit(msg)
44
+ execute_success
45
+ self
46
+ end
47
+ def ready_to_execute
48
+ @is_success = false
49
+ end
50
+ def execute_success
51
+ @is_success = true
52
+ end
53
+ def success?
54
+ @is_success
55
+ end
56
+ def add_workingdirectory
57
+ git.add(@workingdirectory)
58
+ end
59
+ def commit(msg)
60
+ msg ||= auto_commit_msg
61
+ begin
62
+ git.commit(msg,:add_all=>true)
63
+ rescue Git::GitExecuteError => e
64
+ puts e.to_s.colorize(:green)
65
+ end
66
+ end
67
+ def auto_commit_msg
68
+ "auto commit" # TODO: 需要完成
69
+ end
70
+ # undo 如果有修改,保存,然后回到上一次提交
71
+ def undo
72
+ git_save if working_directory_change?
73
+ checkout(1) # check_out 0.当前1.上一个.2.上上个....
74
+ end
75
+ # check out 出前第number个保存
76
+ def checkout(number,options={})
77
+ ready_to_execute
78
+ return self if not_git_directory?
79
+ puts "commits:".colorize(:red)
80
+ ap commits
81
+ git.reset(commits[1])
82
+ execute_success
83
+ self
84
+
85
+ end
86
+ def init(dir)
87
+ @git = Git.init(dir)
88
+ @workingdirectory = dir
89
+ end
90
+ def not_git_directory?
91
+ if @workingdirectory == nil
92
+ puts "Init first,run git init"
93
+ return true
94
+ end
95
+ return false
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,3 @@
1
+ module GitHack
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ describe CommitLineBuilder do
4
+ before do
5
+ g = Git.open(".")
6
+ l = Git::Lib.new(g)
7
+ opts = ["--pretty=raw"]
8
+ @data = l.command_lines('log',opts)
9
+ @linebuilder = CommitLineBuilder.new(@data,0)
10
+ @linebuilder.parse
11
+ end
12
+ specify { @data.size.should be > 1 }
13
+ specify { @linebuilder.object.should_not be nil }
14
+ end
@@ -0,0 +1,89 @@
1
+ # 测试GitRepo类
2
+ #
3
+
4
+ require "spec_helper"
5
+
6
+
7
+ describe GitRepo do
8
+ # test data
9
+ let(:dir_with_git) { project_dir }
10
+ let(:dir_under_git) { join(project_dir,"tmp_git_hack_test") }
11
+ let(:dir_no_git) { "#{ENV["HOME"]}/tmp_git_hack_test" }
12
+
13
+ describe "#get_gitdir " do
14
+ context "When given a .git directory" do
15
+ specify { GitRepo.new(dir_with_git).get_gitdir(dir_with_git).should == dir_with_git }
16
+ end
17
+ context "When given directory that parent have one .git" do
18
+ before do
19
+ @dir = dir_under_git
20
+ refresh_dir(@dir)
21
+ end
22
+ specify { GitRepo.new(@dir).get_gitdir(@dir).should == project_dir }
23
+ after { del_dir(@dir) }
24
+ end
25
+ context "When given no .git directory" do
26
+ before do
27
+ @dir = dir_no_git
28
+ refresh_dir(@dir)
29
+ end
30
+ #specify {GitRepo.new(@dir).get_gitdir(@dir).should be nil}
31
+ after { del_dir(@dir) }
32
+ end
33
+ end # end of #get_gitdir test
34
+ describe '#git_save' do
35
+ context "When given a gitworking directory " do
36
+ before do
37
+ @dir = dir_under_git
38
+ refresh_dir(@dir)
39
+ Git.init(@dir)
40
+ @gitrepo = GitRepo.new(@dir)
41
+ @gitrepo.get_gitdir(@dir)
42
+ @msg = "test commit "
43
+ end
44
+ it "Should be success " do
45
+ add_for_commit("#{@dir}/test")
46
+ @gitrepo.git_save(@msg).should be_success
47
+ # commit without change.
48
+ @gitrepo.git_save(@msg).should be_success
49
+ end
50
+ after { del_dir(@dir) }
51
+ end
52
+ context "When given a nogitworking directory" do
53
+ before do
54
+ @dir = dir_no_git
55
+ refresh_dir(@dir)
56
+ @gitrepo = GitRepo.new(@dir)
57
+ @gitrepo.get_gitdir(@dir)
58
+ end
59
+ it "Should execute false " do
60
+ @gitrepo.git_save("false test commit").should_not be_success
61
+ #expect { not raise a error any more
62
+ # @gitrepo.git_save(@dir)
63
+ #}.to raise_error(SystemExit)
64
+ end
65
+ after { del_dir(@dir) }
66
+ end
67
+ end # end of #git_save est
68
+ describe "#checkout " do
69
+ before (:each) do
70
+ @dir = dir_no_git
71
+ refresh_dir(@dir)
72
+ Git.init(@dir)
73
+ @gitrepo = GitRepo.new(@dir)
74
+ @gitrepo.get_gitdir(@dir)
75
+ end
76
+ context "When given 1,checkout to previous commitish" do
77
+ it "Should be success and no file newfile.txt" do
78
+ puts "Now begin test checkou :#{@dir}"
79
+ add_for_commit("#{@dir}/file.txt")
80
+ @gitrepo.git_save("init")
81
+ add_for_commit("#{@dir}/newfile.txt")
82
+ @gitrepo.git_save("commit second")
83
+ #@gitrepo.checkout(1).should be_success
84
+ #File.exist?("#{@dir}/newfile.txt").should be false
85
+ end
86
+ end
87
+ after { del_dir(@dir) }
88
+ end #--end of #checkout
89
+ end
@@ -0,0 +1,15 @@
1
+ require "spec_helper"
2
+
3
+ describe LineBuilder do
4
+ before do
5
+ g = Git.open(".")
6
+ l = Git::Lib.new(g)
7
+ opts = ["--pretty=raw"]
8
+ @data = l.command_lines('log',opts)
9
+ @linebuilder = LineBuilder.new(@data,0)
10
+ @linebuilder.parse
11
+ end
12
+ specify { @data.size.should be > 1 }
13
+ specify { @linebuilder.object.should_not be nil }
14
+
15
+ end
@@ -0,0 +1,22 @@
1
+ require_relative "../lib/git-hack"
2
+
3
+ include GitHack
4
+ include PathCommon
5
+ require "fileutils"
6
+ require "colorize"
7
+
8
+ # 对目录进行刷新,如果有就删除之,新建
9
+ # 没有则新建
10
+ def refresh_dir(path)
11
+ del_dir(path)
12
+ Dir.mkdir(path)
13
+ end
14
+ def del_dir(path)
15
+ FileUtils.rm_r(path,:force=>true) if File.directory?(path)
16
+ end
17
+ def add_for_commit(path)
18
+ File.open(path,"a") do |file|
19
+ file.puts "test for commit"
20
+ end
21
+ puts "Add file #{path}".colorize(:green)
22
+ end
File without changes
@@ -0,0 +1,18 @@
1
+ require 'colorize'
2
+
3
+
4
+ puts "This is blue".colorize( :blue )
5
+ puts "This is light blue".colorize( :light_blue )
6
+ puts "This is also blue".colorize( :color => :blue )
7
+ puts "This is light blue with red background".colorize( :color => :light_blue, :background => :red )
8
+ puts "This is light blue with red background".colorize( :light_blue ).colorize( :background => :red )
9
+ puts "This is blue text on red".blue.on_red
10
+ puts "This is red on blue".colorize( :red ).on_blue
11
+ puts "This is red on blue and underline".colorize( :red ).on_blue.underline
12
+ puts "This is blue text on red".blue.on_red.blink
13
+ puts "This is uncolorized".blue.on_red.uncolorize
14
+
15
+ String.colors # return array of all possible colors names
16
+ String.modes # return array of all possible modes
17
+ String.color_matrix # displays color matrix with color names
18
+ String.color_matrix( "FOO" ) # display color matrix with "FOO" text
@@ -0,0 +1,65 @@
1
+ # test Git
2
+ #
3
+ require "git"
4
+ require "ap"
5
+
6
+ g = Git.open(".")
7
+
8
+ l = Git::Lib.new(g)
9
+
10
+
11
+ class Builder
12
+
13
+ end
14
+ class LineParser
15
+
16
+ end
17
+
18
+
19
+
20
+
21
+
22
+ #l.full_log_commits
23
+ def process_commit_data(data, sha = nil, indent = 4)
24
+ in_message = false
25
+ #hsh = nil
26
+ #hsh_array = []
27
+ if sha
28
+ hsh = {'sha' => sha, 'message' => '', 'parent' => []}
29
+ else
30
+ hsh_array = []
31
+ end
32
+ data.each do |line|
33
+ line = line.chomp
34
+ if line == ''
35
+ in_message = !in_message
36
+ elsif in_message
37
+ hsh['message'] << line[indent..-1] << "\n"
38
+ else
39
+ data = line.split
40
+ key = data.shift
41
+ value = data.join(' ')
42
+ if key == 'commit'
43
+ sha = value
44
+ hsh_array << hsh if hsh
45
+ hsh = {'sha' => sha, 'message' => '', 'parent' => []}
46
+ end
47
+ if key == 'parent'
48
+ hsh[key] << value
49
+ else
50
+ hsh[key] = value
51
+ end
52
+ end
53
+ end
54
+
55
+ if hsh_array
56
+ hsh_array << hsh if hsh
57
+ hsh_array
58
+ else
59
+ hsh
60
+ end
61
+ end
62
+ data = l.command_lines('log',["--pretty=raw"])
63
+ puts "data:"
64
+ ap data
65
+ log = process_commit_data(data,"commit")
File without changes
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git-hack
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - weizhao
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: colorize
16
+ requirement: &74853510 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *74853510
25
+ - !ruby/object:Gem::Dependency
26
+ name: git
27
+ requirement: &74853280 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *74853280
36
+ description: A more smart tools of git. Come from git-smart
37
+ email:
38
+ - azhao.1981@gmail.com
39
+ executables:
40
+ - git-save
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - .gitignore
45
+ - Gemfile
46
+ - Guardfile
47
+ - README.md
48
+ - Rakefile
49
+ - bin/git-save
50
+ - commit test
51
+ - git-hack.gemspec
52
+ - lib/core_ext/git_patch.rb
53
+ - lib/core_ext/line_builder.rb
54
+ - lib/core_ext/path.rb
55
+ - lib/git-hack.rb
56
+ - lib/git-hack/commit.rb
57
+ - lib/git-hack/commit_line_builder.rb
58
+ - lib/git-hack/git_repo.rb
59
+ - lib/git-hack/version.rb
60
+ - spec/commit_line_builder_spec.rb
61
+ - spec/git_repo_spec.rb
62
+ - spec/line_builder_spec.rb
63
+ - spec/spec_helper.rb
64
+ - spec/tmp/hello_for_rspec
65
+ - tmp/colorize_example.rb
66
+ - tmp/gittest.rb
67
+ - tmp/hello_for_rspec
68
+ homepage: ''
69
+ licenses: []
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project: git-hack
88
+ rubygems_version: 1.8.15
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Facade of git. Make git easy to use.
92
+ test_files: []