Subject: Re: git gui: Possible to see which commands are executed?

From: Dirk Süsserott <[email-masked]>
Date: Tue, 20 May 2008 21:03:10 +0200

Shawn O. Pearce schrieb:
> Dirk Ssserott <[email-masked]> wrote:
>   
>> Is it possible to see which commands are executed by git-gui?
>>     
> ...
>   
>> It would be really cool when git-gui could show the command
>> in a different window *before* it is executed. Some database
>> frontends have an option "show SQL statement", but I think
>> that would be demanded too much.
>>     
>
> Not presently, no.  People have asked for this in the past, but
> its not as easy as it sounds.  git-gui tries to drive the plumbing
> commands when possible, not the porcelain that most humans use.
> Consequently the stream of commands that git-gui issues is quite
> different from what a human would type on the command line, yet
> the end result is equivilant.
>
> I hacked this up earlier today on my Cygwin system, just to show you
> what I mean.  With the attached patch applied I restarted git-gui
> with `git gui --trace` (which this patch introduces) and then used
> git-gui to commit this patch to its own repository.
>
> Stop me when you see a command you might type yourself.  ;-)
>   

Hi Shawn,

thanks for your patch. Actually I had problems applying it and
finally gave up. I'm using the msysGit package which seems quite
similar to the cygwin package but not in all cases, apparently.

