gitty 0.3.7 → 0.4.2
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.
- data/README.textile +40 -0
- data/assets/helpers/hookd_wrapper +1 -11
- data/assets/helpers/update-shared-hooks +22 -0
- data/assets/hooks/auto-submodules +10 -5
- data/lib/gitty/commands/init.rb +19 -4
- data/lib/gitty/commands/install.rb +2 -11
- data/lib/gitty/commands/share.rb +34 -0
- data/lib/gitty/hook.rb +43 -24
- data/lib/gitty/hook_command.rb +1 -0
- data/lib/gitty.rb +4 -0
- data/spec/gitty/hook_spec.rb +15 -0
- metadata +4 -2
data/README.textile
CHANGED
@@ -13,9 +13,49 @@ Missing features:
|
|
13
13
|
|
14
14
|
* Only receive hooks from trusted publishers. (currently when gitty is activated on a repository, any hook published to origin is automatically installed)
|
15
15
|
* It's very young and might break
|
16
|
+
* Remote repository must be named origin for shared hooks to work. This is currently not configurable.
|
16
17
|
|
17
18
|
h2. Documentation
|
18
19
|
|
20
|
+
h3. Initialization
|
21
|
+
|
22
|
+
To use gitty with a git repository, you need to install the basic gitty hooks.
|
23
|
+
|
24
|
+
<pre>
|
25
|
+
git hook init
|
26
|
+
</pre>
|
27
|
+
|
28
|
+
* Any existing hooks will be preserved. They are moved to .git/hooks/local/<hook-name>.d/original
|
29
|
+
|
30
|
+
h3. Enabling sharing
|
31
|
+
|
32
|
+
By default, it's turned off (security reasons). To enable it:
|
33
|
+
|
34
|
+
<pre>
|
35
|
+
git hook init --enable-sharing
|
36
|
+
</pre>
|
37
|
+
|
38
|
+
h3. Adding hooks
|
39
|
+
|
40
|
+
To see available hooks:
|
41
|
+
|
42
|
+
<pre>
|
43
|
+
git hook list
|
44
|
+
</pre>
|
45
|
+
|
46
|
+
To install one:
|
47
|
+
|
48
|
+
<pre>
|
49
|
+
git hook install <hook-name>
|
50
|
+
</pre>
|
51
|
+
|
52
|
+
To share one:
|
53
|
+
|
54
|
+
<pre>
|
55
|
+
git hook share <hook-name>
|
56
|
+
git hook publish -m "added <hook-name>"
|
57
|
+
</pre>
|
58
|
+
|
19
59
|
Read the cucumber features for an idea of how it works and what it does
|
20
60
|
|
21
61
|
h2. Issues
|
@@ -2,17 +2,7 @@
|
|
2
2
|
dirname=$(dirname $0)
|
3
3
|
hooktype=$(basename $0)
|
4
4
|
|
5
|
-
|
6
|
-
remote_branch=$(git show-ref origin/--hooks--)
|
7
|
-
[ -n "$remote_branch" ] && (
|
8
|
-
cd ${dirname}/shared > /dev/null
|
9
|
-
local_rev=$(GIT_OBJECT_DIRECTORY="../../objects" git rev-parse HEAD)
|
10
|
-
[ "${remote_branch%% *}" != "$local_rev" ] && (
|
11
|
-
echo "Hook updates were applied:" 1>&2
|
12
|
-
GIT_OBJECT_DIRECTORY=../../objects git branch origin/--hooks-- ${remote_branch%% *} -f 1>&2
|
13
|
-
GIT_OBJECT_DIRECTORY=../../objects git merge ${remote_branch%% *} 1>&2
|
14
|
-
)
|
15
|
-
)
|
5
|
+
[ -x "$dirname/gitty/update-shared-hooks" ] && . "$dirname/gitty/update-shared-hooks"
|
16
6
|
|
17
7
|
for base_dir in "${dirname}"/{shared,local}; do
|
18
8
|
[ -d "${base_dir}/${hooktype}.d" ] || continue
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# Check for updates. Since there is no post-fetch hook, we check before we're about to run a hook.
|
3
|
+
remote_branch=$(git show-ref origin/--hooks--)
|
4
|
+
[ -n "$remote_branch" ] && (
|
5
|
+
cd ${dirname}/shared > /dev/null
|
6
|
+
local_rev=$(GIT_OBJECT_DIRECTORY="../../objects" git rev-parse HEAD)
|
7
|
+
[ "${remote_branch%% *}" != "$local_rev" ] && (
|
8
|
+
echo "Hook updates were applied:" 1>&2
|
9
|
+
GIT_OBJECT_DIRECTORY=../../objects git branch origin/--hooks-- ${remote_branch%% *} -f 1>&2
|
10
|
+
# This is a bit of a hack. If we're in the middle of commit, we need to borrow the index. But don't worry, we'll put it back!
|
11
|
+
if [ -f ../../index.lock ]; then
|
12
|
+
mv ../../index.lock ../../index.lock_ 1>&2
|
13
|
+
mv ../../index ../../index_ 1>&2
|
14
|
+
fi
|
15
|
+
GIT_OBJECT_DIRECTORY=../../objects git reset HEAD 1>&2
|
16
|
+
GIT_OBJECT_DIRECTORY=../../objects git reset --hard origin/--hooks-- 1>&2
|
17
|
+
if [ -f ../../index.lock_ ]; then
|
18
|
+
mv ../../index.lock_ ../../index.lock 1>&2
|
19
|
+
mv ../../index_ ../../index 1>&2
|
20
|
+
fi
|
21
|
+
)
|
22
|
+
)
|
@@ -8,7 +8,7 @@
|
|
8
8
|
# - If a submodule has been removed from the branch you move to, it alerts you
|
9
9
|
# - If a submodule has been added on the branch you move to, it alerts you
|
10
10
|
# - Otherwise, it checks out the revision for you
|
11
|
-
# version: 0.
|
11
|
+
# version: 0.3
|
12
12
|
# targets: ["pre-rebase", "post-applypatch", "post-checkout", "post-merge"]
|
13
13
|
|
14
14
|
# this is a bit of a hack: when a rebase is ran, we don't want to have the initial checkout update submodules
|
@@ -23,6 +23,7 @@ if File.exist?(".git/queue-rebase-run")
|
|
23
23
|
exit 0
|
24
24
|
end
|
25
25
|
|
26
|
+
# Not pretty... but well tested!! Refactor me.
|
26
27
|
module GitMethods
|
27
28
|
def chdir_parent
|
28
29
|
Dir.chdir('..') until File.directory?('.git') || Dir.pwd == '/'
|
@@ -97,12 +98,12 @@ previous_submodules = list_submodules('HEAD@{1}')
|
|
97
98
|
end
|
98
99
|
end
|
99
100
|
if ref.match(/^refs\/heads/)
|
100
|
-
|
101
|
+
output = %x(git checkout '#{File.basename(ref)}' 2>&1)
|
101
102
|
if $? == 0
|
102
|
-
STDERR.puts "
|
103
|
+
STDERR.puts "Switched to branch #{File.basename(ref)}"
|
103
104
|
exit 0
|
104
105
|
else
|
105
|
-
STDERR.puts "Couldn't update submodule
|
106
|
+
STDERR.puts "Couldn't update submodule: #{output}"
|
106
107
|
exit $?
|
107
108
|
end
|
108
109
|
end
|
@@ -114,7 +115,11 @@ previous_submodules = list_submodules('HEAD@{1}')
|
|
114
115
|
divergent_commits=%x{git rev-list #{ref}..#{local_ref}}.strip
|
115
116
|
if divergent_commits.empty?
|
116
117
|
STDERR.puts "fastforwarding #{local_ref} to #{ref}"
|
117
|
-
|
118
|
+
if File.read(".git/HEAD").include?("ref: refs/heads/#{local_ref}")
|
119
|
+
system("git merge #{ref}")
|
120
|
+
else
|
121
|
+
system("git branch -f #{local_ref} #{ref}")
|
122
|
+
end
|
118
123
|
exec("git checkout #{local_ref}")
|
119
124
|
end
|
120
125
|
end
|
data/lib/gitty/commands/init.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
class Gitty::HookCommand::Init < Gitty::Runner
|
3
3
|
include ::Gitty::Helpers
|
4
|
+
include FileUtils
|
4
5
|
|
5
6
|
CLIENT_HOOKS = %w[
|
6
7
|
applypatch-msg
|
@@ -17,12 +18,23 @@ class Gitty::HookCommand::Init < Gitty::Runner
|
|
17
18
|
]
|
18
19
|
def run
|
19
20
|
puts "Initializing with gitty"
|
20
|
-
|
21
|
-
|
21
|
+
# MESSY!
|
22
|
+
mkdir_p(".git/hooks/gitty")
|
23
|
+
mkdir_p(".git/hooks/shared")
|
24
|
+
mkdir_p(".git/hooks/local")
|
25
|
+
cp((ASSETS_PATH + "helpers/hookd_wrapper").to_s, ".git/hooks/gitty/hookd_wrapper")
|
26
|
+
chmod(0755, ".git/hooks/gitty/hookd_wrapper")
|
27
|
+
if options[:sharing]
|
28
|
+
cp((ASSETS_PATH + "helpers/update-shared-hooks").to_s, ".git/hooks/gitty/update-shared-hooks")
|
29
|
+
chmod(0755, ".git/hooks/gitty/update-shared-hooks")
|
30
|
+
end
|
22
31
|
|
23
32
|
CLIENT_HOOKS.each do |hook|
|
24
|
-
|
25
|
-
|
33
|
+
if File.exist?(".git/hooks/#{hook}")
|
34
|
+
mkdir_p(".git/hooks/local/#{hook}.d")
|
35
|
+
mv(".git/hooks/#{hook}", ".git/hooks/local/#{hook}.d/original")
|
36
|
+
end
|
37
|
+
ln_sf("gitty/hookd_wrapper", ".git/hooks/#{hook}")
|
26
38
|
end
|
27
39
|
|
28
40
|
hooks_rev = remote_hooks_rev
|
@@ -43,6 +55,9 @@ class Gitty::HookCommand::Init < Gitty::Runner
|
|
43
55
|
def option_parser
|
44
56
|
super.tap do |opts|
|
45
57
|
opts.banner = "Usage: git hook init"
|
58
|
+
opts.on("-s", "--enable-sharing", "Enable sharing") do
|
59
|
+
options[:sharing] = true
|
60
|
+
end
|
46
61
|
end
|
47
62
|
end
|
48
63
|
|
@@ -11,22 +11,13 @@ class Gitty::HookCommand::Install < Gitty::Runner
|
|
11
11
|
stderr.puts "no hook named '#{@hookname}' found."
|
12
12
|
exit 1
|
13
13
|
end
|
14
|
-
|
15
|
-
hook.
|
16
|
-
if options[:kind] == :shared
|
17
|
-
stdout.puts "To propagate this change other developers, run 'git hook publish -m \"added #{hook.name}...\""
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def options
|
22
|
-
@options ||= super.update(:kind => :local)
|
14
|
+
hook.install(:local)
|
15
|
+
stdout.puts "#hook #{hook.name} has been installed."
|
23
16
|
end
|
24
17
|
|
25
18
|
def option_parser
|
26
19
|
@option_parser ||= super.tap do |opts|
|
27
20
|
opts.banner = "Usage: git hook install [opts] hook-name"
|
28
|
-
opts.on("-l", "--local", "Local hook (default)") { |l| options[:kind] = :local }
|
29
|
-
opts.on("-s", "--shared", "Remote hook") { |l| options[:kind] = :shared }
|
30
21
|
end
|
31
22
|
end
|
32
23
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Gitty::HookCommand::Share < Gitty::Runner
|
2
|
+
include FileUtils
|
3
|
+
def initialize(args, stdout = STDOUT, stderr = STDERR)
|
4
|
+
super
|
5
|
+
@hookname = args.shift
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
hook = Gitty::Hook.find(@hookname, :install_kind => :local) || Gitty::Hook.find(@hookname, :installed => false)
|
10
|
+
if hook.nil?
|
11
|
+
stderr.puts "no hook named '#{@hookname}' is available"
|
12
|
+
exit 1
|
13
|
+
end
|
14
|
+
if hook.install_kind == :shared
|
15
|
+
stderr.puts "hook #{@hookname} is already installed"
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
unless Gitty.sharing_enabled?
|
19
|
+
stderr.puts "WARNING: sharing is disabled on your repository. Run git hook init --enable-sharing to turn it on."
|
20
|
+
end
|
21
|
+
hook.share!
|
22
|
+
stdout.puts "To propagate this change other developers, run 'git hook publish -m \"added #{hook.name}...\""
|
23
|
+
end
|
24
|
+
|
25
|
+
def options
|
26
|
+
@options ||= super.update(:kind => :local)
|
27
|
+
end
|
28
|
+
|
29
|
+
def option_parser
|
30
|
+
@option_parser ||= super.tap do |opts|
|
31
|
+
opts.banner = "Usage: git hook install [opts] hook-name"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/gitty/hook.rb
CHANGED
@@ -100,28 +100,49 @@ class Gitty::Hook
|
|
100
100
|
@meta_data ||= self.class.extract_meta_data(File.read(path))
|
101
101
|
end
|
102
102
|
|
103
|
+
protected
|
104
|
+
def copy_to(which = :local)
|
105
|
+
target_hook_path = existing_directory!(self.class.installed_hooks_path(which))
|
106
|
+
target_helper_path = existing_directory!(self.class.installed_helpers_path(which))
|
107
|
+
base_directory = self.class.installed_path(which)
|
108
|
+
cp(path, target_hook_path + name)
|
109
|
+
chmod(0755, target_hook_path + name)
|
110
|
+
meta_data["targets"].each do |target|
|
111
|
+
ln_sf(
|
112
|
+
"../hooks/#{name}",
|
113
|
+
file_with_existing_directory!(base_directory + "#{target}.d" + name)
|
114
|
+
)
|
115
|
+
end
|
116
|
+
(meta_data["helpers"] || []).each do |helper|
|
117
|
+
cp(Gitty.find_asset("helpers/#{helper}"), target_helper_path + helper)
|
118
|
+
chmod(0755, target_helper_path + helper)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def destroy
|
123
|
+
target_hook_path = path
|
124
|
+
base_directory = self.class.installed_path(install_kind)
|
125
|
+
meta_data["targets"].each do |target|
|
126
|
+
targetd_path = base_directory + "#{target}.d"
|
127
|
+
rm_f(targetd_path + name)
|
128
|
+
FileUtils.rmdir(targetd_path) if Dir.glob((targetd_path + "*").to_s).empty?
|
129
|
+
end
|
130
|
+
rm(target_hook_path)
|
131
|
+
# TODO - clean up helpers
|
132
|
+
end
|
133
|
+
|
103
134
|
module AvailableHookStrategy
|
104
135
|
def install(which = :local)
|
105
|
-
|
106
|
-
target_helper_path = existing_directory!(self.class.installed_helpers_path(which))
|
107
|
-
base_directory = self.class.installed_path(which)
|
108
|
-
cp(path, target_hook_path + name)
|
109
|
-
chmod(0755, target_hook_path + name)
|
110
|
-
meta_data["targets"].each do |target|
|
111
|
-
ln_sf(
|
112
|
-
"../hooks/#{name}",
|
113
|
-
file_with_existing_directory!(base_directory + "#{target}.d" + name)
|
114
|
-
)
|
115
|
-
end
|
116
|
-
(meta_data["helpers"] || []).each do |helper|
|
117
|
-
cp(Gitty.find_asset("helpers/#{helper}"), target_helper_path + helper)
|
118
|
-
chmod(0755, target_helper_path + helper)
|
119
|
-
end
|
136
|
+
copy_to(which)
|
120
137
|
end
|
121
138
|
|
122
139
|
def uninstall
|
123
140
|
# do nothing
|
124
141
|
end
|
142
|
+
|
143
|
+
def share!
|
144
|
+
copy_to(:shared)
|
145
|
+
end
|
125
146
|
end
|
126
147
|
|
127
148
|
module InstalledHookStrategy
|
@@ -130,15 +151,13 @@ class Gitty::Hook
|
|
130
151
|
end
|
131
152
|
|
132
153
|
def uninstall
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
rm(target_hook_path)
|
141
|
-
# TODO - clean up helpers
|
154
|
+
destroy
|
155
|
+
end
|
156
|
+
|
157
|
+
def share!
|
158
|
+
return nil if install_kind == :shared
|
159
|
+
copy_to(:shared)
|
160
|
+
destroy
|
142
161
|
end
|
143
162
|
end
|
144
163
|
|
data/lib/gitty/hook_command.rb
CHANGED
data/lib/gitty.rb
CHANGED
data/spec/gitty/hook_spec.rb
CHANGED
@@ -138,4 +138,19 @@ EOF
|
|
138
138
|
File.directory?(".git/hooks/local/post-merge.d").should be_false
|
139
139
|
end
|
140
140
|
end
|
141
|
+
|
142
|
+
describe "#share" do
|
143
|
+
it "copies the hook straight to shared when uninstalled" do
|
144
|
+
hook = Gitty::Hook.find("submodule_updater")
|
145
|
+
hook.share!
|
146
|
+
Gitty::Hook.find("submodule_updater", :install_kind => :shared).should_not be_nil
|
147
|
+
end
|
148
|
+
|
149
|
+
it "copies the hook to shared and uninstalls the :local copy" do
|
150
|
+
hook = installed_hook("submodule_updater")
|
151
|
+
hook.share!
|
152
|
+
Gitty::Hook.find("submodule_updater", :install_kind => :local).should be_nil
|
153
|
+
Gitty::Hook.find("submodule_updater", :install_kind => :shared).should_not be_nil
|
154
|
+
end
|
155
|
+
end
|
141
156
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Harper
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-03-
|
12
|
+
date: 2010-03-12 00:00:00 -07:00
|
13
13
|
default_executable: git-hook
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -32,6 +32,7 @@ files:
|
|
32
32
|
- assets/helpers/git-trash
|
33
33
|
- assets/helpers/git-when-introduced
|
34
34
|
- assets/helpers/hookd_wrapper
|
35
|
+
- assets/helpers/update-shared-hooks
|
35
36
|
- assets/hooks/auto-submodules
|
36
37
|
- assets/hooks/clean-patches
|
37
38
|
- assets/hooks/git-prevent-messy-rebase
|
@@ -44,6 +45,7 @@ files:
|
|
44
45
|
- lib/gitty/commands/install.rb
|
45
46
|
- lib/gitty/commands/list.rb
|
46
47
|
- lib/gitty/commands/publish.rb
|
48
|
+
- lib/gitty/commands/share.rb
|
47
49
|
- lib/gitty/commands/shell.rb
|
48
50
|
- lib/gitty/commands/show.rb
|
49
51
|
- lib/gitty/commands/uninstall.rb
|