- 投稿日:2020-06-03T23:56:45+09:00
Rails Tutorial 第6版 学習まとめ 第3章
概要
この記事は私の知識をより確実なものにするためにRailsチュートリアル解説記事を書くことで理解を深め
勉強の一環としています。稀にとんでもない内容や間違えた内容が書いてあるかもしれませんので
ご了承ください。
できればそれとなく教えてくれますと幸いです・・・出典
Railsチュートリアルこれからやること
TwitterライクなサンプルアプリSample_appの作成を通してRailsアプリの作成方法を総合的に学習していく
本章では新しいプロジェクトSample_appの作成から始める。第2章まではかなり詳細まで記事を書いたが第3章以降
コードの量がかなり増えてくるのでRailsチュートリアルを読めばできるところは
省略して書くことにします…セットアップ
初期設定
新規でSample_appを作成し、
Gemfileを更新する。今回も本番用のpg gemをインストールしたくないので--without productionは忘れずに。
新規アプリなのでGitリポジトリを初期化する。
READMEもここで書き換えておく。
READMEを書き換えたらとりあえずコミットしておく。
GithubのSample_app用リモートリポジトリも作成しておく。
リモートリポジトリを作成したらプッシュしておく
Cloud9環境の場合はdevelopment.rbを編集し、アプリをローカル起動できるようにしておく。
とりあえず2章と同じようにhello,world表示のコードだけ追加してherokuにもプッシュしておく。演習
1.Githubのリポジトリのトップページのサイト下部にREADMEが自動表示されている。
もちろんファイルを開いて直接覗いてもいい
2.hello,world!が表示されているのが確認できる。
ここで豆知識
herokuにデプロイしたアプリのドメイン名はheroku domains
で確認できる。静的ページ
開発の習慣として常にmasterブランチ上で作業するのではなく何かを実装するタイミングで都度トピックブランチを作成
して作業するのがいい習慣と言われている。そうすることで作業の分担がしやすい。作業のくくりが見えやすいなど
様々な利点がある。
癖付けに今回から都度トピックブランチを作って作業する$ git checkout -b static-pages静的ページの生成
さっそく静的ページ用のコントローラから作成していく
$ rails g controller StaticPages home helpgenerateは省略形のgでも良い
他にも短縮形があり、そちらを覚えるのをお勧めする。
完全なコマンド 短縮形 $ rails server $ rails s $ rails console $ rails c $ rails generate $ rails g $ rails test $ rails t $ bundle install $ bundle Railsチュートリアル第6版より
https://railstutorial.jp/chapters/static_pages?version=6.0#table-shortcutsとりあえず今の段階でstatic-pagesブランチをリモートにプッシュしておく
-uオプションを使ってoriginをstatic-pagesのアップストリームに設定すると
以降はgit push
だけで同じプッシュができる。generateコマンドでコントローラを自動生成するとroutes.rbファイルも自動更新される。
今回の場合generateでhomeアクションとhelpアクションを作成したのでroutes.rbRails.application.routes.draw do get 'static_pages/home' get 'static_pages/help' # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html root "application#hello" endhomeアクションとhelpアクションのルーティングルールが自動設定されている。
さっそくローカルサーバーを立ち上げstatic_pagesのhomeページを表示してみる。
RailsはURLを指定すると(今回は/static_pages/home)ルーターを参照し、
対応するコントローラのアクションを実行する。(StaticPagesコントローラのhomeアクション)
そのあとにそのアクションに対応するビューを出力する。
静的ページのコントローラでは都度内容が変わることはないので(ページの内容が同じ)アクションは空になっている。演習
1.
$ rails g controller Foo bar baz2.destroyも短縮形dが使える。
$ rails d controller Foo静的なページの調整
現在の状態だと作成されたhomeページ、helpページはHTMLで完結しており、完全に静的なページ
つまりRailsの知識がなくても編集できるページになっているという状態。
ここで第2章のようにユーザーのデータを取得したり投稿のデータを取得したりしてその内容に応じて
表示内容を変える(動的)ような動作をするとRailsの知識(ERB)が必要になる。テストから始める
最初のテスト
aboutページを追加する前にaboutページに対するテストを先行で書いてみる。
generateコマンドでhomeとhelpページに対するテストが自動生成されているので
まずはテストを実行して問題ないことを現時点で確認しておく$ rails t ... Finished in 6.708000s, 0.2982 runs/s, 0.2982 assertions/s. 2 runs, 2 assertions, 0 failures, 0 errors, 0 skipsRed
テスト駆動開発(TDD)のサイクルは
失敗するテスト(未実装の機能に対するテスト等)を書く→失敗(RED)
実際のアプリケーションコードを書いて先に書いたテストをパスさせる→成功(GREEN)
リファクタリング(REFACTOR)の3ステップこれを踏まえてまだ作っていないAboutページのテストを書いてみる
static_pages_controller_test.rbrequire 'test_helper' class StaticPagesControllerTest < ActionDispatch::IntegrationTest ... test "should get about" do get static_pages_about_url assert_response :success end endこのコードではstatic_pagesのaboutページにGETリクエストを送って
レスポンスコードが200 OK(success)になるという内容をテストしている。もちろんまだAboutページを何も実装していないので期待通りエラーをはく
Green
先ほどのエラーメッセージをみてみる
Error: StaticPagesControllerTest#test_should_get_about: NameError: undefined local variable or method `static_pages_about_url' for #<StaticPagesControllerTest:0x000055b65cfc03b0> test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>'詳しく読み解くと
StaticPagesControllerTestのshould_get_aboutで
static_pages_about_urlなんてメソッドは定義されていないよ(AboutのURLがないよ)
と怒られている。これはルーティングを設定していないから
さっそくルーティングを追加してみる。
routes.rbに
get 'static_pages/about'
を追加する。
ルーティングを追加することでstatic_pages_about_urlというヘルパーが有効になる。もういちどテストを流すと今度は
Error: StaticPagesControllerTest#test_should_get_about: AbstractController::ActionNotFound: The action 'about' could not be found for StaticPagesController test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>'これもシンプルなエラーで
aboutアクションが見つからないよと怒られている。
ルーティングを追加して、static_pagesコントローラのaboutアクションを参照するようにした結果である。さっそくAboutアクションを追加してみる
def about endこれをstatic_pagesコントローラの中に書くだけ
アクションの中身はhomeやhelpと同じくまだ完全に静的ページなので空でOKこれでテストを流すと今度は
Error: StaticPagesControllerTest#test_should_get_about: ActionController::MissingExactTemplate: StaticPagesController#about is missing a template for request formats: text/html test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>'これはaboutテンプレート(ビュー)が見つからないよと怒られている。
これもビューを追加して対応する。
app/views/static_pages内にabout.html.erbを追加する。この状態でテストは成功(GREEN)する
Finished in 0.976764s, 3.0714 runs/s, 3.0714 assertions/s. 3 runs, 3 assertions, 0 failures, 0 errors, 0 skips少しだけ動的なページ
タイトルを動的に変更する。
勉強用にレイアウトを無効にしておく$ mv app/views/layouts/application.html.erb layout_fileこのコマンドでapplication.html.erbというレイアウトファイルの名前を一時的に変更し移動することで無効にしている。
先にタイトルのテストを書いておく
タイトルはページごとに変わればいいのでこのようなコードになる。test "should get home" do get static_pages_home_url assert_response :success assert_select "title", "Home | Ruby on Rails Tutorial Sample App" end test "should get help" do get static_pages_help_url assert_response :success assert_select "title", "Help | Ruby on Rails Tutorial Sample App" end test "should get about" do get static_pages_about_url assert_response :success assert_select "title", "About | Ruby on Rails Tutorial Sample App" endtitleタグを選択しその中身が一致することを確かめている。
もちろん未実装のためテストはREDまずはhome,help,aboutページのビューを書き換える。
それぞれのページにタイトルを設定したのでテストはGREENになる。
Finished in 0.062407s, 48.0717 runs/s, 96.1433 assertions/s. 3 runs, 6 assertions, 0 failures, 0 errors, 0 skips演習
1.ダブルクォーテーションで囲った部分(文字列)の中に#{}で変数を囲むとその変数を展開できる。
今回は変数の中にRuby on Rails Tutorial Sample Appという文字列を代入しているのでその文字列が展開される。
共通な部分は変数で代用して変更に柔軟に対応できるようにするのはどのプログラム言語でも変わらない基本事項。def setup @base_title = "Ruby on Rails Tutorial Sample App" end test "should get home" do get static_pages_home_url assert_response :success assert_select "title", "Home | #{@base_title}" end test "should get help" do get static_pages_help_url assert_response :success assert_select "title", "Help | #{@base_title}" end test "should get about" do get static_pages_about_url assert_response :success assert_select "title", "About | #{@base_title}" endレイアウトと埋め込みRuby
現段階だとhome,help,aboutのどのページもHTML構造の大半(headなどの基本タグ)が重複している。
タイトルもRuby on Rails Tutorial Sample Appは共通。
こういった重複を取り除いてDRYすることが大切。provideメソッドはビューで
provide(:シンボル,"文字列")
といった指定をすることで
yieldでシンボルに結びつけた文字列を呼び出せる。
ビューでRubyのコードが使えるのは
ビューが埋め込みRuby[ERB(Embedded RuBy)]という形式のファイルでHTML内にRubyを埋め込めるようになっているから。
<% %>で囲むと中の文を実行するだけ
<%= %>で囲むと中の文を実行して結果がテンプレートに挿入されるという違いがある。この仕組みを使ってタイトル部分を書き換えてみた結果がこちら
<% provide(:title,"Help") %> <!DOCTYPE html> <html> <head> <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title> </head>もちろんテストも通る。
このままだと共通な部分が残ってしまうのでさっそくリファクタリングしてみることにする。
まずは先ほど無効化したレイアウトファイルを有効化するmv layout_file app/views/layouts/application.html.erbそしてhome,help,aboutにそれぞれ個別に入れているtitleタグを丸ごとレイアウトファイルのタイトルタグと入れ替える。
application.html.erb<!DOCTYPE html> <html> <head> <title><%= yield(:title)%> | Ruby on Rails Tutorial Sample App</title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> </head> <body> <%= yield %> </body> </html>yieldの部分には各ページのビューの中身がそのまま代入される。
つまり各ページを表示しようとしたときに表示されているのは
各ページのビューを読み込んだapplication.html.erbである。あとはhtmlタグなどの余計なものが各ページのビューに残ってしまっていて、このままだとapplication.html.erbと
重複してしまうので不要な部分を削除し、各ページのビューはコンテンツだけにする。help.html.erb<% provide(:title,"Help") %> <h1>Help</h1> <p> Get help on the Ruby on Rails Tutorial at the <a href="https://railstutorial.jp/help">Rails Tutorial help page</a>. To get help on this sample app, see the <a href="https://railstutorial.jp/#ebook"><em>Ruby on Rails Tutorial</em> book</a>. </p>演習
1.先にContactのテストを書いておく(TDD)
static_pages_controller_test.rbtest "should get contact" do get static_pages_contact_url assert_response :success assert_select "title", "Contact | #{@base_title}" endあとはroutes.rbにcontactのルーティングを追加し、
static_pages_controllerにcontactアクションを追加し、
contactビューを作成すれば良い。Finished in 1.044651s, 3.8290 runs/s, 7.6581 assertions/s. 4 runs, 8 assertions, 0 failures, 0 errors, 0 skipsテストもパスする。
ルーティングの設定
とりあえずデプロイするためにhello,worldを表示するhelloアクションをルートURLに設定していたが
今回homeページを作ったのでそちらに移す
root 'static_pages/home'
演習
1.
static_pages_controller_test.rbtest "should get root" do get root_url assert_response :success end2.Rubyは行頭に#をつけることでその行をコメントアウトできる
ちなみにWindowsはCTRL+/でその行をコメントアウトできる。
rootURLをコメントアウトする。# root 'static_pages#home'
Error: StaticPagesControllerTest#test_should_get_root: NameError: undefined local variable or method `root_url' for #<StaticPagesControllerTest:0x000055d85cb31200> test/controllers/static_pages_controller_test.rb:10:in `block in <class:StaticPagesControllerTest>'root_urlメソッドが定義されていないとエラーが出た。
rootURLを設定したことでroot_urlヘルパーが使えるようになっていることがわかる。
本章のまとめ
3章の作業が一通り終わったので
コミットしておく
デプロイするときにはテストを走らせるとデプロイ後にバグ発見なんて言うめんどくさいことにならないのでいい。
- 投稿日:2020-06-03T23:33:28+09:00
Git 現在のブランチを名前指定せずにpushする
提起
$ git push fatal: The current branch feature/issue-xxx has no upstream branch. To push the current branch and set the remote as upstream, use git push --set-upstream origin feature/issue-xxxリモートリポジトリと関連付いてないローカルブランチをプッシュしようとするとこのメッセージが表示されます。
$ git push --set-upstream origin feature/issue-xxxメッセージで言われる通りのコマンドを実行すればプッシュされますが、typoも怖いし毎度ブランチ名を指定するのは億劫ですね。
解決
$ git push -u origin HEAD現在のブランチをリモートリポジトリに同じ名前でプッシュする便利な方法です。
-u
は--set-upstream
の省略オプション
- 2回目以降は
git push
でokさらに短くする
alias設定する
~/.zshrc
に追記するalias gp='git push' alias gpo='git push origin HEAD'使う
$ gp $ gpogit config
~/.gitconfig
に追記する[alias] p = !git push po = !git push origin HEAD使う
$ git p $ git po参考
他に書いたGit関連の記事
- 投稿日:2020-06-03T21:58:23+09:00
GitとGitHubの基礎
1. GitとGitHubとGitHub Desktop
1-1. Git とは
- アプリを時系列で、修正点を記録して、管理してくれるシステムのこと。
1-2. GitHub とは
- Gitの仕組みを用い、複数人での開発ができるツールのこと。
- Gitにおけるリモートリポジトリ(サーバー上のリポジトリ)の役割を担い、複数人がリモートリポジトリでプロダクトを共有して開発を行う。
1-3. GitHub Desktop とは
- Gitはターミナル操作するが、ターミナルでの操作の代わりができる。GitHub Desktopを使うことで、ターミナルに慣れていなくてもGitが扱えることがメリット。
- GitHub Desktopの導入:GitHub Desktopをダウンロードし、「Sign in to GitHub.com」から、メールアドレスとpasswordを入力し、gitHubにサインイン。GitHub Desktopのアカウント登録しておく。
2. GitHub Desktopの操作
2-1. GitHub Desktopでローカルリポジトリを扱えるように設定する方法
- GitHub Desktopの
Add an Existing Repository from your Hard Drive...
から、ローカルリポジトリを選択し、追加(Add Repository)する。- Add Repositoryがクリックできない場合は、Git管理用の入れ物(.gitディレクトリ)がないので、git initコマンドで作成する必要がある。
ターミナル% cd ~/projects/ローカルリポジトリ名 % git init2-2. GitHub Desktopからリモートリポジトリを作成する方法
- GitHub Desktopでコミットメッセージ(initial commit)を入力→コミット→プッシュ を行うと、リモートリポジトリがない場合、自動的にリモートリポジトリも作ってくれる。
- その時、非公開にする必要がない場合は、
Keep this code private
のチェックは外して、Publish repositoryすると、GitHub のリモートリポジトリが作成できる。2-3. GitHub Desktopからリモートリポジトリにプッシュする方法
3. GitHubの操作
3-1. GitHubのアカウント登録
- Usename(ニックネーム)、メールアドレス、Password(15文字以上 or 8文字以上で数字を含むもの)を登録。
- Freeプランを選択し、チェックボックスにはチェックは付けずにContinue。
- アンケートページはスルー(skip this step)でok。
3-2. リモートリポジトリの作成方法
名前はローカルリポジトリと同じ、Publicを選択し、リモートリポジトリを作成する。3-3. ローカルリポジトリをリモートリポジトリに紐づける方法
ターミナル% cd ~/projects/ローカルリポジトリ名 % git remote add origin GitHubに作成したリモートリポジトリのURL(https://github.com/GitHubのユーザー名/リモートリポジトリ名.git) % git remote # origin (リモートリポジトリのこと)と出れば、紐付け完了。3-4. 他人のリモートリポジトリを自分の環境に反映する方法
- 複数での開発時、誰かがアプリをリモートリポジトリに作成し、それを共有する。ローカルリポジトリは、各人がそのリモートリポジトリをダウンロードして作成する。
- リモートリポジトリの URL を指定し、そのアプリのローカルリポジトリにダウンロードする。
※ この時、.git
ディレクトリも含まれており、clone 元のリモートリポジトリが指定されてるので、プッシュは、clone 元に push される。但し、他人が勝手にプッシュできないようにする仕様として、リモートリポジトリ保有者がリモートリポジトリの Collaborators に追加することで、プッシュが可能になる。ターミナル% git clone https://github.com/ユーザー名/リモートリポジトリ名.git3-5. Github Comment Trackerの導入
- コードレビューのコメントを見落とさないためのChromeの拡張機能。
- コードレビューのコメントに対応済みかがわかりやすくなる。
- Github Comment Trackerダウンロード
4. ターミナルでのGit操作
4-1. Gitのインストール
今回はHomebrewを使用。
ターミナル% brew install git # Gitのインストール % git --version # インストールできたかを確認4-2. ターミナルでのGit操作
4-2-1. ローカルリポジトリを作成
管理したいアプリを手動でprojectsに移動し、Git管理用の入れ物(
.git
ディレクトリ)を用意する。ターミナル# 最初に、管理したいアプリを手動でprojectsに移動しとく % cd ~/projects/アプリ名 #ディレクトリ移動 % pwd #currentディレクトリを確認 % git init # .gitを作成するコマンドGit管理できているか?の確認方法
そのディレクトリに
.git
という隠しディレクトリが存在しているかで判断できる。ターミナル% cd ~/projects/アプリ名 % ls .git #.gitがあるかを確認 ls: .git: No such file or directory # Git管理できていない場合 HEAD config hooks objects refs # Git管理できている場合4-2-2. インデックスを追加する
バージョン記録したいタイミングまでの修正点を一時的に保存しておく場所(インデックス)を準備する。
ターミナル% git status # 現状を確認(インデックス追加できるディレクトリを確認)
Untracked files:
に記載されたディレクトリがインデックス追加できるので、順番に追加していく。ターミナル% git add ディレクトリ名 % git status
Changes to be committed:
に記載されていたら、インデックスに追加されている状態。4-2-3. コミットする
インデックスに入っている変更点をバージョン記録すること。
ターミナル% git status #現状を確認
Changes to be committed:
に記載されているものがコミット待ちの状態。
nothing to commit
と返ってこれば、コミット待ちのものはない状態。ターミナル% git commit -m 'initial commit' # 空のコミットでプルリクエスト作成する場合 % git commit --allow-empty -m 'create pull request'4-2-4. プッシュする
ローカルリポジトリの変更点を、リモートリポジトリに反映すること。
ターミナル% cd ~/projects/ローカルリポジトリ名 % git push origin ブランチ名4-2-5. プルする
- リモートリポジトリの変更点をローカルリポジトリに取り込むこと。
- マージ後、リモートリポジトリは最新の状態、ローカルリポジトリはマージ前の状態なので、ローカルリポジトリに反映させる必要がある。
ターミナル% git checkout master # masterブランチに移動 % git pull origin master # リモートリポジトリ(origin)のmasterブランチを反映4-2-6. LGTM後、マスターにマージする
- GitHub(リモートリポジトリ):
Merge pull request
をクリックしてマージ実行。- GitHub Desktop: Current Branch:
Master
で、Fetch origin
をクリックし、 History を確認し、Pull origin
をクリック。( Merge pull request に反映を確認)4-3. よく使うGit管理に関するコマンド
コマンド 機能 git init 対象のディレクトリをバージョン管理できる入れ物に格納してくれるイメージ git status インデックスに追加/追加されてない変更修正の確認 git add ●● ●●をインデックスに追加。※ git add . とすると「全て」を対象にできる git commit -m 'メッセージ' コミット git log コミットログの履歴確認(コミットID、コミットメッセージ、日時) git remote add origin リモートリポジトリのURL(https://github.com/GitHubのユーザー名/リモートリポジトリ名.git) ローカルリポジトリにリモートリポジトリの情報を付与し、紐づける git push origin ブランチ名 ローカルの変更点を、リモートに反映。ブランチ名 masterなら、マスターブランチにプッシュ。 git pull origin master リモートリポジトリ(origin)のマスターブランチをローカルリポジトリに反映。 git clone https://github.com/ユーザー名/リモートリポジト名.git リモートリポジトからローカルリポジトリにダウンロード cd ●● currentディレクトリを●●に移動 pwd currentディレクトリの確認 ls ●● currentディレクトリの中の●●を検索 4-4. コミットメッセージ例
コミットメーセージ 意味 Create ●● class クラス作成 Add relation with ●● リレーションの追加 Add presence validation of ●● バリデーションの追加 Add #parse_body for parse body's markdown 5. よくあるトラブル・エラー
5-1. コミット時のエラー
- コミットの時、
Please tell me who you are
というエラーが出た場合は、以下の作業を行う。- GitHub にアカウント登録、usernameとメールアドレスをコマンドで入力する。
ターミナル% git config --global user.email "GitHubに登録したメールアドレス" % git config --global user.name "GitHubに登録したusername"5-2. プッシュを取り消したい
基本、プッシュした情報をローカルリポジトリに戻すことはできない。
そこで、コミットを打ち消すコミットを生成する(git revertコマンド)。プッシュ済みのコミットを消す方法もあるが、git revertでは打ち消したコミットの記録が残る。ターミナル% git log # コミットログの確認 % git revert コミットID # 最新のコミットIDを記載ターミナルが編集できなくなるので、
:q
で脱出。GitHub Desktopを確認すると、git revertで生成したコミットが生成されている。これをpushすれば、リモートリポジトリで打ち消されているハズ。この時、ローカルからも消えるので、注意。5-3. GitHubの管理をPrivate→Publicへ!
Settings から Danger Zone の Make this repository private から変更可能。
- 投稿日:2020-06-03T20:39:19+09:00
git : リモートブランチに初めてpushしたとき表示されたエラーを解決する
はじめに
bitbucketで新しいリポジトリを作って、そのリポジトリに最初にpushするときにつまづきました。その時の解決法と原因を記録しておこうと思います。
bitbucketで新しいリポジトリを作る
ここで自分は「READMEを含めますか?」の欄で「Yes」としてREADMEを一緒に作成しました。
作ったリポジトリに向けて最初のpushをする
ローカルリポジトリでファイルを編集、add、commitまで行って、pushをするというところでerrorとなりました。
(作業ブランチはmasterです)sada@lynx:~/デスクトップ/training$ git push --set-upstream origin master To bitbucket.org:***/***.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'git@bitbucket.org:***/***.git' ヒント: Updates were rejected because the remote contains work that you do ヒント: not have locally. This is usually caused by another repository pushing ヒント: to the same ref. You may want to first integrate the remote changes ヒント: (e.g., 'git pull ...') before pushing again. ヒント: See the 'Note about fast-forwards' in 'git push --help' for details.ヒントの中に「git pullをしてみろ」とあるので実行してみると、pullでもエラーとなりました。
fatal: refusing to merge unrelated histories解決法
過去に全く同じように問題に合われていた方がいたので、参考にさせていただきました。
pullのときのエラー文にあるように、無関係なヒストリーを持ったブランチ同士であるため、mergeができなかったようです。
ちゃんと調べてみたところ
Git 2.9から mergeコマンドとpullコマンドでは,--allow-unrelated-historiesを指定しない限り,無関係なヒストリを持つ2つのブランチをマージすることはできなくなった。
とありました。結果的には「--allow-unrelated-histories」オプションを指定することでpullが成功でき、pushできました。
なぜ無関係なブランチだと言われたのか
参考元の記事でも同様の考察がされていますが、どうやら最初にREADMEを一緒に作ってリポジトリを作成したことが原因のようです。
bitbucketのブランチを見てみると、READMEが「initial commit」になっています。
- リモートのmaster -> READMEをcommit
- ローカルのmaster -> 別ファイルをcommit
リモートとローカルでそれぞれ別の過程でcommitが行われた結果、無関係なブランチと判断されたようです。
- 投稿日:2020-06-03T18:55:25+09:00
GitについてのTips
Gitリポジトリよりファイルを削除した時に変更を反映する
git rm filename.txt
filename.txt
を削除する。git rm --cached filename.txt
filename.txt
をステージングから消す(フォルダ上には残ったまま)git add -u
- 全削除ファイルをステージングに反映する。
https://stackoverflow.com/questions/12373733/staging-deleted-files
Merge のコンフリクト(衝突)を一瞬で解決する
VScodeでコンフリクト のあるファイルを開く。コンフリクト のある箇所で「マージする側の変更を適用する」「マージされる側の変更を適用する」「両方の側の変更を適用する」という選択肢が選べる。
スクリプトで対処
- https://easyengine.io/tutorials/git/git-resolve-merge-conflicts/
- 基本アイディアとしては、
>>>>>>>>
などコンフリクトのある箇所の文字列で検索しコンフリクト のあるファイルを洗い出す →git checkout --ours PATH/FILE
またはgit checkout --theirs PATH/FILE
でどちらかの変更を受け入れる。
- 投稿日:2020-06-03T17:45:47+09:00
【git/基本編】これだけは押さえてほしいgitの仕組み&コマンド完全攻略版
今回やること
gitコマンドを使えることは個人開発でもチーム開発でも必須です
特にチーム開発ではgitを使う機会が非常に多くなります
かなり基本的な仕組みとコマンドのみなので実際に使って身につけていただけたらと思います
git(基本編)
gitの仕組み
①ワークツリー
下記コマンドでワークツリーでの変更をステージに記録していきます
$ git add②ステージ
下記コマンドでステージからローカルリポジトリにコミット(記録を保存)することができます
$ git commit$ git commit -m "" # メッセージ付きで記録(変更)を保存$ git commit -v # 変更内容を確認してからcommitが可能③ローカルリポジトリ
下記コマンドでリモートリポジトリにプッシュ(送る)ことができます
$ git push リモート名 ブランチ名④リモートリポジトリ
リモートリポジトリはGitHubなどのアプリケーションなどのファイル・ディレクトリの履歴を管理するネット上の場所のことです
リモートリポジトリにファイルなどをアップロードすることでバージョンごとに履歴を管理することができるため、開発において不本意な変更があった際に簡単に戻したいバージョンに戻すことができます
もっと詳しい仕組みを知ってちゃんとgitを使いこなしたい方は下の記事をご覧ください
ブランチとは
ブランチとは現在のコミットを指しているただのポインタのことです
それでは以下のgitコマンドでブランチを新規追加していきましょう
$ git branch ブランチ名$ git branch feature # 作成したブランチに移動$ git checkout feature上の2つのコマンドを同時に行うコマンドが下のコマンドです
$ git checkout -b featureもっと詳しくブランチについて知ってから他のgitコマンドを身につけたい方は下の記事をご覧ください
開発の流れ
1. クローンを作る(コピーを作成する)
リモートリポジトリ(GitHub等)のファイルがワークツリーとローカルリポジトリ(.git directoryが)にコピーされる
$ git clone <repository url>2. ブランチを作る
$ git checkout -b feature3. プッシュする
$ git push リモート名 ブランチ名4. 修正する
プロジェクトに変更を加える
5. 完了後にコミットする
$ git add .コミットしていきます
$ git commit -m "First commit"6. プッシュする
$ git push7. Pull requestを送る
GitHub上でプルリクエストを送ります
以上がgitでの開発の流れですが説明はかなり省略しています
もっと詳しく知って実際の開発に役立てたい方は下の記事をご覧ください
新規プロジェクトをGitHubで扱う
①git init
$ git initGit に必要なファイル(.git)がダウンロードされます
②リモートリポジトリ(github)を新規で登録する
GitHubをブラウザで開き新規リポジトリを作成してください
その後下のコマンドを打ち込みます
$ git remote add origin githubのURL③プッシュする
$ git push -u origin masterかなり端折って紹介したのでもっとわかりやすい説明は下の記事からご覧ください
開発で役立つコマンド
リモートから情報を取得する
リモートリポジトリから情報を取得するには以下の2種類の方法があります
- フェッチ(fetch)
- プル(pull)
①フェッチ
以下のgitコマンドでリモートリポジトリから情報を取得できます
$ git fetch リモート名専用に作成されたブランチのワークツリー には以下のgitコマンドを使って反映していきます
$ git merge origin/master②プル
pullコマンドはこのコマンド1つで以下2つの役割を持ちます
$ git fetch origin master $ git merge origin/master実際のプルコマンドは以下です
$ git pull リモート名 ブランチ名簡単なフェッチとプルの使い方だけだとわかりにくいと思うので下の記事もご覧ください
リモート名の変更/削除
リモート名の変更
$ git remote rename 旧リモート名 新リモート名 $ git remote rename sample_app test_appリモートの削除
$ git remote rm リモート名 $ git remote rm test_appもっと詳しく知りたい方は下の記事が役立つと思います
rebaseコマンドの使い方
*基本的な使い方
$ git rebase -I HEAD~数修正したいコミットをpickからeditに変更して保存/ファイルを閉じます(コミット削除:pick~文を削除、コミット並び順変更:pick~文を並び替える)
$ git commit --amendエディタが立ち上がるのでコミットメッセージを変更してください
$ git rebase -continue*ブランチの変更を別ブランチに取り込みたい場合
$ git rebase master $ git merge feature $ git rebase -I HEAD~数修正したいコミットをpickからsquashに変更して保存/ファイルを閉じます
*コミットを分割したい場合
$ git rebase -I HEAD~数分割したいコミットをpickからeditに変更して保存/ファイルを閉じます
$ git reset HEAD^別々にgit addでステージに上げてgit commitでコミットします
$ git add . $ git commit -m "First commit" $ git add . $ git commit -m "Second commit" $ git rebase —continue以上がrebaseの使い方となりますがこれだけだとイメージが湧かないと思います
rebaseは開発において非常に重要な箇所なので是非詳しい説明は下の記事でご覧ください
ここまででgitの基本を押さえられると思います
まだまだgitコマンドはありますが、まずは今回紹介した基礎を身につけて実際に使ってみてください
開発をする際に必ず役立つと思います
今回の元記事は下の記事になります
- 投稿日:2020-06-03T17:45:47+09:00
【git/基本編】これだけわかれば100%オッケーなgitの仕組み&コマンド完全攻略版
今回やること
gitコマンドを使えることは個人開発でもチーム開発でも必須です
特にチーム開発ではgitを使う機会が非常に多くなります
かなり基本的な仕組みとコマンドのみなので実際に使って身につけていただけたらと思います
git(基本編)
gitの仕組み
①ワークツリー
下記コマンドでワークツリーでの変更をステージに記録していきます
$ git add②ステージ
下記コマンドでステージからローカルリポジトリにコミット(記録を保存)することができます
$ git commit$ git commit -m "" # メッセージ付きで記録(変更)を保存$ git commit -v # 変更内容を確認してからcommitが可能③ローカルリポジトリ
下記コマンドでリモートリポジトリにプッシュ(送る)ことができます
$ git push リモート名 ブランチ名④リモートリポジトリ
リモートリポジトリはGitHubなどのアプリケーションなどのファイル・ディレクトリの履歴を管理するネット上の場所のことです
リモートリポジトリにファイルなどをアップロードすることでバージョンごとに履歴を管理することができるため、開発において不本意な変更があった際に簡単に戻したいバージョンに戻すことができます
もっと詳しい仕組みを知ってちゃんとgitを使いこなしたい方は下の記事をご覧ください
ブランチとは
ブランチとは現在のコミットを指しているただのポインタのことです
それでは以下のgitコマンドでブランチを新規追加していきましょう
$ git branch ブランチ名$ git branch feature # 作成したブランチに移動$ git checkout feature上の2つのコマンドを同時に行うコマンドが下のコマンドです
$ git checkout -b featureもっと詳しくブランチについて知ってから他のgitコマンドを身につけたい方は下の記事をご覧ください
開発の流れ
1. クローンを作る(コピーを作成する)
リモートリポジトリ(GitHub等)のファイルがワークツリーとローカルリポジトリ(.git directoryが)にコピーされる
$ git clone <repository url>2. ブランチを作る
$ git checkout -b feature3. プッシュする
$ git push リモート名 ブランチ名4. 修正する
プロジェクトに変更を加える
5. 完了後にコミットする
$ git add .コミットしていきます
$ git commit -m "First commit"6. プッシュする
$ git push7. Pull requestを送る
GitHub上でプルリクエストを送ります
以上がgitでの開発の流れですが説明はかなり省略しています
もっと詳しく知って実際の開発に役立てたい方は下の記事をご覧ください
新規プロジェクトをGitHubで扱う
①git init
$ git initGit に必要なファイル(.git)がダウンロードされます
②リモートリポジトリ(github)を新規で登録する
GitHubをブラウザで開き新規リポジトリを作成してください
その後下のコマンドを打ち込みます
$ git remote add origin githubのURL③プッシュする
$ git push -u origin masterかなり端折って紹介したのでもっとわかりやすい説明は下の記事からご覧ください
開発で役立つコマンド
リモートから情報を取得する
リモートリポジトリから情報を取得するには以下の2種類の方法があります
- フェッチ(fetch)
- プル(pull)
①フェッチ
以下のgitコマンドでリモートリポジトリから情報を取得できます
$ git fetch リモート名専用に作成されたブランチのワークツリー には以下のgitコマンドを使って反映していきます
$ git merge origin/master②プル
pullコマンドはこのコマンド1つで以下2つの役割を持ちます
$ git fetch origin master $ git merge origin/master実際のプルコマンドは以下です
$ git pull リモート名 ブランチ名簡単なフェッチとプルの使い方だけだとわかりにくいと思うので下の記事もご覧ください
リモート名の変更/削除
リモート名の変更
$ git remote rename 旧リモート名 新リモート名 $ git remote rename sample_app test_appリモートの削除
$ git remote rm リモート名 $ git remote rm test_appもっと詳しく知りたい方は下の記事が役立つと思います
rebaseコマンドの使い方
*基本的な使い方
$ git rebase -I HEAD~数修正したいコミットをpickからeditに変更して保存/ファイルを閉じます(コミット削除:pick~文を削除、コミット並び順変更:pick~文を並び替える)
$ git commit --amendエディタが立ち上がるのでコミットメッセージを変更してください
$ git rebase -continue*ブランチの変更を別ブランチに取り込みたい場合
$ git rebase master $ git merge feature $ git rebase -I HEAD~数修正したいコミットをpickからsquashに変更して保存/ファイルを閉じます
*コミットを分割したい場合
$ git rebase -I HEAD~数分割したいコミットをpickからeditに変更して保存/ファイルを閉じます
$ git reset HEAD^別々にgit addでステージに上げてgit commitでコミットします
$ git add . $ git commit -m "First commit" $ git add . $ git commit -m "Second commit" $ git rebase —continue以上がrebaseの使い方となりますがこれだけだとイメージが湧かないと思います
rebaseは開発において非常に重要な箇所なので是非詳しい説明は下の記事でご覧ください
ここまででgitの基本を押さえられると思います
まだまだgitコマンドはありますが、まずは今回紹介した基礎を身につけて実際に使ってみてください
開発をする際に必ず役立つと思います
今回の元記事は下の記事になります
- 投稿日:2020-06-03T15:56:26+09:00
NITICNoobsによるGit/GitHub講座 第5回 〜競合を解決する〜
フライさん(loxygen)です。限界開発鯖でのだのだ言っています。
フライさんにおまかせなのだ!
説明はあまり得意ではありません。※この記事は茨城高専生向けに書かれたものです。
お説明
前回使用したリポジトリを引っ張ってきて、そこでGit Bashを開いておいてください。
現在のコミット履歴は以下のようになっています。
コンフリクト
hello.txt
がこれまでどのように編集されてきたかを見てみましょう。
add-new-func
ブランチとadd-new-func-2
ブランチの編集場所がまるっきりかぶっています。
これではadd-new-func
ブランチとadd-new-func-2
ブランチ両方の内容を取り入れることができません。
だからと言ってどちらかの変更を消し飛ばすのも人間性がありません。通常Gitは
git merge 〇〇
コマンドを打てば自動でマージしてくれますが、こうなってしまうとどうすれば良いのかわかりません。するとGitは「コンフリクト」を宣言します。コンフリクトになると、Gitの代わりに開発者自らの手で変更内容をマージする作業が必要になります。
だから開発者はコンフリクトを忌み嫌うわけですね。確認作業
前回、「マージする前に確認作業をするとお作法がいいよ」という話をしました。
どうして確認作業が必要なんですか
確認作業の説明の前に、存在意義を説明させてください。
ちょっとこの図をご覧ください。
さっき上に出した図の簡略版です。
前回のお練習の中でadd-new-func-2
ブランチを作りましたね。
同じ要領でマージしようとしてみました。すると、先程の理由でコンフリクトします。コミット履歴はこのようになります:
この後手動でマージ作業を行うわけですが、その作業を行うブランチは先程チェックアウトした
master
ブランチです。
前回master
ブランチは品質が保証されるということを記述しましたが、そんなmaster
ブランチで作業をするのは極めておっかないことはわかりますよね。
マージ作業に失敗したらバグがあったり、最悪の場合全く動かない状態のものがmaster
ブランチにコミットされてしまいます。ああ、怖い怖い!確認作業
そこで、
master
ブランチにチェックアウトした状態でのコンフリクトを防ぐために、
事前にadd-new-func-2
ブランチでコンフリクトを発生させるということを行います。
これこそが確認作業です。便宜上確認作業と読んでいますが、正式なお名前はたぶんないです。こういうことです:
master
ブランチからadd-new-func-2
に、逆方向にマージしてからmaster
にマージしています。
こうすることでマージ作業をadd-new-func-2
ブランチで行ってからmaster
にマージすることができます。
master
ブランチじゃないところでマージ作業ができるので、気が楽ですし、何より安全です。確認作業を行った上でマージしてみる
習うより慣れろ、と昔偉い人は言いました。実際にやってみましょう。
逆マージする
まずは
add-new-func-2
にmaster
をマージするんでしたね。
マージの方法は前回説明しました。やってみましょう。Bash$ git checkout add-new-func-2 Switched to branch 'add-new-func-2'. $ git merge master Auto-merging hello.txt CONFLICT (content): Merge conflict in hello.txt Automatic merge failed; fix conflicts and then commit the result.…ん?
failed
ですって?
はい。先程の理由でコンフリクトしました。
git status
も見てみましょう。Bash$ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: hello.txt no changes added to commit (use "git add" and/or "git commit -a")
You have unmerged paths
…まだマージしきれてないやつがあるで!
と言われていますね。ファイルには何が起こっている?
hello.txt
の中身を見てみましょう。
中身はcat
コマンドで見れます。もちろん任意のテキストエディタで見ても大丈夫です。Bash$ cat hello.txt上のコマンドを叩く、またはテキストファイルを任意のエディタで見ると以下のようになっています:
hello.txt<<<<<<< HEAD I am the kindest person. ======= I am the greatest people. >>>>>>> add-new-func-2世界が急に混沌に包まれてしまいました。落ち着いて読み解いて行きましょう。と言っても簡単です。
これだけです。現在のブランチ(マージ先)の状態とマージ元の変更内容が一緒に書いてあるだけです。解消する
解消方法は至って簡単で、2つのブランチの変更内容をいい感じにフュージョンしてやればOKです。1
今回の場合は、I am the kindest human.
とI am the greatest people.
をいい感じにフュージョンしてやればいいわけです。
hello.txt
をご自由に変更してみてください。
おヒント
筆者の場合は…
kindest
とgreatest
については、2つの特徴を両方取り入れて、I am the kindest and greatest ***.
にしたいhuman
とpeople
という単語は不適切2なので、person
に修正したいと考えました。
というわけで、筆者であれば以下のように修正します。
hello.txtI am the kindest and greatest person.
いい感じにフュージョンできたら、「
<<<<<<< HEAD
」から「>>>>>>> add-new-func-2
」は消してください。コンフリクト解消
全てのコンフリクトが解消できたら(今回の場合は一箇所だけなのでこれで終わりです)、いつものようにAddしてCommitしましょう。
Bash$ git add --all
git status
も見ておきましょう。Bash$ git status On branch add-new-func-2 All conflicts fixed but you are still merging. (use "git commit" to conclude merge) Changes to be committed: modified: hello.txt
All conflicts fixed but you are still merging
…「コンフリクトは全部直ったけどまだマージ作業中やで!」と言われています。まだコミットしてないからですね。コミットをしましょう。Bash$ git commit -m "Resolved conflict between master and add-new-func-2" [add-new-func-2 ef01234] Resolved conflict between master and add-new-func-2これでコンフリクトが解消され、
add-new-func-2
上でコンフリクトの修正に成功しました。
コミット履歴はこうなっています:
masterにマージする
これで
master
ブランチとのコンフリクトが起きない状態になったので、心に余裕を持ってマージすることができます。ちゃちゃっとやってしまいましょう。Bash$ git checkout master Switched to branch 'master' Updating 38f1b56..03eafb0 Fast-forward hello.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)一応
hello.txt
の中身も見てみましょう。例のごとくcat
コマンドを使用しますが、お好みのエディタで確認しても大丈夫です。Bash$ cat hello.txt I am the kindest and greatest person.先程修正した内容が正常に
master
ブランチに反映されていますね。
コミット履歴はこうなりました:
これでようやくコンフリクトした状態からのマージに成功しました。お疲れ様でした。
マージ作業を取りやめたい場合
なにか事情があって途中でマージ作業をキャンセルしたくなったとします。その時は以下のコマンドを入力してください:
Bash$ git merge --abort「コンフリクト起こらんやろ!」って場合
例えば小さい変更だったり、他の人が全くいじらなかったところを変更したりした場合などで、コンフリクトする確率は低いと判断できる場合があります。
その場合はちょっとお行儀悪いですが、確認作業を踏まずにmasterにマージして問題ないでしょう。コンフリクトしてしまった場合は、そこで直さずに
git merge --abort
を実行してから、マージする元のブランチにいって確認作業を踏むと世界が平和になります。以下に「コンフリクト起こらんやろ!と信じて
master
ブランチに直接マージしようとしたものの、コンフリクトしてしまい元のブランチで確認作業を行ったときの動き」を記しておきます。
(なお、すでにadd-new-func-2
はマージしてしまったので以下のコマンドは動きません)Bash(動きません)$ git checkout master Switched to branch 'master' $ git merge add-new-func-2 Auto-merging hello.txt CONFLICT (content): Merge conflict in hello.txt Automatic merge failed; fix conflicts and then commit the result. $ git merge --abort # 一旦マージ作業をやめる $ git checkout add-new-func-2 Switched to branch 'add-new-func-2' # 以下確認作業を行うおまとめ
- 別々のブランチで同じファイルの同じ場所を編集するとコンフリクトが起こる
- 以下の「確認作業」を踏むのが好ましい
- 1.
master
ブランチを作業中のブランチにマージする- 2. コンフリクトが発生したら以下の手段を踏む:
- 1.
>>>>>>> 〇〇
と<<<<<<< ⬜⬜
の間をいい感じにフュージョンする- 2. 全部終わったら
git add --all
してgit commit
- 3.
master
ブランチにチェックアウトする- 4. マージする
- 強制ではないので、「多分コンフリクト起こらんやろ〜」と判断できる場合は飛ばしても良い
これでブランチについてはひとまず終了です。ここまで本当にお疲れ様でした!
おリンク
第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 ブランチ(平行世界)編-1
第5回 いまここ
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編執筆者
- 投稿日:2020-06-03T15:37:02+09:00
【git】SourceTreeでリモートリポジトリがクローン出来ない【SourceTree】
経緯
リモートリポジトリを新規でクローンしようとしたところ、下記のようなエラーが発生してクローンすることが出来なかった。
エラー: remote: Forbidden fatal: unable to access 'https://username@bitbucket.org/hogehoge/hoge.git/' : The requested URL returned error: 403試したこと
git cloneコマンドを実行
結果:同様のエラーが発生した
パスワード入力を求められるようなこともナシ解決方法
ユーザー名の後にパスワードを指定する→無事クローン出来た
'https://username:password@bitbucket.org/hogehoge/hoge.git/'
- 投稿日:2020-06-03T14:27:09+09:00
開発チームの生産性・健全性を客観的に知るためにリポジトリ履歴から機械的に可視化するツールを作った
はじめに
ソフトウェア開発のチームの生産性や健全性というものは、内部の体感的として理解できるものの、外部の人間からは見えにくいものです。こういった情報の非対称性は開発チーム外の人々との関係の中での問題の原因になってきました。
また、複数の開発チームやプロダクトを束ねるEM、CTOや、管理職にとってそれぞれの状況を客観的な数字やグラフで可視化することは、全体的な戦略を考える上でも重要な参考情報になります。ですが、アンケートやプロジェクト管理を増やすほど、どんどんと開発メンバーに負担をかけてしまうことになり、計測のし過ぎによる疲れなども誘発してしまいます。
本稿では、gitリポジトリのログ情報から、いくつかのグラフを生成し、チームの状況を可視化するためのツール
gilot
を作成したので、その目的と意図、そして使い方、注意点を解説します。アプローチ方法
gilotのアプローチは、git logのデータを解析して、開発チームのアウトプットがどれだけ安定しているか、どれだけの出力があるのか、何人が実質的にコミットしているのかなどを分析して、可視化します。生産性や健全性そのものが直ちに判断できるわけではありませんが、ひとつの強力なエビデンスになることを期待しています。
バージョン管理システムのログを使う:
これまでも生産性や健全性の可視化という観点では、プロジェクト管理ツールや、アンケート調査などを通じてそれらを可視化する試みは多数あります。これらも重要な可視化のための情報ですが、もう一つの情報源としてバージョン管理システムの情報をソフトウェアプロジェクトに活かしていくという試みが近年では増えてきました。
バージョン管理システムのログは
- 実際の開発者が意識せずとも自然な活動情報が記録されている。
- プログラム言語の種別や環境によらず統一的に分析できる
などのメリットがあるため、実証的なソフトウェア・エンジニアリングの世界では注目されています。
これらの他にも、私自身がかつて自社のプロジェクトの技術的負債の可視化のために、「多くの人」が「多くの修正をしている」箇所を特定し、その技術的負債の重み付けをするという手法と実装し、マネジメントの改善に用いたことがありました。
Perl Hackers Hub 第8回 Perlによる大規模システム開発・設計のツボ(3) -技術的負債の可視化
当時はsvnとgitの2つを用いていましたが、それらのblameの結果から
SRP=R+U+((L/100)-5) R:修正リビジョンのユニーク数 U:修正ユーザのユニーク数 L:モジュールのライン数などから、単一責務原則に違反したモジュールを探索するということを行いました。
ジニ係数を用いて安定度をする
gilotでは、「チームのコミット量がどれだけ安定しているか」をジニ係数を用いて、可視化します。
ジニ係数は、不平等性をあらわす経済学の指標です。所得格差などが大きくなると1に近づき、小さくなると0に近づきます。
ジニ係数がとる値の範囲は 0 から 1 で、係数の値が大きいほどその集団における格差が大きい状態であるという評価になる。特にジニ係数が 0 である状態は、ローレンツ曲線が均等分配線に一致するような状態であり、各人の所得が均一で、格差が全くない状態を表す。逆にジニ係数が 1 である状態は、ローレンツ曲線が横軸に一致するような状態であり、たった1人が集団の全ての所得を独占している状態を表す。社会騒乱多発の警戒ラインは、0.4である。
wikipedia : ジニ係数ここでジニ係数をもう少しイメージするために、ちょっと懐かしい「世界がもし100人の村だったら」の寓話を用いて、ジニ係数を計算してみましょう。
すべての富のうち
6人が59%をもっていて
みんなアメリカ合衆国の人です
74人が39%を
20人が、たったの2%を分けあっています
「世界がもし100人の村だったら」より引用このストーリーから分かる通り、世界は不平等で一部の人に富が偏っているように思えます。この偏り度合いを数値化するにはどうしたら良いのでしょうか。その1つの方法としてジニ係数は用いられます。
カテゴリごとに下から並べて、富の累積比率と人口の累積比をプロットしていきます。この点を結んだ曲線をローレンツ曲線といいます。それに対して、すべての人が同じ富をもっていることを想定した場合の直線を均等分布線といいます。
ジニ係数は、ローレンツ曲線と均等分布線の差の積分を撮ったBの部分と、均等分布線を積分したAの部分の比率で表されます。不平等なほど格差が増えていくわけです。この村の例だと、0.59になります。
ジニ係数を用いたソーシャルゲームの健全状況の予測
このようなジニ係数は、ソーシャルゲームの健全さを測るためにも用いられてきました。一部のコアユーザのみが重課金をしていて、ライトユーザーの割合が少ないという状況が続き、格差が広がってくるとゲームは面白くなくなっていきます。健全なコミュニティでは、強いユーザーに勝ったり逆転できるかもという期待があるものです。あまりに差が付きすぎてしまうと、面白くなくなってしまいます。
コミット量の単位時間ごとの格差が大きいチームと小さいチーム
gilotで注目するのは、経済格差ではありません。また、個々人のコミット量の格差でもありません。注目するのは、「あるタイムスロットごと」の「コミット量全体」がどのようにばらついているかです。
たとえば、この1年間のうち、ある2週間には10万行位以上書き換えられたのに、その他の2週間はほとんどソースコードに触れることはなかったというケースを考えてみましょう。このような状況は、開発サイクルが重く、健全さにかけるリリースプロセスや自動テストが充実していないことによる手動テストの手間などの影が見え隠れします。
あるいは、企画フェーズと開発フェーズが極端に分かれていたり、年末・年度末に向けての開発といったロードマップ志向の開発プロセスを行うためにその時期に向けて大量の変化起こるといった場合にもジニ係数は大きく、格差が拡大していきます。
一方、継続的改善を繰り返す安定したチームは、masterなどの「本番」「リリース」ブランチへのマージが早く、ブランチの生存期間が短い傾向があります。継続的インテグレーションやデプロイメントが充実しているほど、安定してソースコードを改善していくことができます。
このように安定したアウトプットができる状態はチームが一定健全に回っていることの1つのエビデンスになりえます。開発者の生産性について、ソースコードの量自体は、なんら直接的なファクトにはなりませんが、全体に対する割合や修正の度合い、ある期間ごとのでの変化などは見る価値のある統計指標になると考えます。
gilot (ジロー)の使い方
今回開発したツールの使い方を紹介します。
GitHubはこちらです:https://github.com/hirokidaichi/gilotインストール
pip install git+https://github.com/hirokidaichi/gilot簡単な使い方
gilotは、3つのサブコマンド持っています。それをパイプで組み合わせて使います。
あるリポジトリから、グラフを作成するには単純に以下のように行います。gilot log REPO_DIR | gilot plot
gilot log
は対象リポジトリからcsvを生成します。gilot plot
はそのCSVからグラフを生成します。
gilot log
は時間がある程度かかりますので、一度CSVをファイル出力して保存し、その上でgilot plot
を行うことをおすすめします。gilot log REPO_DIR > repo.csv gilot plot -i repo.csv -o graph.png画像ではなく単に、統計情報が欲しい場合は
gilot log REPO_DIR | gilot info > stats.jsonのように、
info
サブコマンドが使えます。出力はjson形式です。gilot log REPO_DIR | gilot info | jq .ginijqコマンドと組み合わせれば、ジニ係数のみ表示するなど必要な統計情報のみを取得することもできます。
期間の指定、ブランチの指定
git logの情報取得にあたって期間を指定することができます。
2つの指定方法があり、何ヶ月間のデータを取得するかの--month
といつからのデータを取得するのかを指定できる--since
の2つのオプションがあります。デフォルトは6ヶ月間です。gilot log REPO --since 2020-01-20 -o REPO.csv gilot log REPO --month 18 -o REPO.csvまた、ログを取得するブランチも指定することができます。デフォルトでは
origin/HEAD
を参照してmasterに相当するものを指定するようにしていますが、開発チームのブランチ運用の方法に応じて指定をしてください。できるかぎり多くの人が触れる可能性があり、リリースされていたり、運用されているシステムと同じコードベースのbranchがツールの特性上は望ましいです。gilot log REPO --branch develop -o REPO.csv複数のリポジトリにまたがって、チーム運営している場合
現代的なチームでは、1つのシステムを提供するのに複数のリポジトリを1つのチームが管理していることが度々あるかと思います。
モノレポ構成になっていないようなマイクロサービスアーキテクチャではなおさら、多くのリポジトリに1つのチームが手を加えることがあるでしょう。このような場合にもそれぞれのリポジトリの結果を結合して評価することができます。単純には以下のような方法です。
gilot log repo-a > repo-a.csv gilot log repo-b > repo-b.csv gilot plot -i repo*.csvPythonのライブラリとして用いてnotebookで使う
https://github.com/hirokidaichi/gilot/blob/master/sample/sample.ipynb4つのグラフとその見方
fig.1:ジニ係数とローレンツ曲線のグラフ
タイムスロットごとのコミット行数量のローレンツ曲線とジニ係数を表示しています。ジニ係数がどの値以下であれば、安全かそうでないかという統一的指標はありません。個人的な観察としては、0.5以下であれば安定したチームのアウトプットがあり、大きければ何らかのファクターが安定したコード出力を妨げているのではないかというのが所感です。
この値は、絶対値に注目するよりも、複数の事業システムがある場合に比較してみるのがよいかもしれない。いわゆるレガシーと呼ばれるものと、最近作ってチームで開発しているものには、大きな差がでてくることがあります。
fig.2:タイムスロット(2週間)あたりのコミット量の分布
あるタイムスロットのコード出力量のヒストグラム。ピークのなだらかな山なりになると、チームの活動の安定がよりわかりやすい。外れ値がいくつもある場合、大きな機能改修・リファクタリング・棚卸しなどの削除等の影響の可能性もあります。
fig.3:タイムスロット(2週間)あたりの実際の追加・削除行数とその差
タイムスロットごとの削除行数・追加行数・総変更行数の推移。緑のエリアが多いほど、機能追加がされており、赤いエリアがリファクタリングや棚卸しなどが行われている可能性を示しています。
総変更行数における削除行数の割合をリファクタ指数として表示しています。とはいえ、単なる割合なのでリファクタリングとは限らないため注意が必要です。fig.4:タイムスロット(2週間)あたりのコミットした開発者の人数
大規模な組織での開発が進むほど、一体何人くらいが実際にはソフトウェアの開発にたずさわっているのかわかりにくくなります。
それらの実態を可視化するため、ある二週間にコミットしたひとの平均値と推移を表示している。兼務などで一部の人数しか関われていない場合なども含めて、おおよそ定常的にリポジトリに手を入れている人間(ボットも含んでしまうが。。)の数がわかる。より詳細な情報が取得したい場合には、次のようにinfoコマンドを用いてデータを取得することができる。
gilot info -i.csv | jq .authors { "mean": 13.357142857142858, "std": 4.70036238958302, "min": 4, "25%": 10, "50%": 15, "75%": 16, "max": 21 }標準偏差が大きくなったり、maxとmeanの差が激しくなる場合も不健全な状態を暗喩している可能性があります。
注意点と実態把握のための手段
gilotの出力は、あくまでリポジトリに対するアクティビティの統計データでしかありません。チームやシステムの実態を、健康診断的にあるいは、毎朝の検温と同じレベルに手軽に観察・アセスメントするためのものです。これを持って病気であるとか、不健全であるとするためのツールではありません。
より詳しい実態についての評価や比較を行いたい場合は、日本CTO協会で公表しているDX Criteriaの調査項目を利用するのがよいでしょう。こちらは、システムと企業全体の人間ドックにあたります。
ビジネスインテリジェンスのためのデータ活用が叫ばれていますが、今後エンジニアリングインテリジェンス(ソフトウェア開発のデータ分析と見える化)も重要になってきています。そのための1ツールとしてご利用ください。
活用への期待
このツールは何しろ手軽にリポジトリの状態を可視化します。情報の中にほとんど機微な情報が含まれないため、外部に公開しても問題はないのではないでしょうか。むしろ、現在我々はこんなかんじでシステム開発をしているよということがわかるようにリアルタイムで採用ページに乗ってくれたりすると、ああ、こんなかんじなんだーとわかって便利ですね。
サンプルケース
以下、著名なOSSプロジェクトのこの半年間のgilot結果を掲載します。
facebook/react
microsoft/TypeScript
tensorflow/tensorflow
pytorch/pytorch
optuna/optuna
あわせて読みたい
- 投稿日:2020-06-03T13:36:47+09:00
HerokuのビルドインサーバーGit管理
Herokuとは。
無料でWEBサービスを開発&公開できるサービスで
ApacheやPHP、データベースのインストールが不要(WEBサーバーのデフォルトはApache、DBはpostgres)。
クラウドサービスで初期費用を抑え開発可能になり、環境構築が容易である。初期設定
Herokuで無料アカウントを作成する。
$ brew install heroku/brew/herokuHerokuへログインする。
$ heroku login編集するディレクトリを作成し移動する。
$ mkdir myapp $ cd myapp //アップロードしたいアプリのディレクトリgitのリポジトリとアクセスURLを作成する。
Anyname
は任意のリポジトリ名で入力する。$ heroku create {Any}name //プロジェクトフォルダへアプリの作成 Creating ⬢ eriapptest... done https://your-app-name.herokuapp.com/ | https://git.heroku.com/{アプリ名}name.git //ドメインとgitのURLが発行される。リポジトリの新規作成し管理するフォルダでgitの初期化を行う。
$ git init //リポジトリ作成 $ git remote add heroku https://git.heroku.com/{アプリ名}.git //サーバと紐付けするコマンドPHPファイルを作成。
<?php echo 'Hello, world!!';リポジトリの変更内容を確認。
$git status変更したファイルをHerokuのリポジトリにpushする。
master
はブランチ名。コミットするファイルの指定。
$ git add . //すべてのファイル・ディレクトリファイルをコミットする。
$ git commit -m"first commit" //mオプションで単一コメントが可Herokuへソースコードの更新。
$ git push heroku masterpushするとデプロイした画面が表示される。
heroku コマンド一覧
DBの作成
Heroku postgresでDBを作成する。
- 投稿日:2020-06-03T11:12:03+09:00
【Git】新しいブランチを作成する。
- 投稿日:2020-06-03T10:22:29+09:00
CodeCommitでプルリクエスト作成したら変更点が多すぎてマージできなくなった
タイトルにもある通り、CodeCommitのコンソール上でプルリクエストを作成し、マージができない状態に陥ったのでメモ。
今回は開発ブランチ(develop)をmasterブランチにマージしようとしたときに、コンソール上に下記のエラーが発生してマージすることができませんでした。
Tips Divergence Exceeded Exception The merge cannot be completed because the divergence between the branches is too great. If you want to merge these branches, use a Git client.上記のエラーをそのまま簡単に訳すと「差分が多すぎるからマージできないよ。マージするならGitクライアント使ってね」といった感じでしょうか。
え、差分多いと(コミット数なのかな・・?)コンソール上でマージできないとかあるんですか・・・。
原因
この記事を見に来ていただいた方、すみません。
いろいろ調べては見てみたものの、具体的にこのエラーになる原因というものがつかめなかったです。もし原因や解消方法がわかる方がいらしたらコメントいただけますと幸いです
回避策
根本的な解決策にはなっていないと思いますが、いったんエラー内容に書いてある通り、ローカル上でマージして、プッシュする形でやりたかったことはできました。
- 投稿日:2020-06-03T08:21:36+09:00
NITICNoobsによるGit/GitHub講座 第3回 ~実際に使ってみよう~
自己紹介
こるくといいます。
限界開発鯖 とかいうヤバい開発者コミュニティに所属している茨城の高専生です。
前回に引き続き、私と他3人が今回もGitの使い方を説明していきます。
前回の記事が読み終わっている前提で話を進めます。はじめに
今回は、実際にGitを使っていきながら、Gitの使い方や概念を覚えます。
ここからが本番です。この記事は、茨城高専の2I向けに執筆された記事です。
実際に手を動かしなら読み進めてください。リポジトリとは?
Gitでは、1つのプロジェクトを、「リポジトリ(Repository)」といいます。
基本的に「リポジトリ」内にあるすべてのファイル・フォルダがGitによって管理されることになります。つくってみよう
百聞は一見にしかず、さっそくリポジトリをつくってみましょう。
まず、ファイルエクスプローラーで、リポジトリを作成したい場所(どこでも構いません)でGit Bash
を起動します。
起動できたら、以下のコマンドを実行してください。$ git init <作成したいリポジトリの名前>
今回は
my-first-repository
とでもしておきましょう。
そうすると、先程開いたフォルダの中に、リポジトリ名と同じフォルダが出来ていると思います。
これがリポジトリです。
しかしこのままでは、リポジトリを操作することが出来ません。
操作できるようにするために、カレントディレクトリをリポジトリのフォルダに移しましょう。
以下のコマンドを実行してください。$ cd <作成したリポジトリの名前>これで作成したリポジトリに入って、操作できるようになりました。
▼ カレントディレクトリとは
カレントディレクトリ (current directory)とは|
「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典コミットとは?
Gitの基本的な考え方であり、いちばん重要なものがこの「コミット」になります。
ここで一旦、そもそもGitがどんなツールだったかを考えます。
Gitとは、バージョン管理ツールです。
ここでいう「バージョン」とは、作業の区切り区切りを意味しています。
Gitでは、バージョンのことを「コミット(Commit)」と呼び、管理しています。
現在の状態を保存して、コミットとして記録することをコミットするといいます。(まんまですね)▼ コミットのイメージ (青丸がコミット)
それぞれのコミットには、ID、編集者、日時、変更内容、編集者のコメント、編集内容などがそれぞれ保存されています。
図のように、プロジェクトが進行していくにつれて「コミット」が積み重なっていくイメージです。
作業中のコミットのことを、HEADとよびます。やってみよう
それでは実際にコミットしてみましょう。
先程の、「リポジトリに入った状態」で、次のコマンドを実行するとコミットできます。$ git add --all $ git commit -m "<コメントの内容>"実行すると、以下のように表示されるはずです。
On branch master nothing to commit, working tree cleanどうやら失敗してしまったようです。
「コミットするものが登録されていません」と怒られてしまいました。
それでは、リポジトリ内に何かしらファイルをつくってみましょう。hello_git.txtHello, Git!今回は試しに、
hello_git.txt
というファイルをつくってみました。
そのうえで、同じコマンドをもう一度実行してみましょう。$ git add --all $ git commit -m "<コメントの内容>"[master (root-commit) e1883d2] test 1 file changed, 1 insertion(+) create mode 100644 hello_git.txtと表示されました。どうやら成功したようです。
コメントについて
コメントは、そのコミットで具体的にどんな変更をしたかわかりやすく書きましょう。
日本語でも英語でも構いませんが、共同開発の場合、プロジェクト単位で書き方を統一しましょう。コミットの方法まとめ
実際にコミットをする際には、
$ git add --all $ git commit -m "<コメント>"というコマンドを使うことが多いです。
このコマンドを実行すると、前回のコミットから変更のあったすべてのファイルをコミットすることが出来ます。
試しに、ファイルを適当に編集して、もう一度コミットしてみましょう。確認しよう
git log
実際にコミットの履歴を確認してみましょう。
以下のコマンドで確認できます。$ git log
いかがでしょうか。このように表示されるはずです。
上から、コミットのID、編集者、日時、コメントが記録されているのがわかると思います。Column
コミット数が増えていくと、単なる
git log
では見づらくなることがあります。
そういうときは、--oneline
オプションを使うことがあります。$ git log --oneline
情報量は少なくはなりますが、非常にスッキリした表示になります。
git diff
次は、ファイルの差分(変更された部分)を見てみましょう。
以下のコマンドで確認できます。$ git diff HEAD^
最新のコミットと、1つ前のコミットの間でどこが変更されたかがわかります。ワークツリーとインデックス
先程、「基本的にリポジトリ内のすべてのファイルやフォルダが管理対象になる」と書きましたが、実際には間違いです。
Gitの管理対象になるすべてのファイルとフォルダが登録されている場所を、「ワークツリー」と呼びます。(覚えなくても構いません)
また、今からコミットするファイルが登録されているところを、「インデックス」と言います。
そして、インデックスにファイルを登録することを、「ステージング」と言います。
ワークツリーとインデックス|サル先生のGit入門【プロジェクト管理ツールBacklog】
https://backlog.com/ja/git-tutorial/intro/04/ステージングされていないファイルは、コミットされません。
そのため、変更をコミットする際には、必ず「ステージング」を行う必要があります。先程からコミットのときに実行している
git add
は、実はステージングをするコマンドです。
このgit add
コマンドは、$ git add <ステージング(今からコミットしたい)ファイル名>
という構成になっています。
前回のコミットから変更のあったすべてのファイルをステージングしたい、という時は、$ git add --all実行すると、前回のコミットから変更のあったすべてのファイルをステージングします。
git status
現在のインデックスの状態や、変更されたファイルを確認するためのコマンドがあります。
$ git status
サンプルですが、このように表示されます。
このコマンドは、コミットをする前にインデックスを確認する用途に使えます。
そうすることで、コミットされてほしくないファイルがコミットされることを未然に防げます。
(個人情報とか認証情報とか。)
認証情報が含まれたコミットをpush
(後述します)すると大変なことになります。
(筆者は何度かやらかしています)▼ 参考
GCPで約800万円の請求がきた話|mun|note共同開発やリモートリポジトリ(後述)を用いた開発を行う場合、
git status
を確認するクセをつけましょう。ここだけ覚えて!今回のまとめ!
✅ Gitでは、1つのプロジェクトを「リポジトリ」という。
✅ リポジトリを操作するときには、そのフォルダにcd
する。
✅ Gitでは、作業履歴を「コミット」として保存する。
✅ 変更したファイルをすべてコミットする時 →git add .
→git commit -m "コメント"
✅git status
を確認するクセをつけよう。リンク
次回
NITICNoobsによるGit/GitHub講座 第4回 〜並行世界を創世する〜
第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 ブランチ(平行世界)編-1
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編
第4回 ブランチ(平行世界)編-1
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編執筆者
- 投稿日:2020-06-03T04:55:14+09:00
NITICNoobsによるGit/GitHub講座 第2回 ~設定しよう~
自己紹介
こるくといいます。
限界開発鯖 とかいうヤバい開発者コミュニティに所属している茨城の高専生です。
前回に引き続き、私と他3人が今回もGitの使い方をに説明していきます。
前回の記事が読み終わっている前提で話を進めます。はじめに
今回は、GitHubアカウントの取得とGitの設定です。
難しいことはありませんので、一緒に設定していきましょう。この記事は、茨城高専の2I向けに執筆された記事です。
実際に手を動かしなら読み進めてください。GitHubアカウントを取得する
アカウントは、こちらから取得できます。
リンクに飛ぶとこんな画面が開きます。
Username
、Email address
、Password
それぞれに入力してください。
一番最後のチェックボックスは、ニュースレターを受け取るかどうかです。
お好みでどうぞ。
あなたの属性を聞かれます。
学生ならばStudent
を選択しましょう。
プログラミングの経験について聞かれます。
該当するものを選びましょう。
GitHubの利用目的について聞かれます。
こちらも該当するものを選びましょう。
最大3つまで選択できます。
最後に何に興味があるか聞かれます。
Python
、machine learning
、C language
、HTML
...みたいな感じで良いでしょう。アンケートの記入が終わったら、入力したメールアドレスに確認のメールが届きます。
メールの指示に従ってメールアドレスを確認してください。
これでGitHubアカウントの取得は完了です。GitHubの概要やメリットは、第6回でkoが説明します。
Gitの設定
いよいよGitの設定です。
まず、インストールしたGit Bash
を開きます。
デスクトップの適当なところで右クリックしてください。
その後、Git Bash Here
を選択すると開けます。
これがGit Bashです。
以降、基本的にGit Bash
を使って作業をしていきますので、覚えておいてください。ユーザー情報の登録
Git Bashが開けたら、以下のコマンドをそれぞれ入力した後、
Enter
を押下してください。※
$
、<>
は入力しないでください。
※""
は入力してください。
※名前
にはGitHub登録時に入力したユーザー名を入力してください。
※mailaddress@sample.com
にはGitHub登録時に入力したメールアドレスを入力してください。$ git config --global user.name <"名前">$ git config --global user.email <mailaddress@sample.com>短いですが、今回はこれで終わりです。
お疲れさまでした!ここだけ覚えて!今回のまとめ!
✅ Gitは、共同開発の際に、GitHubと共に用いられることが多い。
リンク
次回
NITICNoobsによるGit/GitHub講座 第3回 ~実際に使ってみよう~
第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 ブランチ(平行世界)編-1
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編
第4回 ブランチ(平行世界)編-1
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編執筆者
- 投稿日:2020-06-03T03:50:32+09:00
NITICNoobsによるGit/GitHub講座 第6回 GitHub入門編
どうも
ko と申します。
春からぷよぐやみんぐを始めた身ながら未だなんもできません。
限界開発鯖の底辺でクソBotを作ったりしています。今回はGitHubの解説を担当させていただきたいと思います。対戦よろしくお願い致します。
※この記事は茨城高専生2I向けに書かれたものです。
実際に手を動かしながら読み進めてくれると嬉しいです。
お説明
※前回までの説明を理解していること前提で説明をしていきます
今回の記事では、
- GitHubについて
- リモートリポジトリとは
- ローカルリポジトリと何が違うの?
push
について- GitHubにリモートリポジトリを作成し、
push
するまでの流れ
clone
とはpush
コマンドの詳細.gitignore
について主に以上の点について説明していきます。
※以下で
Git Bash
と出てきますが、コマンドプロンプト
でも同様の操作ができます。GitHubとは
GitHubとは、Gitリポジトリをインターネット上に共有し、
様々な利点とともに開発を行えるリポジトリホスティングサービスとなっています。
類似のサービスとしてはGitLabなどが挙げられます。
GitHubを使用する利点
- ローカル(自分のパソコンにある)リポジトリを何らかの理由で破壊してしまった場合、
GitHub下で管理されているリモートリポジトリの内容を持ってくることで修復することができる- 共同開発者と簡単にコードを共有できる
- 他の開発者にソースコードのレビュー(精査)をしてもらえる
- 機能追加のリクエスト(issue)を受けられる
無条件でこれらの徳を得られるので、Gitを使えてGitHubを使わない理由はないと思います。
というかプログラマ業界において、基本的にGitHubは人権です。GitHubの基本的な要素
GitHubでは、Commit履歴やBranchなどの情報を視覚的に扱うことができます。
ファイル名やディレクトリ名をクリックすることでソースコードの内容を見たりできます。
Commit履歴では、diff
(変更内容)を見やすく表示してくれたりします。※ここの情報は誰でも見れるので、くれぐれも個人情報を載せることのないようにしてください。
リモートリポジトリについて
リモートリポジトリとは、GitHubなどのホスティングサービス側で管理されるリポジトリのことです。
ローカルのリポジトリをGitHubにアップロードし、それを共同開発者や協力者と共有することができます。通常、リモートリポジトリ内のファイルを直接書き変えたりすることはありません。
ではどうするかというと、まずローカルリポジトリの内容を変更し、変更後のファイルの状況を
リモートリポジトリに渡してあげる必要があります。
GitHubにリポジトリをアップロードするには「push」というコマンドを使用します。ローカルリポジトリとの違い
ローカルリポジトリは自分しか見えませんが、リモートリポジトリは「インターネット上にいる誰でも」見ることができます。
つまり、パスワードやtoken(識別情報)、API Key、本名などの重要な個人情報を載せてしまうと
悪質なハッキングに遭ってしまう危険性があります。くれぐれも気を付けてください。
その他にも共有したくないファイルがある場合があります。
(例: プロジェクトで使用しているパッケージをまとめたディレクトリなど)Gitでは、そんなファイルを
push
コマンドから無視(ignore
)するように設定することができます。
詳細は下記(.gitignoreについて)で説明していますもしもリモートリポジトリに上げたくないファイルがある場合、
.gitignore
ファイルを記述するといいでしょう。また、リモートリポジトリ内のファイル状態がおかしくなってしまうと共同開発者に迷惑なので取り扱いには少し注意が必要となってきます。
push
とは
push
とは、ローカルの変更内容をリモートリポジトリに報告するコマンドです。
コミットなどの作業をローカルで行うだけでは、その変更内容はリモートに反映されません。
(上の丸一つ一つがコミットを表しています)
Aさんがpush
をすることによって初めて、Bさんは変更を取り寄せることができますし、コードレビュアーはソースコードを読むことができます。
変更を取り寄せる方法は次回で出てきます。リモートリポジトリ作成から
push
するまでの流れ事前準備
自分のパソコンの任意の場所にリポジトリを作成しておいて、任意のファイルを追加しておいてください
↑.git
というディレクトリはgit init
をすると自動的に作成されるので後から作成する必要はありません。
(.git
は隠しファイルになっているので利用している環境によっては見えない場合がありますが問題ありません。)ローカルリポジトリ内で
Git Bash
を起動しておいてください
(またはコマンドプロンプト
を起動しリポジトリのディレクトリまで移動しておいてください。)※ディレクトリを移動する方法についてはこるくが第2回で説明しています。
GitHubアカウントページにアクセスします
https://github.com
ログインしてあればこのような画面が表示されます
左の
Repositories
から、New
を選択します新しいリモートリポジトリの情報を入力します
以下はオプションです
・initialize this repository with a README
このオプションはREADME
(説明書)を生成するので、リモートリポジトリの中身が空ではなくなり、
後述するgit clone
の使用を余儀なくされてしまいます。今回は最初にgit remote add URL
の方から
紹介する予定なのでオフにしておいてください。
・public
orprivate
GitHubにはprivate ripository
という機能があり、機密性を保ちたいコード(会社のプロジェクトや
大会などのコード) を書くときなどにリポジトリをプライベートにして非公開にする
機能があります。今回は特に隠す理由が無いと思いますので、オフにしておきましょう。上記以外にも
add .gitignore
やらadd a license
やらオプションがありますが、
今回はオフにしておいてください。
Create repository
をクリックしますリモートリポジトリとローカルリポジトリを紐づけます。ここのやり方は主に二通りあります
一つ目
一つ目は、あなたのパソコンに先にリモートリポジトリの場所を覚えさせておいて、そこに
push
できるようにする方法です。
Git Bash
で、git remote add origin URL
(URLは自分のリモートリポジトリのURLに置き換えてください)と入力します。
$ git remote add origin <"リモートリポジトリのURL">
これで、ローカルリポジトリのremote
という情報にorigin
という名前のリモートリポジトリURLが追加されました。(なぜorigin
なのかは後ほど)この方法では、ローカルリポジトリが既に存在しており、変更を与えてしまっている場合に役立ちます。二つ目の方法ではリモートリポジトリの内容をダウンロードしてくるためローカルのファイルを移動させて
push
しないといけないという二度手間になってしまいます。
それに対し、この方法(git remote add origin URL
)では、ローカルに与える影響は「リモートリポジトリURLの追加」なので、既にローカルにリポジトリを作ってある場合においても実行できます。
では、コミットして、先ほど行った任意のファイル作成を記録します。Bash$ git add --all $ git commit -m "<コミットメッセージ>"次にその変更内容をリモートに
push
しましょう。Bash$ git push origin master
(このコマンド文の詳細については下で説明します。)
二つ目
この方法では、ローカルにファイルを作る前にリモートリポジトリを作成して行うので今回のような事前準備は必要ありません。
二つ目は、先ほど作成したリモートリポジトリをclone
してくる方法です。
知らないコマンドが出てきました。
clone
とは何かリモートリポジトリの情報、内容のコピーををあなたのパソコン上にダウンロードしてくるコマンドです。ダウンロードしてきたリモートリポジトリの情報にはURLも含まれているので、
clone
するとその後はpush
を行うことができます。先ほどの
initialize this repository with a README
のオプションをオンにしていた場合や
共同開発を行うとき、最初にリポジトリを初期化した人以外などの場合はこちらの方法を使うことが多いです。コマンド
リポジトリを保存したいディレクトリに移動して
git clone URL
(ここのURLもリモートリポジトリのURLに置き換えてください。) と入力します。Bash$ git clone <"リモートリポジトリのURL">(ここで、
warning: You appear to have cloned an empty repository
と警告が出ることがありますが、
これは「リポジトリをクローンしてきたけどこれ空っぽだよ?間違ってたりしない?」と心配してくれているだけなので問題ありません。)
(ちなみにここのコマンドにはorigin
という単語が含まれていませんが、その説明も後ほど行います。)
git clone
でダウンロードしてきたリポジトリは、既にGitリポジトリとして初期化されているのでgit init
をする必要はありません。
任意のファイルを追加して一連の流れを執り行いましょう。
Bash$ git add --all $ git commit -m "<任意のメッセージ>" [master (root-commit) 96f6293] <ここにコミットメッセージが表示されます> 1 file changed, 1 insertion(+) create mode 100644 <追加したファイル> $ git push origin master Username for 'https://github.com': <ユーザー名> Password for 'https://<ユーザー名>@github.com': (パスワードを入力)← 表示はすべて「*」になってしまいますが問題ありません。 Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Writing objects: 100% (3/3), 392 bytes | 392.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 To <"リモートリポジトリのURL"> * [new branch] master -> master上記の二種類の操作(
remote add
かclone
)のうちどちらかを実行することで紐づけは完了です。
ローカルリポジトリがリモートリポジトリの場所を覚えていてくれるので、次から簡単にpush
をすることができるようになります。リモートリポジトリのURLが
origin
として登録されていることを実際に確認してみましょう。$ git remote origin
remote
にorigin
が追加されていることがわかります
URL
も確認することができます。$ git remote get-url origin https://github.com/ユーザー名/リポジトリ名
ちゃんと登録されていることが確認できたでしょうか。
場合によって使い分けることになるので、両方覚えておきましょう。
git remote add origin URL
で、remote
の情報にorigin
という名前でURLを追加git clone URL
でリモートリポジトリをコピーしてくる6. うまくいっていれば、これで先ほど作成したリモートリポジトリにローカルの内容が反映されているはずです。
リモートリポジトリのURLにアクセスして確認してみましょう。
https://github.com/ユーザー名/リポジトリ名
pushの詳細
GitHub上でリポジトリを共有するには、
Git Bash
かコマンドプロンプト
で
git push リモートリポジトリ名 ブランチ名
と入力します。この
リモートリポジトリ名
というのは、リモートリポジトリ作成時に入力したRepository name
とは異なります。
上の説明で使用されていたorigin
というのがここでのリモートリポジトリ名です。(ローカルにおけるリモートのURLの名前と言った方がわかりやすいかもしれません。)
リモートリポジトリ名には自由な名前を付けることもできますが、通常の開発目的で作成した場合、メインのリモートリポジトリにはorigin
という名前を付けるのが慣習です。(clone
した場合は、リポジトリをダウンロードしてきた時点で自動でorigin
が登録されています。)
次はブランチ名
についてです。上の説明でのブランチ名はmaster
となっていましたが、これはpush
したいブランチのブランチ名によって変化します。
例えばadd-feature
ブランチをpush
したいとなったら、git push origin add-feature
となります。ということで、
git push origin master
というのは
「origin
という名前が付けられたURLに存在するリモートリポジトリのmaster
ブランチに
ローカルリポジトリのmaster
ブランチの変更内容をpush
する。」
とも言い換えることができます。ちなみに一つのローカルリポジトリに対して、リモートリポジトリを複数関連付けることは可能です。
その場合はメイン以外のリモートリポジトリの名前はorigin
とはせず、役割に対応した名前を付けることになります。origin
というのはあくまでもメインのリモートリポジトリのみに付ける名前というのが慣習です。
.gitignore
とはGitリポジトリ内に
.gitignore
ファイルを作成し、その中で、無視してほしいファイルや拡張子などを
指定することでリモートリポジトリにpush
されないようにすることができます。
では実際に.gitignore
を活用してみましょう。
1. リポジトリ直下に.gitignore
ファイルを作成します。
2. では例として
personal_info.txt
ファイルを作ってみます
(実際には個人情報を載せないでくださいね!執筆者は責任を負いませんからね!)
この状態でgit status
を使用し、personal_info.txt
と.gitignore
両方の追加が変更内容として表示されるのを確認してください。$ git status On branch master Your branch is up to date with 'origin/master'. Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore personal_info.txt nothing added to commit but untracked files present (use "git add" to track)
personal_info.txt
の変更が確認されてしまっています
このままadd --all
してpush
してしまうと、personal_info.txt
がインターネット上にアップロードされてしまいます。3.
.gitignore
に、追跡しないでほしいファイル名personal_info.txt
を記入しましょう
そうすると、
personal_info.txt
の表示が暗くなっています。これでpersonal_info.txt
がignore
されたことになります。
(これはVSCodeでの表示です。お使いの環境によっては変化する可能性があります。)
VSCodeについてはこちらに説明があります。
git status
でも確認してみましょう$ git status On branch master Your branch is up to date with 'origin/master'. Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore ← さっきはあった「personal_info.txt」が消えている nothing added to commit but untracked files present (use "git add" to track)無事、変更が追跡されていないことが確認できます。
4. 練習も兼ねて
push
してみましょう$ git add --all $ git commit -m ".gitignoreを追加" [master ec72b94] gitignoreを追加 1 file changed, 1 insertion(+) create mode 100644 .gitignore $ git push origin master Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Delta compression using up to 2 threads Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 308 bytes | 154.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To https://github.com/ko50/testrepo.git 55c6bad..ec72b94 master -> master5. GitHubを確認しても
personal_info.txt
はアップロードされていないはずです
これで個人情報をpush
の魔の手から守ることができます
※ちなみに、個人情報を含むファイルを既にリモートリポジトリに
push
してしまった場合、
後から.gitignore
に追記しても commit履歴から見れてしまうので、その時はcommit
自体を
なかったことにする必要があります。(その場合の対処法は今回では扱いません。)まとめ
- GitHubは人権 使えないとGitを習得した意味がほとんどないまである
- リモートリポジトリに個人情報は載せないようにする
- ローカル(自分のパソコン)にリモートリポジトリの情報を登録するには二つの方法がある
git remote add origin URL
で、remote
の情報にorigin
という名前でURLを追加git clone URL
でリモートリポジトリをコピーしてくる- ローカルの変更内容は
push
しないとリモートリポジトリには反映されない
git push リモートリポジトリ名 ブランチ名
- メインのリモートリポジトリ名は特別な理由が無ければ
origin
にする- パスワードなどは
.gitignore
を使用して追跡されないようにする- コードを外部に漏らしたくないときはリポジトリを
private
にして保護する他パートへのリンク
次回
NITICNoobsによるGit/GitHub講座 第7回 ~fetch/pull~
第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 ブランチ(平行世界)編-1
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編執筆者
- 投稿日:2020-06-03T03:31:05+09:00
NITICNoobsによるGit/GitHub講座 第8回 〜Pull Request/Issue〜
自己紹介
どうも、isso0424です。又の名をいっそうです。
高専2年生でぷよぐやみんぐを趣味でやっています。
限界開発鯖で無限に通話をしてます。
何やってるかは以下のtwitterやGitHub見てもらえればわかると思います。
GitHub
今回は僕がGit&GitHub解説を進めていきます。気づいたかも知れませんが俗に言うコピペと呼ばれる魔法を使いました。
お目次
- Issue
- Pull Request
今回はGitHubの実践編になります。
お説明
Issue
これはリポジトリに結び付けられる
課題
や問題点
などを指す言葉です。使用する場面
Issueを使用する場面はそこそこあります
- 新機能の実装
- バグの報告
- 改善点の提案
立て方
ダークテーマを拡張機能で入れているので違和感があるかも知れませんが気にしないでください。
ここでCodeの隣のIssueボタンを押すとIssueの一覧が見れます。
(おそらく)まだIssueを作成していないと思うので右上の
New Issue
ボタンを押して新しいIssueを作成しましょう。
この画面で以下の情報が指定できます。
名前 意味 Title Issueのタイトル Comment Issueに付けるコメント Assignees Issueの担当者(self assignにより自分でIssueを解決するという意思表示ができる) Labels Issueについたラベル(Bugなど)Issueの方向性を示す その他は割愛します。
そして、Submit new issue
を押すことでIssueを立てることができます。閉じ方
IssueはCloseすることで解決したことを示します。
それぞれのIssueのページでClose Issue
というボタンを押すと閉じれます。
また、後述のリンクされたPull Request
がマージされた際にも閉じられます。Pull Request
これはブランチを、GitHub上で別なブランチにマージする為のものです。
作り方
まず、
git checkout -b hogeで
hoge
ブランチに移動します。次に、ファイルを編集します。
その後、コミットしてgit push origin hogeで
origin
に対してhoge
の変更をpushします。その後、GitHubへ行き
Pull Request
のボタンをクリックすると以下のような画面に飛びます。右上の
New Pull Request
を押すとIssue
のような感じでPull Request
の作成画面に飛びます。今回は
master
をbase
にhoge
をマージするので左上のcompare
をhoge
に変更します。ここで
Create New Pull Request
というボタンを押すとPull Request
を作成するページに飛びます。ここは
Issue
と似ていますが一点だけ相違点があります。
それはReviewers
の指定ができることです。
Reviewers
というのは後述のReview
を行う人員を指します。
今回は個人リポジトリなので指定しなくて問題ありません。そして
Create pull request
を押すとPull Request
を作成できます。
すると下のスクショのような画面に移るはずです。
Pull Requestのマージ
これはとても簡単で
Merge Pull Request
を押すだけでマージできます。
共同開発の場合は、Reviewer
からのApprove
(後述)の上でマージすることになります。
Pull Requestのレビュー
Pull Request
でのコードの変更に対してはレビューという形で指摘などをすることができます。
レビューをするにはまず、File changed
というボタンをクリックします。
そして、下のような画面に飛びます。
ここでレビューを行います。
指摘したい場所の行番号にカーソルを持っていって出てくる+
をクリックします。
すると以下のようなフォームが出てきます。
ここでStart a review
を押すとレビューが開始します。
あとは気になるところを指摘していきます。最後にレビューの種類を決めます。
レビューの種類には以下のものがあります。
名前 意味 Approve マージしていいぞ Request Changes こんなコードマージさせれるか書き直してこい Comment 特に特殊な意味の無いコメント
Reviewers
全員からApprove
がもらえればそれはマージする許可が出たということなのでマージします。
逆にRequest Changes
が来たらコメントを元に修正する必要があります。ここで重大な事実なんですがなんと Pull Requestを立てた本人は自分のPull Requestに対してApproveやRequest Changesを出せません。
というわけで今回は
Comment
だけにしておきましょう。すると、
Pull Request
の画面に戻ると下のようにコメントが追加されます。これがレビューです。
Issueとのリンク
Pull Request
の大切な機能としてIssue
とリンクさせる事ができることが挙げられます。
リンクと言われてもピンとこないかも知れませんがこのPull RequestはこのIssueを解決しました
というのを示すものになります。
そして、Pull Request
が後述のようにマージされると同時にIssue
はClose
されます。おまとめ
- プロジェクトの課題は
Issue
という形で示す。- 別ブランチの変更をリモートの別ブランチに適用するときは
Pull Request
を立てるPull Request
はレビューを募れるおリンク
1回目〜〜インストール編〜〜
2回目〜〜設定編〜〜
3回目〜〜基本技能編〜〜
4回目〜〜平行世界編-1〜〜
5回目〜〜平行世界編-2〜〜
6回目〜〜GitHub編〜〜
7回目〜〜fetch/pull編〜〜
8回目〜〜Issue/PR編〜〜 ←イマココ執筆者
- 投稿日:2020-06-03T03:04:58+09:00
大きな機能開発を細かくレビューしてもらうときに使いたいGitHubのSquash Marge
チーム開発において、大きな機能開発をいきなり大きなPRを作るとレビューが大変です。
また、レビューの段階で設計的に良くない点が見つかって大きな書き直しに迫られることもあるかと思います。
このようなことはある程度規模の大きくなってきたアプリケーションに、複数の機能を並行して開発している経験があるならイメージが付きやすいと思います。そんな作業途中のコミットログやレビューでの指摘事項の修正が、すべてmasterブランチのコミットログに残ってしまうのは格好わるいような気がします。
そんなときに今の会社に入って運用されているマージのルールがとてもよかったのでメモしておきます。Squash Mergeとは
GitHubには3つのマージ方法がある、ということを意識したことがある人はどれぐらいいるでしょうか?
▼をクリックすると、このようなメニューが開いてマージの方法を選択することができます。
そのうちの1つがSquash Mergeというもので、マージする際に途中のコミットログが消えて1つのコミットに集約されなおされます。詳しくはこちらのQiitaが参考になると思います。
ブランチの運用ルール
- master
- masterブランチ。本番へデプロイされる
- develop/XXXX
- 機能ブランチ。 masterへは「Create merge commit」 する
- work/XXXX/YYYY
- 作業ブランチ。 develop/XXXXから派生ブランチとして切る。 develop/XXXXへ「Squash and Marge」 する
workブランチではPRを作るとき派生元の積極的にコミットを詰んでいってかまいません。レビューの指摘内容とかもここで詰んでいくのが主です。PRを作るとき、ベースブランチは develop/XXXX を選びます。
最終的に、developにマージするとき、「Squash and Merge」を選ぶと developブランチの1つのコミットになります。developブランチはmasterへマージされる前の最終確認的な運用をします。
このブランチのPRで指摘があった場合は、別途workブランチを切り直して修正したほうがコミットログがきれいでしょう。
最後に「Create merge commit」すると、 workブランチのPR単位のコミットログが並びます。コミットグラフっぽいものを書いていくとこんな感じでしょうか。
◯[master] |\ | ◯[develop/X] (まだコミットが積まれてないので本当は枝分かれしてないけどイメージ | |\ | | ◯[work/X/Y1] wip | | ◯ feat: 機能1のwork1 | | ◯ fix: 機能1のレビュー指摘事項の修正developブランチとworkブランチを切って、workブランチで作業します。
develop/Xブランチに向かってPRを切り、workブランチをsquashマージします。◯[master] |\ | ◯ [develop/X] work1 (#1)squashマージすると、develop/XブランチにPR1個分のコミットが1つのコミットとして積まれます
次のworkブランチも切りましょう。◯[master] |\ | ◯[develop/X] work1 (#1) | |\ | | ◯[work/X/Y2] feat: 機能1のwork2work2のブランチもdevelop/XブランチにSquashマージします。
◯[master] |\ | ◯[develop/X] | | | ◯ work1 (#1) | | | ◯ work2 (#2)develop/Xブランチにwork2の作業内容が1コミットにまとめられて積まれます。
◯[master] |\ | ◯[develop/X] | | | ◯ work1 (#1) | | | ◯ work2 (#2) |/ ◯[master] Merge pull request #3 from develop/X最後にCreate commit and mergeすると、PR単位のコミットログだけが残ります!
コミットログが作業中のようなコメントではなく、PRに紐付いた1つのまとまりとしてコミットされるので、とても見通しがよいのではないでしょうか!Squash Mergeなんて知らなかったよ、という私なので、とても感動したという話でした。
余談
マージ方法の選択は完全なる手動オペです。最後に選択してマージした方法が記録されるようです。
自動的に選択してもらう方法はないっぽい?なのでしばしば間違いが起こりますが、それについては特に気にしてない感じで運用してます。
うまいことやるとコミットログが綺麗になって気持ちいい、くらいですね。
間違えたからといって目くじらを立てているとつらくなってしまうかもしれません。
- 投稿日:2020-06-03T03:04:58+09:00
大きな機能開発を細かくレビューしてもらうときに使いたいGitHubのSquash Merge
チーム開発において、大きな機能開発をいきなり大きなPRを作るとレビューが大変です。
また、レビューの段階で設計的に良くない点が見つかって大きな書き直しに迫られることもあるかと思います。
このようなことはある程度規模の大きくなってきたアプリケーションに、複数の機能を並行して開発している経験があるならイメージが付きやすいと思います。そんな作業途中のコミットログやレビューでの指摘事項の修正が、すべてmasterブランチのコミットログに残ってしまうのは格好わるいような気がします。
そんなときに今の会社に入って運用されているマージのルールがとてもよかったのでメモしておきます。Squash Mergeとは
GitHubには3つのマージ方法がある、ということを意識したことがある人はどれぐらいいるでしょうか?
▼をクリックすると、このようなメニューが開いてマージの方法を選択することができます。
そのうちの1つがSquash Mergeというもので、マージする際に途中のコミットログが消えて1つのコミットに集約されなおされます。詳しくはこちらのQiitaが参考になると思います。
ブランチの運用ルール
- master
- masterブランチ。本番へデプロイされる
- develop/XXXX
- 機能ブランチ。 masterへは「Create merge commit」 する
- work/XXXX/YYYY
- 作業ブランチ。 develop/XXXXから派生ブランチとして切る。 develop/XXXXへ「Squash and Merge する
workブランチではPRを作るとき派生元の積極的にコミットを詰んでいってかまいません。レビューの指摘内容とかもここで詰んでいくのが主です。PRを作るとき、ベースブランチは develop/XXXX を選びます。
最終的に、developにマージするとき、「Squash and Merge」を選ぶと developブランチの1つのコミットになります。developブランチはmasterへマージされる前の最終確認的な運用をします。
このブランチのPRで指摘があった場合は、別途workブランチを切り直して修正したほうがコミットログがきれいでしょう。
最後に「Create merge commit」すると、 workブランチのPR単位のコミットログが並びます。コミットグラフっぽいものを書いていくとこんな感じでしょうか。
◯[master] |\ | ◯[develop/X] (まだコミットが積まれてないので本当は枝分かれしてないけどイメージ | |\ | | ◯[work/X/Y1] wip | | ◯ feat: 機能1のwork1 | | ◯ fix: 機能1のレビュー指摘事項の修正developブランチとworkブランチを切って、workブランチで作業します。
develop/Xブランチに向かってPRを切り、workブランチをsquashマージします。◯[master] |\ | ◯ [develop/X] work1 (#1)squashマージすると、develop/XブランチにPR1個分のコミットが1つのコミットとして積まれます
次のworkブランチも切りましょう。◯[master] |\ | ◯[develop/X] work1 (#1) | |\ | | ◯[work/X/Y2] feat: 機能1のwork2work2のブランチもdevelop/XブランチにSquashマージします。
◯[master] |\ | ◯[develop/X] | | | ◯ work1 (#1) | | | ◯ work2 (#2)develop/Xブランチにwork2の作業内容が1コミットにまとめられて積まれます。
◯[master] |\ | ◯[develop/X] | | | ◯ work1 (#1) | | | ◯ work2 (#2) |/ ◯[master] Merge pull request #3 from develop/X最後にCreate commit and mergeすると、PR単位のコミットログだけが残ります!
コミットログが作業中のようなコメントではなく、PRに紐付いた1つのまとまりとしてコミットされるので、とても見通しがよいのではないでしょうか!Squash Mergeなんて知らなかったよ、という私なので、とても感動したという話でした。
余談
マージ方法の選択は完全なる手動オペです。最後に選択してマージした方法が記録されるようです。
自動的に選択してもらう方法はないっぽい?なのでしばしば間違いが起こりますが、それについては特に気にしてない感じで運用してます。
うまいことやるとコミットログが綺麗になって気持ちいい、くらいですね。
間違えたからといって目くじらを立てているとつらくなってしまうかもしれません。
- 投稿日:2020-06-03T02:50:58+09:00
Githubのeditばかり使う人へ送る"Squash merge workflow"
前書き
この記事は特にGithubのEditを使い糞Commitを量産している方に見てもらいたいです。
GithubのEditは本当に楽ちんなので巨大ファイルじゃない限りWebIDEとかも使う気になれませんよね。ですが、何回も何回もUpdate ***.xxxを繰り返しているのではないかと思いました。それでLocalにCloneしてSoft ResetしてForce Pushしていた過去が私にはあります。
# 疑問符アレルギーの方は閲覧すると危険なので注意してください。
実践
まずGithubにて新しいRepositoryを作りましょう。そうしたら
README.md
を作りますよね、、、????そしたらこの段階でBranchを切ります。名前はどんなのが良いんでしょうか、王道の
develop
か、それとも?名前は置いといて、
README.md
でも編集してください、この記事を見たら1回Typoするので2回Commitされてるはずです。次にPull Requestを
master
に送り、このままMerge、しないでください。プルダウンリストの二番目にあるSquash and merge
を選択して、Mergeします!後書き
これならDevelopでくそこみとなんかいもできて、Masterよごさなくていいね!
あと、もじに色つけるのめんどいね、、<font color="Lime">Repository</font>
- 投稿日:2020-06-03T02:04:25+09:00
NITICNoobsによるGit/GitHub講座 第4回 〜並行世界を創世する〜
フライさん(loxygen)です。限界開発鯖でのだのだ言っています。
フライさんにおまかせなのだ!
説明はあまり得意ではありません。※この記事は茨城高専生向けに書かれたものです。
お説明
ここからちょっと難しくなってきます。対戦よろしくおねがいします。
今回は「ブランチ」について解説していきます。このお話は、プログラマーを世界を操る神として例えるとしやすい(当社比)ので、神になりきって読んでくださると読みやすいかと思います。ブランチってどんなの?
ブランチというのは、履歴を分岐して記録していくための機能です。噛み砕くと並行世界のようなものでしょうか。
ブランチを新しく作成することを「ブランチを切る」といいます。
「ブランチを切る」のは「並行世界を新しく創る」と同義ですね。どういうタイミングで切っていくんや?
大体は、一つの機能ごと、または機能の小さな集まりごとにブランチを切っていきます。テキストエディタを例に取るなら、
- テキストを編集する機能を実装するブランチ
- ファイルを読み込み・保存する機能を実装するブランチ
もちろん他にもいろいろなやり方があります。
masterブランチ
リポジトリを作成すると、必ず一つ、
master
という名前がついたブランチが生成されています。いわゆる現実世界です。
masterブランチがメインのブランチになります。プログラムの完成品を置いていく場所ですね。マージ
並行世界でたくさん変更を加えたあとは、まとめて現実世界にその変更を反映させます。並行世界だけに変更を加えても現実世界は何の変化もないですからね。
この「まとめて現実世界にその変更を反映させる」ことをマージ(merge)と言います。ブランチの存在意義
変更履歴が必然的に美しくなる
ブランチを切らないで、何も考えずに実装していったとしましょう。
以下の図はコミット履歴を表した図です。
一つの○が一つのコミットで、線がコミット同士のつながりです。同じ色のコミットは同じ機能を実装しています。複数の機能の実装が入り組んでしまっていて、履歴がわかりにくくなっています。
今は問題ないかも知れませんが、後から見たり、また他の人が見たりしたときに「」となる可能性は十分あります。ここでブランチを使用してみましょう。
一つ、または機能のまとまりごとにブランチを切っていくと説明しましたね。機能(=同じ色)ごとにブランチを切ってみましょう。
具体的には、こんな感じになります:
masterブランチの編集履歴が単純化されていますね。複数の機能が混じることなく、機能実装ごとにコミットが分かれています。
上の図と比べたら大分キレイになっていますね。
あまり詳しく考えずに「嗚呼確かにそうかもな」ってだけ思って頂ければ幸いです。品質を保証できる
ブランチがあることのもうひとつの利点は、
master
ブランチ上のプログラムの品質を保証できることです。
現実世界でバグが起こったら嫌ですよね。SCP1どころの騒ぎじゃなくなるかもしれません。
そこで、各々のブランチ(=並行世界)でバグを潰したあとにmaster
ブランチにマージします。するとどうなるでしょうか。
master
ブランチ(=現実世界)のバグはかなり抑えられた状態になります。つまりこれは、master
ブランチ上のプログラムの品質が保証されているということになりますね。
これがもう一つの利点です。キーボードかたかたしよう
そろそろ用語の解説に飽きてきたので、ブランチ切ってコミットしてマージしてみましょう。
作業したいフォルダでGit Bashを開いておいてくださいね。リポジトリを生成してInitial Commitする
リポジトリがないとマジで何も始まらないので作ります。
以下のコマンドを入力してEnterを押してください。
こるくも言っていましたが、$
は入力しないでくださいね。Bash$ git init (任意のリポジトリ名)「
(任意のリポジトリ名)
」は、お好きな名前にしてください。Enterを押すと
Initialized empty Git repository in /path/to/your/selection/(任意のリポジトリ名)/.git/と表示されます。新しいリポジトリが生成されました。
リポジトリに移動しましょう。Bash$ cd (任意のリポジトリ名)ブランチはコミットを単位に切っていきます。つまりコミットがないとブランチを切ることができません。というわけでInitial Commitをしちゃいましょう。
リポジトリに
hello.txt
という名前で以下のファイルを生成して保存してください。hello.txtI am the smartest person.そうしたらInitial commitします。
Add
を忘れないでくださいね。筆者は忘れてしまいました。Bash$ git add --all
git status
を確認する癖をつけましょう。つけて困ることはありません。Bash$ git status
すると以下の出力を得ることができます。
BashOn branch add-new-func Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: hello.txt「緑色で
new file: hello.txt
」 …「次のコミットでhello.txt
が新しいファイルとして登録されるで!」と出力されていますね。新しくhello.txt
というファイルを作ったので正常です。もし
hello.txt
が赤く表示されていればadd
し忘れています。しましょう。
このままコミットして問題なさそうなのでコミットしちゃいましょう。Bash$ git commit -m "Initial Commit"以下のように表示されます。
[master (root-commit) 1234567] Initial Commit 1 file changed, 1 insertion(+) create mode 100644 hello.txtこれでこのリポジトリのコミット履歴はこうなりました:
Initial Commitだけがある状態です。HEAD(≒現在位置)もInitial Commitにいます。ブランチを切る
これまで入力と出力を分けて書いていましたが、ここから一緒に書いてしまいます。
入力する際は、$
から行末までを入力してください。ここで並行世界を創世しましょう。新しいコマンドのお出ましです。
以下のコマンドを入力してEnterを押してください。Bash$ git branch add-new-func
このコマンドを叩くと、
add-new-func
というブランチが切られます。新しく並行世界を創世するわけです。
並行世界を創世しただけじゃ何も始まらないので、創世した並行世界に移動しましょう。Bash$ git checkout add-new-func Switched to branch 'add-new-func'このコマンドを叩くと
add-new-func
ブランチに移動します。ちなみに以下のコマンドを打つと上記の2つの操作を同時に行うことができます。
Bash$ git checkout -b add-new-func Switched to a new branch 'add-new-func'通常はこちらを使います。一行で済んで楽ですからね。
試しに
git status
を叩いてみましょう。Bash$ git status On branch add-new-func nothing to commit, working tree clean
On branch add-new-func
、つまり「add-new-func
ブランチにいますよ」と表示されていますね。さて、一連のコマンドを打った後、コミット履歴はこうなりました。
・・・?なんも変わってないやん。
なんかadd-new-funcブランチ
って文字列は認識できるけどそれ以外はなんも変わってないやん。この時点ではまだコミット履歴上の変化はありません。それではここにコミットをしてみましょう。
並行世界に歴史を刻む
先程作ったファイルを以下のように変更してください。
hello.txtI am the kindest human.そしてコミットします。コミットメッセージは何でも構いません。
Bash$ git add --all $ git status Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: hello.txt $ git commit -m "Edit hello.txt" [add-new-func c48284a] Edit hello.txt 1 file changed, 1 insertion(+), 1 deletion(-)あっ!?なんか縦にズレとる!
そうです。並行世界で変更を加えたのでちょっとズレました。現実世界はどうなってるん?
並行世界(=
master
から切ったブランチ)で変更を加えましたが、現実世界(=master
ブランチ)はどうなってるんでしょうか。一旦master
に戻ってどんなもんか見てみましょう。Bash$ git checkout master Switched to brach 'master'このコマンドで現実世界に帰ることができます。
-b
はいらないので注意してください。
ちなみに、ブランチ間を移動することを「チェックアウト」と呼びます。ここで、
hello.txt
の中身を見てみましょう。「cat
」というコマンドを使用してみます。
cat
コマンドは、ファイルの中身を見るコマンドです。
全てGit Bashで完結させたかったので使っていますが、もちろんお好みのエディタで大丈夫です。以降についても同様です。Bash$ cat hello.txt I am the smartest person.
cat
のあとにファイル名を入力してEnter
すると、そのファイルの中身が表示されます。
お気づきかもしれませんが、並行世界で加えた変更がありません。
でも消し飛ばされたわけではありません。並行世界に帰ってみましょうか。Bash$ git checkout add-new-func Switched to branch 'add-new-func'同じコマンドを打って
hello.txt
を見てみます。Bash$ cat hello.txt I am the kindest person.変更が帰ってきました。
そうです。並行世界で変更を加えても、現実世界には反映されないようになってるんです。
そりゃそうだろと言えばそりゃそうなんですが、なんだかすごいですよね。本当に世界を行き来してるみたいじゃありませんか?お練習
一旦masterブランチに帰りましょう。
Bash$ git checkout master Switched to branch 'master'.そうしたら、以下の操作をしてみてください。
・add-new-func-2ブランチを切る。 ・hello.txtの中身を以下のように変更する: I am the greatest people. ・自由なコミットメッセージでコミットする。第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
以下に答えを書いておきます。行き詰まったり、正解を確認したいときに見てくださいね。
お答え
Answer
まずブランチを切りましょう。
Bash$ git checkout -b add-new-func-2 Switched to a new branch 'add-new-func-2'.そしたらファイルの中身を指示されたとおりに変更します。お好みの方法でどうぞ。
保存したらコミットします。
Bash$ git add --all $ git status Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: hello.txt $ git commit -m "(何かしらメッセージをどうぞ)" [add-new-func d2ad39f] (入力したメッセージ) 1 file changed, 1 insertion(+), 1 deletion(-)これで完成です!
このルーチンは生涯で$N$回 ($N \geqq 任意の数字$)回やるので、なんとしてでも身につけておきましょう。
マージする
並行世界に変更を加えただけでは現実世界(
master
ブランチ)に変更は反映されません。というわけでマージもしてみましょう。マージの流れ
- マージしたい先のブランチにチェックアウトします。
git merge <マージするブランチ>
をします。- 上手く行けばマージ完了です!
この流れでマージします。上手く行かなかった場合については、次回説明します。
実際にマージしてみる。
今のところ、コミット履歴は以下のようになっているはずです:
master
ブランチからadd-new-func
ブランチとadd-new-func-2
ブランチが生えている状態です。HEAD
は動かすのでどこでも大丈夫です。
それでは並行世界の歴史を現実世界に反映していきましょう。まず、マージする先のブランチにチェックアウトします。
今回はmasterブランチにMergeしたいので、masterブランチにチェックアウトしましょう。Bash$ git checkout master Switched to branch 'master'一応ここで
hello.txt
を見ておきます。Bash$ cat hello.txt I am the smartest person.並行世界上では変わっていますが、現実世界上では変わっていませんね。smartest personのままです。
そうしたら実際にマージしてみます。
Bash$ git merge add-new-func Updating 1234567..890abcd Fast-forward hello.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)なんかいろいろ出てきましたね。エラーは見た感じ出てないみたいです。
hello.txt
を見てみましょう。Bash$ cat hello.txt I am the kindest person.…おっ?中身が変わりましたね。smartest personがkindest personになっています。中身が
add-new-func
ブランチのものと同一になりました。ここで、コミット履歴は以下のようになっています。
ァ!なんかくっついてる!2
はい。mergeをしたことによってadd-new-func
ブランチの歴史がmaster
ブランチの歴史に併合しました。
こうして並行世界の変更が現実世界にも適用されました。コンフリクト
第5回で詳しく説明しますが、
add-new-func-2
ブランチは「コンフリクト」というエラーが発生してマージすることができません。
マージしないまま第5回に進んでくださいね。マージする前の確認作業
上記のエラーを防ぐために、マージ作業を執り行う前にある確認作業をするとお作法がいいです。3これも一緒に第5回で説明しますので、ぜひ頭に置いておいてください。
おまとめ
- ブランチは並行世界のようなもの
- masterブランチは現実世界のようなもの
- ブランチの利点は:
- 変更履歴が必然的にキレイになる
- masterブランチの品質を保証できる
- ブランチの操作には以下のコマンドを使用する:
git checkout -b <ブランチ名>
…ブランチを切る
中身はgit branch <ブランチ名>
→git checkout <ブランチ名>
git checkout <ブランチ名>
…ブランチ間を移動(チェックアウト)git merge <ブランチ名>
…ブランチをマージするここまでお疲れ様でした。が、ブランチの話にはあと少しだけ続きがあります。
第4回はかなり膨れてしまったのでここで切り上げますが、第5回で同じリポジトリを使用するので取っておいてくださいね。おリンク
第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 いまここ
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編執筆者
- 投稿日:2020-06-03T01:31:32+09:00
NITICNoobsによるGit/GitHub講座 第1回 ~インストールしてみよう~
自己紹介
こるくといいます。
限界開発鯖 とかいうヤバい開発者コミュニティに所属している茨城の高専生です。
今回からn回に渡り、「Gitを触ったことがない」という方のために、私と他3人でGitとGitHubの使い方をゼロから伝授していきます。※とりあえずGitをインストールしたい人はこちら
はじめに
この記事は、茨城高専の2I向けに執筆された記事です。
実際に手を動かしなら読み進めてください。Gitとは?
Gitとは、ソースコード(実際に書かれたプログラムのこと)を円滑に管理することができるソフトウェアです。
ソースコード以外にも、テキストファイルなら何でも管理できます。
小説やレポートをGit管理してもいいでしょう。
現在、IT業界のデファクト・スタンダードです。
エンジニア、エンジニアになりたい人みんなが使っています。
人権といっても過言ではありません。
さらに共同開発に向いています。メリット
「フォルダが汚くなりがち。」
「きちんとファイルを体系立てて管理したい。」
そう思ったことはありませんか?Gitは、それを叶えるソフトウェアです。
Gitをつかえば、こんなファイル管理とはおさらばです。
面倒な管理を、あなたに代わってやってくれます。
(あと使ってるとかっこいい)バージョン間で、
- どこが変更されたのか (diff表示)
- 誰が変更したのか
- それは何のためなのか (コメント)
といったことの管理を自動でやってくれます。
しかも、バージョンを指定するだけでそのバージョンに戻れたりもします。
後述しますが、他の人と並行して作業し、お互いの作業の成果物を結合させる、なんてことも出来ます。
と、このようなメリットがあるので共同開発においてGitやGitHubは必要不可欠な存在になります。
逆に、Gitを使わずに共同開発をしようとするとどうなるのでしょうか。
Gitを使わないと...?
- ファイルの共有にslackやメール、dropboxなどを用いる必要がある。
- 次の作業に移るごとにバックアップをいちいち作る必要がある。
- いつ、だれが、どこを編集したのかわからない。
- 複数人で並行作業した際に、その作業をまとめるのに時間がかかる。
地獄ですね、絶対にこんな開発はしたくありません。確実にハゲマス。
インストール!
では、Gitの素晴らしさがわかったところで、実際にWindowsにGitをインストールしてみましょう。
ダウンロード
まず、以下のリンクに飛びます。
Git - Downloading Packageほとんどの場合、
64-bit Git-for Windows Setup
を選択しておけば問題ありません。
自分の環境にあったものをダウンロードしてください。インストーラーの起動
ダウンロードしたファイルをクリックしてインストーラーを実行しましょう。
ライセンス条項が出てきます。
内容を確認して、問題がなければNext
をクリック。インストール先の設定
ここではインストール先を設定することが出来ます。
お好みで設定していただいて構いませんが、特別な事情が無い限りそのままにしておきましょう。オプションの調整
基本的にデフォルトのままで構いません。
Use a TrueType font in all console windows
はデフォルトでは無効ですが、後述する「Git bash」の文字がなめらかになります。
デスクトップにGit bashのショートカットを作成したい場合は、On the Desktop
を選択してください。スタートメニューの設定
Gitをスタートメニューに追加するかどうか尋ねられます。
追加したくない場合、Don't create a Start Menu folder
を選択してください。デフォルトのテキストエディタの設定
Git bash内でテキストを書くとき、どのソフトウェアを使うかの設定です。
デフォルトではVim
ですが、初心者にはおすすめしません。
Visual Studio Code as Git's default editor
選択することをおすすめします。
VS Code
を選択する場合、事前にインストールされている必要があります。
VS Code
はプログラムを書く際のソフトウェア(エディタ)として、かなり有名です。
入れておいて損はないでしょう。
(※ 余談ですが筆者はJetBrains IDE信者です)▼ VS Code の導入記事
VisualStudioCodeのインストールと日本語化環境変数の設定
Gitを使うにあたり、どのような環境にするか聞いてきます。
特に理由がなければ、Git from the command line and also from 3rd-party software
を選択。接続方式の設定
後述する「リモートリポジトリ」を利用する際に、どのような接続方式を用いるか設定することが出来ます。
特に理由がなければ、Use the OpenSSL library
を選択しておくと後々幸せになれます。改行方法の選択
WindowsとUNIX系のOS(macOSやLinuxなど)では、システム内で「改行」を表す方法が異なります。
そのため、後述する「コミット」時に、Windowsの方法のままにしておくか、UNIX系の方法に修正するかどうか聞かれます。
特に理由がなければ、Checkout Windows-style, commit Unix-style line endings
を選択。Gitが利用するターミナルエミュレーターの設定
Gitでは、文字で命令を入力して使います(
CLI
) 。
(GUI
でGitを扱う方法もありますが割愛します)この画面では、デフォルトでWindowsに入っている
Command Prompt
を使うか、新たにMinTTY
を導入するか聞いてきています。基本的に
Use MinTTY (the default terminal of MSYS2)
を選択しておくことをおすすめします。
git pull
コマンドの挙動の設定
git pull
コマンドにどのような挙動をさせるか設定できます。今はとりあえず
Default (fast-forward or merge)
を設定しておいて問題ありません。※
git pull
については第n回で解説しています。その他の設定
細かいの設定を調節することが出来ます。
デフォルトのままで問題ありません。実験的機能の設定
実験的な新機能を追加するかどうか聞いてきます。
気になる方は選択してみましょう。
ですが実験的な機能は不安定なことも多いので、無理に有効にする必要はありません。もうひといき!
インストール時の設定はこれで完了です。
後は自動でインストールを進めてくれます。完了!
この画面でインストールは完了です。
すぐに触ってみたい人はLaunch Git Bash
を選択しておきましょう。
Next
をクリックしてインストールの作業は完了です。
お疲れさまでした!ここだけ覚えて!今回のまとめ!
✅ Gitは、バージョン管理システムである。
✅ Gitは、現在のIT業界のデファクト・スタンダードになっている。
✅ Gitは、共同開発で多く使われる。リンク
次回
NITICNoobsによるGit/GitHub講座 第2回 ~設定しよう~
第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 ブランチ(平行世界)編-1
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編執筆者
- 投稿日:2020-06-03T01:30:13+09:00
NITICNoobsによるGit/GitHub講座 第7回 〜fetch/pull〜
自己紹介
どうも、isso0424です。又の名をいっそうです。
高専2年生でぷよぐやみんぐを趣味でやっています。
何やってるかは以下のtwitterやGitHub見てもらえればわかると思います。
GitHub
今回は僕がGit&GitHub解説を進めていきます。お目次
- fetch
- pull
お説明
fetch
fetchが今回最初に説明するコマンドになります。
これはリモートリポジトリから変更を引っ張ってくるコマンドです。使い方
git fetch [リモートリポジトリ]これで終わりって言えば終わりなんですけど、具体的な例を見てみましょう。
例
もともと以下のようなファイルがあったとします。
demo.txtI'm genius. yesそこに、origin/masterにAさんが変更をpushします。
変更内容は以下の通りです。demo.txtI'm genius. noそして、この状態であなたが
demo.txtI`m noob. yesという変更を加えようとします。
しかしまだ待ってください。
この状態でファイルを変更しようとするとCONFLICTします。
なぜなら、リモートの変更とローカルの変更が矛盾して衝突してしまうからです。
は?CONFLICT?しらねえよ
って人は今すぐ
第五回を見てきてください。このときに,前述のfetchを使います。
というわけで編集前にgit fetch originを実行します。
これによりリモートの変更がローカルに適用され、以下のようなログが出ます。remote: Enumerating objects: 5, done. remote: Counting objects: 100% (5/5), done. remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), 223 bytes | 223.00 KiB/s, done. From URL hoge..fuga master -> origin/masterこれは
リモートの変更取ってきたぞ!
というGit君からの喜びの叫びです。さて、変更は取ってきただけでは意味がありません。
これをローカルに適用するためマージしましょう。git merge origin/master origin/master: remoteリポジトリ"origin"のmasterブランチこれで、リモートの更新にローカルが追いついたため、pushできるようになります。
この状態で前述の変更を行い、pushすることができます。git push origin masterこれで世界に平和が訪れました。
pull
前回と合わせてmerge,fetchについて学んできました。
毎回fetchしてからmergeしても良いのですが段々面倒になってきます。そんなワガママな希望にも答えてくれるのがgit君です。
gitにはpullというコマンドがあります。使い方
git pull [リモートリポジトリ名] [リモートリポジトリのブランチ名]これにより現在作業しているブランチにリモートリポジトリのブランチをマージすることができます。
つまり、pullはfetchとマージを組み合わせたコマンドと考える事ができます。
例
先程の例を流用します。
先程の例でfetchをしたタイミングでgit pull origin masterを実行します
この時点で、origin/masterがmasterに対してマージされます。
そのため、この時点でファイルの編集に入ることができます。あとは先程の例のマージ後と同じです。
おまとめ
- リモートの変更内容を取ってくる時はfetch
- リモートのあるブランチの最新状態と同期させたい時はpull
次回はGitHubのPullRequest/Issueについて説明します。
おリンク
1回目〜〜インストール編〜〜
2回目〜〜設定編〜〜
3回目〜〜基本技能編〜〜
4回目〜〜平行世界編-1〜〜
5回目〜〜平行世界編-2〜〜
6回目〜〜GitHub編〜〜
7回目〜〜fetch/pull編〜〜 ←イマココ
8回目〜〜Issue/PR編〜〜執筆者