From: "Florian Schüller" <florian.schueller@gmail.com>
To: paulus@ozlabs.org, git@vger.kernel.org
Cc: "Florian Schüller" <florian.schueller@gmail.com>
Subject: [PATCH 1/4] Inotify Support
Date: Wed, 8 Mar 2017 21:52:52 +0100 [thread overview]
Message-ID: <20170308205255.18976-2-florian.schueller@gmail.com> (raw)
In-Reply-To: <20170308205255.18976-1-florian.schueller@gmail.com>
Just automatically update gitk when working in a terminal on the same repo
Features:
* Detects inotify support
if inotify is not detected the options is not available
in the preferences
* Enable/Disable auto update in the preferences
* Select "debounce" time for redraw
i.e. the redraw will be postponed for the given time.
if a new change is detected in this time the redraw is postponed
even more
* Automatically scroll to the new HEAD after redrawing
* Depending on the type of change the UI is "Updated" or "Reloaded"
Open points for now:
* release watches for deleted directories seems to
cause problems in tcl-inotify (so I don't)
I'm not sure how often that happens in ".git/"
Signed-off-by: Florian Schüller <florian.schueller@gmail.com>
---
gitk | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 170 insertions(+), 1 deletion(-)
diff --git a/gitk b/gitk
index a14d7a1..a2850d7 100755
--- a/gitk
+++ b/gitk
@@ -8,6 +8,12 @@ exec wish "$0" -- "$@"
# either version 2, or (at your option) any later version.
package require Tk
+try {
+ package require inotify
+ set have_inotify true
+} on error {em} {
+ set have_inotify false
+}
proc hasworktree {} {
return [expr {[exec git rev-parse --is-bare-repository] == "false" &&
@@ -11489,6 +11495,7 @@ proc prefspage_general {notebook} {
global NS maxwidth maxgraphpct showneartags showlocalchanges
global tabstop limitdiffs autoselect autosellen extdifftool perfile_attrs
global hideremotes want_ttk have_ttk maxrefs
+ global autoupdate have_inotify autoupdatedebounce
set page [create_prefs_page $notebook.general]
@@ -11505,13 +11512,21 @@ proc prefspage_general {notebook} {
${NS}::checkbutton $page.showlocal -text [mc "Show local changes"] \
-variable showlocalchanges
grid x $page.showlocal -sticky w
+
${NS}::checkbutton $page.autoselect -text [mc "Auto-select SHA1 (length)"] \
-variable autoselect
spinbox $page.autosellen -from 1 -to 40 -width 4 -textvariable autosellen
grid x $page.autoselect $page.autosellen -sticky w
+
${NS}::checkbutton $page.hideremotes -text [mc "Hide remote refs"] \
-variable hideremotes
grid x $page.hideremotes -sticky w
+ if { $have_inotify } {
+ ${NS}::checkbutton $page.autoupdate -text [mc "Auto-update upon change (ms)"] \
+ -variable autoupdate
+ spinbox $page.autoupdatedebounce -from 10 -to 60000 -width 7 -textvariable autoupdatedebounce
+ grid x $page.autoupdate $page.autoupdatedebounce -sticky w
+ }
${NS}::label $page.ddisp -text [mc "Diff display options"]
grid $page.ddisp - -sticky w -pady 10
@@ -11765,7 +11780,8 @@ proc prefsok {} {
global oldprefs prefstop showneartags showlocalchanges
global fontpref mainfont textfont uifont
global limitdiffs treediffs perfile_attrs
- global hideremotes
+ global hideremotes autoupdate
+ global gitdir
catch {destroy $prefstop}
unset prefstop
@@ -11814,6 +11830,8 @@ proc prefsok {} {
if {$hideremotes != $oldprefs(hideremotes)} {
rereadrefs
}
+
+ handle_inotify $gitdir true
}
proc formatdate {d} {
@@ -12295,6 +12313,13 @@ set autoselect 1
set autosellen 40
set perfile_attrs 0
set want_ttk 1
+set autoupdate 1
+set autoupdatedebounce 100
+#timer id for inotify reloading
+set reload_id -1
+#timer id for inotify updating (less than reload)
+set update_id -1
+set inotify_instance -1
if {[tk windowingsystem] eq "aqua"} {
set extdifftool "opendiff"
@@ -12390,6 +12415,7 @@ set config_variables {
filesepbgcolor filesepfgcolor linehoverbgcolor linehoverfgcolor
linehoveroutlinecolor mainheadcirclecolor workingfilescirclecolor
indexcirclecolor circlecolors linkfgcolor circleoutlinecolor
+ autoupdate autoupdatedebounce
}
foreach var $config_variables {
config_init_trace $var
@@ -12477,6 +12503,149 @@ if {$i >= [llength $argv] && $revtreeargs ne {}} {
}
}
+#function to be called after inotify reload-timeout
+proc reload_helper {} {
+ #puts "RELOAD"
+ global reload_id
+ set reload_id -1
+ reloadcommits
+ set head [exec git rev-parse HEAD]
+ selbyid $head
+}
+
+#function to be called after inotify update-timeout
+proc update_helper {} {
+ #puts "UPDATE"
+ global update_id
+ set update_id -1
+ updatecommits
+ set head [exec git rev-parse HEAD]
+ selbyid $head
+}
+
+proc inotify_handler { fd } {
+ global autoupdate reload_id update_id autoupdatedebounce
+ set events [inotify_watch read]
+ set watch_info [inotify_watch info]
+ set update_view false
+ set reloadcommits false
+
+ #cancel pending timer
+ if { $reload_id ne -1 } {
+ #puts "cancel a reload"
+ after cancel $reload_id
+ set reload_id -1
+ set update_view true
+ set reloadcommits true
+ }
+
+ if { $update_id ne -1 } {
+ #puts "cancel an update"
+ after cancel $update_id
+ set update_id -1
+ set update_view true
+ }
+
+ foreach {event} $events {
+ set current_watchid [dict get $event watchid]
+ set flags [dict get $event flags]
+ set event_filename [dict get $event filename]
+
+ foreach {path watchid watch_flags} $watch_info {
+ if {$watchid eq $current_watchid} {
+ set watch_path $path
+ }
+ }
+
+ set full_filename [file join $watch_path $event_filename]
+ #check wether we should do update or reload below
+ #puts "Got: $full_filename / $event_filename ($flags)"
+
+ if {$flags eq "nD"} {
+ inotify_watch add $full_filename "nwds"
+ }
+ if {![string match *.lock $event_filename]} {
+ if { $flags eq "d" } {
+ #stuff like deleting branches should result in reloading
+ set reloadcommits true
+ }
+ set update_view true
+ }
+
+ #simple commit just needs updating right?
+ #if { $event_filename eq "COMMIT_EDITMSG" } {
+ # set reloadcommits true
+ #}
+ }
+
+ #reloadcommits or updatecommits - depending on file and operation?
+ if { $update_view } {
+ if { $reloadcommits } {
+ #puts "schedule reload"
+ set reload_id [after $autoupdatedebounce reload_helper]
+ } else {
+ #puts "schedule update"
+ set update_id [after $autoupdatedebounce update_helper]
+ }
+ }
+}
+
+proc watch_recursive { dir } {
+ inotify_watch add $dir "nwaCmMds"
+
+ foreach i [glob -nocomplain -dir $dir *] {
+ if {[file type $i] eq {directory}} {
+ watch_recursive $i
+ }
+ }
+}
+
+proc enable_inotify { dir redraw} {
+ global inotify_instance autoupdatedebounce reload_id
+
+ if { $inotify_instance ne -1 } {
+ updatecommits
+ } else {
+ set inotify_instance [inotify create "inotify_watch" "::inotify_handler"]
+ watch_recursive $dir
+ if { $redraw } {
+ set reload_id [after $autoupdatedebounce reload_helper]
+ }
+ }
+}
+
+proc disable_inotify {} {
+ global inotify_instance reload_id update_id
+
+ if { $inotify_instance ne -1 } {
+ rename inotify_watch {}
+ set inotify_instance -1
+ }
+
+ if { $reload_id ne -1 } {
+ after cancel $reload_id
+ set reload_id -1
+ }
+
+ if { $update_id ne -1 } {
+ after cancel $update_id
+ set update_id -1
+ }
+}
+
+proc handle_inotify { dir redraw } {
+ global have_inotify autoupdate
+ if { $have_inotify } {
+ if { $autoupdate } {
+ enable_inotify $dir $redraw
+ } else {
+ disable_inotify
+ }
+ }
+}
+
+handle_inotify $gitdir false
+
set nullid "0000000000000000000000000000000000000000"
set nullid2 "0000000000000000000000000000000000000001"
set nullfile "/dev/null"
--
2.9.3
next prev parent reply other threads:[~2017-03-08 21:01 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-08 20:52 [PATCH 0/4] Gitk Inotify support Florian Schüller
2017-03-08 20:52 ` Florian Schüller [this message]
2017-03-08 20:52 ` [PATCH 2/4] Update of German translation Florian Schüller
2017-03-08 20:52 ` [PATCH 3/4] Updated de-Translator Florian Schüller
2017-03-08 20:52 ` [PATCH 4/4] ignore backup files Florian Schüller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170308205255.18976-2-florian.schueller@gmail.com \
--to=florian.schueller@gmail.com \
--cc=git@vger.kernel.org \
--cc=paulus@ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).