-
Notifications
You must be signed in to change notification settings - Fork 22
Add tcl9.0 compatibility #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Nice! Please sign off 872b4ac. |
Rebased on the updated #14, added signoff as noted. |
Yes - I tried to keep these branches independent, and there are no merge conflicts, but obviously lib/choose_repository.tcl will not work correctly on Tcl 9.0 UNLESS do_clone is updated per #16. But, I think that patch is ok again as updated just now. Let me know if/when you wish this rebased. |
This can now be rebased on the master branch that I have just pushed out. (Did you receive a notification of that event?) |
Per 6eb420e ("git-gui: Always disable the Tcl EOF character when reading", 2007-07-17), git-gui should disable Tcl's EOF character detection on all files when on Windows: the default is disabled on all other platforms (and with Tcl 9.0, is disabled on Windows too). This EOF character is for compatibility with files / applications written for file systems that know only the disc sectors allocated, and not the number of bytes used. This has nothing to do with git. But, git-gui does not set -eofchar {} on all channels. To avoid any further leakage, let's just add this to the Windows specific override of open. This override is needed only as long as Tcl 8.x is in use (Tcl 9.0 makes -eofchar {} default on all platforms). Signed-off-by: Mark Levedahl <[email protected]>
git-gui has many cases where -translation binary and -encoding binary are configured on the same channel. But, -translation binary defines a binary channel, which sets up -encoding iso8859-1 as part of its work. Tcl 8.x defines -encoding binary as an alias of -encoding iso8859-1, and this alias is deleted in Tcl 9.0. Let's delete the redundant encoding definition now. Signed-off-by: Mark Levedahl <[email protected]>
git-gui currently configures some channels as '-encoding binary' when the channel is not really binary (e.g, the channel is consumed as lines of text). In 8.6, '-encoding binary' is an alias for '-encoding iso8859), but TIP 699 removes this alias for Tcl 9.0. Let's switch to '-encoding iso8859-1' to be compatible across Tcl versions. Signed-off-by: Mark Levedahl <[email protected]>
git-gui has many instances of '-translation binary' and '-encoding $SOMETHING' on the same channel. As eofchar is always null given a prior commit, the net effect of having '-translation binary' in such configuration is only to change how text line endings are handled. For cases where the channel is opened to be consumed via gets, the eol translation is irrelevant because Tcl's gets is documented to recognize any of \n, \r, and \r\n as a line ending. So, keep only the '-encoding $SOMETHING' configuration in these cases, making the configuration more clear. Signed-off-by: Mark Levedahl <[email protected]>
This was just a rebase - no changes to code or commit messages. Yes, I got notification of update to origin/master, thank you!. Progress :^) |
Commit cfa7125 causes an unacceptable regression for me. I have files checked into the repository with CRLF ending. With this change, the diff looks like this for me: @@ -981,7 +985,7 @@ IDR_MAINFRAME MENU
POPUP "&File"
BEGIN
MENUITEM "&New\tCtrl+N", ID_FILE_NEW
- MENUITEM "New &SOM...", ID_FILE_NEW_SOM
+ MENUITEM "New &SOM...\tCtrl+M", ID_FILE_NEW_SOM
MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
MENUITEM SEPARATOR
POPUP "&Export" Apparently, the CR causes an additional line break. The command is
As you can see, the A solution is direly needed. |
Pure conjecture here, I won't be in a place where I can try / test things for a couple of days... The valid line separators are \r, \r\n, and \n, with \r retired since Apple switched to BSD unix. To my knowledge, \r \n is not a valid line ending: if git diff is introducing this on output, there is a bug that should be fixed, regardless of a workaround in gi-gui. I do not understand the mechanism where \r \n does not translate into two lines, I'll need to stare at code for a while when I can. It is possible that Tcl's crlf translation code ignores ANSI escapes, and my patch disables that translation so we get two line endings because other git-gui code now gets invoked. Does disabling the change to lib/diff.tcl in cfa7125 fix the problem you see? |
This is definitely not the case. The files have
Git has no bug here. It passes the bytes through unchanged.
If the Tcl translation would ignore the ANSI escapes, then it would see a
I'll test this in a moment. |
Reverting just the change in lib/diff.tcl does fix the problem and restores to original behavior. |
*j6t* left a comment (j6t/git-gui#15)
<#15 (comment)>
Does disabling the change to lib/diff.tcl in cfa7125
<cfa7125>
fix the problem you see?
I'll test this in a moment.
Reverting just the change in lib/diff.tcl does fix the problem and restores to original
behavior.Message ID: ***@***.***>
The "problem" is that git is splitting \r\n into \r<ansi color command>\n, sometimes.
proc read_diff consumes the output of git-diff in a gets loop, and within each line the
color codes are found/removed so the uncolored text is processed in a state machine, while
the text is also drawn on the ttext widget using colors as defined.
Without 'translation lf', any eol marker becomes \n. So, <color>\r\n becomes <color>\n,
while \r<color>\n becomes \n<color>\n, and we get two lines displayed.
With 'translation lf', \r<color>\n is parsed as two lines by read_diff, but apparently
read_diff does not advance the screen line twice.
So, leaving 'translation lf' in place is the correct thing to do, read_diff was apparently
taught long ago to deal with splitting the eol marker long ago. Will amend the commit to
do this, and add commentary about why we have to leave this in place.
I maintain that git-diff splitting the eol marker is a bug.
|
It isn't, really. If Git isn't told to do anything special with the file contents, but still regard it as text, then the The color escape is (likely) a reset. It is present in the added line, because at this point, right before the BTW, the lines look like this in - MENUITEM "New &SOM...", ID_FILE_NEW_SOM
+ MENUITEM "New &SOM...\tCtrl+M", ID_FILE_NEW_SOM^M In the removed line, |
I just discovered another case that shows that is important not to mangle the output of It also means, that the data written into the patch must not undergo any translation, either. But this seems to be the case already, because with the change in |
On 7/30/25 5:27 AM, Johannes Sixt wrote:
*j6t* left a comment (j6t/git-gui#15)
<#15 (comment)>
I just discovered another case that shows that is important not to mangle the output of
|git diff| in any way: It is required to keep /Stage Hunk/ and /Stage Line/ working. If
the line terminators are mangled, these commands do not work anymore, because the patch
that Git GUI constructs does not match the data that |git apply| sees in the repository
and files.
It also means, that the data written into the patch must not undergo any translation,
either. But this seems to be the case already, because with the change in |lib/diff.tcl|
reverted <#15 (comment)>, these
commands work again.
My bigger worry here is that there is another path where \r\n gets mangled. I've basically
avoided this in my repos by having all \n endings, even on Windows, since the 90's, and I
really only use Linux now. I need to create a repo like yours and test many things myself
before I update any patches. I should be able to get to that this weekend.
|
git-gui configures '-translation lf' on a number of channels. The default configuration is 'auto', which on input changes any occurrence of \n, \r, or \r\n to \n, and on output changes any such EOL sequence to a platform dependent value (\n on Unix, \r\n on Windows). Such translation can be necessary, but much of what is configured now is redundant. In particular, many of the channels configured this way are then consumed by gets, which already recognizes any of \n, \r, or \r\n as terminators. Configuring a channel to first change these line endings, then give the result to gets, is redundant. The valid uses of -translation lf are for output where we do not want \r\n on Windows, and for consuming entire files without going through gets, assuring that \n will be used internally. Let's remove all the others that only serve to confuse. lib/diff.tcl must have -translation lf because \r\n might be stored in the repository (e.g., on Windows, with no crlf translation enabled), and git will treat \n as the line ending, while the preceding \r is just whitespace, and these may be split by ANSI color coding. git-gui's read_diff handles this correctly as-is. Signed-off-by: Mark Levedahl <[email protected]>
Tcl 9 imposes strict requirements on namespaces for variables, while Tcl 8 does not. lib/themed.tcl does not use the fully qualified name for the "color" namespace, with result that variables are not found with Tcl 9.0. Fix this. Signed-off-by: Mark Levedahl <[email protected]>
git-gui invokes many git commands expecting output in utf-8 encoding, but git accepts extended ascii (code page unknown) as utf-8 without validating, so cannot guarantee valid utf-8 on output. In particular, using any extended ascii code page has long been acceptable on git given that everyone on a project is aware of and uses that same code page to view all data. utf-8 accepts only 7-bit ascii characters in single bytes, and any characters outside of that base set require at least two bytes for representation in unicode. Tcl is a string based language, and transcodes all input data to an internal unicode format, and to whatever format is requested on output: "pure" binary is recoded byte by byte using iso8859-1. Tcl8.x silently recodes invalid utf-8 as binary data, so extended ascii characters maintain their binary value on output but may not display correctly. Tcl 8.7 added three profiles to control this behaviour: strict (raises exceptions), replace (replaces each invalid byte with ?), and the default tcl8 maintaining the old behavior. Tcl 9 changes the default profile to strict, meaning any invalid utf-8 raises an exception that git-gui does not handle. An example of this in the git repository is commit 7eb93c8965 ("[PATCH] Simplify git script", 2005-09-07). This includes extended ascii characters in the author name and commit message. The tcl8 profile used so far has acceptable behavior given git-gui's acceptance: this allows git-gui to accept extended ascii though it may display incorrectly. Let's continue that behavior by overriding open to use the tcl8 profile on Tcl9 and later: Tcl 8.6 does not understand fconfigure -profile, and Tcl 8.7 maintains the tcl8 profile. Signed-off-by: Mark Levedahl <[email protected]>
git-gui in the prior commit learned to apply -profile tcl8 when reading files, avoiding errors on non-binary data streams whose encoding is not utf-8. But, git-gui also consumes binary data streams (generally blobs from commits) as the output of commands, and internally decodes this to support various displays. With Tcl9, errors occur in this decoding for the same reasons described in the previous commit: basically, the underlying data may contain extended ascii characters violating the assumption of utf-8 encoding. This problem has a similar fix to the prior issue: we must use the tlc8 profile when converting this data to the internal unicode format. Do so, again only on Tcl9 as Tcl8.6 does not recognize -profile, and only Tcl 9.0 makes strict the default. Signed-off-by: Mark Levedahl <[email protected]>
TclTk 9.0 is now shipping, and git-gui is now patched to support use of this newer version. Adjust required versions to allow Tcl/Tk >= 8.6, including 9.x. Signed-off-by: Mark Levedahl <[email protected]>
lib/diff.tcl again has -translation lf for the channel reading output of git-diff. I added a comment in the file stating why, and that will link future readers back to this commit. No other changes in the branch - I looked carefully at all the loops consuming output of channels modified by this, tested all with a repo containing dos line endings with changes to such lines, everything worked for me. |
Thank you very much for the update. |
Modify git-gui to work correctly under Tcl9.0 allowing this to be used in addition to Tcl 8.6. This depends upon #14.