jbox-gitolite 1.2.6 → 1.2.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +19 -12
- data/AUTHORS +10 -0
- data/CHANGELOG.md +82 -0
- data/Gemfile +3 -2
- data/Guardfile +13 -10
- data/LICENSE +19 -0
- data/README.md +216 -29
- data/Rakefile +9 -53
- data/bin/_guard-core +29 -0
- data/bin/guard +29 -0
- data/gitolite.gemspec +18 -23
- data/lib/gitolite.rb +3 -2
- data/lib/gitolite/config/repo.rb +4 -4
- data/lib/gitolite/version.rb +1 -1
- data/spec/spec_helper.rb +16 -15
- data/spec/support/helper.rb +12 -0
- data/spec/{config_spec.rb → unit_tests/config_spec.rb} +1 -1
- data/spec/{dirty_proxy_spec.rb → unit_tests/dirty_proxy_spec.rb} +0 -0
- data/spec/{gitolite_admin_spec.rb → unit_tests/gitolite_admin_spec.rb} +8 -8
- data/spec/{group_spec.rb → unit_tests/group_spec.rb} +0 -0
- data/spec/{repo_spec.rb → unit_tests/repo_spec.rb} +1 -1
- data/spec/{ssh_key_spec.rb → unit_tests/ssh_key_spec.rb} +44 -44
- metadata +49 -150
- data/.gemtest +0 -0
- data/LICENSE.txt +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e7825bb9c6f3423a935e4bfd9b482296577f1c15dc6c924d2df0579de1f59659
|
4
|
+
data.tar.gz: 37ed0629b3d2cbb1e885bbde1cac279f3a482a6a7ff63421d462d240613b65de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0ef97ab85caf23a87f97daf00294172a62c06c1991f06a01aa69f4c268a4dc872bcbbfc1c9507ce9d19c9290e03b45c64ed69bdeb91b4393811727360e7c65c
|
7
|
+
data.tar.gz: f4088bc0777e3e0ae102f6e80adcadab620dad7a2ff01f3dabf1b418b52523e2fa1448a57c245099a63ce03644792cfbbccf2b5be1305198a88d9dfbfefa6fc2
|
data/.travis.yml
CHANGED
@@ -1,14 +1,21 @@
|
|
1
1
|
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
sudo: false
|
2
4
|
rvm:
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
- 2.6.5
|
6
|
+
- 2.5.7
|
7
|
+
- 2.4.9
|
8
|
+
- ruby-head
|
9
|
+
addons:
|
10
|
+
apt:
|
11
|
+
packages:
|
12
|
+
- libicu-dev
|
13
|
+
before_script:
|
14
|
+
- git config --global user.email "test@example.com"
|
15
|
+
- git config --global user.name "Test"
|
16
|
+
before_script:
|
17
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
18
|
+
- chmod +x ./cc-test-reporter
|
19
|
+
- ./cc-test-reporter before-build
|
20
|
+
after_script:
|
21
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/AUTHORS
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Alexander Simonov <alex@simonov.me>
|
2
|
+
Andreas Pfohl <andreas@pf0hl.de>
|
3
|
+
Cristian Livadaru <cristian@livadaru.net>
|
4
|
+
Geoffrey Broadwell <geoffb@corp.sonic.net>
|
5
|
+
Jakub Jirutka <jakub@jirutka.cz>
|
6
|
+
Nicolas Rodriguez <nrodriguez@jbox-web.com>
|
7
|
+
Pavel Gabriel <alovak@gmail.com>
|
8
|
+
Pete Elmore <pete@debu.gs>
|
9
|
+
Pierre GUINOISEAU <pierre@guinoiseau.eu>
|
10
|
+
Stafford Brunk <wingrunr21@gmail.com>
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
#### [Release 1.2.7](https://github.com/jbox-web/gitolite/releases/tag/v1.2.7)
|
2
|
+
***
|
3
|
+
**Date :** October 25, 2019
|
4
|
+
|
5
|
+
**Changelog :**
|
6
|
+
|
7
|
+
* Bump gitlab-grit to version [2.7.2](https://github.com/gitlabhq/grit/blob/master/History.txt)
|
8
|
+
|
9
|
+
#### [Release 1.2.6](https://github.com/jbox-web/gitolite/releases/tag/v1.2.6)
|
10
|
+
***
|
11
|
+
**Date :** September 10, 2014
|
12
|
+
|
13
|
+
**Changelog :**
|
14
|
+
|
15
|
+
* Bump gitlab-grit to version [2.7.1](https://github.com/gitlabhq/grit/blob/master/History.txt)
|
16
|
+
|
17
|
+
#### [Release 1.2.5](https://github.com/jbox-web/gitolite/releases/tag/v1.2.5)
|
18
|
+
***
|
19
|
+
**Date :** July 22, 2014
|
20
|
+
|
21
|
+
**Changelog :**
|
22
|
+
|
23
|
+
* Grit mangle the options hash, clone it.
|
24
|
+
|
25
|
+
#### [Release 1.2.4](https://github.com/jbox-web/gitolite/releases/tag/v1.2.4)
|
26
|
+
***
|
27
|
+
**Date :** July 22, 2014
|
28
|
+
|
29
|
+
**Changelog :**
|
30
|
+
|
31
|
+
* Raises ```Grit::Git::CommandFailed``` when the ```:raise``` option is set true and the ```git``` command exits with a non-zero exit status.
|
32
|
+
|
33
|
+
#### [Release 1.2.3](https://github.com/jbox-web/gitolite/releases/tag/v1.2.3)
|
34
|
+
***
|
35
|
+
**Date :** July 16, 2014
|
36
|
+
|
37
|
+
**Changelog :**
|
38
|
+
|
39
|
+
* Bump to version 2.7.0 of [gitlab-grit](https://github.com/gitlabhq/grit)
|
40
|
+
|
41
|
+
#### [Release 1.2.2](https://github.com/jbox-web/gitolite/releases/tag/v1.2.2)
|
42
|
+
***
|
43
|
+
**Date :** April 29, 2014
|
44
|
+
|
45
|
+
**Changelog :**
|
46
|
+
|
47
|
+
* Rollback to GRATR (Plexus crash in Rails environment, don't know why...)
|
48
|
+
* Add commit tests for GitoliteAdmin
|
49
|
+
|
50
|
+
#### [Release 1.2.1](https://github.com/jbox-web/gitolite/releases/tag/v1.2.1)
|
51
|
+
***
|
52
|
+
**Date :** April 22, 2014
|
53
|
+
|
54
|
+
**Changelog :**
|
55
|
+
|
56
|
+
* Allow key names with '+' character in them
|
57
|
+
* Replace GRATR by Plexus
|
58
|
+
* Test if file generation works
|
59
|
+
* Add tests for GitoliteAdmin
|
60
|
+
* Bump to last version of development gems
|
61
|
+
|
62
|
+
#### [Release 1.2.0](https://github.com/jbox-web/gitolite/releases/tag/v1.2.0)
|
63
|
+
***
|
64
|
+
**Date :** April 19, 2014
|
65
|
+
|
66
|
+
**Changelog :**
|
67
|
+
|
68
|
+
Actually there's not much changes but the last modifications (thread safety, options added) justify this major update.
|
69
|
+
|
70
|
+
By the way the wiki has been updated and the test infrastructure too.
|
71
|
+
|
72
|
+
#### [Release 1.1.11](https://github.com/jbox-web/gitolite/releases/tag/v1.1.11)
|
73
|
+
***
|
74
|
+
**Date :** April 14, 2014
|
75
|
+
|
76
|
+
**Changelog :**
|
77
|
+
|
78
|
+
* Fix thread safety
|
79
|
+
* Pass env options as hash to Grit (such as GIT_SSH)
|
80
|
+
* Pass options hash to save method
|
81
|
+
* Add Grit.debug option
|
82
|
+
* Add Grit::Git.git_timeout option
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -1,13 +1,16 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
guard :rspec, :
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
4
|
+
require 'guard/rspec/dsl'
|
5
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
6
|
+
|
7
|
+
# RSpec files
|
8
|
+
rspec = dsl.rspec
|
9
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
10
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
11
|
+
watch(rspec.spec_files)
|
8
12
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
watch('spec/spec_helper.rb') { :rspec }
|
13
|
+
# Ruby files
|
14
|
+
ruby = dsl.ruby
|
15
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
13
16
|
end
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,48 +1,239 @@
|
|
1
1
|
## ![logo](https://raw.github.com/jbox-web/gitolite/gh-pages/images/git_logo.png) gitolite
|
2
2
|
|
3
|
-
|
3
|
+
[![GitHub license](https://img.shields.io/github/license/jbox-web/gitolite.svg)](https://github.com/jbox-web/gitolite/blob/devel/LICENSE)
|
4
|
+
[![Gem](https://img.shields.io/gem/v/jbox-gitolite.svg)](https://rubygems.org/gems/jbox-gitolite)
|
5
|
+
[![Gem](https://img.shields.io/gem/dv/jbox-gitolite/1.2.6.svg)](https://rubygems.org/gems/jbox-gitolite/versions/1.2.6)
|
6
|
+
[![Build Status](https://travis-ci.org/jbox-web/gitolite.svg?branch=devel)](https://travis-ci.org/jbox-web/gitolite)
|
7
|
+
[![Code Climate](https://codeclimate.com/github/jbox-web/gitolite.png)](https://codeclimate.com/github/jbox-web/gitolite)
|
8
|
+
[![Test Coverage](https://codeclimate.com/github/jbox-web/gitolite/badges/coverage.svg)](https://codeclimate.com/github/jbox-web/gitolite)
|
4
9
|
|
5
|
-
|
10
|
+
### A Ruby interface to manage the Gitolite Git backend system, easy ;)
|
6
11
|
|
7
|
-
|
12
|
+
This gem is designed to provide a Ruby interface to the [Gitolite](https://github.com/sitaramc/gitolite) Git backend system via [gitlab-grit](https://github.com/gitlabhq/grit) gem.
|
8
13
|
|
9
14
|
It provides these functionalities :
|
10
15
|
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
16
|
+
* SSH Public Keys Management
|
17
|
+
* Repositories Management
|
18
|
+
* Gitolite Admin Repository Bootstrapping
|
14
19
|
|
15
|
-
|
20
|
+
***Please note : this project is not maintained anymore.***
|
16
21
|
|
17
|
-
You'll find a new implementation of this library here : https://github.com/
|
22
|
+
***You'll find a new implementation of this library here : [gitolite-rugged](https://github.com/jbox-web/gitolite-rugged).***
|
18
23
|
|
19
|
-
|
24
|
+
## Requirements ##
|
20
25
|
|
26
|
+
* Ruby 1.9.x or 2.0.x
|
27
|
+
* a working [Gitolite](https://github.com/sitaramc/gitolite) installation
|
21
28
|
|
22
|
-
##
|
29
|
+
## Installation ##
|
23
30
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
* [![Dependency Status](https://gemnasium.com/jbox-web/gitolite.svg)](https://gemnasium.com/jbox-web/gitolite)
|
31
|
+
```ruby
|
32
|
+
gem 'jbox-gitolite', '~> 1.2.6'
|
33
|
+
```
|
28
34
|
|
29
|
-
|
30
|
-
* Ruby 1.9.x or 2.0.x
|
31
|
-
* a working [gitolite](https://github.com/sitaramc/gitolite) installation
|
32
|
-
* the <tt>gitolite-admin</tt> repository checked out locally
|
35
|
+
then `bundle install`.
|
33
36
|
|
34
|
-
##
|
37
|
+
## Usage
|
38
|
+
|
39
|
+
### Load a gitolite-admin repo
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
require 'gitolite'
|
43
|
+
ga_repo = Gitolite::GitoliteAdmin.new("/path/to/gitolite/admin/repo")
|
44
|
+
|
45
|
+
# or with options :
|
46
|
+
ga_repo = Gitolite::GitoliteAdmin.new("/path/to/gitolite/admin/repo", :config_file => 'example.conf',
|
47
|
+
:debug => true,
|
48
|
+
:timeout => 20,
|
49
|
+
:env => {'GIT_SSH' => '/path/to/script/file'})
|
50
|
+
```
|
51
|
+
|
52
|
+
This method can only be called on an existing gitolite-admin repo. If you need to create a new gitolite-admin repo, see "Bootstrapping".
|
53
|
+
|
54
|
+
### Configuration Files
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
conf = ga_repo.config
|
58
|
+
|
59
|
+
# Empty configs can also be initialized
|
60
|
+
conf2 = Config.init # => defaults to a filename of gitolite.conf
|
61
|
+
conf2 = Config.init("new_config.conf")
|
62
|
+
|
63
|
+
# Filename is set to whatever the filename was when the config was created
|
64
|
+
conf.filename # => "gitolite.conf"
|
65
|
+
conf2.filename # => "new_config.conf"
|
66
|
+
|
67
|
+
# Filename can be changed via the setter
|
68
|
+
conf2.filename = "new_config.conf"
|
69
|
+
|
70
|
+
# *to_file* will write the config out to the file system using the value of the filename attribute.
|
71
|
+
# An alternative filename can also be specified
|
72
|
+
conf.to_file("/new/config/path") # => writes /new/config/path/gitolite.conf
|
73
|
+
conf.to_file("/new/config/path", "test.conf") # => writes /new/config/path/test.conf
|
74
|
+
```
|
75
|
+
|
76
|
+
### Repo management
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
repo = Gitolite::Config::Repo.new("AwesomeRepo")
|
80
|
+
|
81
|
+
# For a list of permissions, see http://sitaramc.github.com/gitolite/conf.html#gitolite
|
82
|
+
repo.add_permission("RW+", "", "bob", "joe", "susan")
|
83
|
+
|
84
|
+
# Set a git config option to the repo
|
85
|
+
repo.set_git_config("hooks.mailinglist", "gitolite-commits@example.tld") # => "gitolite-commits@example.tld"
|
86
|
+
|
87
|
+
# Unset a git config option from the repo
|
88
|
+
repo.unset_git_config("hooks.mailinglist") # => "gitolite-commits@example.tld"
|
89
|
+
|
90
|
+
# Set a gitolite option to the repo
|
91
|
+
repo.set_gitolite_option("mirroring.master", "kenobi") # => "kenobi"
|
92
|
+
|
93
|
+
# Remove a gitolite option from the repo
|
94
|
+
repo.unset_gitolite_option("mirroring.master") # => "kenobi"
|
95
|
+
|
96
|
+
# Add repo to config
|
97
|
+
conf.add_repo(repo)
|
98
|
+
|
99
|
+
# Delete repo by object
|
100
|
+
conf.rm_repo(repo)
|
101
|
+
|
102
|
+
# Delete a repo by name
|
103
|
+
conf.rm_repo("AwesomeRepo")
|
104
|
+
conf.rm_repo(:AwesomeRepo)
|
105
|
+
|
106
|
+
# Test if repo exists by name
|
107
|
+
conf.has_repo?('cool_repo') # => false
|
108
|
+
conf.has_repo?(:cool_repo) # => false
|
109
|
+
|
110
|
+
# Can also pass a Gitolite::Config::Repo object
|
111
|
+
repo = Gitolite::Config::Repo.new('cool_repo')
|
112
|
+
conf.has_repo?(repo) # => true
|
113
|
+
|
114
|
+
# Get a repo object from the config
|
115
|
+
repo = conf.get_repo('cool_repo')
|
116
|
+
repo = conf.get_repo(:cool_repo)
|
117
|
+
```
|
118
|
+
|
119
|
+
### SSH Key Management
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
# Three ways to create keys : manually, from an existing key, or from a string representing a key
|
123
|
+
key = Gitolite::SSHKey.new("ssh-rsa", "big-public-key-blob", "email")
|
124
|
+
key2 = Gitolite::SSHKey.from_file("/path/to/ssh/key.pub")
|
125
|
+
|
126
|
+
key_string = File.read("/path/to/ssh/key.pub")
|
127
|
+
key3 = Gitolite::SSHKey.from_string(key_string, "owner")
|
35
128
|
|
36
|
-
|
129
|
+
# Create key with a name #
|
130
|
+
key = Gitolite::SSHKey.new("ssh-rsa", "big-public-key-blob", "email", "keyname")
|
131
|
+
key2 = Gitolite::SSHKey.from_file("/path/to/ssh/key.pub")
|
37
132
|
|
38
|
-
|
133
|
+
key_string = File.read("/path/to/ssh/key.pub")
|
134
|
+
key3 = Gitolite::SSHKey.from_string(key_string, "owner", "keyname")
|
39
135
|
|
40
|
-
|
41
|
-
|
136
|
+
# Add the keys
|
137
|
+
ga_repo.add_key(key)
|
138
|
+
ga_repo.add_key(key2)
|
139
|
+
ga_repo.add_key(key3)
|
42
140
|
|
43
|
-
|
141
|
+
# Remove key2
|
142
|
+
ga_repo.rm_key(key2)
|
143
|
+
```
|
44
144
|
|
45
|
-
|
145
|
+
### Save changes ###
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
ga_repo.save(commit_message, :author => 'John Doe <john.doe@example.com>')
|
149
|
+
```
|
150
|
+
|
151
|
+
When this method is called, all changes get written to the file system and commited in git. For the time being, gitolite assumes full control of the gitolite-admin repository.
|
152
|
+
This means that any keys in the keydir that are not being tracked will be removed and any human changes to gitolite.conf will be erased.
|
153
|
+
The commit message is optional. A generic message is set if missing. Optionally you can pass the author as above.
|
154
|
+
|
155
|
+
### Apply changes ###
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
ga_repo.apply
|
159
|
+
```
|
160
|
+
|
161
|
+
This method will push all changes to <tt>origin master</tt>.
|
162
|
+
|
163
|
+
### Save and apply ###
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
ga_repo.save_and_apply(commit_message)
|
167
|
+
```
|
168
|
+
|
169
|
+
This method will add files, commit and push all changes to <tt>origin master</tt> in the same transaction.
|
170
|
+
The commit message is optional. A generic message is set if missing.
|
171
|
+
|
172
|
+
### Updating remote changes ###
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
# In order to avoid conflicts, this will perform a reset! by default
|
176
|
+
# pass :reset => false to disable the reset (Git conflicts will have to be manually fixed)
|
177
|
+
ga_repo.update
|
178
|
+
ga_repo.update(:reset => false)
|
179
|
+
|
180
|
+
# Update while performing a rebase
|
181
|
+
ga_repo.update(:rebase => true)
|
182
|
+
```
|
183
|
+
|
184
|
+
### Reloading from the file system ###
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
ga_repo.reload!
|
188
|
+
```
|
189
|
+
|
190
|
+
### Resetting to HEAD, destroying all local changes (including untracked files) ###
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
# This will also perform a reload!
|
194
|
+
ga_repo.reset!
|
195
|
+
```
|
196
|
+
|
197
|
+
### Bootstrapping ###
|
198
|
+
|
199
|
+
```ruby
|
200
|
+
ga_repo = GitoliteAdmin.bootstrap("/path/to/new/gitolite/repo")
|
201
|
+
```
|
202
|
+
|
203
|
+
This will create the folders <tt>conf</tt> and <tt>keydir</tt> in the supplied path. A config file will also be created in the conf directory.
|
204
|
+
The default configuration supplies RW+ permissions to a user named git for a repo named <tt>gitolite-admin</tt>. You can specify an options hash to change some values :
|
205
|
+
|
206
|
+
```ruby
|
207
|
+
ga_repo = GitoliteAdmin.bootstrap("/path/to/new/gitolite/repo", {:user => "admin", :perm => "RW"})
|
208
|
+
```
|
209
|
+
|
210
|
+
You can also pass a message to be used for the initial bootstrap commit :
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
ga_repo = GitoliteAdmin.bootstrap("/path/to/new/gitolite/repo", {:message => "Bootstrapped new repo"})
|
214
|
+
```
|
215
|
+
|
216
|
+
Please note that while bootstrapping is supported, I highly recommend that the initial gitolite-admin repo be created by gitolite itself.
|
217
|
+
|
218
|
+
## Caveats ##
|
219
|
+
|
220
|
+
### Windows compatibility ###
|
221
|
+
|
222
|
+
The grit gem (which is used for under-the-hood git operations) does not currently support Windows. Until it does, gitolite will be unable to support Windows.
|
223
|
+
|
224
|
+
### Group Ordering ###
|
225
|
+
|
226
|
+
When the gitolite backend parses the config file, it does so in one pass. Because of this, groups that are modified after being used do not see those changes reflected in previous uses.
|
227
|
+
|
228
|
+
For example:
|
229
|
+
|
230
|
+
```sh
|
231
|
+
@groupa = bob joe sue
|
232
|
+
@groupb = jim @groupa
|
233
|
+
@groupa = sam
|
234
|
+
```
|
235
|
+
|
236
|
+
Group ```b``` will contain the users <tt>jim, bob, joe, and sue</tt>
|
46
237
|
|
47
238
|
## Contribute
|
48
239
|
|
@@ -51,7 +242,3 @@ You can contribute to this plugin in many ways such as :
|
|
51
242
|
* Contributing code (features or bugfixes)
|
52
243
|
* Reporting a bug
|
53
244
|
* Submitting translations
|
54
|
-
|
55
|
-
You can also donate :)
|
56
|
-
|
57
|
-
[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FBT7E7DAVVEEU)
|