tbgit 1.0.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 +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +60 -0
- data/Rakefile +2 -0
- data/bin/tbgit +46 -0
- data/lib/tbgit/version.rb +3 -0
- data/lib/tbgit.rb +240 -0
- data/tbgit.gemspec +23 -0
- metadata +83 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 79c2967cde856714bce60cf664f8be7adc3e7812
|
4
|
+
data.tar.gz: b566769fe5d56253d6592c84675fa535bc2772ca
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d85851c9450b364b65c35dc0428f28a83e4f493835796ad076bad72220340b2496eb731cbe0640ff378bd3fa87bef8c9b5e2b3d184d718f28a6eb0be53f9d3ba
|
7
|
+
data.tar.gz: 6295061e28c79499a9aa8510f769479671eda32b2a08aaaccd20246da276f1fdbeb43edc92b9c1dc128235a85b5e778c5107ba3fc4ae3298d7a40cd660a5bd34
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Charlie Proctor
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Tbgit
|
2
|
+
|
3
|
+
TBGit is a command-line utility to facilitate the management of multiple GitHub student repositories.
|
4
|
+
- created by Charlie Proctor at 2014 YEI Tech Bootcamp
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
$ gem install tbgit
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
Commands:
|
13
|
+
- setup sets up a tbgit environment. See decription below
|
14
|
+
- push pushes all local student branches to their remote master branches
|
15
|
+
- pull pulls all remote master branches to local student branches
|
16
|
+
- merge merges a specified branch with each student branch and then commits the changes
|
17
|
+
- status runs `git status` on each students branch and displays the results
|
18
|
+
|
19
|
+
- add-remotes adds each student's repository as a remote
|
20
|
+
- create-locals creates a local branch to track the students remote master branch
|
21
|
+
- these are both part of the setup process
|
22
|
+
|
23
|
+
##TBGit Environment
|
24
|
+
- it's a regular git repository -- with lots of fancy features!
|
25
|
+
- there is a master branch for teachers to work off of (create hw files, etc..)
|
26
|
+
- teachers can obviously create and work off other branches if desired
|
27
|
+
- each student's repository is a remote of the git repo
|
28
|
+
- there is a local branch to track each student's remote master branches
|
29
|
+
|
30
|
+
##Setup
|
31
|
+
1. Teachers create the student repositories (https://github.com/education/teachers_pet works perfectly well for this)
|
32
|
+
- initialize these repos with a README or push out a starter file.
|
33
|
+
- create a file with a list of the students github usernames (one on each line)
|
34
|
+
- you will need this during the setup process
|
35
|
+
2. Teachers create a repo for themselves. This will serve as the base for the tbgit environment.
|
36
|
+
3. Change to that repo's directory, execute `tbgit setup`, and follow the instructions.
|
37
|
+
|
38
|
+
##A Typical Workflow
|
39
|
+
1. Teachers create the assignment (on the master branch) and make a final commit when they're ready to deploy it
|
40
|
+
2. Teachers pull all the students' repos to make sure they're up to date.
|
41
|
+
- `tbgit pull`
|
42
|
+
3. Teachers merge their master branch with each student's local branch
|
43
|
+
- `tbgit merge`
|
44
|
+
4. At this point, teachers should check to make sure their were no merge conflicts. If there were, go in and fix them.
|
45
|
+
- feel free to `git checkout <username>` a few different branches
|
46
|
+
4. Teachers push each students local branch to the student's remote master branch
|
47
|
+
- `tbgit push`
|
48
|
+
5. Make sure it worked. Do a victory lap.
|
49
|
+
|
50
|
+
To view student solutions at any point, just `tbgit pull` and `git checkout <username>`
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
## Contributing
|
55
|
+
|
56
|
+
1. Fork it ( https://github.com/[my-github-username]/tbgit/fork )
|
57
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
58
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
59
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
60
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/tbgit
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'tbgit'
|
4
|
+
|
5
|
+
tbgit = Main::TBGit.new
|
6
|
+
|
7
|
+
case ARGV[0]
|
8
|
+
when "setup"
|
9
|
+
tbgit.gather
|
10
|
+
|
11
|
+
tbgit.add_remotes
|
12
|
+
tbgit.spacer
|
13
|
+
|
14
|
+
tbgit.git_update
|
15
|
+
tbgit.spacer
|
16
|
+
|
17
|
+
tbgit.create_local_tracking_remotes
|
18
|
+
tbgit.switch_to_master
|
19
|
+
tbgit.spacer
|
20
|
+
|
21
|
+
tbgit.git_remote
|
22
|
+
tbgit.spacer
|
23
|
+
|
24
|
+
tbgit.git_branch
|
25
|
+
tbgit.spacer
|
26
|
+
when "pull"
|
27
|
+
tbgit.update_repos(ARGV[0])
|
28
|
+
when "push"
|
29
|
+
tbgit.update_repos(ARGV[0])
|
30
|
+
when "merge"
|
31
|
+
tbgit.merge_and_commit
|
32
|
+
when "status"
|
33
|
+
tbgit.git_status
|
34
|
+
when "add-remotes"
|
35
|
+
tbgit.gather
|
36
|
+
tbgit.spacer
|
37
|
+
|
38
|
+
tbgit.add_remotes
|
39
|
+
when "create-locals"
|
40
|
+
tbgit.gather
|
41
|
+
tbgit.spacer
|
42
|
+
|
43
|
+
tbgit.create_local_tracking_remotes
|
44
|
+
else
|
45
|
+
tbgit.help
|
46
|
+
end
|
data/lib/tbgit.rb
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
require "tbgit/version"
|
2
|
+
require "tempfile"
|
3
|
+
|
4
|
+
module Main
|
5
|
+
|
6
|
+
class TBGit
|
7
|
+
|
8
|
+
def spacer
|
9
|
+
puts "********************************************************************************"
|
10
|
+
end
|
11
|
+
|
12
|
+
#confirms a given message
|
13
|
+
def confirm(message)
|
14
|
+
print message + " (y/n) "
|
15
|
+
response = $stdin.gets.chomp
|
16
|
+
if response == 'y'
|
17
|
+
#do nothing
|
18
|
+
else
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
#three simple git methods
|
24
|
+
def switch_to_master
|
25
|
+
puts "git checkout master"
|
26
|
+
system "git checkout master"
|
27
|
+
end
|
28
|
+
def git_remote
|
29
|
+
puts "git remote"
|
30
|
+
system "git remote"
|
31
|
+
end
|
32
|
+
def git_branch
|
33
|
+
puts "git branch"
|
34
|
+
system "git branch"
|
35
|
+
end
|
36
|
+
|
37
|
+
#gather necessary information
|
38
|
+
def gather
|
39
|
+
puts 'Students file |../students|:'
|
40
|
+
@students_file = $stdin.gets.chomp
|
41
|
+
if @students_file == ""
|
42
|
+
@students_file = "../students"
|
43
|
+
end
|
44
|
+
|
45
|
+
puts 'Organization name |yale-stc-developer-curriculum|:'
|
46
|
+
@organization = $stdin.gets.chomp
|
47
|
+
if @organization == ""
|
48
|
+
@organization = "yale-stc-developer-curriculum"
|
49
|
+
end
|
50
|
+
|
51
|
+
puts 'Student Repo Name |TechBootcampHomework|:'
|
52
|
+
@reponame = $stdin.gets.chomp
|
53
|
+
if @reponame == ""
|
54
|
+
@reponame = "TechBootcampHomework"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#update remotes
|
59
|
+
def git_update
|
60
|
+
puts "git remote update"
|
61
|
+
system "git remote update"
|
62
|
+
end
|
63
|
+
|
64
|
+
#add each student repository as a remote
|
65
|
+
def add_remotes
|
66
|
+
confirm("Each student repository will be added as a remote. Continue?")
|
67
|
+
students = IO.readlines(@students_file)
|
68
|
+
students.each do |username|
|
69
|
+
username.delete!("\n")
|
70
|
+
|
71
|
+
puts "Adding Remote: " + username
|
72
|
+
remote_command = "git remote add " + username + " https://github.com/"+@organization+"/" + username + "-"+@reponame+".git"
|
73
|
+
puts remote_command
|
74
|
+
system remote_command
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
#create local branches to track remote student repositories
|
79
|
+
def create_local_tracking_remotes
|
80
|
+
confirm("Local branches will be created to track remote student repositories. Continue?")
|
81
|
+
students = IO.readlines(@students_file)
|
82
|
+
students.each do |username|
|
83
|
+
username.delete!("\n")
|
84
|
+
|
85
|
+
puts "Creating Local Branch to Track Remote: " + username
|
86
|
+
checkout_command = "git checkout --track -b " + username + " remotes/" + username + "/master"
|
87
|
+
puts checkout_command
|
88
|
+
system checkout_command
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
#returns a list of students
|
95
|
+
def all_remotes_list
|
96
|
+
remote_file = Tempfile.new("remotes")
|
97
|
+
system "git remote >> " + remote_file.path
|
98
|
+
|
99
|
+
puts "git remote >> " + remote_file.path
|
100
|
+
|
101
|
+
return IO.readlines(remote_file)
|
102
|
+
end
|
103
|
+
|
104
|
+
#used for push / pull
|
105
|
+
def update_repos(pushpull)
|
106
|
+
if pushpull == "push"
|
107
|
+
confirm("Each local student branch will be pushed to their remote master branch. Continue?")
|
108
|
+
else
|
109
|
+
confirm("Each remote student master branch will be pulled to the local branch. Continue?")
|
110
|
+
end
|
111
|
+
|
112
|
+
all_remotes = all_remotes_list
|
113
|
+
all_remotes.each do |branch|
|
114
|
+
branch.delete!("\n")
|
115
|
+
|
116
|
+
if branch != "origin"
|
117
|
+
checkout_command = "git checkout " + branch
|
118
|
+
if pushpull == "push"
|
119
|
+
pushpull_command = "git push " + branch + " " + branch + ":master"
|
120
|
+
else
|
121
|
+
pushpull_command = "git pull " + branch + " master"
|
122
|
+
end
|
123
|
+
|
124
|
+
puts checkout_command
|
125
|
+
system checkout_command
|
126
|
+
|
127
|
+
puts pushpull_command
|
128
|
+
system pushpull_command
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
switch_to_master
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
#merges from master (or another branch) to each student branch and commits the changes
|
138
|
+
def merge_and_commit
|
139
|
+
|
140
|
+
confirm("A merge and commit will be performed on each local student branch (from the branch you specify). Continue?")
|
141
|
+
puts "Merge from branch: "
|
142
|
+
merge_branch = $stdin.gets.chomp
|
143
|
+
|
144
|
+
puts "Commit Message: "
|
145
|
+
message = $stdin.gets.chomp
|
146
|
+
|
147
|
+
all_remotes = all_remotes_list
|
148
|
+
all_remotes.each do |branch|
|
149
|
+
branch.delete!("\n")
|
150
|
+
|
151
|
+
if branch != "origin"
|
152
|
+
checkout_command = "git checkout " + branch
|
153
|
+
merge_command = "git merge --no-commit " + merge_branch.to_s
|
154
|
+
stage_changes = "git add --all"
|
155
|
+
commit_command = "git commit -am '" + message + "'"
|
156
|
+
|
157
|
+
puts checkout_command
|
158
|
+
system checkout_command
|
159
|
+
|
160
|
+
puts merge_command
|
161
|
+
system merge_command
|
162
|
+
|
163
|
+
puts stage_changes
|
164
|
+
system stage_changes
|
165
|
+
|
166
|
+
puts commit_command
|
167
|
+
system commit_command
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
switch_to_master
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
def git_status
|
177
|
+
all_remotes = all_remotes_list
|
178
|
+
all_remotes.each do |branch|
|
179
|
+
branch.delete!("\n")
|
180
|
+
|
181
|
+
puts "git status " + branch
|
182
|
+
system "git status " + branch
|
183
|
+
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def help
|
188
|
+
puts ""
|
189
|
+
puts "TBGit is a command-line utility to facilitate the management of multiple GitHub student repositories."
|
190
|
+
puts " ~ created by Charlie Proctor at 2014 YEI Tech Bootcamp"
|
191
|
+
puts " ~ partly based off of https://github.com/education/teachers_pet"
|
192
|
+
puts " Commands:"
|
193
|
+
puts " ~ setup sets up a tbgit environment. See decription below"
|
194
|
+
puts " ~ push pushes all local student branches to their remote master branches"
|
195
|
+
puts " ~ pull pulls all remote master branches to local student branches"
|
196
|
+
puts " ~ merge merges a specified branch with each student branch and then commits the changes"
|
197
|
+
puts " ~ status runs `git status` on each students branch and displays the results"
|
198
|
+
puts ""
|
199
|
+
puts " ~ add-remotes adds each student's repository as a remote"
|
200
|
+
puts " ~ create-locals creates a local branch to track the students remote master branch"
|
201
|
+
puts " ^----> these are both part of the setup process"
|
202
|
+
puts ""
|
203
|
+
puts " TBGit Environment"
|
204
|
+
puts " ~ it's a regular git repository -- with lots of fancy features!"
|
205
|
+
puts " ~ there is a master branch for teachers to work off of (create hw files, etc..)"
|
206
|
+
puts " --> teachers can obviously create and work off other branches if desired"
|
207
|
+
puts " ~ each student's repository is a remote of the git repo"
|
208
|
+
puts " ~ there is a local branch to track each student's remote master branches"
|
209
|
+
puts ""
|
210
|
+
puts " Setup"
|
211
|
+
puts " 1. Teachers create the student repositories (https://github.com/education/teachers_pet works perfectly well for this)"
|
212
|
+
puts " --> make sure the repos are all private, but that you have access to them!"
|
213
|
+
puts " --> initialize these repos with a README or push out a starter file."
|
214
|
+
puts " --> create a file with a list of the students github usernames (one on each line)"
|
215
|
+
puts " --- you will need this during the setup process"
|
216
|
+
puts " 2. Teachers create a repo for themselves. This will serve as the base for the tbgit environment."
|
217
|
+
puts " 3. Change to that repo's directory, execute `tbgit setup`, and follow the instructions."
|
218
|
+
puts ""
|
219
|
+
puts " A Typical Workflow"
|
220
|
+
puts " 1. Teachers create the assignment (on the master branch) and make a final commit when they're ready to deploy it"
|
221
|
+
puts " 2. Teachers pull all the students' repos to make sure they're up to date."
|
222
|
+
puts " --> `tbgit pull`"
|
223
|
+
puts " 3. Teachers merge their master branch with each student's local branch"
|
224
|
+
puts " --> `tbgit merge`"
|
225
|
+
puts " 4. At this point, teachers should check to make sure their were no merge conflicts. If there were, go in and fix them."
|
226
|
+
puts " --> feel free to `git checkout <username>` a few different branches"
|
227
|
+
puts " 4. Teachers push each students local branch to the student's remote master branch"
|
228
|
+
puts " --> `tbgit push`"
|
229
|
+
puts " 5. Make sure it worked. Do a victory lap."
|
230
|
+
puts ""
|
231
|
+
puts " To view student solutions at any point, just `tbgit pull` and `git checkout <username>`"
|
232
|
+
puts ""
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
|
238
|
+
|
239
|
+
end #class
|
240
|
+
end #module
|
data/tbgit.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'tbgit/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "tbgit"
|
8
|
+
spec.version = Tbgit::VERSION
|
9
|
+
spec.authors = ["Charlie Proctor"]
|
10
|
+
spec.email = ["charlie@charlieproctor.com"]
|
11
|
+
spec.summary = %q{TBGit is a command-line utility to facilitate the management of multiple GitHub student repositories.}
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = ["tbgit"]
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tbgit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Charlie Proctor
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-05-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: ''
|
42
|
+
email:
|
43
|
+
- charlie@charlieproctor.com
|
44
|
+
executables:
|
45
|
+
- tbgit
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".gitignore"
|
50
|
+
- Gemfile
|
51
|
+
- LICENSE.txt
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- bin/tbgit
|
55
|
+
- lib/tbgit.rb
|
56
|
+
- lib/tbgit/version.rb
|
57
|
+
- tbgit.gemspec
|
58
|
+
homepage: ''
|
59
|
+
licenses:
|
60
|
+
- MIT
|
61
|
+
metadata: {}
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 2.2.2
|
79
|
+
signing_key:
|
80
|
+
specification_version: 4
|
81
|
+
summary: TBGit is a command-line utility to facilitate the management of multiple
|
82
|
+
GitHub student repositories.
|
83
|
+
test_files: []
|