bin/git-ctags

changeset 440
aacbd4032a4c
parent 187
84c6fa7ebc05
child 441
650cbc95b9b0
equal deleted inserted replaced
439:f1df55abb64a 440:aacbd4032a4c
1 #!/usr/bin/env ruby
2
3 # Meant for use as a git hook:
4 # CTAGS_HOOK=1 ~/.git_helpers/ctags &>/dev/null </dev/null &
5 # or an aliased cmd on demand:
6 # git config alias.ctags '!.git/hooks/ctags'
7 # or disable when you wish:
8 # CTAGS_SKIP=1 git rebase
9
10 # Create a tags file (target) using git's list of tracked files. If
11 # .git/ctags.conf exists in the repo it is passed to the ctags invocation.
12 #
13 # When run w/o env, immediately run ctags and replace tags file.
14 #
15 # When run with CTAGS_HOOK, it's assumed to be a BG process and we want to wait
16 # for git to be done applying changes no matter how the hook is triggered.
17 # Wait five seconds, then bail if we can't get a lock on the tags file or if
18 # it's been updated within the last minute. Only then, run ctags and replace
19 # the tags file.
20
21 exit if ENV['CTAGS_SKIP']
22
23 ctags = 'ctags'
24
25 dir = `git rev-parse --show-toplevel`.chomp
26
27 conf = "#{dir}/.git/ctags.conf"
28 target = "#{dir}/.tags"
29 tmp = "#{dir}/.tags.#{$$}~"
30
31 opts = File.exists?(conf) ? "--options=#{conf}" : ''
32
33 sleep 5 if ENV['CTAGS_HOOK']
34
35 open(target, File::RDONLY|File::CREAT, 0644) do |f|
36 if ENV['CTAGS_HOOK']
37 exit unless f.flock(File::LOCK_EX|File::LOCK_NB)
38 exit unless (Time.now - f.mtime) > 60
39 end
40
41 system(<<-CMD) or exit $?.exitstatus
42 git ls-files \
43 | #{ctags} --tag-relative -L - -f"#{tmp}" #{opts} \
44 && mv #{tmp} #{target}
45 CMD
46 end
47
48
49

mercurial