# HG changeset patch # User Meredith Howard # Date 1481406124 18000 # Node ID e731ef81637c8a097f3a81325a6036bc7ed37e71 # Parent eefccfe398e92406cef9766c4f2349fe885651bc support hg in git-ctags, deduplicate hg helper stuff diff --git a/.hg_helpers/ctags b/.hg_helpers/ctags deleted file mode 100755 --- a/.hg_helpers/ctags +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env ruby - -# Meant for use as a git hook: -# CTAGS_HOOK=1 .git/hooks/ctags &>/dev/null 60 - end - - system( <<-CMD ) or exit $?.exitstatus - hg stat -Aqn \ - | #{ctags} --tag-relative -L - -f"#{tmp}" #{opts} \ - && mv #{tmp} #{target} - CMD -end - - - diff --git a/.hg_helpers/hooks/ctags-hook b/.hg_helpers/hooks/ctags-hook deleted file mode 100755 --- a/.hg_helpers/hooks/ctags-hook +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# in repo .hg/hgrc: -# [hooks] -# changegroup = ~/.hg_helpers/hooks/ctags-hook -export CTAGS_HOOK=1 -~/.hg_helpers/ctags /dev/null 2>&1 & diff --git a/.hgrc b/.hgrc --- a/.hgrc +++ b/.hgrc @@ -19,7 +19,7 @@ pager = LESS='FSRX' less [alias] fetch = pull --rebase -ctags = !~/.hg_helpers/ctags +ctags = !~/bin/git-ctags [merge-tools] vimdiff.executable = vim diff --git a/bin/git-ctags b/bin/git-ctags --- a/bin/git-ctags +++ b/bin/git-ctags @@ -2,17 +2,27 @@ exit if ENV['CTAGS_SKIP'] ARGV.each { |o| exec('perldoc', $0) if o.match('help') } -ctags = 'ctags' +ctags_bin = ENV['CTAGS_BIN'] || 'ctags' -dir = `git rev-parse --show-toplevel`.chomp +if (dir = `git rev-parse --show-toplevel 2>/dev/null`.chomp) != '' + list_cmd = 'git ls-files' + conf = "#{dir}/.git/ctags.conf" +elsif (dir = `hg root 2>/dev/null`.chomp) != '' + list_cmd = 'hg stat -Aqn' + conf = "#{dir}/.hg/ctags.conf" +else + abort 'not an hg or git repository' +end -conf = "#{dir}/.git/ctags.conf" target = "#{dir}/.tags" tmp = "#{dir}/.tags.#{$$}~" opts = File.exists?(conf) ? "--options=#{conf}" : '' -sleep 5 if ENV['CTAGS_HOOK'] +if ENV['CTAGS_HOOK'] + fork and exit + sleep 5 +end open(target, File::RDONLY|File::CREAT, 0644) do |f| if ENV['CTAGS_HOOK'] @@ -21,8 +31,8 @@ open(target, File::RDONLY|File::CREAT, 0 end system(<<-CMD) or exit $?.exitstatus - git ls-files \ - | #{ctags} --tag-relative -L - -f"#{tmp}" #{opts} \ + #{list_cmd} \ + | #{ctags_bin} --tag-relative -L - -f"#{tmp}" #{opts} \ && mv #{tmp} #{target} CMD end @@ -38,7 +48,7 @@ git-ctags - run ctags on git tracked fil git ctags - echo 'CTAGS_HOOK=1 git ctags &' >> .git/hooks/post-checkout + echo 'CTAGS_HOOK=1 git ctags' >> .git/hooks/post-checkout git checkout some/branch CTAGS_SKIP=1 git checkout some/branch @@ -48,12 +58,35 @@ git-ctags - run ctags on git tracked fil Create a .tags file (target) using git's list of tracked files. If C<.git/ctags.conf> exists in the repo it is passed to the ctags invocation. -When run w/o env, immediately run ctags and replace tags file. +When run with C set, additional behavior is enabled to avoid excess +re-runs during multiple VCS operations, and the work is moved to background as +well. + +=head2 Mercurial + +Mercurial repositories are supported too, with git taking priority when finding +a repo root. To add a hook, in the repository C<.hg/hgrc>, add: + + [hooks] + update = CTAGS_HOOK=1 git ctags + +In a Mercurial repo, additional options can be put in C<.hg/ctags.conf>. -When run with C, it's assumed to be a BG process and we want to -wait for git to be done applying changes no matter how the hook is triggered. -Wait five seconds, then bail if we can't get a lock on the tags file or if it's -been updated within the last minute. Only then, run ctags and replace the tags -file. +=head1 ENVIRONMENT + +=head2 CTAGS_SKIP + +If true, exit immediately. + +=head2 CTAGS_HOOK + +If true, run as a VCS hook. This causes git-ctags to fork and exit, wait five +seconds, then try to lock and update the tags file if it hasn't been updated in +the last minute. + +=head2 CTAGS_BIN + +If set, use this to invoke ctags rather than assuming C can be found in +path. =cut