git-hack 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/git-goto +5 -0
- data/bin/git-redo +5 -0
- data/bin/git-undo +5 -0
- data/lib/core_ext/git_patch.rb +3 -0
- data/lib/core_ext/line_builder.rb +25 -2
- data/lib/git-hack.rb +1 -1
- data/lib/git-hack/commit_line_builder.rb +32 -11
- data/lib/git-hack/git_repo.rb +55 -12
- data/lib/git-hack/simple_line_builder.rb +19 -0
- data/lib/git-hack/version.rb +1 -1
- data/spec/commit_line_builder_spec.rb +38 -1
- data/spec/git_repo_spec.rb +56 -9
- data/spec/line_builder_spec.rb +36 -1
- data/tmp/classtest.rb +16 -0
- data/tmp/cli.rb +3 -0
- data/tmp/cli2.rb +3 -0
- data/tmp/coretest.rb +8 -0
- data/tmp/hello +1 -0
- metadata +18 -6
data/bin/git-goto
ADDED
data/bin/git-redo
ADDED
data/bin/git-undo
ADDED
data/lib/core_ext/git_patch.rb
CHANGED
@@ -8,13 +8,16 @@ class LineBuilder
|
|
8
8
|
@data = data
|
9
9
|
@index = index
|
10
10
|
@object = nil
|
11
|
+
@is_parse = false
|
11
12
|
end
|
12
13
|
def parse
|
14
|
+
@is_parse = true
|
15
|
+
return nil if is_over?
|
13
16
|
begin
|
14
17
|
next unless in?
|
15
18
|
process_line
|
16
|
-
end until (
|
17
|
-
|
19
|
+
end until ( out? || is_over?)
|
20
|
+
self
|
18
21
|
end
|
19
22
|
# 行处理函数,必须被重写
|
20
23
|
def process_line
|
@@ -29,4 +32,24 @@ class LineBuilder
|
|
29
32
|
def out?
|
30
33
|
@index += 1
|
31
34
|
end
|
35
|
+
# 是否数据结构
|
36
|
+
def is_over?
|
37
|
+
@index >= @data.size
|
38
|
+
end
|
39
|
+
def get_next
|
40
|
+
return nil if is_over?
|
41
|
+
return self.class.new(@data,@index).parse
|
42
|
+
end
|
43
|
+
# 得出剩下的
|
44
|
+
def rest
|
45
|
+
return [] if is_over?
|
46
|
+
next_b = get_next
|
47
|
+
return [next_b] + ( next_b.is_over? ? [] : next_b.rest)
|
48
|
+
end
|
49
|
+
# 找出全部的
|
50
|
+
def find_all
|
51
|
+
return [] if is_over? && @object == nil
|
52
|
+
parse unless @is_parse
|
53
|
+
[self] + rest
|
54
|
+
end
|
32
55
|
end
|
data/lib/git-hack.rb
CHANGED
@@ -1,34 +1,55 @@
|
|
1
1
|
|
2
2
|
require_relative "../core_ext/line_builder"
|
3
|
+
class String
|
4
|
+
def uncolorize
|
5
|
+
self.gsub(/\e\[(\d+)*m/,"")
|
6
|
+
end
|
7
|
+
end
|
3
8
|
|
4
9
|
|
5
10
|
module GitHack
|
6
11
|
class CommitLineBuilder < LineBuilder
|
12
|
+
attr_accessor :commit
|
7
13
|
def initialize(data,index)
|
8
14
|
super(data,index)
|
9
15
|
@is_message = false
|
10
|
-
@commit = { '
|
16
|
+
@commit = { 'sha'=>nil, 'message' => '', 'parent' => [] }
|
17
|
+
@is_next_commit = false
|
11
18
|
end
|
12
19
|
def process_line
|
13
20
|
@is_message
|
14
21
|
line = @data[@index]
|
15
|
-
line = line.chomp
|
22
|
+
line = line.chomp.uncolorize
|
16
23
|
if line == ""
|
17
24
|
@is_message = !@is_message
|
18
|
-
elsif is_message
|
19
|
-
@commit
|
25
|
+
elsif @is_message
|
26
|
+
@commit['message'] << line+"\n"
|
20
27
|
else
|
21
28
|
data = line.split
|
22
|
-
key = data.shift
|
23
|
-
value = data.join(" ")
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
@key = key = data.shift
|
30
|
+
@value = data.join(" ")
|
31
|
+
|
32
|
+
if @key == "commit"
|
33
|
+
if @commit['sha']
|
34
|
+
@is_next_commit = true
|
35
|
+
else
|
36
|
+
@commit['sha'] = @value
|
37
|
+
end
|
38
|
+
elsif @key == 'parent'
|
39
|
+
@commit[@key] << @value
|
29
40
|
else
|
41
|
+
@commit[@key] = @value
|
30
42
|
end
|
31
43
|
end
|
44
|
+
@object = @commit
|
45
|
+
end
|
46
|
+
def out?
|
47
|
+
if @is_next_commit
|
48
|
+
return true
|
49
|
+
else
|
50
|
+
@index += 1
|
51
|
+
return false
|
52
|
+
end
|
32
53
|
end
|
33
54
|
end
|
34
55
|
end
|
data/lib/git-hack/git_repo.rb
CHANGED
@@ -13,7 +13,7 @@ module GitHack
|
|
13
13
|
#
|
14
14
|
class GitRepo < Git::Path
|
15
15
|
include PathCommon
|
16
|
-
attr_accessor :git,:commits,:work,:remote
|
16
|
+
attr_accessor :git,:commits,:work,:remote,:current_commit
|
17
17
|
def initialize(path)
|
18
18
|
@workingdirectory = get_gitdir(path)
|
19
19
|
@commits = []
|
@@ -22,8 +22,11 @@ module GitHack
|
|
22
22
|
@git ||= Git.open(@workingdirectory ,:log => Logger.new(STDOUT))
|
23
23
|
end
|
24
24
|
def commits
|
25
|
-
@commits if !@commits.empty?
|
26
|
-
|
25
|
+
return @commits if !@commits.empty?
|
26
|
+
l = Git::Lib.new(git)
|
27
|
+
opts = ["--pretty=raw"]
|
28
|
+
@data = l.command_lines_patch('log',opts)
|
29
|
+
return @commits = CommitLineBuilder.new(@data,0).find_all
|
27
30
|
end
|
28
31
|
# 得到本身或是上层目录中.git文件的路经
|
29
32
|
def get_gitdir(path)
|
@@ -67,32 +70,72 @@ module GitHack
|
|
67
70
|
def auto_commit_msg
|
68
71
|
"auto commit" # TODO: 需要完成
|
69
72
|
end
|
70
|
-
# undo
|
73
|
+
# undo 回到上一次提交
|
71
74
|
def undo
|
72
|
-
|
73
|
-
checkout(1) # check_out 0.当前1.上一个.2.上上个....
|
75
|
+
git_goto(1)
|
74
76
|
end
|
75
|
-
#
|
76
|
-
def
|
77
|
+
# redo 到当前提交的下一个提交
|
78
|
+
def redo
|
77
79
|
ready_to_execute
|
78
80
|
return self if not_git_directory?
|
79
|
-
|
80
|
-
|
81
|
-
git.
|
81
|
+
next_commit = get_next_commit
|
82
|
+
return self if !next_commit
|
83
|
+
git.reset_hard(next_commit)
|
82
84
|
execute_success
|
83
85
|
self
|
86
|
+
end
|
87
|
+
def git_goto(number,options={})
|
88
|
+
number = number.to_i
|
89
|
+
goto(number,options)
|
84
90
|
|
85
91
|
end
|
92
|
+
# 回到前第number个保存
|
93
|
+
#
|
94
|
+
def goto(number,options={})
|
95
|
+
ready_to_execute
|
96
|
+
return self if not_git_directory?
|
97
|
+
git.reset_hard(commits[number].commit['sha'])
|
98
|
+
execute_success
|
99
|
+
self
|
100
|
+
end
|
86
101
|
def init(dir)
|
87
102
|
@git = Git.init(dir)
|
88
103
|
@workingdirectory = dir
|
89
104
|
end
|
90
105
|
def not_git_directory?
|
91
106
|
if @workingdirectory == nil
|
92
|
-
puts "
|
107
|
+
puts "Not a git directory ,run `git init` first"
|
93
108
|
return true
|
94
109
|
end
|
95
110
|
return false
|
96
111
|
end
|
112
|
+
def get_next_commit
|
113
|
+
file = File.open("#{@workingdirectory}/.git/logs/HEAD")
|
114
|
+
data = []
|
115
|
+
file.each { |line|
|
116
|
+
data << line
|
117
|
+
}
|
118
|
+
commit_data = SimpleLineBuilder.new(data,0).find_all
|
119
|
+
commit = commit_data.find do |c|
|
120
|
+
c.object == current_commit
|
121
|
+
end
|
122
|
+
commit_sha = commit ? commit.value : nil
|
123
|
+
end
|
124
|
+
def current_commit
|
125
|
+
@current_commit if @current_commit
|
126
|
+
data = data_from_file("#{@workingdirectory}/.git/HEAD")
|
127
|
+
commit_file_data = SimpleLineBuilder.new(data,0).parse
|
128
|
+
commit_file = commit_file_data.value
|
129
|
+
@current_commit = data_from_file("#{@workingdirectory}/.git/#{commit_file}")
|
130
|
+
@current_commit = @current_commit[0].chomp
|
131
|
+
end
|
132
|
+
def data_from_file(path)
|
133
|
+
file = File.open(path)
|
134
|
+
data = []
|
135
|
+
file.each { |line|
|
136
|
+
data << line
|
137
|
+
}
|
138
|
+
data
|
139
|
+
end
|
97
140
|
end
|
98
141
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
require_relative "../core_ext/line_builder"
|
3
|
+
|
4
|
+
module GitHack
|
5
|
+
class SimpleLineBuilder < LineBuilder
|
6
|
+
attr_accessor :value
|
7
|
+
def initialize(data,index)
|
8
|
+
super(data,index)
|
9
|
+
end
|
10
|
+
def process_line
|
11
|
+
line = @data[@index]
|
12
|
+
line = line.chomp.split
|
13
|
+
@object = line.shift
|
14
|
+
@value = line.shift
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
data/lib/git-hack/version.rb
CHANGED
@@ -5,10 +5,47 @@ describe CommitLineBuilder do
|
|
5
5
|
g = Git.open(".")
|
6
6
|
l = Git::Lib.new(g)
|
7
7
|
opts = ["--pretty=raw"]
|
8
|
-
@data = l.
|
8
|
+
@data = l.command_lines_patch('log',opts)
|
9
9
|
@linebuilder = CommitLineBuilder.new(@data,0)
|
10
10
|
@linebuilder.parse
|
11
11
|
end
|
12
12
|
specify { @data.size.should be > 1 }
|
13
13
|
specify { @linebuilder.object.should_not be nil }
|
14
|
+
specify { @linebuilder.is_over?.should_not be true }
|
15
|
+
specify { @linebuilder.get_next.should_not be nil }
|
16
|
+
specify { @linebuilder.rest.size.should be > 0 }
|
17
|
+
specify { @linebuilder.find_all.size.should be > 0 }
|
18
|
+
it "Show Some data" do
|
19
|
+
puts @linebuilder.index
|
20
|
+
puts @data.size
|
21
|
+
puts "find_all.size: #{@linebuilder.find_all.size}"
|
22
|
+
|
23
|
+
end
|
24
|
+
context "When come to the last " do
|
25
|
+
before do
|
26
|
+
@last = CommitLineBuilder.new(@data,@data.size-1)
|
27
|
+
@last.parse
|
28
|
+
end
|
29
|
+
specify { @last.should be_is_over }
|
30
|
+
|
31
|
+
specify { @last.get_next.should be nil }
|
32
|
+
specify { @last.rest.size.should be 0 }
|
33
|
+
specify { @last.find_all.size.should be 1 }
|
34
|
+
end
|
35
|
+
context "When is over" do
|
36
|
+
before do
|
37
|
+
@over = CommitLineBuilder.new(@data,@data.size)
|
38
|
+
@over.parse
|
39
|
+
end
|
40
|
+
specify { @over.should be_is_over }
|
41
|
+
|
42
|
+
specify { @over.get_next.should be nil }
|
43
|
+
specify { @over.rest.size.should be 0 }
|
44
|
+
specify { @over.find_all.size.should be 0 }
|
45
|
+
it "Show Find_all" do
|
46
|
+
# puts "lash find_all"
|
47
|
+
# ap @over.find_all
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
14
51
|
end
|
data/spec/git_repo_spec.rb
CHANGED
@@ -65,25 +65,72 @@ describe GitRepo do
|
|
65
65
|
after { del_dir(@dir) }
|
66
66
|
end
|
67
67
|
end # end of #git_save est
|
68
|
-
describe "#
|
68
|
+
describe "#goto " do
|
69
69
|
before (:each) do
|
70
70
|
@dir = dir_no_git
|
71
71
|
refresh_dir(@dir)
|
72
72
|
Git.init(@dir)
|
73
73
|
@gitrepo = GitRepo.new(@dir)
|
74
74
|
@gitrepo.get_gitdir(@dir)
|
75
|
+
add_for_commit("#{@dir}/file.txt")
|
76
|
+
@gitrepo.git_save("init")
|
77
|
+
add_for_commit("#{@dir}/newfile.txt")
|
78
|
+
@gitrepo.git_save("commit second")
|
75
79
|
end
|
76
|
-
context "When given 1
|
80
|
+
context "When given 1" do
|
77
81
|
it "Should be success and no file newfile.txt" do
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
@gitrepo.
|
83
|
-
|
84
|
-
|
82
|
+
@gitrepo.goto(1).should be_success
|
83
|
+
File.exist?("#{@dir}/newfile.txt").should be false
|
84
|
+
end
|
85
|
+
it "Should still get 2 commit" do
|
86
|
+
@gitrepo.commits.size.should == 2
|
87
|
+
@gitrepo.goto(1).should be_success
|
88
|
+
@gitrepo.commits.size.should == 2
|
89
|
+
@gitrepo.goto(0).should be_success
|
90
|
+
File.exist?("#{@dir}/newfile.txt").should be true
|
91
|
+
end
|
92
|
+
end
|
93
|
+
context "When given 2," do
|
94
|
+
it "Should goto the last commit" do
|
95
|
+
@gitrepo.goto(1).should be_success
|
96
|
+
File.exist?("#{@dir}/newfile.txt").should be false
|
97
|
+
@g = GitRepo.new(@dir)
|
98
|
+
@g.get_gitdir(@dir)
|
99
|
+
@gitrepo.goto(0).should be_success
|
100
|
+
File.exist?("#{@dir}/newfile.txt").should be true
|
85
101
|
end
|
86
102
|
end
|
87
103
|
after { del_dir(@dir) }
|
88
104
|
end #--end of #checkout
|
105
|
+
describe "#redo" do
|
106
|
+
before (:each) do
|
107
|
+
@dir = dir_no_git
|
108
|
+
refresh_dir(@dir)
|
109
|
+
Git.init(@dir)
|
110
|
+
@gitrepo = GitRepo.new(@dir)
|
111
|
+
@gitrepo.get_gitdir(@dir)
|
112
|
+
add_for_commit("#{@dir}/file.txt")
|
113
|
+
@gitrepo.git_save("init")
|
114
|
+
add_for_commit("#{@dir}/newfile.txt")
|
115
|
+
@gitrepo.git_save("commit second")
|
116
|
+
end
|
117
|
+
context "When no undo" do
|
118
|
+
it "Should be failed" do
|
119
|
+
@gitrepo.redo.should_not be_success
|
120
|
+
end
|
121
|
+
end
|
122
|
+
context "When undo first" do
|
123
|
+
it "Should be success" do
|
124
|
+
File.exist?("#{@dir}/newfile.txt").should be true
|
125
|
+
@gitrepo.undo
|
126
|
+
File.exist?("#{@dir}/newfile.txt").should be false
|
127
|
+
@g = GitRepo.new(@dir)
|
128
|
+
@g.get_gitdir(@dir)
|
129
|
+
@g.redo.should be_success
|
130
|
+
File.exist?("#{@dir}/newfile.txt").should be true
|
131
|
+
end
|
132
|
+
end
|
133
|
+
after{ del_dir(@dir) }
|
134
|
+
end
|
135
|
+
|
89
136
|
end
|
data/spec/line_builder_spec.rb
CHANGED
@@ -4,12 +4,47 @@ describe LineBuilder do
|
|
4
4
|
before do
|
5
5
|
g = Git.open(".")
|
6
6
|
l = Git::Lib.new(g)
|
7
|
+
@lib = l
|
7
8
|
opts = ["--pretty=raw"]
|
8
|
-
@data = l.
|
9
|
+
@data = l.command_lines_patch('log',opts)
|
9
10
|
@linebuilder = LineBuilder.new(@data,0)
|
10
11
|
@linebuilder.parse
|
11
12
|
end
|
12
13
|
specify { @data.size.should be > 1 }
|
13
14
|
specify { @linebuilder.object.should_not be nil }
|
15
|
+
specify { @linebuilder.is_over?.should_not be true }
|
16
|
+
specify { @linebuilder.get_next.should_not be nil }
|
17
|
+
specify { @linebuilder.rest.size.should be > 0 }
|
18
|
+
specify { @linebuilder.find_all.size.should be > 0 }
|
19
|
+
it "Show Some data" do
|
20
|
+
puts @linebuilder.index
|
21
|
+
puts @data.size
|
22
|
+
|
23
|
+
end
|
24
|
+
context "When is come to the last" do
|
25
|
+
before do
|
26
|
+
@last = LineBuilder.new(@data,@data.size-1)
|
27
|
+
@last.parse
|
28
|
+
end
|
29
|
+
specify { @last.should be_is_over }
|
30
|
+
|
31
|
+
specify { @last.get_next.should be nil }
|
32
|
+
specify { @last.rest.size.should be 0 }
|
33
|
+
specify { @last.find_all.size.should be 1 }
|
34
|
+
end
|
35
|
+
context "When is over" do
|
36
|
+
before do
|
37
|
+
@over = LineBuilder.new(@data,@data.size)
|
38
|
+
@over.parse
|
39
|
+
end
|
40
|
+
specify { @over.should be_is_over }
|
14
41
|
|
42
|
+
specify { @over.get_next.should be nil }
|
43
|
+
specify { @over.rest.size.should be 0 }
|
44
|
+
specify { @over.find_all.size.should be 0 }
|
45
|
+
it "Show Find_all" do
|
46
|
+
# puts "lash find_all"
|
47
|
+
# ap @over.find_all
|
48
|
+
end
|
49
|
+
end
|
15
50
|
end
|
data/tmp/classtest.rb
ADDED
data/tmp/cli.rb
ADDED
data/tmp/cli2.rb
ADDED
data/tmp/coretest.rb
ADDED
data/tmp/hello
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
dlfdfld
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-hack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: colorize
|
16
|
-
requirement: &
|
16
|
+
requirement: &22140160 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *22140160
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: git
|
27
|
-
requirement: &
|
27
|
+
requirement: &22139340 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,12 +32,15 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *22139340
|
36
36
|
description: A more smart tools of git. Come from git-smart
|
37
37
|
email:
|
38
38
|
- azhao.1981@gmail.com
|
39
39
|
executables:
|
40
|
+
- git-goto
|
41
|
+
- git-redo
|
40
42
|
- git-save
|
43
|
+
- git-undo
|
41
44
|
extensions: []
|
42
45
|
extra_rdoc_files: []
|
43
46
|
files:
|
@@ -46,7 +49,10 @@ files:
|
|
46
49
|
- Guardfile
|
47
50
|
- README.md
|
48
51
|
- Rakefile
|
52
|
+
- bin/git-goto
|
53
|
+
- bin/git-redo
|
49
54
|
- bin/git-save
|
55
|
+
- bin/git-undo
|
50
56
|
- commit test
|
51
57
|
- git-hack.gemspec
|
52
58
|
- lib/core_ext/git_patch.rb
|
@@ -56,14 +62,20 @@ files:
|
|
56
62
|
- lib/git-hack/commit.rb
|
57
63
|
- lib/git-hack/commit_line_builder.rb
|
58
64
|
- lib/git-hack/git_repo.rb
|
65
|
+
- lib/git-hack/simple_line_builder.rb
|
59
66
|
- lib/git-hack/version.rb
|
60
67
|
- spec/commit_line_builder_spec.rb
|
61
68
|
- spec/git_repo_spec.rb
|
62
69
|
- spec/line_builder_spec.rb
|
63
70
|
- spec/spec_helper.rb
|
64
71
|
- spec/tmp/hello_for_rspec
|
72
|
+
- tmp/classtest.rb
|
73
|
+
- tmp/cli.rb
|
74
|
+
- tmp/cli2.rb
|
65
75
|
- tmp/colorize_example.rb
|
76
|
+
- tmp/coretest.rb
|
66
77
|
- tmp/gittest.rb
|
78
|
+
- tmp/hello
|
67
79
|
- tmp/hello_for_rspec
|
68
80
|
homepage: ''
|
69
81
|
licenses: []
|