Gitで、add忘れ、commit忘れ、merge忘れ、push忘れを防止するための工夫 check-git-status
2011/05/22
2011/05/24
仕事でもgitを使い初めることになったけど、自分も含めてadd忘れ、commit忘れ、merge忘れ、push忘れが発生するだろうなと思っていた。
これらを無くすことは、結構難しい問題ではあるんだけど、自分のローカルのリポジトリの状態を一発で確認できるだけでも、対策になると考えた。
check git status
- https://github.com/smeghead/check-git-status (最新版はgithubにあります)
今回は、Ubuntu限定でシステムトレイのアイコンをクリックしたら、自分のローカルのgitリポジトリ一覧を表示して、tooltipでgit statusの結果が見れるという簡単なものを、とりあえず目指したので、gtk周りが簡単らしいという噂の、pygtkを使ってみた。
- check-git-status.py
#!/usr/bin/python import os, sys import gtk import egg.trayicon # egg == python-gnome2-extras import gitutils if len(sys.argv) != 2: exit('ERROR: required argument search path.') searchPath = sys.argv[1] trayIconImage = os.path.dirname(__file__) + '/icon.png' def callback(widget, event): repos = gitutils.notCleanRepogitoryInfos(searchPath) menu = gtk.Menu() tooltips = gtk.Tooltips() tooltips.enable() tooltips.set_delay(100) for r in repos: menuitem_x = gtk.ImageMenuItem(r['menuItem']) menuitem_x.set_image(gtk.image_new_from_file('%s/%s.png' % (os.path.dirname(__file__), r['flag']))) tooltips.set_tip(menuitem_x, r['path'] + "\n" + r['status']) menu.append(menuitem_x) menuitem_exit = gtk.MenuItem("Exit") menu.append(menuitem_exit) menuitem_exit.connect("activate", lambda x: gtk.main_quit()) menu.show_all() menu.popup(None, None, None, event.button, event.time, tray) tray = egg.trayicon.TrayIcon("TrayIcon") box = gtk.EventBox() img = gtk.Image() img.set_from_file(trayIconImage) box.add(img) tray.add(box) tray.show_all() box.connect("button-press-event", callback) gtk.main() # vim: set ts=4 sw=4 sts=4 expandtab fenc=utf-8: |
gtkに関する部分は、このファイルだけで完結してしまった。簡単でいい。
- gitutils.py
#!/usr/bin/python import os, sys import subprocess def findRepogitories(baseDir, acc): for filename in os.listdir(baseDir): fullPath = os.path.join(baseDir, filename) if os.path.isdir(fullPath) and filename == '.git': acc.append(baseDir) if os.path.isdir(fullPath): findRepogitories(fullPath, acc) return acc def execCommand(cmd, path): p = subprocess.Popen(cmd, shell=True, cwd=path, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) return p.stdout.read().strip() def createRepoInfo(path): branch = execCommand('git symbolic-ref HEAD', path) status = execCommand('git status', path) flag = 'C' if status.find('Changes not staged for commit:') > -1 else '_' flag += 'U' if status.find('Untracked files:') > -1 else '_' name = path.split('/')[-1] menuItem = name if branch != u'refs/heads/master': menuItem += ' (' + branch + ')' return { 'name': name, 'path': path, 'branch': branch, 'status': status, 'flag': flag, 'menuItem': menuItem } def getRepogitoryInfos(repogitories): return map(createRepoInfo, repogitories) def repogitoryInfos(path): repoPaths = findRepogitories(path, []) return getRepogitoryInfos(repoPaths) def notCleanRepogitoryInfos(path): return filter(lambda x: x['status'].find('working directory clean') == -1, repogitoryInfos(path)) if __name__ == '__main__': path = sys.argv[1] print 'begin test.' repoPaths = findRepogitories(path, []) repos = getRepogitoryInfos(repoPaths) print repos print 'completed test.' # vim: set ts=4 sw=4 sts=4 expandtab fenc=utf-8: |
こっちは、gitリポジトリを探したり、statusを取得したりするユーティリティを格納してるファイル。 外部コマンド呼んでるだけです。
使い方
- 第一引数に、gitリポジトリの検索対象となるディレクトリを指定します。
$ ./check-git-status.py ~/work |
- システムトレイに、アイコンが表示されるのでクリックすると、変更があるリポジトリ一覧が表示されます。
- メニュー項目のリポジトリ名にマウスオーバーすると、git statusの結果がtooltipで表示されます。
今後の展開
このツールは、仕事でも使っていくし、add忘れ、commit忘れ、merge忘れ、push忘れの全ての対策もできてないので、ちょこちょこ更新していこうと思います。
Unityで使うには
- まず、メニュー項目にアイコンを表示する設定にする。( https://blog.starbug1.com/archives/899 を参考に)
- Unityで、システムトレイに表示するアプリリストに、’check-git-status’を追加する。
gsettings set com.canonical.Unity.Panel systray-whitelist "['JavaEmbeddedFrame', 'Mumble', 'Wine', 'Skype', 'hp-systray', 'scp-dbus-service', 'Dropbox', 'check-git-status']" |