20210607のGitに関する記事は5件です。

[基礎]Gitコマンドについてまとめてみた②

はじめに 続きまとめていきます! 自分用なので、①を見たい方はこちらをご覧ください。 ブランチ関連のコマンド ブランチを新規追加する terminal git branch ブランチ名 ブランチの一覧 terminal git branch git branch -a ブランチの切り替え terminal git checkout 既存ブランチ #ブランチを新規作成した上で切り替える git branch -b ブランチ名 変更履歴をマージする terminal git merge ブランチ名 git merge リモート名/ブランチ名  ブランチの変更・削除 terminal git branch -m ブランチ名 #作業中のブランチ名の変更 git branch -d ブランチ #削除 git branch -D ブランチ名 #強制終了 リベース関連のコマンド ※リベースで気を付けないといけないのは、Githubにpushしたコミットは絶対にリベースしてはいけません!!!親コミットが変わってしまい、プッシュできなくなります そして、プッシュできなくなったからといって、git push -f とするのも絶対にやめましょう!完全に履歴が壊れてしまいます リベースで履歴を整えた形にする terminal git rebase ブランチ プルのリベース型 terminal git pull --rebase リモート名 ブランチ名 複数のコミットをやり直す terminal git rebase -i コミットid git rebase -i HEAD~3 # やり直したいcommitをeditにする edit gh21f6d ヘッダー修正 pick 193054e ファイル追加 pick 84gha0d README修正 # やり直したら実行する git commit --amend # 次のコミットへ進む(リベース完了) git rebase --continue コミットの並び替えや削除 terminal git rebase -i HEAD~3 pick gh21f6d ヘッダー修正 pick 193054e ファイル追加 #消したら削除できる pick 84gha0d README修正 コミットをまとめる terminal git rebase -i HEAD~3 #コミットは1つにまとめる pick gh21f6d ヘッダー修正 squash 193054e ファイル追加 squash 84gha0d README修正 コミットの分割 terminal git rebase -i HEAD~3 pick gh21f6d ヘッダー修正 pick 193054e ファイル追加 pick 41gha0d READMEとindex修正 # コミットを分割する pick gh21f6d ヘッダー修正 pick 193054e ファイル追加 edit 84gha0d READMEとindex修正 git reset HEAD^ git add README git commit -m 'README修正' git add index.html git commit -m 'index.html修正' git rebase --continue タグ付コマンド タグ一覧 terminal git tag タグの作成(注釈付タグ) terminal git tag -a タグ名 -m メッセージ タグの作成(軽量なもの) terminal git tag タグ名 タグのデータ表示 terminal git show タグ名 タグをリモートリポジトリに送信する terminal git push リモート名 タグ名 #一斉にタグを送信 git push origin --tags スタッシュのコマンド 作業の一時避難 terminal git stash git stash save 避難した作業の確認 terminal git stash list 避難した作業の復元 terminal #最初の作業を復元 git stash apply ステージの状況も復元 terminal git stash apply --index 特定の作業を復元する terminal git stash apply スタッシュ名 git stash stash@{1} 避難した作業を削除する terminal #最新の作業を削除する git stash drop #特定の作業を削除する git stash drop スタッシュ名 git stash drop stash@{1} #全作業を削除する git drop clear おわりに 基本的なコマンドを抑えました。 もっと勉強して開発にスムーズに入れるように準備します
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsチュートリアル(第6版) 第13章 アカウントの有効化

