ローカルの作業フォルダをgitリポジトリにしてBitbucketにpushする

# 概要
> ローカルにある作業フォルダを、それをそのままgitリポジトリとして、Bitbucketもコミットしたい！
> サブ リポジトリを含むhgリポジトリのプロジェクトを、gitリポジトリ +サブ モジュールなプロジェクトとして作り直したい

昨年あたりに、BitbucketがMercurialのサポートを辞めると言う勧告があった。私は10年近くBitbucketを使っており、Mercurialのリポジトリしかなかったので、
それらMercurialのメモリアルをどうしようか考える必要に迫られた。と言っても、随分と今更だけど。

細かいことはとりあえず諦め。単にgitから仕切り直したものもあったので、その時の作業の備忘録。と、その中で他でも活用できそうなコマンドを抜粋。

2^64煎じです。

# 環境 (参考)
*  Windows 10
*  TortoiseGit
*  TortoiseHg  - チェックアウト用

# Bitbucketのhgリポジトリをgitリポジトリ化する作業の概略
ざっくり表現すると、pullしたhgの作業コピーのフォルダを、そのままgitにpullする。  
**※ hgでのこれまでのコミット履歴は一切保持しない**

## 主な作業
1. **hgリポジトリをpull** して作業コピーを作成
2. 作業コピーから **.hg** フォルダのファイルを **削除**
3. 作業コピーの **.hgignore** 確認し、 **.gitignore** に **書き直す**
4. 作業コピーの **.hgsub** **.hgsubstate** 確認し、サブ リポジトリの状況を把握しておく
5. 作業コピーの **サブ リポジトリ情報** を **削除** する。  
   (**.hgsub**、 **.hgsubstate**、 **実際のサブ リポジトリ フォルダ**)
6. **bitbacket** から **hgリポジトリ** を **削除** する  
   **※次の手順で作成するリポジトリのURLが衝突しないのであれば、無理に削除する必要は無い**
7. **bitbacket** に **gitリポジトリ** を **作成** する  
   **※githubなど他のサービスでも可**
8. **作業コピー** を **gitで初期化** し、gitの作業コピーにする
8. **作業コピー** に **submodueを追加** する  
   **※hgにサブ リポジトリのあったもの場合**
9. **作業コピー** に変更を **commit**
10. **gitリポジトリにpush**
11. push結果を **サイトで確認**  
    (ﾟДﾟ)ｳﾏｰ

実際には上記以外に、

* README.mdの画像を事前に収集し、登録方法を考え直す。
* 『ダウンロード』ページに掲載していたファイルを事前に収集し、登録し直し。
* Excel表でリポジトリの情報をまとめて、パターン分けなど整理して作業。

などを行っています。(非常に面倒臭い)

# 準備
## (準備①) gitクライアントの改行コードの変換設定の確認
git初心者の私は度々diffで心当たりのない変更が検出され、躓いたところ。gitにはFTP同様 **テキスト ファイルの改行コードを、プラットフォームに合わせて変更する** 文化がある様子。

しかし、このご時世に、最早テキスト ファイルのCRLFの存在意義がもはや感じられないので。`AutoCrLf` を `input` にして

* コミット時        ： LFに変換
* チェックアウト時に ： 変換なし

で利用する。

本来であれば変換しないほうが良いとは思うけど。元より、変換をすることがデフォルトになっている市場なので、どうせ変換するのであれば、アンチCRLF派としては、身の回りのテキスト ファイルくらいは、CRLFを根絶したい。

(最近はテキスト エディタのデフォルト設定もLFにしてる。最早 **Windowsの改行コードはCRLF** とか言っている時代じゃないので。)

![Settings - Tortoise Git.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72257/7208c95c-6186-2844-e057-fd7ff6823e38.png)


# git操作コマンド抜粋
## パターン① ローカルの作業コピーをそのままgitリポジトリにpush
gitやhgの情報などの無い、単純な作業フォルダを作った後に以下を作業。

```sh
cd  "${作業フォルダ}"
git init
git remote add origin https://userid@bitbucket.org/workspace/repository.git
git add .
git commit -m "${なんか良い感じのコミット メッセージ}"
git push -u origin master
git push --set-upstream origin master
```

実は今までコレを知らなくて。。。ローカルのソースを新規にGitに登録する際も、新規リポジトリをcloneして、そこにコピーしていたよ。。。

## パターン② ローカルの作業コピーに特定のリビジョンのサブモジュールを追加して、gitリポジトリにpush
githubのプロジェクトをBitbucketにhgリポジトリとしてコピーし、サブ リポジトリとして構築していたがリポジトリあった。

