git_auto_checkout 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/LICENSE.md +27 -0
- data/README.md +25 -0
- data/bin/git_auto_checkout +10 -0
- data/git_auto_checkout.gemspec +21 -0
- data/lib/git_auto_checkout/git_checkout_helper.rb +220 -0
- data/lib/git_auto_checkout/git_commit.rb +9 -0
- data/lib/git_auto_checkout.rb +17 -0
- metadata +55 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fc2d259e57441831e2508602620f44fe6389a579
|
4
|
+
data.tar.gz: 7110b85ae44612489fc2af228965d4e792771756
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0b6df09b625bbf784fde84e8ef6eedd9505dcd1d92a19840f2309f9a2ebb714e1ce93c48dc0dda573f7746ff224641423e73151901ce69da890b2945472779d1
|
7
|
+
data.tar.gz: 251532dd6b62f0ad2b28535149ec21eab3d4e04334e026dbdcd3170bc8e0944dcc85bc43058e3b58cfedf35182881e71f82753d88180efec619f0881a714e164
|
data/.gitignore
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Copyright (c) 2014, Sam Rossi
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
* Redistributions of source code must retain the above copyright notice, this
|
8
|
+
list of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
this list of conditions and the following disclaimer in the documentation
|
12
|
+
and/or other materials provided with the distribution.
|
13
|
+
|
14
|
+
* Neither the name of git_auto_checkout nor the names of its
|
15
|
+
contributors may be used to endorse or promote products derived from
|
16
|
+
this software without specific prior written permission.
|
17
|
+
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Installation
|
2
|
+
|
3
|
+
The repostory is a typical Ruby gem, so it can be installed by cloning and
|
4
|
+
locally building the .gem file. As of right now, the gem is *not* published on
|
5
|
+
rubygems.org, so `gem install git_auto_checkout` won't work. I expect to publish
|
6
|
+
it there sometime soon, but for now, folllow these steps to install:
|
7
|
+
|
8
|
+
## Prerequisites
|
9
|
+
|
10
|
+
You must have git installed on your system, as well as the "gem" command
|
11
|
+
available.
|
12
|
+
|
13
|
+
## Then run the following commands in your terminal
|
14
|
+
|
15
|
+
1. `git clone https://github.com/saghmrossi/git_auto_checkout/`
|
16
|
+
2. `cd git_auto_checkout`
|
17
|
+
3. `gem build git_auto_checkout.gemspec`
|
18
|
+
4. `gem install --local git_auto_checkout*.gem`
|
19
|
+
|
20
|
+
# Usage
|
21
|
+
|
22
|
+
Assuming your gem paths are set up properly, the gem installation makes the
|
23
|
+
"git_auto_checkout" executable available to you from anywhere. Run it in a
|
24
|
+
directory that is a git repository and follow the prompts to checkout branches
|
25
|
+
or past commits.
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$:.push File.expand_path('../lib, __FILE__')
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'git_auto_checkout'
|
5
|
+
s.version = '0.1.0'
|
6
|
+
s.license = 'BSD 3-Clause'
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ['Saghm Rossi']
|
9
|
+
s.email = ['saghmrossi@gmail.com']
|
10
|
+
s.homepage = ''
|
11
|
+
s.summary = %q{Helper to checkout out old commits.}
|
12
|
+
s.description = %q{
|
13
|
+
Gives a console-based prompt of all of the past commits,
|
14
|
+
and allows the user to select one to checkout.
|
15
|
+
}
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map do |f|
|
18
|
+
File.basename(f)
|
19
|
+
end
|
20
|
+
s.require_paths = ['lib']
|
21
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
require 'git_auto_checkout/git_commit'
|
2
|
+
|
3
|
+
module GitAutoCheckout
|
4
|
+
class GitCheckoutHelper
|
5
|
+
# Internal: Gets the Array of GitCommits.
|
6
|
+
attr_reader :commits
|
7
|
+
|
8
|
+
# Internal: Intialize a CheckoutHelper.
|
9
|
+
def initialize(page_size = 8)
|
10
|
+
@page_size = page_size
|
11
|
+
log = `git log`.split("\n")
|
12
|
+
|
13
|
+
parse_all_commits(log)
|
14
|
+
get_git_branches
|
15
|
+
end
|
16
|
+
|
17
|
+
# Internal: Prompt the user to select a past commit or quit, and checkout
|
18
|
+
# the past commit if one was selected.
|
19
|
+
#
|
20
|
+
# Returns nothing.
|
21
|
+
def make_commit
|
22
|
+
commit_or_branch = prompt_user_until_quit_or_commit_selection
|
23
|
+
return unless commit_or_branch
|
24
|
+
|
25
|
+
git_checkout(commit_or_branch)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Internal: Go through all the commits and parses out the hash strings and
|
31
|
+
# messages.
|
32
|
+
#
|
33
|
+
# log - String output of `git log`.
|
34
|
+
#
|
35
|
+
# Returns nothing (adds commits directly to instance variable.
|
36
|
+
def parse_all_commits(log)
|
37
|
+
@commits = []
|
38
|
+
@commits << parse_one_commit(log) until log.empty?
|
39
|
+
|
40
|
+
# Show commits newest to oldest.
|
41
|
+
@commits.reverse
|
42
|
+
end
|
43
|
+
|
44
|
+
# Internal: Prompts user for selection of a past commit.
|
45
|
+
#
|
46
|
+
# idx - Which commit index to start listing from.
|
47
|
+
# error - Incorrect input String previously given, or nil if there was none.
|
48
|
+
#
|
49
|
+
# Returns hash String of selected commit, or false if none was chosen.
|
50
|
+
# Raises error (through #parse_one_commit if the log String is malformed
|
51
|
+
# (e.g. each commit message is not preceded and succeeded by an empty line).
|
52
|
+
# Raises error (through #parse_commit_hash) if no commit was found.
|
53
|
+
def prompt_user_until_quit_or_commit_selection(idx = 0, error=false)
|
54
|
+
print_commit_prompt(idx, error)
|
55
|
+
|
56
|
+
selection = gets.chomp!
|
57
|
+
number = selection.to_i
|
58
|
+
selection = number if selection == '0' || number != 0
|
59
|
+
|
60
|
+
return case selection
|
61
|
+
when 'b'
|
62
|
+
prompt_user_until_quit_or_branch_selection
|
63
|
+
when 'q'
|
64
|
+
false
|
65
|
+
when 'p'
|
66
|
+
idx = [idx - @page_size, 0].max
|
67
|
+
prompt_user_until_quit_or_commit_selection(idx, false)
|
68
|
+
when 'n'
|
69
|
+
idx = [idx + @page_size, commits.size - @page_size].min
|
70
|
+
idx = [idx, 0].max
|
71
|
+
prompt_user_until_quit_or_commit_selection(idx, false)
|
72
|
+
when idx...idx + @page_size
|
73
|
+
@commits[selection.to_i].hash_string
|
74
|
+
else
|
75
|
+
selection = invalid_entry(selection)
|
76
|
+
prompt_user_until_quit_or_commit_selection(idx, selection)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Internal: Report error if there is one, and prompts user for input.
|
81
|
+
#
|
82
|
+
# idx - Which commit index to start listing from.
|
83
|
+
# error - Incorrect input String previously given, or nil if there was none.
|
84
|
+
#
|
85
|
+
# Returns nothing.
|
86
|
+
def print_commit_prompt(idx, error)
|
87
|
+
system 'clear'
|
88
|
+
|
89
|
+
puts error if error
|
90
|
+
puts 'Enter a number to checkout that commit'
|
91
|
+
puts 'Enter "b" to see a list of branches to checkout'
|
92
|
+
puts 'Enter "p" to scroll to the previous set of commits'
|
93
|
+
puts 'Enter "n" to scroll to the next set of commits'
|
94
|
+
puts 'Enter "q" to quit without checking out anything'
|
95
|
+
puts '----------------------------------------------'
|
96
|
+
|
97
|
+
@commits[idx...idx + @page_size].each_with_index do |commit, i|
|
98
|
+
puts "#{idx + i}: #{commit.message}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Internal: Remove and parse the first commit from the log and returns it
|
103
|
+
# serialized into a GitCommit.
|
104
|
+
#
|
105
|
+
# log - String output of `git log`.
|
106
|
+
#
|
107
|
+
# Returns the GitCommit parsed from the log.
|
108
|
+
# Raises error if the log String is malformed (e.g. each commit message is
|
109
|
+
# not preceded and succeeded by an empty line).
|
110
|
+
# Raises error (through #parse_commit_hash) if no commit was found.
|
111
|
+
def parse_one_commit(log)
|
112
|
+
commit, idx = parse_commit_hash(log)
|
113
|
+
log.slice!(0, idx)
|
114
|
+
|
115
|
+
log.each_with_index do |line, i|
|
116
|
+
next unless line.empty?
|
117
|
+
|
118
|
+
commit.message = log[i + 1].strip
|
119
|
+
raise 'weird message ending' if log[i + 2] && !log[i + 2].empty?
|
120
|
+
|
121
|
+
log.slice!(0, i + 2)
|
122
|
+
|
123
|
+
return commit
|
124
|
+
end
|
125
|
+
|
126
|
+
raise 'no message found'
|
127
|
+
end
|
128
|
+
|
129
|
+
# Internal: Parse the hash string of the first commt in the log.
|
130
|
+
#
|
131
|
+
# log - String output of `git log`.
|
132
|
+
#
|
133
|
+
# Returns the newly created GitCommit and the index of the first line after
|
134
|
+
# the hash String found.
|
135
|
+
# Raises error if no commit was found.
|
136
|
+
def parse_commit_hash(log)
|
137
|
+
commit = GitCommit.new
|
138
|
+
|
139
|
+
log.each_with_index do |line, i|
|
140
|
+
line = line.split
|
141
|
+
next unless line.first == 'commit'
|
142
|
+
|
143
|
+
commit.hash_string = line.last
|
144
|
+
return commit, i + 1
|
145
|
+
end
|
146
|
+
|
147
|
+
raise 'no commit found'
|
148
|
+
end
|
149
|
+
|
150
|
+
# Internal: Checkouts out a past commit specified by the hash string.
|
151
|
+
#
|
152
|
+
# commit_hash_string - String of past git commit to checkout.
|
153
|
+
#
|
154
|
+
# Returns nothing.
|
155
|
+
def git_checkout(commit_or_branch)
|
156
|
+
system 'clear'
|
157
|
+
`git checkout #{commit_or_branch}`
|
158
|
+
end
|
159
|
+
|
160
|
+
def get_git_branches
|
161
|
+
@branches = `git branch`.split("\n").reject { |branch| branch.chr == "*" }
|
162
|
+
@branches.map!(&:strip)
|
163
|
+
end
|
164
|
+
|
165
|
+
def prompt_user_until_quit_or_branch_selection(idx = 0, error=false)
|
166
|
+
if @branches.empty?
|
167
|
+
return prompt_user_until_quit_or_commit_selection(
|
168
|
+
0,
|
169
|
+
'No other branches exist'
|
170
|
+
)
|
171
|
+
end
|
172
|
+
|
173
|
+
print_branch_prompt(idx, error)
|
174
|
+
|
175
|
+
selection = gets.chomp!
|
176
|
+
number = selection.to_i
|
177
|
+
selection = number if selection == '0' || number != 0
|
178
|
+
|
179
|
+
return case selection
|
180
|
+
when 'c'
|
181
|
+
prompt_user_until_quit_or_commit_selection
|
182
|
+
when 'q'
|
183
|
+
false
|
184
|
+
when 'p'
|
185
|
+
idx = [idx - @page_size, 0].max
|
186
|
+
prompt_user_until_quit_or_branch_selection(idx, false)
|
187
|
+
when 'n'
|
188
|
+
idx = [idx + @page_size, commits.size - @page_size].min
|
189
|
+
prompt_user_until_quit_or_branch_selection(idx, false)
|
190
|
+
when idx...idx + @page_size
|
191
|
+
@branches[selection.to_i]
|
192
|
+
else
|
193
|
+
selection = invalid_entry(selection)
|
194
|
+
prompt_user_until_quit_or_branch_selection(idx, selection)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
|
199
|
+
def print_branch_prompt(idx, error)
|
200
|
+
system 'clear'
|
201
|
+
|
202
|
+
puts error if error
|
203
|
+
puts 'Enter a number to checkout that branch'
|
204
|
+
puts 'Enter "c" to see a list of commits to checkout'
|
205
|
+
puts 'Enter "p" to scroll to the previous set of commits'
|
206
|
+
puts 'Enter "n" to scroll to the next set of commits'
|
207
|
+
puts 'Enter "q" to quit without checking out anything'
|
208
|
+
puts '----------------------------------------------'
|
209
|
+
|
210
|
+
@branches[idx...idx + @page_size].each_with_index do |branch, i|
|
211
|
+
puts "#{idx + i}: #{branch}"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def invalid_entry(error)
|
216
|
+
"Invalid entry \"#{error}\"; try again"
|
217
|
+
end
|
218
|
+
end # End class
|
219
|
+
end # End module
|
220
|
+
1
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'git_auto_checkout/git_checkout_helper'
|
4
|
+
|
5
|
+
module GitAutoCheckout
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def run
|
9
|
+
if `git rev-parse --is-inside-work-tree 2>&1`.split.first == "fatal:"
|
10
|
+
$stderr.puts "Error: current directory is not a git repository"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
git_checkout_helper = GitCheckoutHelper.new
|
15
|
+
git_checkout_helper.make_commit
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: git_auto_checkout
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Saghm Rossi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-01 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: "\n Gives a console-based prompt of all of the past
|
14
|
+
commits,\n and allows the user to select one to checkout.\n
|
15
|
+
\ "
|
16
|
+
email:
|
17
|
+
- saghmrossi@gmail.com
|
18
|
+
executables:
|
19
|
+
- git_auto_checkout
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- ".gitignore"
|
24
|
+
- LICENSE.md
|
25
|
+
- README.md
|
26
|
+
- bin/git_auto_checkout
|
27
|
+
- git_auto_checkout.gemspec
|
28
|
+
- lib/git_auto_checkout.rb
|
29
|
+
- lib/git_auto_checkout/git_checkout_helper.rb
|
30
|
+
- lib/git_auto_checkout/git_commit.rb
|
31
|
+
homepage: ''
|
32
|
+
licenses:
|
33
|
+
- BSD 3-Clause
|
34
|
+
metadata: {}
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
requirements: []
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 2.4.1
|
52
|
+
signing_key:
|
53
|
+
specification_version: 4
|
54
|
+
summary: Helper to checkout out old commits.
|
55
|
+
test_files: []
|