mercurialリポジトリをgitに変換しようと hg-fast-export.sh したら死亡

結論としては

変換元のhgリポジトリのコミッタとして "<>" が居ると死ぬらしい。

解決策

コミッタのマッピングファイルを作成して指定しましょう。端折ると死ぬ。

# マッピングファイルの例
<>=devnull <devnull@localhost>
# マッピングファイルを指定して変換
$ ../fast-export/hg-fast-export.sh -r ../editor_configs_hg/ -A ../authors

問題発生時のログとかポイントとか

  • -A を指定なしで実行
  • <> <devnull@localhost> でなんか死んでる
[ir9@hina-pc editor_config]$ ../fast-export/hg-fast-export.sh -r ../editor_configs_hg/
master: Exporting full revision 1/9 with 14/0/0 added/changed/removed files
master: Exporting simple delta revision 2/9 with 2/0/0 added/changed/removed files
master: Exporting simple delta revision 3/9 with 1/0/1 added/changed/removed files
master: Exporting simple delta revision 4/9 with 3/0/0 added/changed/removed files
master: Exporting simple delta revision 5/9 with 1/0/0 added/changed/removed files
master: Exporting simple delta revision 6/9 with 4/0/0 added/changed/removed files
fatal: Invalid raw date "<devnull@localhost> 1434525763 +0900" in ident:  <> <devnull@localhost> 1434525763 +0900
fast-import: dumping crash report to .git/fast_import_crash_11997
master: Exporting simple delta revision 7/9 with 3/0/0 added/changed/removed files
Traceback (most recent call last):
  File "../fast-export/hg-fast-export.py", line 427, in <module>
    options.statusfile,authors=a,sob=options.sob,force=options.force,hgtags=options.hgtags,notes=options.notes))
  File "../fast-export/hg-fast-export.py", line 357, in hg2git
    c=export_commit(ui,repo,rev,old_marks,max,c,authors,sob,brmap,hgtags,notes)
  File "../fast-export/hg-fast-export.py", line 218, in export_commit
    export_file_contents(ctx,man,added,hgtags)
  File "../fast-export/hg-fast-export.py", line 136, in export_file_contents
    wr(d)
  File "../fast-export/hg-fast-export.py", line 37, in wr
    wr_no_nl(msg)
  File "../fast-export/hg-fast-export.py", line 34, in wr_no_nl
    sys.stdout.write(msg)
IOError: [Errno 32] Broken pipe

改修後の上手くいったログ例

  • -A を指定したところうまくいきました
[ir9@hina-pc editor_config]$ ../fast-export/hg-fast-export.sh -r ../editor_configs_hg/ -A ../authors
Loaded 1 authors
master: Exporting full revision 1/9 with 14/0/0 added/changed/removed files
master: Exporting simple delta revision 2/9 with 2/0/0 added/changed/removed files
master: Exporting simple delta revision 3/9 with 1/0/1 added/changed/removed files
master: Exporting simple delta revision 4/9 with 3/0/0 added/changed/removed files
master: Exporting simple delta revision 5/9 with 1/0/0 added/changed/removed files
master: Exporting simple delta revision 6/9 with 4/0/0 added/changed/removed files
master: Exporting simple delta revision 7/9 with 3/0/0 added/changed/removed files
master: Exporting simple delta revision 8/9 with 8/1/0 added/changed/removed files
master: Exporting thorough delta revision 9/9 with 15/1/0 added/changed/removed files
Issued 9 commands
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:       5000
Total objects:           30 (        54 duplicates                  )
      blobs  :           14 (        39 duplicates          1 deltas of         14 attempts)
      trees  :           12 (        10 duplicates          4 deltas of         12 attempts)
      commits:            4 (         5 duplicates          0 deltas of          0 attempts)
      tags   :            0 (         0 duplicates          0 deltas of          0 attempts)
Total branches:           1 (         1 loads     )
      marks:           1024 (         9 unique    )
      atoms:             38
Memory total:          2344 KiB
       pools:          2110 KiB
     objects:           234 KiB
---------------------------------------------------------------------
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =         44
pack_report: pack_mmap_calls          =          6
pack_report: pack_open_windows        =          2 /          2
pack_report: pack_mapped              =      48588 /      48588
---------------------------------------------------------------------

ファイルパス周りの用語が解らなくなりはじめて死亡

やだ恥ずかしい……

パス例 日本語圏 英語圏
notepad.exe
.\notepad.exe
..\notepad.exe
相対パス relative path
\windows\notepad.exe absolute path
c:\windows\notepad.exe 絶対パス / フルパス fully qualified path (完全修飾パス)

…で、良いのかしら…?

ここで、完全じゃない修飾パス "qualified path" はあるのかしら? とかいう疑問もあるんですが、ドキュメントによっては次のように書かれているのがありまして…

Converts a relative or unqualified path name to a fully qualified path name.

PathResolve function | Microsoft Docs