However, you were right. The trace doesn't show the commands I
would use on a regular basis (I couldn't stop you :-)).
On the other hand it possibly helps to /understand/ (or at least
/see/) what's going on under the hood.

For that reason I'd greatly appreciate seeing your patch in some
future version of Git. It doesn't do any harm, does it? People
that don't like it can simply omit the '--trace' switch.

Junio? The list?

    Dirk

>   C:/cygwin/usr/local/git/bin/git.exe --version
>   < git version 1.5.5.1.450.gee27
>   C:/cygwin/usr/local/git/bin/git.exe --exec-path
>   < /usr/local/git/bin
>   C:/cygwin/usr/local/git/bin/git-rev-parse.exe --git-dir
>   < .git
>   C:/cygwin/usr/local/git/bin/git-rev-parse.exe --show-prefix
>   < 
>   C:/cygwin/usr/local/git/bin/git-config.exe --null --list
>   C:/cygwin/usr/local/git/bin/git-rev-parse.exe --verify HEAD
>   < 76bb40cde0e15e8d0e8493abb0bd18a5d6386ad7
>   C:/cygwin/usr/local/git/bin/git-update-index.exe -q --unmerged --ignore-missing --refresh
>   C:/cygwin/usr/local/git/bin/git-diff-index.exe --cached -z 76bb40cde0e15e8d0e8493abb0bd18a5d6386ad7
>   C:/cygwin/usr/local/git/bin/git-diff-files.exe -z
>   C:/cygwin/usr/local/git/bin/git-ls-files.exe --others -z --exclude-per-directory=.gitignore --exclude-from=.git/info/exclude
>   C:/cygwin/usr/local/git/bin/git-rev-parse.exe --verify HEAD
>   < 76bb40cde0e15e8d0e8493abb0bd18a5d6386ad7
>   C:/cygwin/usr/local/git/bin/git-update-index.exe -q --unmerged --ignore-missing --refresh
>   C:/cygwin/usr/local/git/bin/git-diff-index.exe --cached -z 76bb40cde0e15e8d0e8493abb0bd18a5d6386ad7
>   C:/cygwin/usr/local/git/bin/git-diff-files.exe -z
>   C:/cygwin/usr/local/git/bin/git-ls-files.exe --others -z --exclude-per-directory=.gitignore --exclude-from=.git/info/exclude
>   C:/cygwin/usr/local/git/bin/git-update-index.exe --add --remove -z --stdin
>   C:/cygwin/usr/local/git/bin/git-var.exe GIT_COMMITTER_IDENT
>   < Shawn O. Pearce <[email-masked]> 1211130496 -0400
>   C:/cygwin/usr/local/git/bin/git-rev-parse.exe --verify HEAD
>   < 76bb40cde0e15e8d0e8493abb0bd18a5d6386ad7
>   C:/cygwin/bin/sh.exe -c 'if test -x "$1";then exec "$@";fi'
>   C:/cygwin/bin/sh.exe .git/hooks/pre-commit 2>@1
>   C:/cygwin/bin/sh.exe -c 'if test -x "$1";then exec "$@";fi'
>   C:/cygwin/bin/sh.exe .git/hooks/commit-msg .git/GITGUI_EDITMSG 2>@1
>   C:/cygwin/usr/local/git/bin/git-write-tree.exe
>   C:/cygwin/usr/local/git/bin/git-cat-file.exe commit 76bb40cde0e15e8d0e8493abb0bd18a5d6386ad7
>   C:/cygwin/usr/local/git/bin/git-commit-tree.exe 26a475c0a74f51872513993c41e8e15286df9fa5 -p 76bb40cde0e15e8d0e8493abb0bd18a5d6386ad7 <.git/GITGUI_EDITMSG
>   < cc33ff6ec3582522edaae00354d9b96a797ecf09
>   C:/cygwin/usr/local/git/bin/git-update-ref.exe -m 'commit: git-gui: Add a --trace command line option' HEAD cc33ff6ec3582522edaae00354d9b96a797ecf09 76bb40cde0e15e8d0e8493abb0bd18a5d6386ad7
>   < 
>   C:/cygwin/bin/sh.exe -c 'if test -x "$1";then exec "$@";fi'
>   C:/cygwin/bin/sh.exe .git/hooks/post-commit 2>@1
>
> Right.  So I'm not certain how useful this patch really is.  It is
> fairly short as all calls to git go through one of three procedures.
>
>
> --8<--
> git-gui: Add a --trace command line option
>
> ---
>  git-gui.sh |   47 +++++++++++++++++++++++++++++++++++++++--------
>  1 files changed, 39 insertions(+), 8 deletions(-)
>
> diff --git a/git-gui.sh b/git-gui.sh
> index 9df4971..6a8831a 100755
> --- a/git-gui.sh
> +++ b/git-gui.sh
> @@ -122,6 +122,14 @@ set _reponame {}
>  set _iscygwin {}
>  set _search_path {}
>  
> +set _trace [lsearch -exact $argv --trace]
> +if {$_trace >= 0} {
> +	set argv [lreplace $argv $_trace $_trace]
> +	set _trace 1
> +} else {
> +	set _trace 0
> +}
> +
>  proc appname {} {
>  	global _appname
>  	return $_appname
> @@ -245,6 +253,21 @@ proc get_config {name} {
>  ##
>  ## handy utils
>  
> +proc _trace_exec {cmd} {
> +	if {!$::_trace} return
> +	set d {}
> +	foreach v $cmd {
> +		if {$d ne {}} {
> +			append d { }
> +		}
> +		if {[regexp {[ \t\r\n'"$?*]} $v]} {
> +			set v [sq $v]
> +		}
> +		append d $v
> +	}
> +	puts stderr $d
> +}
> +
>  proc _git_cmd {name} {
>  	global _git_cmd_path
>  
> @@ -339,7 +362,7 @@ proc _lappend_nice {cmd_var} {
>  }
>  
>  proc git {args} {
> -	set opt [list exec]
> +	set opt [list]
>  
>  	while {1} {
>  		switch -- [lindex $args 0] {
> @@ -359,12 +382,18 @@ proc git {args} {
>  	set cmdp [_git_cmd [lindex $args 0]]
>  	set args [lrange $args 1 end]
>  
> -	return [eval $opt $cmdp $args]
> +	_trace_exec [concat $opt $cmdp $args]
> +	set result [eval exec $opt $cmdp $args]
> +	if {$::_trace} {
> +		puts stderr "< $result"
> +	}
> +	return $result
>  }
>  
>  proc _open_stdout_stderr {cmd} {
> +	_trace_exec $cmd
>  	if {[catch {
> -			set fd [open $cmd r]
> +			set fd [open [concat [list | ] $cmd] r]
>  		} err]} {
>  		if {   [lindex $cmd end] eq {2>@1}
>  		    && $err eq {can not find channel named "1"}
> @@ -375,6 +404,7 @@ proc _open_stdout_stderr {cmd} {
>  			# to try to start it a second time.
>  			#
>  			set fd [open [concat \
> +				[list | ] \
>  				[lrange $cmd 0 end-1] \
>  				[list |& cat] \
>  				] r]
> @@ -387,7 +417,7 @@ proc _open_stdout_stderr {cmd} {
>  }
>  
>  proc git_read {args} {
> -	set opt [list |]
> +	set opt [list]
>  
>  	while {1} {
>  		switch -- [lindex $args 0] {
> @@ -415,7 +445,7 @@ proc git_read {args} {
>  }
>  
>  proc git_write {args} {
> -	set opt [list |]
> +	set opt [list]
>  
>  	while {1} {
>  		switch -- [lindex $args 0] {
> @@ -435,7 +465,8 @@ proc git_write {args} {
>  	set cmdp [_git_cmd [lindex $args 0]]
>  	set args [lrange $args 1 end]
>  
> -	return [open [concat $opt $cmdp $args] w]
> +	_trace_exec [concat $opt $cmdp $args]
> +	return [open [concat [list | ] $opt $cmdp $args] w]
>  }
>  
>  proc githook_read {hook_name args} {
> @@ -455,12 +486,12 @@ proc githook_read {hook_name args} {
>  		}
>  
>  		set scr {if test -x "$1";then exec "$@";fi}
> -		set sh_c [list | $interp -c $scr $interp $pchook]
> +		set sh_c [list $interp -c $scr $interp $pchook]
>  		return [_open_stdout_stderr [concat $sh_c $args]]
>  	}
>  
>  	if {[file executable $pchook]} {
> -		return [_open_stdout_stderr [concat [list | $pchook] $args]]
> +		return [_open_stdout_stderr [concat [list $pchook] $args]]
>  	}
>  
>  	return {}
>