Message ID | 89fe0380cd3a373e7e23d663b506466fd6cb5fb6.1674559397.git.gitgitgadget@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | gitk: handle long command-lines | expand |
"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com> writes: > From: Johannes Schindelin <johannes.schindelin@gmx.de> > > To avoid running into command line limitations, some of Git's commands > support the `--stdin` option. > > Let's use exactly this option in the three rev-list/log invocations in > gitk that would otherwise possibly run the danger of trying to invoke a > too-long command line. Makes perfect sense. I do not know the point of saying exactly here, though. > While it is easy to redirect either stdin or stdout in Tcl/Tk scripts, > what we need here is both. We need to capture the output, yet we also > need to pipe in the revs/files arguments via stdin (because stdin does > not have any limit, unlike the command line). To help this, we use the > neat Tcl feature where you can capture stdout and at the same time feed > a fixed string as stdin to the spawned process. Nice, so this is not about "we may have too many args to fit in our memory", but about "we may have too many args for system to spawn the subprocess with". > One non-obvious aspect about this change is that the `--stdin` option > allows to specify revs, the double-dash, and files, but *no* other > options such as `--not`. It sounds like a design mistake, which may want to be fixed, but of course gitk cannot depend on Git it runs with having such a fix, and use of "^" prefix is a good alternative (after all, "--not" was invented to save us writing ^ in front of many revs). Good.
diff --git a/gitk b/gitk index 0ae7d685904..92375ca6a2a 100755 --- a/gitk +++ b/gitk @@ -405,14 +405,16 @@ proc start_rev_list {view} { if {$revs eq {}} { return 0 } - set args [concat $vflags($view) $revs] + set args $vflags($view) } else { + set revs {} set args $vorigargs($view) } if {[catch { set fd [open [concat | git log --no-color -z --pretty=raw $show_notes \ - --parents --boundary $args "--" $files] r] + --parents --boundary $args --stdin \ + "<<[join [concat $revs "--" $files] "\\n"]"] r] } err]} { error_popup "[mc "Error executing git log:"] $err" return 0 @@ -554,13 +556,19 @@ proc updatecommits {} { set revs $newrevs set vposids($view) [lsort -unique [concat $oldpos $vposids($view)]] } - set args [concat $vflags($view) $revs --not $oldpos] + set args $vflags($view) + foreach r $oldpos { + lappend revs "^$r" + } } else { + set revs {} set args $vorigargs($view) } if {[catch { set fd [open [concat | git log --no-color -z --pretty=raw $show_notes \ - --parents --boundary $args "--" $vfilelimit($view)] r] + --parents --boundary $args --stdin \ + "<<[join [concat $revs "--" \ + $vfilelimit($view)] "\\n"]"] r] } err]} { error_popup "[mc "Error executing git log:"] $err" return @@ -10231,10 +10239,16 @@ proc getallcommits {} { foreach id $seeds { lappend ids "^$id" } + lappend ids "--" } } if {$ids ne {}} { - set fd [open [concat $cmd $ids] r] + if {$ids eq "--all"} { + set cmd [concat $cmd "--all"] + } else { + set cmd [concat $cmd --stdin "<<[join $ids "\\n"]"] + } + set fd [open $cmd r] fconfigure $fd -blocking 0 incr allcommits nowbusy allcommits