今回は、git同士に出来るので、本家のリポジトリをサブ モジュールとして登録する形にした。ただし、当時のソース状況を再現するため、当時のリビジョンも当時に合わせて追加する。

(例) SharpVectors (当方が、2015年作業当時に利用していたと思われるリビジョン)
https://github.com/ElinamLLC/SharpVectors/tree/1779a39f3c1575cd5e09cd89147e57529ca11fb1

※ サブ モジュール登録先のフォルダは予め削除して置くこと。
(残っていると **git submodule add** でエラーになるため。)

```sh
# 初期化
cd  "${作業コピーのフォルダ}"
git remote add origin https://userid@bitbucket.org/workspace/repository.git
git init

# サブ モジュールを追加し、任意のリビジョンをチェックアウト
git submodule add https://github.com/ElinamLLC/SharpVectors.git "sub/SharpVectors"
cd "sub/SharpVectors"
git checkout 1779a39f3c1575cd5e09cd89147e57529ca11fb1

# 変更を追加してcommit、push
cd  "${作業コピーのフォルダ}"
git add .
git commit -m "${なんか良い感じのコミット メッセージ}"
git push -u origin master
git push --set-upstream origin master
```

## パターン③ gitリポジトリの特定のリビジョンからforkして、gitリポジトリにpush
gitリポジトリをhgリポジトリ化した後、変更を加えているものがあった。

そのため、forkしたリポジトリを作り直し、当時のリビジョンに変更を改めて加えて、gitリポジトリ上で変更を再現しなおす。これまではhgにコミットし直したためそれ以前の履歴が無かったが、gitでやり直すことで、履歴を保持した **gitとしてのfork** に合わせる事にもなる。

なお、手法により履歴の残り方が変わるため、2つのfork方法を試した。

(ちなみに私が残すことにしたのは **fork方法②** の方)

(例)
SharpVectors (当方が作業当時に利用していたと思われるリビジョン)
https://github.com/ElinamLLC/SharpVectors/tree/1779a39f3c1575cd5e09cd89147e57529ca11fb1
対象のリビジョンのSHA-1: **1779a39f3c1575cd5e09cd89147e57529ca11fb1**

### (fork方法①) fork後にロールバック

サービス側でforkを行ったあとに作業。
![import - bitbucket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72257/bf7dd3c3-b329-1f57-7cd4-6ea2ca6d3f31.png)


```sh
cd  "${作業コピー用のフォルダ}"
git clone https://userid@bitbucket.org/workspace/sharpvectors.git .
git reset -hard 1779a39f3c1575cd5e09cd89147e57529ca11fb1
git push --force

# 変更の追加作業は至って普通なので割愛
```

変更を追加してコミットした後の、リビジョン グラフはこんな感じ。fork時点のコミット履歴は保持されたまま、派生した感じ。

※ 作業年月：2020年07月
![revision graph (1) - bitbucket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72257/396eabce-e77b-928f-f704-7dca0372f548.png)
![revision graph (2) - bitbucket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72257/3cc40e33-86e0-93a5-08da-9b613205d03a.png)

なんか納得いかない。。。。:thinking:

### (fork方法②) 自分でfork、ロールバック後にcommit, push版
コミット履歴の内容に少々納得がいかなかったで、自前でfork手順を再現にチャレンジしてみる。一応これで合っているんじゃないかなぁと思う。
なおupstreamについてはBitbucketでforkしたときにも含まれていなかったので入れていないけど。礼儀として良いのかは謎。

(そもそもforkとupstreamの関係性が理解できていないので。。。)


```sh
cd  "${作業コピー用のフォルダ}"
# 任意のリビジョンの作業コピーを作成
git clone https://github.com/ElinamLLC/SharpVectors.git .
git reset --hard 1779a39f3c1575cd5e09cd89147e57529ca11fb1

# リポジトリのURLを書き換え
git remote rm origin
git remote add origin https://userid@bitbucket.org/workspace/sharpvectors.git

# 変更を追加してcommit、push
git push -u origin master
git push --set-upstream origin master

# 変更の追加作業は至って普通なので割愛
```

リビジョン グラフはこんな感じ。当時の版で派生した感じ。

※ 作業年月：2020年07月

![revision graph (3) - bitbucket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72257/4b6a3ea7-c0ad-b942-cf63-a0833b252722.png)


### (おまけ) メインプロジェクトにサブ モジュールを追加
```sh
# 初期化
cd  "${作業コピー用のフォルダ}"
git remote add origin https://userid@bitbucket.org/workspace/repository.git

# サブ モジュールを追加
git submodule add https://userid@bitbucket.org/workspace/sharpvectors.git "sub/SharpVectors"

# 変更を追加してcommit、push
git add .
git commit -m "${なんか良い感じのコミット メッセージ}"
git push -u origin master
git push --set-upstream origin master
```