第13章 短いメッセージを投稿できるようにするためのリソース「マイクロポスト」機能を追加していく。 手順として ・Micropostデータモデル作成 ・Userモデルとhas_manyおよびbelong_toメソッドで関連付け ・結果を処理し表示するための必要なフォームを作る Micropostモデル 今回のマイクロポストモデルはテストされて、デフォルトの順序を持つ。また、親であるユーザーが破棄されたら自動的に破棄されるものになる。 トピックブランチを作成しておく。 $ git checkout -b user-microposts 基本的なモデル Micropostモデルは、マイクロポストの内容を保存するcontent属性と、特定のユーザーとマイクロポストを関連付けるためのuser_id属性を持つ。 参照:railsチュートリアル String型とText型 ・String型は、255文字まで格納できる ・Text型は、それ以上。また、Text用のテキストエリアを使うので、より自然な投稿フォームになる。将来のことを考えるとこっち。さらに、パフォーマンスでは差は出ないとのこと。 Micropostモデルを生成する $ rails generate model Micropost content:text user:references これでApplicationRecordを継承したモデルが作られた。 app/models/micropost.rb class Micropost < ApplicationRecord belongs_to :user end user:referencesという引数を含めていたため、belongs_toというコードが追加されている。 このreferences型を利用している点が、Userモデルとの最大の違いになる。 これを利用すると、自動的にインデックスと外部キー参照付きのuser_idカラムが追加されて、UserとMicropostを関連付ける下準備をしてくれる。 Userモデルと同様にcreated_atとupdated_atというカラムが追加されてる。 インデックスが付与されたMicropostのマイグレーション db/migrate/[timestamp]_create_microposts.rb class CreateMicroposts < ActiveRecord::Migration[6.0] def change create_table :microposts do |t| t.text :content t.references :user, foreign_key: true t.timestamps end add_index :microposts, [:user_id, :created_at] end end 上のコードでは、user_idとcreated_atカラムにインデックスが付与されている。これで、user_idに関連付けられたすべてのマイクロポストを作成時刻の逆順で取り出しやすくなる。 また、user_idとcreated_atの両方を1つの配列に含めている。これで、Active Recordは両方のキーを同時に扱う複合キーインデックス(Multiple Key Index)を作成する。 マイグレートする $ rails db:migrate Micropostのバリデーション Micropostモデル単体を動くようにする。 Micropostの初期テストは手順 ・setupでfixtureのサンプルユーザーと紐だ付けた新しいマイクロポストを作成 ・次に、作成したマイクロポストが有効かどうかのチェック ・最後に、あらゆるマイクロポストはユーザーのidを持つべきなので、user_idの存在性のバリデーションに対するテストを追加 test/models/micropost_test.rb require 'test_helper' class MicropostTest < ActiveSupport::TestCase def setup @user = users(:michael) # このコードは慣習的に正しくない @micropost = Micropost.new(content: "Lorem ipsum", user_id: @user.id) end test "should be valid" do assert @micropost.valid? end test "user id should be present" do @micropost.user_id = nil assert_not @micropost.valid? end end 1つ目のテストは、現実に即しているかどうかをテスト(reality check) 2つ目のテストは、user_idが存在しているかどうか(nilではないか) user_idに対する存在性のバリデーション app/models/micropost.rb class Micropost < ApplicationRecord belongs_to :user validates :user_id, presence: true end 次にcontent属性に対するバリデーションの追加。 test/models/micropost_test.rb test "content should be present" do @micropost.content = " " assert_not @micropost.valid? end test "content should be at most 140 characters" do @micropost.content = "a" * 141 assert_not @micropost.valid? end content属性も存在性と、140文字より長くならないという制限を加える。 マイクロポストにバリデーションを追記する。 app/models/micropost.rb class Micropost < ApplicationRecord belongs_to :user validates :user_id, presence: true validates :content, presence: true, length: { maximum: 140 } end User/Micropostの関連付け 個々のモデル間で関連付けをしておく。 今回は、それぞれのマイクロポストは一人のユーザーと関連付けられ、それぞれのユーザーは潜在的に複数のマイクロポストと関連付けられている。 MicropostとそのUserはbelongs_toの関係性 参照:railsチュートリアル UserとそのMicropostはhas_manyの関係性 参照:railsチュートリアル このような関係を行うことで メソッド  用途 micropost.user  Micropostに紐付いたUserオブジェクトを返す  user.microposts  Userのマイクロポストの集合をかえす  user.microposts.create(arg) userに紐付いたマイクロポストを作成する  user.microposts.create!(arg) userに紐付いたマイクロポストを作成する(失敗時に例外を発生) user.microposts.build(arg) userに紐付いた新しいMicropostオブジェクトを返す user.microposts.find_by(id: 1) userに紐付いていて、idが1であるマイクロポストを検索する 上のメソッドが使えるようになる。 注意点として Micropost.create Micropost.create! Micropost.new ではなく user.microposts.create user.microposts.create! user.microposts.build となっている。 紐づいているユーザーを通してマイクロポストを作成することができる。新規のマイクロポストがこの方法で作成される場合、user_idは自動的に正しい値に設定される。 最初の書き方↓ @user = users(:michael) # このコードは慣習的に正しくない @micropost = Micropost.new(content: "Lorem ipsum", user_id: @user.id) 書き換えると↓ @user = users(:michael) @micropost = @user.microposts.build(content: "Lorem ipsum") buildメソッドはオブジェクトを返すがデータベースには反映されない。 一度関連付けを定義すれば、@micropost変数のuser_idには、関連するユーザーidが自動的に設定される。 UserモデルとMicropostモデルを紐づける。 Micropostは、belongs_to :user Userモデルは、has_many :micropostsと追加する app/models/user.rb class User < ApplicationRecord has_many :microposts . . . end setupメソッドを修正し、正しいテストにする。 test/models/micropost_test.rb def setup @user = users(:michael) @micropost = @user.microposts.build(content: "Lorem ipsum") end マイクロポストを改良する UserとMicropostを関連付けを改良する。 ユーザーのマイクロポストを特定の順序で取得できるようにしたり、マイクロポストをユーザーに依存させ、ユーザーの削除と同時にマイクロポストも自動的に削除されるようにする。 デフォルトスコープ user.micropostメソッドはデフォルト状態では読み出し順序に何も保証がない。 ブログやTwitterの慣習に従い、作成時間の逆順、最も新しいマイクロポストを最初に表示する。 これを実装するには、default scopeを使う。 このテストは、一見成功しているように思えるが、「アプリケーション側の実装が本当は間違っているのにテストが成功してしまう」トラップがある。 なので、テスト駆動開発で進める。 テスト内容 データベース上のマイクロポストが、fixture内のマイクロポスト(most_recet)と同じであるか検証する。 test/models/micropost_test.rb require 'test_helper' class MicropostTest < ActiveSupport::TestCase . . . test "order should be most recent first" do assert_equal microposts(:most_recent), Micropost.first end end fixtureでコメント、作成日、ユーザーへの関連付けを行う。 test/fixtures/microposts.yml orange: content: "I just ate an orange!" created_at: <%= 10.minutes.ago %> user: michael tau_manifesto: content: "Check out the @tauday site by @mhartl: https://tauday.com" created_at: <%= 3.years.ago %> user: michael cat_video: content: "Sad cats are sad: https://youtu.be/PKffm2uI4dk" created_at: <%= 2.hours.ago %> user: michael most_recent: content: "Writing a short test" created_at: <%= Time.zone.now %> user: michael fixtureファイル内では日付を更新可能となっている。 続いて、Railsのdefault_scopeメソッドを使う。 このメソッドは、データベースから要素を取得した時のデフォルトの順序を指定するメソッドになる。 特定の順序にしたい場合、default_scopeの引数にorderを与える。 例えば、created_atカラムの順にしたい場合は以下の通り。 order(:created_at) デフォルトの順序が昇順の為、小さい値から大きい値にソートされる。つまり最も古い投稿が最初に来る。 順序を逆にするには、生のSQLを引数に与える。 order('created_at DESC') DESCは、SQLの降順(descending)を指す。これで新しい投稿から古い投稿の順に並ぶ。 なんとRails4.0以降は、Rubyの文法でも書けるようになった。 order(created_at: :desc) default_scopeでマイクロポストを順序付ける app/models/micropost.rb class Micropost < ApplicationRecord belongs_to :user default_scope -> { order(created_at: :desc) } validates :user_id, presence: true validates :content, presence: true, length: { maximum: 140 } end 上のコードでは、ラムダ式という文法を使っている。 これは、Procやlambda(無名関数)と呼ばれるオブジェクトを作成する文法。 ->というラムダ式は、ブロックを引数に取り、Procオブジェクトを返す。 このオブジェクトは、callメソッドが呼ばれたとき、ブロック内の処理を評価する。 Dependent: destroy マイクロポストに第二の要素を追加する。 サイト管理者はユーザーを破棄する権限を持つため、ユーザーが破棄されたらユーザーのマイクロポストも同時に破棄されるべき。 has_manyメソッドにオプションを渡してあげればOK app/models/user.rb class User < ApplicationRecord has_many :microposts, dependent: :destroy . . . end dependent: :destroyというオプションを使うことで、ユーザーが削除されたら、そのユーザーに紐づいたマイクロポストも一緒に削除される。 持ち主の存在しないマイクロポストがデータベースに取り残される問題を防ぐ。 Userモデルを検証する。 テスト内容 ・ユーザーを作成する ・そのユーザーに紐づいたマイクロポストを作成する ・その後、ユーザーを削除してみて、マイクロポストが1つ減っているかどうか確認する test/models/user_test.rb require 'test_helper' class UserTest < ActiveSupport::TestCase def setup @user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar") end . . . test "associated microposts should be destroyed" do @user.save @user.microposts.create!(content: "Lorem ipsum") assert_difference 'Micropost.count', -1 do @user.destroy end end end マイクロポストを表示する ユーザープロフィールにマイクロポストを表示させるため、最初に極めて神父rなERbテンプレートを作成する。 次に、サンプルデータ生成タスクにマイクロポストのサンプルを追加し、画面にサンプルデータが表示されるようにする。 マイクロポストの描画 ユーザーのプロフィール画面(show.html.erb)で、そのユーザーのマイクロポストを表示させたり、これまでに投稿した総数も表示させる。 Micropostのコントローラーとビューを作成するために、コントローラを生成する。 $ rails generate controller Microposts _micropost.html.erbパーシャルを使って、マイクrポストのコレクションを表示しようとすると以下のようになる。 <ol class="microposts"> <%= render @microposts %> </ol> ulタグではなく、順序付きリストのolタグを使っている。 マイクロポストが特定の順序に依存しているため。 対応するパーシャのコード↓ app/views/microposts/_micropost.html.erb <li id="micropost-<%= micropost.id %>"> <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %> <span class="user"><%= link_to micropost.user.name, micropost.user %></span> <span class="content"><%= micropost.content %></span> <span class="timestamp"> Posted <%= time_ago_in_words(micropost.created_at) %> ago. </span> </li> time_ago_in_wordsというヘルパーメソッドを使っている。これは、「〇分前に投稿」といった文字列を出力するもの。 <li id="micropost-<%= micropost.id %>"> これは、各マイクロポストにCSSのidを割り振っている。将来的に、各マイクロポストを操作したくなった時に役立つ。 ページ分割するため、will_paginateメソッドを使う。 <%= will_paginate @microposts %> 第10章のユーザー一覧画面のコードでは、<%= will_paginate %>という単純なコードだった。 実は、上のコードは引数なしで動作していた。will_paginateがUsersコントーラのコンテキストにおいて、@userインスタンス変数が存在していることを前提としてたから。このインスタンス変数は、ActiveRecord::Relationクラスのインスタンス。 今回の場合は、Usersコントローラのコンテキストからマイクロポストをページネーションしたいため(コンテキストが異なる)、明示的に@microposts変数をwill_paginateに渡す必要がある。 従って、そのようなインスタンス変数をUsersコントローラのshowアクションで定義しなければならない。 @micropostsインスタンス変数をshowアクションに追加する。 app/controllers/users_controller.rb class UsersController < ApplicationController . . . def show @user = User.find(params[:id]) @microposts = @user.microposts.paginate(page: params[:page]) end . . . end マイクロポストの関連付けを経由し、micropostテーブルに到達して、必要なマイクロポストのページを引き出している。 最後に、マイクロポストの投稿数を表示するが、これはcountメソッドでOK user.microposts.count 関連付けを通して、countメソッドを呼び出している。 なんとcountメソッドでは、データベース上のマイクロポストを全部読みだしてから結果の配列にlengthを呼ぶような、無駄な処理はしていない。 (そりゃぁそうでなければね) データーベースに代わりに計算してもらい、特定のuser_idに紐づいたマイクロポストの数をデータベースに問い合わせている。countメソッドよりもさらに高速なcounter cacheも使うことが可能。 プロフィール画面にマイクロポストを表示させる。 if @user.microposts.any?を使って、ユーザーのマイクロポストが1つもない場合には空のリストを表示させないようにしている。 app/views/users/show.html.erb <% provide(:title, @user.name) %> <div class="row"> <aside class="col-md-4"> <section class="user_info"> <h1> <%= gravatar_for @user %> <%= @user.name %> </h1> </section> </aside> <div class="col-md-8"> <% if @user.microposts.any? %> <h3>Microposts (<%= @user.microposts.count %>)</h3> <ol class="microposts"> <%= render @microposts %> </ol> <%= will_paginate @microposts %> <% end %> </div> </div> マイクロポストのサンプル すべてのユーザーにマイクロポストを追加すると時間が掛かるので、takeメソッドを使って最初の6人だけ追加する。 User.order(:created_at).take(6) orderメソッドを経由することで、最初の6人を明示的に呼び出すようにしている。 1ページの表示限界数(30)を越えさせるのに、それぞれ50個分のマイクロポストを追加する。 また、各投稿内容はFaker gemにLorem.sentenceというメソッドを使う。 db/seeds.rb # ユーザーの一部を対象にマイクロポストを生成する users = User.order(:created_at).take(6) 50.times do content = Faker::Lorem.sentence(word_count: 5) users.each { |user| user.microposts.create!(content: content) } end 開発環境のデータベースで生成 $ rails db:migrate:reset $ rails db:seed 参照:railsチュートリアル CSSを整えて、、 app/assets/stylesheets/custom.scss /* microposts */ .microposts { list-style: none; padding: 0; li { padding: 10px 0; border-top: 1px solid #e8e8e8; } .user { margin-top: 5em; padding-top: 0; } .content { display: block; margin-left: 60px; img { display: block; padding: 5px 0; } } .timestamp { color: $gray-light; display: block; margin-left: 60px; } .gravatar { float: left; margin-right: 10px; margin-top: 5px; } } aside { textarea { height: 100px; margin-bottom: 5px; } } span.image { margin-top: 10px; input { border: 0; } } プロフィール画面のマイクロポストをテスト プロフィール画面で表示されるマイクロポストに対して、統合テストを書く。 まずは、プロフィール画面用の統合テストを生成する。 $ rails generate integration_test users_profile マイクロポスト用のfixtureにいくつかデータを追加 test/fixtures/microposts.yml orange: content: "I just ate an orange!" created_at: <%= 10.minutes.ago %> user: michael tau_manifesto: content: "Check out the @tauday site by @mhartl: https://tauday.com" created_at: <%= 3.years.ago %> user: michael cat_video: content: "Sad cats are sad: https://youtu.be/PKffm2uI4dk" created_at: <%= 2.hours.ago %> user: michael most_recent: content: "Writing a short test" created_at: <%= Time.zone.now %> user: michael <% 30.times do |n| %> micropost_<%= n %>: content: <%= Faker::Lorem.sentence(word_count: 5) %> created_at: <%= 42.days.ago %> user: michael <% end %> テスト内容 プロフィール画面にアクセス後 ・ページタイトルとユーザー名 ・Gravatar ・マイクロポストの投稿数 ・ページ分割されたマイクロポスト という順番でテストする。 test/integration/users_profile_test.rb require 'test_helper' class UsersProfileTest < ActionDispatch::IntegrationTest include ApplicationHelper def setup @user = users(:michael) end test "profile display" do get user_path(@user) assert_template 'users/show' assert_select 'title', full_title(@user.name) assert_select 'h1', text: @user.name assert_select 'h1>img.gravatar' assert_match @user.microposts.count.to_s, response.body assert_select 'div.pagination' @user.microposts.paginate(page: 1).each do |micropost| assert_match micropost.content, response.body end end end 第12章と同様に、response.bodyを使っている。これには、そのページの完全なHTMLが含まれている。 従って、そのページのどこかしらにマイクロポストの投稿数があれば、以下のように探してマッチできる。 assert_match @user.microposts.count.to_s, response.body 上のはassert_selectよりも抽象的なメソッド。 特にassert_selectではどのHTMLタグを探すか指定しなければならない。 assert_matchメソッドはその必要がない。 さらに、assert_selectの引数ではネストした文法を使う。 assert_select 'h1>img.gravatar' h1タグの内側にあるgrabatarクラス月のimgタグがあるかどうかをチェックしてる。 マイクロポストを操作する データモデリングとマイクロポスト表示テンプレートが完成したので、続いてWeb経由でそれらを作成するためのインターフェースに取り掛かる。 やること ・ステータスフィード実装 ・ユーザーがマイクロポストをWeb経由で破棄できるようにする 従来のRails開発と子なる点が1つある。 Micropostリソースへのインターフェイスは、主にプロフィールページとHomeページのコントローラを経由し実行されるため、Micropostコント―羅にはnewやeditアクションは不要。 つまり、createやdestroyがあればOK Micropostsリソースは下記になる。 resources :microposts, only: [:create, :destroy] Micropostsリソースが提供するRESTfulルート HTTPリクエスト URL アクション 名前付きルート POST /microposts create microposts_path DELETE /microposts/1 destroy micropost_path(micropost) マイクロポストのアクセス制御 Micropostsリソース開発では、コントローラ内のアクセス制御から始める。 関連付けられたユーザーを通してマイクロポストにアクセスするので、createアクションやdestroyアクションを利用するユーザーはログイン済である必要がある。 ログイン済か調べるテストは、Usersコントローラ用のテストがそのまま使える。 正しいリクエストを各アクションに発行し、マイクロポスト数が変化してないかどうか、リダイレクトされるかどうかを確認する。 test/controllers/microposts_controller_test.rb require 'test_helper' class MicropostsControllerTest < ActionDispatch::IntegrationTest def setup @micropost = microposts(:orange) end test "should redirect create when not logged in" do assert_no_difference 'Micropost.count' do post microposts_path, params: { micropost: { content: "Lorem ipsum" } } end assert_redirected_to login_url end test "should redirect destroy when not logged in" do assert_no_difference 'Micropost.count' do delete micropost_path(@micropost) end assert_redirected_to login_url end end ここでリファクタリングの必要性あり。 第10章では、beforeフィルタのlogged_in_userメソッドを使って、ログインを要求した。第10章では、Usersコントローラ内にこのメソッドがあったので、beforeフィルターを指定した。 なので、Micropostsコントローラでも同様に必要になる。 なので、各コントローラーが継承するApplicationコントローラに、このメソッドを移す。 app/controllers/application_controller.rb class ApplicationController < ActionController::Base include SessionsHelper private # ユーザーのログインを確認する def logged_in_user unless logged_in? store_location flash[:danger] = "Please log in." redirect_to login_url end end end Usersコントローラからは、logged_in_userは削除しておこう。 これでMicropostsコントローラーからもlogged_in_userメソッドを呼び出せるようになった。 これで、createアクションやdestroyアクションに対するアクセス制限が、beforeフィルターで簡単に実装できるようになった。 app/controllers/microposts_controller.rb class MicropostsController < ApplicationController before_action :logged_in_user, only: [:create, :destroy] def create end def destroy end end マイクロポストを作成する 第7章でやった、HTTP POSTリクエストをUsersコントローラのcreateアクションに発行するHTMLフォームを作成することで、ユーザーのサインアップをやった。 今回もこれと似てる。違いとして、別のmicropost/neeページを使う代わりに、ホーム画面にフォームを置くという点。 この節での目標 ・ユーザーのログイン状態に応じて、ホーム画面の表示を変更する事 マイクロポストのcreateアクションを作る。 app/controllers/microposts_controller.rb class MicropostsController < ApplicationController before_action :logged_in_user, only: [:create, :destroy] def create @micropost = current_user.microposts.build(micropost_params) if @micropost.save flash[:success] = "Micropost created!" redirect_to root_url else render 'static_pages/home' end end def destroy end private def micropost_params params.require(:micropost).permit(:content) end end ユーザー用アクションと似てるが、違いは新しいマイクロポストをbuildするためにUser/Micropost関連付けを使っているというところ。 micropost_paramsでStrong Parmetersを使っていることで、マイクロポストのcotent属性だけがWeb経由で変更可能になっている。 マイクロポスト作成フォーム構築のために、サイト訪問者がログインしてるかどうかに応じ、異なるHTMLを提供するコード app/views/static_pages/home.html.erb <% if logged_in? %> <div class="row"> <aside class="col-md-4"> <section class="user_info"> <%= render 'shared/user_info' %> </section> <section class="micropost_form"> <%= render 'shared/micropost_form' %> </section> </aside> </div> <% else %> <div class="center jumbotron"> <h1>Welcome to the Sample App</h1> <h2> This is the home page for the <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a> sample application. </h2> <%= link_to "Sign up now!", signup_path, class: "btn btn-lg btn-primary" %> </div> <%= link_to image_tag("rails.svg", alt: "Rails logo", width: "200px"), "https://rubyonrails.org/" %> <% end %> 上のコードを動かすためパーシャルを作る必要がある。 Homeページの新しいサイドバー app/views/shared/_user_info.html.erb <%= link_to gravatar_for(current_user, size: 50), current_user %> <h1><%= current_user.name %></h1> <span><%= link_to "view my profile", current_user %></span> <span><%= pluralize(current_user.microposts.count, "micropost") %></span> ユーザー情報に、そのユーザーが投稿したマイクロポスト総数が表示される。 pluralizeメソッドを使って、"1 micropost"や"2 microposts"とするよう調整してる。 マイクロポスト作成フォームを定義する。ユーザー登録フォームに似てる。 app/views/shared/_micropost_form.html.erb <%= form_with(model: @micropost, local: true) do |f| %> <%= render 'shared/error_messages', object: f.object %> <div class="field"> <%= f.text_area :content, placeholder: "Compose new micropost..." %> </div> <%= f.submit "Post", class: "btn btn-primary" %> <% end %> フォームを動かすため、2か所変更が必要。 1つは、関連付けを使って以下のように@micropostと定義すること @micropost = current_user.microposts.build app/controllers/static_pages_controller.rb class StaticPagesController < ApplicationController def home @micropost = current_user.microposts.build if logged_in? end current_userメソッドはユーザーがログインしている時しか使えないので、@micropost変数もログインしているときのみ定義されるようになる。 2つめは、エラーメッセージのパーシャルを再定義すること。 <%= render 'shared/error_messages', object: f.object %> 今回は@mircropost変数を使う。フォーム変数fをf.objectとし、関連付けられたオブジェクトにアクセスすることができる。 form_with(model: @user, local: true) do |f| 上のようにf.objectが@userとなる場合と form_with(model: @micropost, local: true) do |f| f.objectが@micropostになる場合がある。 パーシャルにオブジェクトを渡すため、値がオブジェクトで、キーがパーシャルでの変数名と同じハッシュを利用する。 object: f.objectはerror_messagesパーシャルの中でobjectという変数名を作成してくれるので、この変数名を使ってエラーメッセージを更新すれば良い。 app/views/shared/_error_messages.html.erb <% if object.errors.any? %> <div id="error_explanation"> <div class="alert alert-danger"> The form contains <%= pluralize(object.errors.count, "error") %>. </div> <ul> <% object.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> この時点でテストは失敗する。error_messagesパーシャルの他の出現場所がヒント。 このパーシャルは、他の場所で使われていたため、ユーザー登録、パスワード再設定、ユーザー編集のそれぞれのビューを更新する必要がある。 各ビューを更新した結果を下記に示す。 app/views/users/new.html.erb <% provide(:title, 'Sign up') %> <h1>Sign up</h1> <div class="row"> <div class="col-md-6 col-md-offset-3"> <%= form_with(model: @user, local: true) do |f| %> <%= render 'shared/error_messages', object: f.object %> <%= f.label :name %> <%= f.text_field :name, class: 'form-control' %> <%= f.label :email %> <%= f.email_field :email, class: 'form-control' %> <%= f.label :password %> <%= f.password_field :password, class: 'form-control' %> <%= f.label :password_confirmation, "Confirmation" %> <%= f.password_field :password_confirmation, class: 'form-control' %> <%= f.submit "Create my account", class: "btn btn-primary" %> <% end %> </div> </div> app/views/users/edit.html.erb <% provide(:title, "Edit user") %> <h1>Update your profile</h1> <div class="row"> <div class="col-md-6 col-md-offset-3"> <%= form_with(model: @user, local: true) do |f| %> <%= render 'shared/error_messages', object: f.object %> <%= f.label :name %> <%= f.text_field :name, class: 'form-control' %> <%= f.label :email %> <%= f.email_field :email, class: 'form-control' %> <%= f.label :password %> <%= f.password_field :password, class: 'form-control' %> <%= f.label :password_confirmation, "Confirmation" %> <%= f.password_field :password_confirmation, class: 'form-control' %> <%= f.submit "Save changes", class: "btn btn-primary" %> <% end %> <div class="gravatar_edit"> <%= gravatar_for @user %> <a href="https://gravatar.com/emails">change</a> </div> </div> </div> app/views/password_resets/edit.html.erb <% provide(:title, 'Reset password') %> <h1>Reset password</h1> <div class="row"> <div class="col-md-6 col-md-offset-3"> <%= form_with(model: @user, url: password_reset_path(params[:id]), local: true) do |f| %> <%= render 'shared/error_messages', object: f.object %> <%= hidden_field_tag :email, @user.email %> <%= f.label :password %> <%= f.password_field :password, class: 'form-control' %> <%= f.label :password_confirmation, "Confirmation" %> <%= f.password_field :password_confirmation, class: 'form-control' %> <%= f.submit "Update password", class: "btn btn-primary" %> <% end %> </div> </div> フィードの原型 マイクロポスト投稿フォームが動作するようになった。 しかし、現時点では投稿した内容をすぐにみる事ができない。なぜなら、Homeページにまだマイクロポストを表示する部分が実装されないから。 フォームが正しく動作してるかチェックする場合 正しいエントリー投稿→プロフィールページに移動→ポストを表示 になるが、これは面倒だ。 なので、ユーザー自身のポストを含むマイクロポストのフィードがないと不便。 参照:railsチュートリアル すべてのユーザーがフィードを持つため、feedメソッドはUserモデルで作るのが良い。 フィードの原型では、まずは現在ログインしているユーザーのマイクロポストをすべて取得する。 第14章で完全なフィードを実装するので、今回はwhereメソッドでこれを実現する。 Micropostモデルに変更を加える。 app/models/user.rb class User < ApplicationRecord . . . # 試作feedの定義 # 完全な実装は次章の「ユーザーをフォローする」を参照 def feed Micropost.where("user_id = ?", id) end private . . . end 上のコードにある疑問符は、セキュリティ上重要だ。 Micropost.where("user_id = ?", id) 疑問符があることで、SQLクエリに代入する前にidがエスケープされるため、SQLインジェクション(SQL Injection)と呼ばれる深刻なセキュリティホールを避けられる。 この場合、id属性は単なる整数(self.idはユーザーのid)であるため危険でないが、SQL文に変数を代入する場合は常にエスケープしておこう。 サンプルアプリケーションにフィード機能を導入するために、ログインユーザーのフィード用にインスタンス変数@feed_itemsを追加、Homeページにはフィード用のパーシャルを追加する。 先ほどあった下記のコード @micropost = current_user.microposts.build if logged_in? これが if logged_in? @micropost = current_user.microposts.build @feed_items = current_user.feed.paginate(page: params[:page]) end 前置if文に変わる。 (1行の時は後置if文、2行の時は前置if文を使うのがRubyの慣習) homeアクションにフィードのインスタンス変数を追加する。 app/controllers/static_pages_controller.rb class StaticPagesController < ApplicationController def home if logged_in? @micropost = current_user.microposts.build @feed_items = current_user.feed.paginate(page: params[:page]) end end ステータスフィードのパーシャル app/views/shared/_feed.html.erb <% if @feed_items.any? %> <ol class="microposts"> <%= render @feed_items %> </ol> <%= will_paginate @feed_items %> <% end %> ステータスフィードのパーシャルは、Micropostのパーシャルとは異なる。 <%= render @feed_items %> このとき、@feed_itemsの各要素がMicropostクラスを持っていたため、RailsはMicropostのパーシャルを呼び出すことができた。 このように、Railsは対応する名前のパーシャルを、渡されたリソースのディレクトリ内から探しにいくことができる。 あとはいつものようにフィードパーシャルを表示すればHomeページにフィードを追加できる。 この結果はHomeページのフィードとして表示される。 app/views/static_pages/home.html.erb <% if logged_in? %> <div class="row"> <aside class="col-md-4"> <section class="user_info"> <%= render 'shared/user_info' %> </section> <section class="micropost_form"> <%= render 'shared/micropost_form' %> </section> </aside> <div class="col-md-8"> <h3>Micropost Feed</h3> <%= render 'shared/feed' %> </div> </div> しかし、マイクロポストの投稿が失敗すると、Homeページは@feed_itemsインスタンス変数を期待しているため、現状では壊れる。 解決法として、Micropostコントローラのcreateアクションへの送信が失敗した場合に備え、必要なフィード変数をこのブランチで渡しておくこと。 app/controllers/microposts_controller.rb def create @micropost = current_user.microposts.build(micropost_params) if @micropost.save flash[:success] = "Micropost created!" redirect_to root_url else @feed_items = current_user.feed.paginate(page: params[:page]) render 'static_pages/home' end end しかし、この時点ではわざと長いマイクロポストを投稿するとエラーが出る。 ページネーション用のリンクを表示すると、"2"のリンクと"Next"のリンクがどちらも同じ次のページを指している。 createアクションはMicropostsコントローラにあるので、このURLは「/microposts?page=2」となります。しかし、これはMicropostsの存在していないindexアクションを開こうとしている。 その結果、どちらのリンクをクリックしてもエラーが発生する。 この問題は、Homeページに対応するcontrollerパラメータとactionパラメータを明示的にwill_paginateに渡せばOK 例として、static_pagesコントローラとhomeアクションを渡すと次の通り。 app/views/shared/_feed.html.erb <% if @feed_items.any? %> <ol class="microposts"> <%= render @feed_items %> </ol> <%= will_paginate @feed_items, params: { controller: :static_pages, action: :home } %> <% end %> マイクロポストを削除する 削除機能を追加する。 これは、ユーザー削除と同じように"delete"リンクでOK。 今回は自分が投稿したマイクロポストのみ削除リンクが動作するようにする。 まずは、マイクロポストのパーシャルに削除リンクを追加する。 app/views/microposts/_micropost.html.erb <li id="micropost-<%= micropost.id %>"> <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %> <span class="user"><%= link_to micropost.user.name, micropost.user %></span> <span class="content"><%= micropost.content %></span> <span class="timestamp"> Posted <%= time_ago_in_words(micropost.created_at) %> ago. <% if current_user?(micropost.user) %> <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %> <% end %> </span> </li> 次に、Micropostsコントローラのdestroyアクションを定義する。 ユーザーの実装とほぼ同じ。違いは、admin_userフィルターで@user変数を使うのではなく、関連付けを使いマイクロポストを見つけるようにする点。 これで、あるユーザーが他のユーザーのマイクロポストを削除しようとすると、自動的に失敗するようになる。 correct_userフィルター内でfindメソッドを呼び出すことで、現在のユーザーが削除対象のマイクロポストを保有してるかどうか確認する。 app/controllers/microposts_controller.rb class MicropostsController < ApplicationController before_action :logged_in_user, only: [:create, :destroy] before_action :correct_user, only: :destroy . . . def destroy @micropost.destroy flash[:success] = "Micropost deleted" redirect_to request.referrer || root_url end private def micropost_params params.require(:micropost).permit(:content) end def correct_user @micropost = current_user.microposts.find_by(id: params[:id]) redirect_to root_url if @micropost.nil? end end destroyメソッドではリダイレクトを使っている。 request.referrer || root_url ここでrequest.referrerというメソッドを使っている。 このメソッドはフレンドリーフォワーディングのrequest.url変数と似ており、一つ前のURLを返す。(今回なら、Homeページ) なので、マイクロポストがHomeページから削除された場合でもプロフィールページから削除された場合でも、request.referrerを使うことによりDELETEリクエストが発行されたページに戻れる。 また、元に戻すURLが見つからなくても||演算子でroot_urlをデフォルトに設定してるので問題なし。 マイクロポスト作成 マイクロポスト削除 フィード画面のマイクロポストをテストする Micropostモデルとそのインターフェイスが完成した。 あとは、Micropostsコントローラの認可をチェックするテストと、それらをまとめる統合テストだ。 マイクロポスト用のfixtureに、別々のユーザーに紐づけられたマイクロポストを追加する。 別のユーザーに所属しているマイクロポストを追加 test/fixtures/microposts.yml ants: content: "Oh, is that what you want? Because that's how you get ants!" created_at: <%= 2.years.ago %> user: archer zone: content: "Danger zone!" created_at: <%= 3.days.ago %> user: archer tone: content: "I'm sorry. Your words made sense, but your sarcastic tone did not." created_at: <%= 10.minutes.ago %> user: lana van: content: "Dude, this van's, like, rolling probable cause." created_at: <%= 4.hours.ago %> user: lana 続いて、自分以外のユーザーのマイクロポストは削除しようとした時、適切にリダイレクトされることを確認する。 test/controllers/microposts_controller_test.rb test "should redirect destroy for wrong micropost" do log_in_as(users(:michael)) micropost = microposts(:ants) assert_no_difference 'Micropost.count' do delete micropost_path(micropost) end assert_redirected_to root_url end 最後に、統合テストを書く。 統合テストの内容 ・ログイン ・マイクロポストのページ分割確認 ・無効なマイクロポストを投稿 ・有効なマイクロポストを投稿 ・マイクロポストの削除 ・他のユーザーのマイクロポストには[delete]リンクが非表示 という順番でテストする。 統合テストを生成する。 $ rails generate integration_test microposts_interface マイクロポストUIに対する統合テスト test/integration/microposts_interface_test.rb require 'test_helper' class MicropostsInterfaceTest < ActionDispatch::IntegrationTest def setup @user = users(:michael) end test "micropost interface" do log_in_as(@user) get root_path assert_select 'div.pagination' # 無効な送信 assert_no_difference 'Micropost.count' do post microposts_path, params: { micropost: { content: "" } } end assert_select 'div#error_explanation' assert_select 'a[href=?]', '/?page=2' # 正しいページネーションリンク # 有効な送信 content = "This micropost really ties the room together" assert_difference 'Micropost.count', 1 do post microposts_path, params: { micropost: { content: content } } end assert_redirected_to root_url follow_redirect! assert_match content, response.body # 投稿を削除する assert_select 'a', text: 'delete' first_micropost = @user.microposts.paginate(page: 1).first assert_difference 'Micropost.count', -1 do delete micropost_path(first_micropost) end # 違うユーザーのプロフィールにアクセス(削除リンクがないことを確認) get user_path(users(:archer)) assert_select 'a', text: 'delete', count: 0 end end マイクロポストの画像投稿 ここでは、画像付きマイクロポスト投稿の機能を実装する。 手順として、まずは開発環境のβ版を実装し、その後いくつかの改善を通して本番環境用の完成版を実装する。 画像アップロード機能を追加するための2つの視覚要素 ・1つ目は、画像をアップロードするためのフォーム ・2つ目は、1つ目に投稿された画像そのもの 参照:railsチュートリアル モックアップ画像 基本的な画像アップロード Railsでファイルをアップロードする簡単な方法は、Railsに組み込まれているActive Storage機能を使う事。 Active Storageで画像を簡単に扱えて、画像に関連付けるモデルも自由に指定可能となる。 また、Active Storageは汎用性が高く、平文テキスト、PDFファイルや音声等様々なバイナリファイルも扱える。 Active Storageインストールコマンド $ rails active_storage:install 上のコマンドで、添付ファイルの保存に用いるデータモデルを作成するためのデータベースマイグレーションが1つ作られる。 次にマイグレーションを実行 $ rails db:migrate Active Storageの中で最初に知るべきことは、has_one_attachedメソッドだ。 これは、指定のモデルとアップロードされたファイルを関連付けるのに使う。 下の場合は、imageを指定してMicropostモデルと関連付けてる。 app/models/micropost.rb class Micropost < ApplicationRecord belongs_to :user has_one_attached :image default_scope -> { order(created_at: :desc) } validates :user_id, presence: true validates :content, presence: true, length: { maximum: 140 } end このアプリケーションでは、「マイクロポスト1件につき画像は1件」という設計をしているが、Active Storageは他にもhas_many_attachedオプションも提供してる。文字通り、Active Recordオブジェクト1件につき複数のファイルを添付できるもの。 Homeページに画像をアップロードを追加するのに、マイクロポストフォームにfile_fieldタグを含める。 マイクロポストのcreateフォームに画像アップロードを追加 app/views/shared/_micropost_form.html.erb <%= form_with(model: @micropost, local: true) do |f| %> <%= render 'shared/error_messages', object: f.object %> <div class="field"> <%= f.text_area :content, placeholder: "Compose new micropost..." %> </div> <%= f.submit "Post", class: "btn btn-primary" %> <span class="image"> <%= f.file_field :image %> </span> <% end %> 最後に、Micropostsコントローラを更新し、新たに作成したmicropostオブジェクトに画像を追加できるようにする。 Active Storage APIにはそのためのattachメソッドが提供されており、これを使う。 具体的にMicropostsコントローラのcreateアクションの中で、アップロードされた画像を@micropostオブジェクトにアタッチする。 このアップロード許可のために、micropost_paramsメソッドを更新し、:imageを許可済み属性リストに追加して、Web経由で更新できるようにする。 app/controllers/microposts_controller.rb class MicropostsController < ApplicationController before_action :logged_in_user, only: [:create, :destroy] before_action :correct_user, only: :destroy def create @micropost = current_user.microposts.build(micropost_params) @micropost.image.attach(params[:micropost][:image]) if @micropost.save flash[:success] = "Micropost created!" redirect_to root_url else @feed_items = current_user.feed.paginate(page: params[:page]) render 'static_pages/home' end end def destroy @micropost.destroy flash[:success] = "Micropost deleted" redirect_to request.referrer || root_url end private def micropost_params params.require(:micropost).permit(:content, :image) end def correct_user @micropost = current_user.microposts.find_by(id: params[:id]) redirect_to root_url if @micropost.nil? end end 一度画像がアップロードされれば、micropostパーシャルのimage_tagヘルパーを用いて、関連付けられたmicropost.imageを描画できる。 また、画像の無いテキストのみのマイクロポストでは画像を表示させないようにするため、attached?という論理値を返すメソッドを使っている。 app/views/microposts/_micropost.html.erb <li id="micropost-<%= micropost.id %>"> <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %> <span class="user"><%= link_to micropost.user.name, micropost.user %></span> <span class="content"> <%= micropost.content %> <%= image_tag micropost.image if micropost.image.attached? %> </span> <span class="timestamp"> Posted <%= time_ago_in_words(micropost.created_at) %> ago. <% if current_user?(micropost.user) %> <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %> <% end %> </span> </li> 画像の検証 画像アップロード機能を持たせたが、欠点がある。それは、アップロードされた画像に対する制限がないため、もしユーザーが巨大なファイルを上げたり、無効なファイルを上げると問題が発生する。 この欠点を直すために、画像サイズやフォーマットに対するバリデーションを実装する。 Railsチュートリアル執筆時点では、Active Storageは、こうしたフォーマット機能やバリデーションがネイティブでサポートされていないとのこと。 なので、そのような機能をgemで追加する。 gem 'active_storage_validations', '0.8.2' いつものようにbundle installする。 このgemでは、content_typeを検査する事で画像をバリデーションできる。 content_type: { in: %w[image/jpeg image/gif image/png], message: "must be a valid image format" } 上記のコードは、サポートする画像フォーマットに対応する画像MIME typeをチェックしてる。 配列構文%w[]がある。 同じく、ファイルサイズも以下のようにバリデーション可能。 size: { less_than: 5.megabytes, message: "should be less than 5MB" } 上はtimeヘルパーの時に使った構文と同じで、画像の最大サイズを5MBに制限してる。 これらのバリデーションをまとめた結果をMicropostモデルに追加する。 app/models/micropost.rb class Micropost < ApplicationRecord . . . validates :image, content_type: { in: %w[image/jpeg image/gif image/png], message: "must be a valid image format" }, size: { less_than: 5.megabytes, message: "should be less than 5MB" } end 参照:railsチュートリアル 先ほどのモデルに追加バリデーションを強化するために、クライアント側でも画像アップロードのサイズやフォーマットをチェックする仕組みを入れる。 まずは、JavaScript(jQuery)にて、ユーザーがアップロードしようとする画像が大きすぎたらアラートを表示するようにする。 jQueryでファイルサイズをチェックする。 app/views/shared/_micropost_form.html.erb <script type="text/javascript"> $("#micropost_image").bind("change", function() { var size_in_megabytes = this.files[0].size/1024/1024; if (size_in_megabytes > 5) { alert("Maximum file size is 5MB. Please choose a smaller file."); $("#micropost_image").val(""); } }); </script> 最後に、acceptパラメータをfile_field入力タグで用いれば、有効なフォーマットでないとアップロードできない事をユーザーに伝えられる。 app/views/shared/_micropost_form.html.erb <%= form_with(model: @micropost, local: true) do |f| %> <%= render 'shared/error_messages', object: f.object %> <div class="field"> <%= f.text_area :content, placeholder: "Compose new micropost..." %> </div> <%= f.submit "Post", class: "btn btn-primary" %> <span class="image"> <%= f.file_field :image, accept: "image/jpeg,image/gif,image/png" %> </span> <% end %> <%= f.file_field :image, accept: "image/jpeg,image/gif,image/png" %> このコードは最初に有効な画像フォーマットだけを選択可能にしておき、それ以外のファイルタイプを灰色で表示するもの。 ブラウザ側に色々コードを追加したが、このコードは無効なファイルをアップロードしにくくするだけ。 その気になればcurl等でPOSTリクエストを直接発行して、無効なファイルをアップロードできてしまう。 なので、サーバー側のバリデーションは必要なのだ。 画像のリサイズ ファイルサイズのバリデーションは実装した。 今度は、画像サイズ(縦横の長さ)に対する制限がない。なので、大きすぎる画像サイズがアップロードされるとレイアウトが崩壊する。 かといって、ユーザーで画像サイズを変更させるのは大変不便だ。 そのため、画像を表示させる前にサイズを変更するようにする。 参照:railsチュートリアル 画像を操作するプログラムが必要なので、ImageMagickを使う。 開発環境にインストールする。 $ sudo apt-get -y install imagemagick 続いて、画像処理のためにいくつかgemを追加する。 image_processinggem、Ruby製ImageMagickプロセッサのmini_magickgemが必要だ。 gem 'image_processing', '1.9.3' gem 'mini_magick', '4.9.5' いつものようにbundle installする。 これで、Active Storageが提供するvariantメソッドで変換済画像を作成できるようになる。 特にresize_to__limitオプションを用いて、下記のように画像の幅や高さが500ピクセルを越えないように制約をかけとく。 image.variant(resize_to_limit: [500, 500]) 上記のコードをdisplay_imageメソッドにおいて利便性を高めよう。 app/models/micropost.rb # 表示用のリサイズ済み画像を返す def display_image image.variant(resize_to_limit: [500, 500]) end display_imageをmicropostパーシャルで使えるようになった。 リサイズ済のdisplay_imageを使う。 <li id="micropost-<%= micropost.id %>"> <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %> <span class="user"><%= link_to micropost.user.name, micropost.user %></span> <span class="content"> <%= micropost.content %> <%= image_tag micropost.display_image if micropost.image.attached? %> </span> <span class="timestamp"> Posted <%= time_ago_in_words(micropost.created_at) %> ago. <% if current_user?(micropost.user) %> <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %> <% end %> </span> </li> 上記のコードに <%= image_tag micropost.display_image if micropost.image.attached? %> があるが、そこにdisplay_imageメソッドを使ってる。 variantによるリサイズは、<%= image_tag micropost.display_image if micropost.image.attached? %>で最初に呼ばれる時にオンデマンドで実行される。以後、結果をキャッシュするので効率が良い。 本番環境での画像アップロード 画像アップロード機能を実装したが、このままで本番環境に適さない。 本番環境では、ファイルシステムではなくクラウドストレージサービスに画像を保存するようにする。 今回はAWSのS3(Simple Storage Service)を使う。 S3を使うためgemを設定する。 gem 'aws-sdk-s3', '1.46.0', require: false 例のごとくbundle installを実行する。 AWSの設定方法は省く。 railsチュートリアルに画像付きで細かく載っているため。 最後に Micropostsリソースによって、良い感じにTwitterっぽくなった。 次章は、ユーザーをお互いフォローする仕組みを作っていく。 ユーザー同士のリレーションシップモデリングを学んで、マイクロポストフィードにどんな感じで関連するか学ぶ。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[基礎]Gitコマンドについてまとめてみた①

