ローカルの作業フォルダを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. bitbacketgitリポジトリ作成 する
    ※githubなど他のサービスでも可
  8. 作業コピーgitで初期化 し、gitの作業コピーにする
  9. 作業コピーsubmodueを追加 する
    ※hgにサブ リポジトリのあったもの場合
  10. 作業コピー に変更を commit
  11. gitリポジトリにpush
  12. push結果を サイトで確認
    (゚Д゚)ウマー

実際には上記以外に、

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

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

準備

(準備①) gitクライアントの改行コードの変換設定の確認

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

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

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

で利用する。

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

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

git操作コマンド抜粋

パターン① ローカルの作業コピーをそのままgitリポジトリにpush

gitやhgの情報などの無い、単純な作業フォルダを作った後に以下を作業。

cd  "${作業フォルダ}"
git init
git remote add origin https://[email protected]/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 でエラーになるため。)

# 初期化
cd  "${作業コピーのフォルダ}"
git remote add origin https://[email protected]/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を行ったあとに作業。

cd  "${作業コピー用のフォルダ}"
git clone https://[email protected]/workspace/sharpvectors.git .
git reset -hard 1779a39f3c1575cd5e09cd89147e57529ca11fb1
git push --force

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

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

※ 作業年月:2020年07月

なんか納得いかない。。。。

(fork方法②) 自分でfork、ロールバック後にcommit, push版

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

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

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

# リポジトリのURLを書き換え
git remote rm origin
git remote add origin https://[email protected]/workspace/sharpvectors.git

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

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

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

※ 作業年月:2020年07月

(おまけ) メインプロジェクトにサブ モジュールを追加

# 初期化
cd  "${作業コピー用のフォルダ}"
git remote add origin https://[email protected]/workspace/repository.git

# サブ モジュールを追加
git submodule add https://[email protected]/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の様な、スタンドアロンでシンプルなクライアントを探したい。

謝辞