# 気になりごと
## Q. なんかpushするときに `git push` を2回やってない？
A. 違いがよくわかってない。。。 溜めに溜めていた作業だったので消化を優先してしまっていたので。。。
(origin? master? upstream? ご指摘があると嬉しいです。)

## Q. `git clone` でフォルダを自動で作ってくれるよ？
A. clone先のフォルダ名を決めるのは対話ユーザー(私)。それにWindows愛用者だけど心は **Case Sensitive** なので。
(勿論Linuxも大好き)

## Q. commitしたユーザー情報とか認証どうなっているの？
A. 全くわからん。Bitbucketにgitでcommitやpushはするのは初めてだと思ったのに、聞かれなかった気がする。。。



# 雑記
## 雑記①
これまで拘りがあってMercurialを使ってきていたわけではなく。

かれこれ10年以上前にバージョン管理のホスティング サービスを探していた時に、プライベート リポジトリが無料で無制限だったのがBitbucketだった。そして当時のBitbucketはMercurialだけだった。また、まだGitとMercurialとの戦いも評価出来る段階ではなかったので、次世代のバージョン管理を勉強する意味も兼ねてBitbucketでMercurialを使い始め、これまで使い続けていた感じ。

そんな人意外に居るのでは？と思ったりするので。似た境遇の人に届いたらと思った次第。

## 雑記②
しかし、最近の状況ではGitに軍配のあがる勢いには感じるものの、使ってみると、これまた結構複雑な仕組みで。もとより、分散管理のパラダイムを独学で全然習得出来なかった阿呆な私には、GitはMercurial以上に敷居が高く、つらい。。。

あと、Explorer Shell拡張型はコンテキスト メニューが開くのが遅くなり、日常用に ~~クソ~~ 支障をきたすので、やっぱり好きではない。

(Dropboxしかり、OneDriveしかり、Google Driveしかり。コンテキスト メニューは多用するため、瞬間で開いて欲しい身としては、いい加減勘弁して欲しい)

TortoiseHgやRapidSVNの様な、スタンドアロンでシンプルなクライアントを探したい。


# 謝辞
* ElinamLLC/SharpVectors: SharpVectors - SVG# Reloaded: SVG DOM and Rendering in C# for the .Net.
  https://github.com/ElinamLLC/SharpVectors
  参考例として、そのまま使わせて頂きました。

* git addしたらCRLF will be replaced by LFなエラー - Qiita
  https://qiita.com/suzuki-koya/items/6b9f1e79b9d662e15afe

* Gitでaddをしたらwarning: LF will be replaced by CRLFメッセージが出力された | 完璧になんてなれない
  https://sawatan.com/git/git%E3%81%A7add%E3%82%92%E3%81%97%E3%81%9F%E3%82%89warning-lf-will-be-replaced-by-crlf%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%81%8C%E5%87%BA%E5%8A%9B%E3%81%95%E3%82%8C%E3%81%9F

* Gitでaddしたら、「warning: CRLF will be replaced by LF」ってのが出た | Webフリーランスとして働く
  https://adan.jp.net/blog/programing/1748

* gitのサブモジュールにて特定のブランチやコミットを使用する | ハックノート
  https://hacknote.jp/archives/23006/

* Github内の過去のバージョンを取得する方法 - Qiita
  https://qiita.com/samurai_runner/items/7812749493554208aeae

* How do I check out a specific version of a submodule using 'git submodule'? - Stack Overflow
  https://stackoverflow.com/questions/10914022/how-do-i-check-out-a-specific-version-of-a-submodule-using-git-submodule

* 汚してしまったGitワークツリーをヘッドリビジョンに戻す
  https://lab.unicast.ne.jp/2011/06/02/%E6%B1%9A%E3%81%97%E3%81%A6%E3%81%97%E3%81%BE%E3%81%A3%E3%81%9Fgit%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%84%E3%83%AA%E3%83%BC%E3%82%92%E3%83%98%E3%83%83%E3%83%89%E3%83%AA%E3%83%93%E3%82%B8%E3%83%A7/

* [git reset (--hard/--soft)]ワーキングツリー、インデックス、HEADを使いこなす方法 - Qiita
  https://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe

* gitで特定のcommitバージョン/リビジョンを指すアレをなんと呼ぶか問題 - Qiita
  https://qiita.com/bigwheel/items/0b331451558637ee29b3