git_cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +62 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/git_cli.gemspec +33 -0
- data/lib/git_cli.rb +220 -0
- data/lib/git_cli/add_commit.rb +147 -0
- data/lib/git_cli/branch.rb +273 -0
- data/lib/git_cli/clone.rb +42 -0
- data/lib/git_cli/delta.rb +229 -0
- data/lib/git_cli/diff.rb +88 -0
- data/lib/git_cli/git_core.rb +85 -0
- data/lib/git_cli/global.rb +33 -0
- data/lib/git_cli/ignore.rb +79 -0
- data/lib/git_cli/init.rb +65 -0
- data/lib/git_cli/log.rb +96 -0
- data/lib/git_cli/os/linux/utils.rb +62 -0
- data/lib/git_cli/os/macos/.keep +0 -0
- data/lib/git_cli/os/win/.keep +0 -0
- data/lib/git_cli/pull.rb +48 -0
- data/lib/git_cli/push.rb +76 -0
- data/lib/git_cli/repos.rb +117 -0
- data/lib/git_cli/stash.rb +224 -0
- data/lib/git_cli/tags.rb +333 -0
- data/lib/git_cli/version.rb +19 -0
- metadata +115 -0
@@ -0,0 +1,229 @@
|
|
1
|
+
# Copyright (C) 2020 Chris Liaw <chrisliaw@antrapol.com>
|
2
|
+
# Author: Chris Liaw <chrisliaw@antrapol.com>
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
module GitCli
|
20
|
+
module Delta
|
21
|
+
|
22
|
+
def status
|
23
|
+
|
24
|
+
check_vcs
|
25
|
+
|
26
|
+
cmd = []
|
27
|
+
cmd << "cd"
|
28
|
+
cmd << @wsPath
|
29
|
+
cmd << "&&"
|
30
|
+
cmd << @vcs.exe_path
|
31
|
+
cmd << "status"
|
32
|
+
|
33
|
+
cmdln = cmd.join(" ")
|
34
|
+
log_debug "Status : #{cmdln}"
|
35
|
+
res = os_exec(cmdln) do |st, res|
|
36
|
+
|
37
|
+
if st.success?
|
38
|
+
[true, res]
|
39
|
+
else
|
40
|
+
[false, res]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end # status
|
45
|
+
|
46
|
+
def modified_files
|
47
|
+
|
48
|
+
check_vcs
|
49
|
+
|
50
|
+
cmd = []
|
51
|
+
cmd << "cd"
|
52
|
+
cmd << @wsPath
|
53
|
+
cmd << "&&"
|
54
|
+
cmd << @vcs.exe_path
|
55
|
+
cmd << "diff --name-only --diff-filter=M"
|
56
|
+
|
57
|
+
cmdln = cmd.join(" ")
|
58
|
+
log_debug "Modified files : #{cmdln}"
|
59
|
+
dirs = []
|
60
|
+
files = []
|
61
|
+
res = os_exec(cmdln) do |st, res|
|
62
|
+
|
63
|
+
if st.success?
|
64
|
+
res.each_line do |l|
|
65
|
+
l.chomp!
|
66
|
+
if File.directory?(File.join(@wsPath,l))
|
67
|
+
dirs << l
|
68
|
+
else
|
69
|
+
files << l
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
[true, dirs.sort, files.sort]
|
74
|
+
else
|
75
|
+
[false, [], []]
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end # modified files
|
80
|
+
|
81
|
+
def conflicted_files
|
82
|
+
|
83
|
+
check_vcs
|
84
|
+
|
85
|
+
cmd = []
|
86
|
+
cmd << "cd"
|
87
|
+
cmd << @wsPath
|
88
|
+
cmd << "&&"
|
89
|
+
cmd << @vcs.exe_path
|
90
|
+
cmd << "diff --name-only --diff-filter=U"
|
91
|
+
|
92
|
+
cmdln = cmd.join(" ")
|
93
|
+
log_debug "Conflicted files : #{cmdln}"
|
94
|
+
dirs = []
|
95
|
+
files = []
|
96
|
+
res = os_exec(cmdln) do |st, res|
|
97
|
+
|
98
|
+
if st.success?
|
99
|
+
res.each_line do |l|
|
100
|
+
l.chomp!
|
101
|
+
if File.directory?(File.join(@wsPath,l))
|
102
|
+
dirs << l
|
103
|
+
else
|
104
|
+
files << l
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
[true, dirs.sort, files.sort]
|
109
|
+
else
|
110
|
+
[false, [], []]
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end # conflicted files
|
115
|
+
|
116
|
+
def new_files
|
117
|
+
|
118
|
+
check_vcs
|
119
|
+
|
120
|
+
cmd = []
|
121
|
+
cmd << "cd"
|
122
|
+
cmd << @wsPath
|
123
|
+
cmd << "&&"
|
124
|
+
cmd << @vcs.exe_path
|
125
|
+
cmd << "ls-files --others --exclude-standard --directory"
|
126
|
+
|
127
|
+
cmdln = cmd.join(" ")
|
128
|
+
log_debug "New Files : #{cmdln}"
|
129
|
+
dirs = []
|
130
|
+
files = []
|
131
|
+
res = os_exec(cmdln) do |st, res|
|
132
|
+
|
133
|
+
if st.success?
|
134
|
+
res.each_line do |l|
|
135
|
+
l.chomp!
|
136
|
+
if File.directory?(File.join(@wsPath,l))
|
137
|
+
dirs << l
|
138
|
+
else
|
139
|
+
files << l
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
[true, dirs.sort, files.sort]
|
144
|
+
else
|
145
|
+
[false, [], []]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end # new_files
|
150
|
+
|
151
|
+
def deleted_files
|
152
|
+
|
153
|
+
check_vcs
|
154
|
+
|
155
|
+
cmd = []
|
156
|
+
cmd << "cd"
|
157
|
+
cmd << @wsPath
|
158
|
+
cmd << "&&"
|
159
|
+
cmd << @vcs.exe_path
|
160
|
+
cmd << "ls-files -d"
|
161
|
+
|
162
|
+
cmdln = cmd.join(" ")
|
163
|
+
log_debug "Deleted files : #{cmdln}"
|
164
|
+
dirs = []
|
165
|
+
files = []
|
166
|
+
res = os_exec(cmdln) do |st, res|
|
167
|
+
|
168
|
+
if st.success?
|
169
|
+
res.each_line do |l|
|
170
|
+
l.chomp!
|
171
|
+
if File.directory?(File.join(@wsPath,l))
|
172
|
+
dirs << l
|
173
|
+
else
|
174
|
+
files << l
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
[true, dirs.sort, files.sort]
|
179
|
+
else
|
180
|
+
[false, [], []]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
end # deleted_files
|
185
|
+
|
186
|
+
def reset_file_changes(path)
|
187
|
+
|
188
|
+
raise_if_empty(path, "Path cannot be empty for reset file changes operation", GitCliException)
|
189
|
+
|
190
|
+
check_vcs
|
191
|
+
|
192
|
+
cmd = []
|
193
|
+
cmd << "cd"
|
194
|
+
cmd << @wsPath
|
195
|
+
cmd << "&&"
|
196
|
+
cmd << @vcs.exe_path
|
197
|
+
cmd << "checkout --"
|
198
|
+
cmd << path
|
199
|
+
|
200
|
+
cmdln = cmd.join(" ")
|
201
|
+
log_debug "Reset file changes local changes (given file permanent) : #{cmdln}"
|
202
|
+
res = os_exec(cmdln) do |st, res|
|
203
|
+
[st.success?, res]
|
204
|
+
end
|
205
|
+
|
206
|
+
end # reset file changes
|
207
|
+
|
208
|
+
def reset_all_changes
|
209
|
+
|
210
|
+
check_vcs
|
211
|
+
|
212
|
+
cmd = []
|
213
|
+
cmd << "cd"
|
214
|
+
cmd << @wsPath
|
215
|
+
cmd << "&&"
|
216
|
+
cmd << @vcs.exe_path
|
217
|
+
cmd << "reset --hard"
|
218
|
+
|
219
|
+
cmdln = cmd.join(" ")
|
220
|
+
log_debug "Reset all local changes (permanent) : #{cmdln}"
|
221
|
+
res = os_exec(cmdln) do |st, res|
|
222
|
+
[st.success?, res]
|
223
|
+
end
|
224
|
+
|
225
|
+
end # reset all changes
|
226
|
+
|
227
|
+
|
228
|
+
end
|
229
|
+
end
|
data/lib/git_cli/diff.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# Copyright (C) 2020 Chris Liaw <chrisliaw@antrapol.com>
|
2
|
+
# Author: Chris Liaw <chrisliaw@antrapol.com>
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
module GitCli
|
20
|
+
module Diff
|
21
|
+
|
22
|
+
def diff
|
23
|
+
diff_branch("","")
|
24
|
+
end
|
25
|
+
|
26
|
+
def diff_file_with_last_commit(file)
|
27
|
+
|
28
|
+
diff_common({ args: "#{file}", log_tag: "Diff file compare with last commit" })
|
29
|
+
|
30
|
+
end # diff_file_with_last_commit
|
31
|
+
alias :diff_file :diff_file_with_last_commit
|
32
|
+
|
33
|
+
# head_to_head = true == "git diff b1..b2" -> compare head-to-head of the given two branches
|
34
|
+
def diff_branch(b1, b2, opts = { head_to_head: true })
|
35
|
+
|
36
|
+
if not ((b1.nil? or b1.empty?) and (b2.nil? or b2.empty?))
|
37
|
+
diff_common({ args: "#{b1}..#{b2}", log_tag: "Diff against head of two branches" })
|
38
|
+
else
|
39
|
+
diff_common({ args: "", log_tag: "Diff workspace with last commit" })
|
40
|
+
end
|
41
|
+
|
42
|
+
end # diff_branch
|
43
|
+
|
44
|
+
# changes to push to repos if 'git commit -a' is run
|
45
|
+
def diff_working_with_last_commit
|
46
|
+
|
47
|
+
diff_common({ args: "HEAD^ HEAD", log_tag: "Diff working with last commit" })
|
48
|
+
|
49
|
+
end # diff_working_with_last_commit
|
50
|
+
|
51
|
+
# this show different for item already put inside 'git add'
|
52
|
+
def diff_index_with_last_commit
|
53
|
+
|
54
|
+
diff_common({ args: "--cached", log_tag: "Diff index (file added with 'git add') with last commit" })
|
55
|
+
|
56
|
+
end # diff_index_with_last_commit
|
57
|
+
|
58
|
+
def diff_common(opts = { })
|
59
|
+
|
60
|
+
check_vcs
|
61
|
+
|
62
|
+
cmd = []
|
63
|
+
cmd << "cd"
|
64
|
+
cmd << @wsPath
|
65
|
+
cmd << "&&"
|
66
|
+
cmd << @vcs.exe_path
|
67
|
+
cmd << "diff"
|
68
|
+
|
69
|
+
if not (opts[:args].nil? or opts[:args].empty?)
|
70
|
+
cmd << opts[:args]
|
71
|
+
end
|
72
|
+
|
73
|
+
cmdln = cmd.join(" ")
|
74
|
+
log_debug "#{opts[:log_tag]} : #{cmdln} "
|
75
|
+
|
76
|
+
res = os_exec(cmdln) do |st, res|
|
77
|
+
|
78
|
+
if st.success?
|
79
|
+
[true, res.strip!]
|
80
|
+
else
|
81
|
+
[false, res]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Copyright (C) 2020 Chris Liaw <chrisliaw@antrapol.com>
|
2
|
+
# Author: Chris Liaw <chrisliaw@antrapol.com>
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
|
18
|
+
require_relative 'global'
|
19
|
+
|
20
|
+
module GitCli
|
21
|
+
module GitCore
|
22
|
+
|
23
|
+
include Antrapol::ToolRack::ConditionUtils
|
24
|
+
#extend Antrapol::ToolRack::ConditionUtils
|
25
|
+
|
26
|
+
def exe_path
|
27
|
+
if @gitPath.nil? or @gitPath.empty?
|
28
|
+
st, path = is_installed?
|
29
|
+
@gitPath = path.strip if st
|
30
|
+
end
|
31
|
+
|
32
|
+
@gitPath
|
33
|
+
end # exe_path
|
34
|
+
|
35
|
+
def version
|
36
|
+
|
37
|
+
if @version.nil? or @version.empty?
|
38
|
+
path = exe_path
|
39
|
+
cmd = "#{path} version"
|
40
|
+
log_debug "version : #{cmd}"
|
41
|
+
os_exec(cmd) do |st, res|
|
42
|
+
# as current dev version
|
43
|
+
if st.success?
|
44
|
+
res.strip!
|
45
|
+
# based on version 2.25.1
|
46
|
+
@version = res.split(" ")[-1]
|
47
|
+
[true,@version]
|
48
|
+
else
|
49
|
+
[false,""]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
else
|
53
|
+
[true, @version]
|
54
|
+
end
|
55
|
+
|
56
|
+
end # version
|
57
|
+
|
58
|
+
private
|
59
|
+
def is_installed?
|
60
|
+
|
61
|
+
if Antrapol::ToolRack::RuntimeUtils.on_linux?
|
62
|
+
require_relative 'os/linux/utils'
|
63
|
+
GitCli::Global.instance.logger.debug "Running on Linux is detected"
|
64
|
+
st, path = GitCli::OS::Linux::Utils.is_installed?("git")
|
65
|
+
GitCli::Global.instance.logger.debug "'git' install check return [#{st},#{path}]"
|
66
|
+
|
67
|
+
[st, path]
|
68
|
+
|
69
|
+
elsif Antrapol::ToolRack::RuntimeUtils.on_mac?
|
70
|
+
GitCli::Global.instance.logger.debug "Running on MacOS is detected"
|
71
|
+
require_relative 'os/macos/utils'
|
72
|
+
|
73
|
+
elsif Antrapol::ToolRack::RuntimeUtils.on_window?
|
74
|
+
GitCli::Global.instance.logger.debug "Running on MS Window is detected"
|
75
|
+
require_relative 'os/win/utils'
|
76
|
+
|
77
|
+
else
|
78
|
+
GitCli::Global.instance.logger.debug "Cannot determine which OS am i running...Confused"
|
79
|
+
raise RuntimeError, "Unknown platform"
|
80
|
+
end
|
81
|
+
|
82
|
+
end # is_installed?
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Copyright (C) 2020 Chris Liaw <chrisliaw@antrapol.com>
|
2
|
+
# Author: Chris Liaw <chrisliaw@antrapol.com>
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
|
18
|
+
require 'tlogger'
|
19
|
+
require 'singleton'
|
20
|
+
|
21
|
+
module GitCli
|
22
|
+
class Global
|
23
|
+
include Singleton
|
24
|
+
|
25
|
+
attr_reader :logger
|
26
|
+
def initialize
|
27
|
+
@logger = Tlogger.new
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class GitCliException < StandardError; end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Copyright (C) 2020 Chris Liaw <chrisliaw@antrapol.com>
|
2
|
+
# Author: Chris Liaw <chrisliaw@antrapol.com>
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
module GitCli
|
20
|
+
module Ignore
|
21
|
+
|
22
|
+
def ignore(val)
|
23
|
+
with_ignore_file do |f|
|
24
|
+
f.puts val
|
25
|
+
end
|
26
|
+
log_debug ".gitignore file updated with line '#{val}'"
|
27
|
+
[true,".gitignore file updated"]
|
28
|
+
end
|
29
|
+
|
30
|
+
def ignore_rules
|
31
|
+
st, root = workspace_root
|
32
|
+
root.strip!
|
33
|
+
if st
|
34
|
+
rulesFile = File.join(root,".gitignore")
|
35
|
+
if File.exist?(rulesFile)
|
36
|
+
File.open(rulesFile,"r") do |f|
|
37
|
+
@cont = f.read
|
38
|
+
end
|
39
|
+
@cont
|
40
|
+
else
|
41
|
+
""
|
42
|
+
end
|
43
|
+
else
|
44
|
+
""
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def update_ignore_rules(rules)
|
49
|
+
st, root = workspace_root
|
50
|
+
root.strip!
|
51
|
+
if st
|
52
|
+
rulesFile = File.join(root,".gitignore")
|
53
|
+
File.open(rulesFile,"w") do |f|
|
54
|
+
f.write rules
|
55
|
+
end
|
56
|
+
end
|
57
|
+
log_debug ".gitignore files is updated!"
|
58
|
+
[true,".gitignore file is updated"]
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def with_ignore_file(&block)
|
63
|
+
if block
|
64
|
+
st, root = workspace_root
|
65
|
+
root.strip!
|
66
|
+
if st
|
67
|
+
igPath = File.join(root,".gitignore")
|
68
|
+
FileUtils.touch(igPath) if not File.exist?(igPath)
|
69
|
+
File.open(igPath,"a") do |f|
|
70
|
+
block.call(f)
|
71
|
+
end
|
72
|
+
else
|
73
|
+
raise GitCliException, "Cannot get workspace root. Probably not a GIT workspace?"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|