libgit2 / libgit2/libgit2sharp

i18n.commitEncoding is EVIL

オープン
#532 コメント 3 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
C#
スター
3.5k
フォーク
925
PR マージ指標
30日以内にマージされた PR はありません

説明

Recently days I am researching i18n.commitEncoding, It's real an EVIL!!

First of all, I am a Chinese that OS language is en-us with Chinese(simplified) region. The commonly used encoding is GB2312(also GBK, code page 936).

The i18n.commitEncoding was defined in here that Character encoding the commit messages are stored in; git itself does not care per se, but this information is necessary.

OK, It's mean this config will affect the commit messages. but, I have find no any documents to define the format of encoding. I open the references window of Git GUI, and find the Default File Contents Encoding field. First item is System(cp936) of change menu, however, have an item Chinese Simplified (GB2312). They are equivalent in my first impression of two items.

I created a new repository then submit 3 commits with difference i18n.commitEncoding to test they. Both of they commit messages are four words Chinese, and i18n.commitEncoding followed by default, gb2312, cp936. (pushed to https://github.com/Aimeast/TestForFirst/commits/i18n)

  • git.exe can display the second commit
  • Git GUI can display the first and third commits
  • GitHub can display the first and second commits, third commit displayed as Japanese
  • LibGit2Sharp can display the first and second commits (third commit not same with Github)

OK, the result real funny. I decompress objects files for digging.

  • The first and second commits (e2266b and 38a2b0) were stored as utf-8
  • The third commit (bd9f62) was stored as gb2312

After my analysis, git.exe can identify format start with cp and followed by code page number. So, we can explain why there is such result.

Now, let's into the issue. The code

        // NativeMethods.git_commit_message
        [DllImport(libgit2)]
        [return : MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(Utf8NoCleanupMarshaler))]
        internal static extern string git_commit_message(GitObjectSafeHandle commit);

It's always marshal as Utf-8 result in third commit message was messy code. So, I suggest that return raw data then decode string in Proxy.git_commit_message. But, the evil is .Net Framework not support some encoding which supported by git.exe.

Hereafter is my code for detect the encoding for a commit

        public static Encoding CpAsEncoding(this Commit commit)
        {
            try
            {
                var encoding = commit.Encoding;

                if (encoding.StartsWith("cp", StringComparison.OrdinalIgnoreCase))
                    return Encoding.GetEncoding(int.Parse(encoding.Substring(2)));

                return Encoding.GetEncoding(encoding);
            }
            catch
            {
                return Encoding.UTF8;
            }
        }

Not perfect codes, but It's working.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

NativeMethods.git_commit_message と Proxy.git_commit_message から始め、Commit.Encoding がどのように公開されているか、また Utf8NoCleanupMarshaler がネイティブの結果をどのように処理しているかを確認します。default、gb2312、cp936 のエンコーディングを使用した 3 つのサンプルコミットと動作を比較します。Git がサポート対象のコードページエンコーディングを宣言した場合に、コミットメッセージが正しくデコードされれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
csharp, git
領域
devtools
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。