はじめに 実は共同開発は愚か、GithubDesktopを使用していたため、あまりコマンド操作になれてなかったり、リベース周りに慣れていなかったりするのでこちらにアウトプットしていきます。 入社までに完璧にするぜ! 見づらさはご了承ください 基本的なコマンド ローカルリポジトリの新規作成 .gitディレクトリが作成される。 圧縮ファイル ツリーファイル コミットファイル インデックスファイル 設定ファイル terminal git init リモートリポジトリのコピーを作成 terminal git clone リポジトリ名 変更をステージに上げてからコミット terminal git add ファイル名 git add ディレクトリ名 git commit -m(-v) "コミットメッセージ" 差分を調べる terminal #git addする前の変更分 git diff git diff ファイル名 #git add した後の変更分 git diff --staged 変更履歴の確認 terminal git log git log --oneline #1行で表示する git log -p index.html #ファイルの変更差分を表示する git log -n コミット数 #表示数の制限 ファイルの削除 terminal #リモートもローカルでも消す場合 git rm ファイル名 git rm -r ディレクトリ名 #リモート側のみでローカルには残したい時 git rm --cached ファイルの移動を記録する terminal git mv 旧ファイル 新ファイル #上記コマンドは以下をまとめたもの mv 旧ファイル 新ファイル git rm 旧ファイル git add 新ファイル  リモートリポジトリを新規追加する 慣例的にoriginにすることが多いが、当然それ以外でもOK terminal git remote add origin https://github.com/~~~~ プッシュする terminal git push リモート名 ブランチ git push origin master コマンドにエイリアスをつける terminal git config --global alias.ci commit git config --global alias.st status git config --global alias.br branch 変更を元に戻すコマンド ワークツリーでファイルへの変更を取り消す ブランチを切り替えるコマンドとよく似ているので混同しないように注意 terminal git checkout -- ファイル名 git checkout -- ディレクトリ名 #全変更を取り消す魔法の言葉 git checkout -- . ステージした変更を取り消す git addした後にやっぱなし!をしたい時 ワークツリーには影響なし terminal git reset HEAD ファイル名 git reset HEAD ディレクトリ名 #ステージの全変更を消す git reset HEAD 直前のコミットをやりなおす方法 ただし、リモートリポジトリにPushしたコミットはやり直し厳禁 :terminal git commit --amend Githubとあれこれするタイプのコマンド リモート表示 terminal git remote #対応するURLを表示 git remote -v リモートリポジトリを新規追加 terminal git remote add リモート名 リモートURL git remote add tutiral htpps://~~~~~ リモートから情報を取得(フェッチ) git fetch はリモートリポジトリからローカルリポジトリへ下ろすだけ ワークツリー terminal git fetch リモート名 git fetch origin リモートから情報を取得してマージする (プル) terminal git pull リモート名 ブランチ名 #上記コマンドは下記と同じ git fetch origin master git merge origin/master リモートの詳細 terminal git remote show リモート名 git remote show origin リモートの変更 terminal git remote rename 旧リモート名 新リモート名 リモートの削除 terminal git remote rm リモート名 続き まだまだリベースとかもやっていきま〜す!!↓ https://qiita.com/tochisuke221/items/ef3fc32ba904d23ed258
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gitで違うリポジトリのブランチを取り込みたい

結論 git -b ブランチ名 clone リポジトリのURL cd プロジェクト名 rm -rf .git //前のリポジトリの.gitディレクトリを消去 git init git branch -M main git add . git commit -m "最初のコミット" git push -u origin main これで違うリポジトリの好きなブランチをローカルに取り込んで、新しいプロジェクトとして管理できる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

terminalでGitの認証情報を更新する

MacのTerminalでGitを使っている場合、usename, passwordは一度入力すると以後聞かれなくなると思いますが、その後ユーザやパスワードを変更したくなった時にどうするかを記します。 キーチェーンを開く gitなどで検索し、該当の認証情報を削除する コマンドラインのgitのクレデンシャル情報は下記の画像の通り、「アクセス制御」タブの「これらのアプリケーションによるアクセスを常に許可」に git-credential-osxkeychain が入っているかと思います。 この認証情報を消した後再度pushなどをすると、username, passwordが聞かれます。 以上、認証情報の削除は自己責任で行ってください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む