"unqualified path" とはなんぞと(ぉ orz

書き方からし相対パスとは別物なんじゃないかと思うんですが… 良くわからんぜ…

ファイル名に数字が入ったディレクトリをExplorerで名前ソートで表示した場合、ただの文字列比較じゃない感じでソートされるヤツの文字列比較関数があったァァァァ!!!

StrCmpLogicalW

へぇえええ!!

しかしなんというか、こんな関数よく実装したよねって思う。超面倒な気がするんだけど(ぉ

(皆さんご周知の事ではありますが、偶には思い出すべきです故にあえて言いますが)VC6は糞

#include <iostream>

template<typename T>
class A
{
public:

    A()
    {
        std::cout << "A()" << std::endl;
    }

    A(const A<T>& t)
    {
        std::cout << "A<T>()" << std::endl;
    }

    template<typename U>
    A(const A<U>& u)
    {
        std::cout << "A<U>()" << std::endl;
    }

};

int main()
{
    A<int>  int1;
    A<int>  int2(int1);
    A<long> long_(int1);

    return 0;
}
// VC2005
A()
A<T>()
A<U>()

まぁ、当然ですね。

これをまだどこかの中小企業で明らかに現役で使わされているであろう VC++6.0 でコンパイルすると…

>cl /EHsc a.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

a.cpp
a.cpp(21) : error C2535: '__thiscall A<U>::A<U>(const class A<U> &)' : メンバ関数は、すでに定義または宣言されています。
        a.cpp(15) : 'A<T>::A<T>' の宣言を確認してください。
        a.cpp(26) : コンパイルされたクラスのテンプレートのインスタンス化 'A<T>' の参照を確認してください
a.cpp(31) : error C2668: 'A<int>::A<int>' : オーバーロード関数の呼び出しを解決することができません。(新機能 ; ヘルプを参照)

どうやら A(A<T>& t) と A(A<U>& u) がカブっている扱いするようです。

まぁ50歩くらい譲れば気持ちは分からんでもないので、A(A<T>& t) の方を消すとコンパイルが通ります。 A int2(int1); が A(A<U>& t) の方に解決されて、上手くやってくれるのでしょう。

// VC6
A()
A<U>()
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄」
―――――――――――――‐┬┘
                        |
       ____.____    |
     |        |        |   | 
     |        | ∧_∧ |   | 
     |        |( ´∀`)つ ミ | 
     |        |/ ⊃  ノ |   |
        ̄ ̄ ̄ ̄' ̄ ̄ ̄ ̄    |    ミ[VC6]


デフォルトコピーコンストラクタ発動してんじゃねーよ!! コピコン書いただろ! ダメって言っただろ!! なんでコンパイラ自身が自動で用意したのはOKなんだよコンナロー!!

というわけで VC6は糞

で、思いつきでコード弄くった

ホント思いつきで、A<U>() の ctor に "void* vc6_is_kuso = NULL" を追加してみました。

#include <iostream>

template<typename T>
class A
{
public:

    A()
    {
        std::cout << "A()" << std::endl;
    }

    A(const A<T>& t)
    {
        std::cout << "A<T>()" << std::endl;
    }

    template<typename U>
    A(const A<U>& u, void* vc6_is_kuso = NULL)
    {
        std::cout << "A<U>()" << std::endl;
    }

};

int main()
{
    A<int>  int1;
    A<int>  int2(int1);
    A<long> long_(int1);

    return 0;
}
// vc6
>cl /EHsc a.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

a.cpp
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:a.exe
a.obj

>a
A()
A<T>()
A<U>()
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄」
―――――――――――――‐┬┘
                        |
       ____.____    |
     |        |        |   | 
     |        | ∧_∧ |   | 
     |        |( ´∀`)つ ミ | 
     |        |/ ⊃  ノ |   |
        ̄ ̄ ̄ ̄' ̄ ̄ ̄ ̄    |    ミ[VC6] ミ[VB6]

PathQuoteSpaces() の戻り値の型がモノによって異なっていて死亡

// VC6
LWSTDAPI_(void)     PathQuoteSpacesA(LPSTR lpsz);
LWSTDAPI_(void)     PathQuoteSpacesW(LPWSTR lpsz);
// VC2003
LWSTDAPI_(void)     PathQuoteSpacesA(LPSTR lpsz);
LWSTDAPI_(void)     PathQuoteSpacesW(LPWSTR lpsz);
// VC2005
LWSTDAPI_(void)     PathQuoteSpacesA(LPSTR lpsz);
LWSTDAPI_(void)     PathQuoteSpacesW(LPWSTR lpsz);
// VC2010 // "BOOL" …だと…?
LWSTDAPI_(BOOL)     PathQuoteSpacesA(__inout_ecount(MAX_PATH) LPSTR lpsz);
LWSTDAPI_(BOOL)     PathQuoteSpacesW(__inout_ecount(MAX_PATH) LPWSTR lpsz);

えぇ…? ('A`)

http://ir9.jp/hd16/hd0627_00.png
http://ir9.jp/hd16/hd0627_01.png
http://ir9.jp/hd16/hd0627_02.png
http://ir9.jp/hd16/hd0627_03.png

(順に VC6/2003/2005/2010)




ちなみに、Web上のMSDN では 戻り値が BOOL だったりしますが、VC6/2003/2005 の ヘルプでは void となってたりします (↓順に VC6/2003/2005 の MSDN ヘルプ)

http://ir9.jp/hd16/hd0627_04.png
http://ir9.jp/hd16/hd0627_05.png
http://ir9.jp/hd16/hd0627_06.png

で、戻り値の型を環境によって変えちゃって良いんですかね…? 特に void → BOOL で戻り値が「無し」から「なんか4byteある」の状態になるので、スタックぶっ壊れないの? と思ってみたりはしますが、__stdcall → 呼び出し先の関数がスタックの調整を行うので、変わっても問題無い感じなんですかね…? 個人レベルではめっちゃおっかない感いっぱいなんですけど(ぉ

とりあえず何が言いたいかというと、おのれ Micros●ft!!!!

追記

PathUnquoteSpaces() も似たような問題がありました

Web上じゃ void なのに、SDKの定義は BOOL … どういう事だってばよ…!?

if() のカッコ内で変数定義出来なくて死亡

struct A
{
	A(){}
	A(int dummy){}

	operator bool () const {
		return true;
	}
};

if(int n = 1)
{	// 当然OK

}

if(A a(1))
{	// C2059

}

if(A a)
{	// C2059

}

if(A a = A(1))
{	// OK

}

へー

…真ん中もOKになりませんかね(ぉ