Gitでローカルリポジトリを後からリモート管理にする方法
すごく初歩的な課題なのですが、ローカルでGit管理した後に、GitHubやBitBucket管理に移行する方法がが分からなかったので調べてみました。
この記事のゴール
ローカルのGitリポジトリを、新規作成したBitBucketのリポジトリにPUSHする!
背景
Gitを使う場面でよく見かけるのが、GitHubなどからCloneして使う方法ですよね。
存在するリポジトリをローカルに持ってきて使うのはその通りなのですが、自分で作ったソフトウェアをGit管理するには、どうしたらいいんだろう?と思ったのがきっかけです。
- ソフトウェアを開発するときは、先にGitHub上で空のリポジトリを作って、Cloneするところから始めないとダメ?
- ローカルでコードを書き始めてから、GitHub管理に移行するには、上記のように改めてCloneして、そこにファイルを手で移動しないとダメ?
そんな不便なはずなし!
やってみる
ローカルリポジトリを作成
ここでは、BitBucketでソースコード管理することを前提に作業を進めます。
まずは、ローカルでGit管理開始
> dev % > dev % mkdir hello > dev % cd hello > hello % echo "print('hello!');" > hello.py > hello % python hello.py hello!
とりあえず、ディレクトリ作ってHelloだけ表示するPythonプログラム作成
> hello % git init Initialized empty Git repository in /Users/momoizo/Documents/dev/hello/.git/
git init コマンドで、ローカルリポジトリ作成!
先程作った、hello.py をリポジトリに追加します。
git status で状態を見つつ、add からの commit !
> hello % git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) hello.py nothing added to commit but untracked files present (use "git add" to track) > hello % git add . > hello % git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: hello.py > hello % git commit -m "first commit" [master (root-commit) 93e51ea] first commit 1 file changed, 1 insertion(+) create mode 100644 hello.py > hello %
これで、ローカルリポジトリが作成できました。
次に、このリポジトリをBitBucketにアップしてみます。
BitBucketにリポジトリ作成
BitBucketは、Atlassian社が提供するオンラインのGitリポジトリです。
オンラインのGitリポジトリといえば、GitHubが有名ですが、BitBucketは、他にもドキュメント管理や、タスク管理などの機能も無料で使えるなどの特徴があります。
(GitHubも、いろんな機能を持っていますが)
今後、開発でそれらの機能も使ってみたいので、今回はBitBucketで作業を進めます。
Create Repositoryで先に進むと、次のような画面が出ます。
ここでポイントになるのは、「Readmeを含めますか?」です。
「No」を選んだ場合、空のリポジトリが作成され、ローカルリポジトリのPUSHも非常に簡単なのです。
でも、せっかくなので、初期ReadMeを自動生成して欲しい気も。
以降は、それぞれのパターンでPUSHの仕方を記載します。
ローカルリポジトリをPUSH(1):ReadMeを含めなかった場合
実は、空の状態でリポジトリを作ると、BitBucketの画面でローカルリポジトリをPUSHするためのコマンドを教えてくれます!
試しに、このコマンドを実行してみましょう。
> hello % git remote add origin https://momoizo@bitbucket.org/momoizo/hello_python.git > hello % git push -u origin master Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Writing objects: 100% (3/3), 233 bytes | 233.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To https://bitbucket.org/momoizo/hello_python.git * [new branch] master -> master Branch 'master' set up to track remote branch 'master' from 'origin'. > hello %
できた!簡単でしたね!
※初めて接続する場合、BitBucketの認証を求められるかもしれません。
ローカルリポジトリをPUSH(2):ReadMeを含めた場合
次に、ReadMeを含めたリポジトリを作った場合です。
この場合、画面に案内されるのは、「clone して使ってね」という操作のみです。
試しに、リモートリポジトリに接続してPUSHしてみます。
リモートリポジトリに接続
既存のリモートリポジトリがある場合は削除して、改めて追加しなおします。
> hello % git remote origin > hello % git remote rm origin > hello % git remote add origin https://momoizo@bitbucket.org/momoizo/hello_python.git > hello % git remote -v origin https://momoizo@bitbucket.org/momoizo/hello_python.git (fetch) origin https://momoizo@bitbucket.org/momoizo/hello_python.git (push) > hello %
そのままPUSH
git push コマンドでリモートリポジトリにPUSHします。 git push origin master は、originというリモートリポジトリの、master ブランチにソースコードをPUSHするという意味です。
> hello % git push origin master To https://bitbucket.org/momoizo/hello_python.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'https://momoizo@bitbucket.org/momoizo/hello_python.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. > hello %
失敗!リジェクト(拒否)されてしまいました…
ヒントを見ていると、push の前に pull して。と言っているようです。
リモートリポジトリには、ローカルにはない「ReadMeの追加」という操作が入っているので、先にその修正を取り込まないといけない(Pullしないといけない)のですね。
リモートリポジトリの内容をPULLする
指摘にしたがって、PULLしてみましょう。
> hello % git pull origin master warning: no common commits remote: Counting objects: 3, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From https://bitbucket.org/momoizo/hello_python * branch master -> FETCH_HEAD * [new branch] master -> origin/master fatal: refusing to merge unrelated histories > hello %
失敗!! 「unrelated histories」つまり、編集履歴の関連が無いのでマージ(統合)できない。ということのようです。
確かに、それぞれ別々に編集してきたので、統合が難しいのかもしれません。
ただ今回は、同じ名前のファイルが無いため(リモートは、ReadMe.mdのみ)強引にマージしても問題は起こりません。
では、やってみましょう。
mergeのオプションに「--allow-unrelated-histories」をつけることで、強制的にマージさせることが出来ます。
先程のpull コマンドの結果を見ると、リモートリポジトリの内容はローカルの「origin/master」という 新しいブランチに持ってきていることがわかります。
(実は、pull コマンドは、fetch (リモートからローカルに持ってくる)操作と、merge (統合)操作を同時に行うコマンドなのです。)
ですから、後はブランチから、ローカルの master にマージできればOKです。
merge コマンドを使いましょう。
> hello % git merge --allow-unrelated-histories origin/master -m "remote merge" Merge made by the 'recursive' strategy. README.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 README.md > hello %
README.mdが追加されました!
あとは、これをリモートにPUSHすれば…
> hello % git push origin master Enumerating objects: 6, done. Counting objects: 100% (6/6), done. Delta compression using up to 8 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (5/5), 498 bytes | 498.00 KiB/s, done. Total 5 (delta 0), reused 0 (delta 0) To https://bitbucket.org/momoizo/hello_python.git aea44a4..2f1675d master -> master > hello %
できました!
BitBucketを確認してみたところ、ソースに hello.py が追加されています。
大成功!
まとめ
リモートリポジトリが空なら(履歴が無いなら)、そのままローカルリポジトリのソースをPUSHすることが出来ました。
仮に、リモートリポジトリに中身があっても、うまくローカルリポジトリにマージすれば、PUSHすることが出来ました。
コマンド操作なので、Gitに慣れていないと混乱するかもしれませんが、簡単なケースで色々試してみてください!
それでは!
わかばちゃんと学ぶ Git使い方入門〈GitHub、Bitbucket、SourceTree〉
- 作者:湊川 あい
- 発売日: 2017/04/21
- メディア: 単行本(ソフトカバー)