チェリー本:アクセスメソッドの省略

インスタンス変数を読み出したり書き込んだりするメソッドを暗黙的に定義してくれる方法がRubyでは用意されている。下記のようにattr_accessorメソッド、attr_readerメソッド、attr_writerメソッドを用いる。 下記のように各アクセスレベルに応じて、アクセスメソッドの定義を省略して、インスタンス変数にアクセスできる。

class User
  attr_accessor :name   # 読み書きするメソッドを暗黙的に定義
  attr_reader   :age    # 読み取り専用のメソッドを暗黙的に定義
  attr_writer   :gender # 書き込み専用メソッドを暗黙的に定義

  def initialize(name, age, gender)
    @name = name
    @age = age
    @gender = gender
  end
end
  user = User.new('Alice', 30, 'female')

  puts user.name
  user.name = 'Elice'
  puts user.name

  puts user.age
#  user.age = 20 #読み取り専用なので、書き込みメソッドは自分で定義しないと、『メソッドがない』というエラーになる
  puts user.age

#  puts user.gender #書き込み専用なので、読み取りメソッドは自分で定義しないと、『メソッドがない』というエラーになる
  user.gender = 'man'
#  puts user.gender #書き込み専用なので、読み取りメソッドは自分で定義しないと、『メソッドがない』というエラーになる

後置ifの使いどころ

単純に見栄えくらいしか変わらんと思っていた後置if後置unlessは、ちゃんと使いどころがある。

下のコードの場合、Xであるか、そうでないかの2パターンしか存在しない。そうした場合、その条件を網羅していることを視覚的に伝えるためには、三項演算子if式を使った方がわかりやすい。

逆に後置if後置unlessを使うような状況としては、『aのパターンだけ特別に違う処理を実行したい』というようなとき。そうしてあげることで、『たまにaのパターンがあるんだな』ということがわかるようになる。

# 修正前のコード
scores.each do |s|
  shots << 10     if     s == 'X'
  shots << s.to_i unless s == 'X'
end

# 修正後のコード 三項演算子ver.
scores.each do |s|
  shots << (s == 'X' ? 10 : s.to_i)
end

# 修正後のコード if式ver.
scores.each do |s|
  shots << if == 'X'
             10
           else
             s.to_i
           end
end

チェリー本:組み込みライブラリと標準ライブラリとgemの違い

いずれもプログラムでライブラリとして利用できるものだけど、使うまでの準備が少し違うというイメージ。 まず、包含で示すと下記のようになる。

hogan.png

また、ライブラリ読み込み、事前インストールの観点では、それぞれ下記のような違いがある。

項目 ライブラリ読み込み 事前インストール
組み込みライブラリ 不要 不要
標準ライブラリ 必要 不要
gem 必要 必要

標準ライブラリの中でも特に利用頻度の高いものは、組み込みライブラリと呼ばれ、ライブラリ読み込みせずに利用できる。 標準ライブラリやgemはrequireを用いてライブラリを読み込む。

gemについては外部ライブラリであるため、ライブラリとして読み込むために、bundlerで事前インストールが必要になる。

チェリー本:requireでは相対パスでライブラリを指定しない

requirerequire_relativeで自作のプログラムをライブラリとして読み込ませる際に、相対パスで指定できるが、requireの方は相対パスでの指定は推奨されない。今回はその理由についてまとめる。

項目 相対パスの起点 機能
require カレントディレクト カレントディレクトリから
相対パスでファイル読み込み
require_relative 定義ファイルがある場所 定義ファイルの場所から
相対パスでファイル読み込み

上の表に違いとしてまとめたが、相対パスの起点が異なる。これにより、実行時には下記のような違いが出てくる。

require_relativeの場合は、定義ファイルの位置が起点となるため、どこで実行しようが定義ファイルとの位置関係から実行するライブラリは一意に定まる。

requireの場合は、カレントディレクトリの位置が起点となるため、現在のカレントディレクトリの位置により読み込むライブラリが動的に変化してしまい、意図しない同名ファイルを読み込むことで、セキュリティ上の脆弱性に発展してしまう可能性がある。

上記の理由から、requireで自作ライブラリを読み込ませるときには相対パスで指定してはダメ😤。そもそも、自作ライブラリについてはrequire_relativeを用いると覚えておけばよさそう。

読みやすいコードを書くコツ

リーダブルコードを読んだので、大事だなと思ったことをまとめる。

第一部:表面上の改善

第二章:名前に情報を詰め込む

ここでのポイントは、名前は短いコメントであると考えること。いい名前をつければ、それだけ多くの情報を伝えることができるようになるため。じゃあ、どんな名前がいい名前なの?🧐ってことだけど、本では下記のテーマとポイントが紹介されていた。

テーマ ポイント
明確な単語を選ぶ 気取った言い回しよりも明確で正確な名前にする。類語辞典などでより明確なものを選んであげるのが有効
汎用的な名前を避ける
(または使う状況を選ぶ)
変数の値を表すような名前にする。tmpのような名前は、情報の一時保管として使用するような時に使う。
抽象的な名前よりも具体的な名前を使う メソッドの動作をそのまま表すような名前にする
接尾辞や接頭辞を使って情報を追加 N進数や単位、危険や注意を喚起する情報を追加する
名前の長さを決める スコープが小さければ(スコープが数行の変数)短い名前でもよい。名前の省略形を使う場合は、一般的に使用されるものを使用する(stringstrdocumentdocみたいな感じ)。無くても意味が変わらないならその単語を削除する
名前のフォーマットで情報を伝える クラス名をキャメルケース、変数名をスネークケースというように、名前のフォーマットを見るだけで情報が伝わるようにする。

第三章 誤解されない名前

ここでのポイントは、名前が他の意味と誤解されないかどうかを自問自答するという点。書いたコードが、意図通り正しく理解できるような名前となっているかを意識することが大事。どんなことに気をつけるかは、下記が紹介されていた。

使用する場面 説明
上下の限界値を決める max_min_を接頭辞にする。
包含的範囲(最終要素も含める) firstlastを使用する
包含/排他的範囲(最終要素を含めない) beginendを使用する
ブール値を扱う ishasを使う

上記以外にも、『肯定形で単語を利用する』、『単語に対するユーザの期待に沿うような名前付け(get()size()のようなものは軽量なメソッドであるということが一般的に浸透している)を意識する』なども重要とのことだった。

第四章 美しさ

ここでのポイントは、見た目が美しいコードの方が使いやすいという点。さっと流し読みができるのが、誰にとっても使いやすいコードと言える。コードを読みやすくするためには、3つの原則が大事とのこと。

  • 読み手が慣れているパターンと一貫性のあるレイアウトを使う
  • 似ているコードは似ているように見せる
  • 関連するコードはまとめてブロックする

上記の原則を基に、具体的に気をつけることは下記が紹介されていた。

要点 説明
一貫性のある簡潔な改行位置 複数のコードブロックで同じようなことをしていたら、改行位置を揃えて、シルエットも同じようにする
メソッドを使った整列 複数のコードブロックで同じようなことをしていたら、ヘルパーメソッドを用いてテストケースの大切な部分が見えやすくできないかを考え、シルエットも同じようにする
縦の線をまっすぐにする 空白などを用いて列を整列させ、概要を把握しやすくする
一貫性と意味のある並び 重要度順、アルファベット順、入力フォームと同じ順など、意味なる並びがあればそれに従わせる。また、ある場所でA・B・Cと並んでいたものを、他の場所でB・C・Aのように並べない。
宣言をブロックにまとめる メソッド内を論理的なグループに分けてあげる。(例えば、コンストラクタ、デストラクタはグループ化して配置する)
コードを段落に分割する 文章と同じように、コードも段落に分割する。改行を使って大きなブロックを論理的な『段落』に分ける

第五章 コメントすべきことを知る

ここでのポイントは、コメントの目的はコードの意図を読み手に理解してもらうという点。コードの意図を理解してもらうために、本では下記観点が紹介されていた。

観点 説明
不要なコメントを知る ・コードからすぐわかることを書かない
・ひどい名前はコメントではなく名前を変える
 (自己文書化した名前が望ましい)
自分の考えを残す ・なぜ他のやり方ではなくこうしているかの大切な考えを残す
・コードの品質や状態がわかるようにする
・定数を決めたときの理由を残す
読み手の立場になって考える ・『え?』と思われそうなところにコメントを残す
 (『普通は〇〇なのに、なんで△△?』と思われる場所)
・ハマりそうな罠を示す
 (当該コードを使う前に気づけるようにする)
・『全体像』がわかる情報をつける
・関数内部の塊を要約する
 (塊を関数に分割できるならそっちのが望ましい)

自分の考えを残す観点の『コードの品質や状態がわかるようにする』は、プログラマがよく使う記法があって、それを用いてわかるようにするらしい。

記法 典型的な意味
TODO: 後で手をつける
FIXME: 既知の不具合があるコード
HACK: あまりキレイじゃない解決策
XXX: 危険!大きな問題がある

上記のように、色々書いたが、自分の考えを上手にコメントするというのもなかなかハードルが高い😅(ライターズブロックというらしい)。 そうは言っても書き始めないと何もならないので、本ではコメントの作業を3つの手順に分解し、上手なコメントを意識した方法で書き出すことを推奨していた。

  • 頭の中にあるコメントをとにかく書きだす
  • コメントを読んで(どちらかといえば)改善が必要なものを見つける
  • 改善する

また、この章を通して、すごく印象的だった言葉は下記。 > コメントを読むとその分だけコードを読む時間がなくなる。コメントは画面を占領してしまう。言い換えれば、コメントにはそれだけの価値を持たせるべき

それほどのことを考えてコメントをつけていなかったので、今後はコメントの価値ということも頭に入れてコードを書いていきたい。

第六章 コメントは正確で簡潔に

ここでのポイントは、コメントは簡潔で多くの情報を詰め込むように意識するという点。そのためのポイントを、本では下記が紹介されていた。

ポイント 説明
代名詞を避ける 読み手によって何を指しているかわからなくなる可能性があるから、
代名詞を使わず明確に書く
シンプルに書く コードの振る舞いを単純かつ直接的に書く
例えば、『~によって優先度を変える』でなく『~でなければ優先度を高くする』
正確に書く コードの動作を正確に示すようなコメントを残す
例えば、『改行の数を数える』でなく『'\n'の数を数える』
実例を書く rubyの公式のメソッドの説明で見るような実例を載せる。
p "foo".rjust(10) # =&gt; " foo"
コードの意図を書く 動作を高レベルに説明し、プログラムの意図を正しく伝える。
例えば、『逆順にイテレート』ではなく『値段の高い順に表示』
名前付き引数を使う 引数のみだと動作が分かりにくい時、名前付き引数で分かりやすくする。C++とかならインランインコメントを用いる
情報密度の高い言葉を使う パターンやイディオムを説明するための言葉や表現(専門用語的なもの)で簡潔に示す。

第二部:ループとロジックの単純化

第七章 制御フローを読みやすくする

ここでのポイントは、制御フローの構成を考えて、より読みやすくなる方法を覚えておくという点。これまでのプログラマたちの経験から、ある程度『読みやすいコードとはなんぞや?』という観点があり、本では下記が紹介されていた。

観点 説明
条件式の引数の並び順 変化する『調査対象』の式を左側、変化しない『比較対象』の式を右側にする
例えば、"現在気温" > "クーラーON閾値温度"
if/elseの並び順 肯定系で書く。単純、目立つ、関心を引くような条件を先に書く。
理由は目立つコードで集中を欠けせないため。
三項演算子、do-while、gotoは使い所を考える コードが読みにくくなることが多いので、基本的には使わずに、代替となるもので対応する。
関数から早く返す 早めに返すと、ネストを削除したりコードをクリーンにできる。ガード節(関数上部で単純な条件を先に処理するもの)が便利。
ネストを浅くする ネストが深い場合、条件を覚えておく必要があり、コード読むのが大変になるので、基本的に浅い方がいい。浅くする方法としては、早めに返したり、ループではcontinueを使って処理を飛ばしてしまう。

この中で印象的だったのは、『関数から早く返す』という観点。現職ではretunrnは一つということが推奨されていたので、『へー😲』となった。確かに、早く返してしまえばそれ以降は読む必要がなくなるので、読みやすいコードになる気がした。

第八章 巨大な式を分割する

ここでのポイントは、巨大な式は分割して、読み手がコードを飲み込みやすくするという点。コードの式が長いと理解が難しくなるため、コードを飲み込みやすくするための処理や分割方法が紹介されていた。

ポイント 説明
説明変数 式を分割するために、式を表す変数を使う。
要約変数 大きなコードの塊を小さな名前に置き換える。
それにより管理や把握を簡単にできる。
ド・モルガンの法則を使う De-Morgan.png
違う手法を考える 複雑なロジックになってしまった場合は、全く異なる手法で考えてみる。例えば、問題を否定したり、反対のことを考えてみる。

第九章 変数と読みやすさ

ここでのポイントは、変数を適当に使うと理解しにくくなるという点。理解しにくくなるような使い方は下記のようなもの。

  • 変数をやたらめったら使う
    8章では、説明変数や要約変数を用いることで、コードが読みやすくなることを学んだけど、不要な変数が使われていると変数の数が大きくなって、理解しにくくなってしまう。
  • スコープの大きい変数を利用する
    スコープが大きいとスコープを把握する時間が長くなる。
  • 変数を頻繁に変更する
    現在の値を把握するのが難しくなる。

上記のような理解しにくくなるような方法を知り、それを避けることを本章で学んだ。

観点 ポイント
不要な変数を削除する ・役に立たない一時変数
(複雑な式を分割していない、不明確、重複コードの削除でない)
・中間結果
(中間結果を保持するだけの変数)
・制御フロー変数
(データではなくプログラムの実行を制御するだけの変数)
大きなスコープを避ける グローバル変数
・大きなファイル、クラス、関数
・見えなくても良い場所で見えてしまう変数
変数は一度だけ書き込む ・変数を操作する場所は少ない方が良い
(操作する場所が多いと現在値の把握が難しくなる)

第三部:コードの再編成

第二部では、コードを読みやすくするためにプログラムの構造を少しだけ変更する技法を学んだ。第三部では、コードを大きく変更する技法を学ぶ。学ぶ内容は3種類。 * プログラムの主目的と関係のない『無関係の下位問題』を抽出する * コードを再編成して、1度に1つのことをやるようにする * 最初にコードを言葉で説明する。その説明を基にきれいな解決策を作る。

第十章 無関係の下位問題を抽出する

ここでのポイントは、プロジェクト固有のコードから汎用コードを分離するという点。無関係の下位問題とは、ある関数やコードブロックの各コード行が処理する内容が、その関数の責務(目標)に対して直接的な効果がない部分のコードのことを指す。ある関数の責務に対して無関係の下位の問題を解決することから、『無関係の下位問題』と言われている。

無関係の下位問題の抽出については、下記の流れで抽出を行うと良いらしい。

  1. 関数やコードブロックの内容から、『ここの責務は何か?』を考える
  2. 当該部分の中で、責務に直接関係しない部分を考える
  3. 無関係の下位問題を解決しているコードがある程度あれば、それを抽出して別の関数にする

抽出する時の観点を下記にまとめる。

観点 説明
再利用可能な処理 無関係の下位問題は自己完結しているので、どの関数から呼ばれても処理を実行できる。
ユーティリティコード このライブラリに『こんな関数があればなぁ』と思うときに、自身で複数のプロジェクトで使えるユーティリティコードとして実装する

無関係の下位問題を解決していくと汎用コードがたくさん出来てくる。汎用コードはプロジェクトから切り離されているため、コード開発もテストも理解も楽になる。 ただし、やりすぎも良くない😅。小さな関数を作りすぎると、あちこちのコードを飛び回ることになるため、逆に読みにくくなる。

第十一章 一度に一つのことを

ここでのポイントは、関数の論理的な『段落』を作るという点。関数の中で一つの処理という意味もあるし、関数の中でもコードを小さく構成し、論理的な区分に分けてあげるとわかりやすくなる。それを図示したものが下記の図。下図の左側の方法では、一つの関数の中でいろんなことをちょっとずつコードで実施している。右側の方法ではタスクの種類によってまとめて実施している。理解しやすいのは、文章を読むのと同じで論理的な区分を設けてコードを書く右側となる。 logis.png

では、どうやって『一度に1つのタスクをする』ようにするかというと、下記の手順が紹介されていた。

  1. コードが行っているタスク(細かなものから抽象的なものまで)を全て列挙
  2. タスクをできるだけ異なる関数に分割する。少なくとも異なる領域に分割する

具体例としては、下記のようなもの。 bunkatsu.png

第十二章 コードに想いを込める

ここでのポイントは、プログラムを書く前にプログラムを簡単な言葉で説明するという点。

自分の考えを人に伝えるときには、誰でもわかるように『簡単な言葉』かつ端的に伝えることが日常生活でも重要だけど、それはコードにも当てはまる。なので、一度自分の言葉でコードを簡単に言語化するのが重要ということ。

言語化することで得られる旨味は下記。 * 説明で使用した単語やフレーズで分割すべき下位問題がわかるようになる * 人の思考を重視したコードになることで、人が理解しやすいコードになる

じゃあ、実際にどのようにしてコードを書いていくか?ってことは、本では下記が紹介されている。 1. コードの動作を簡単な言葉で説明する。(同僚がわかるレベル) 2. その説明で使用しているキーワードやフレーズに注目する 3. その説明に合わせてコードを書く

その他にも、重要な点が紹介されていた。 * ライブラリを上手に使う
簡単なコードを書くために欠かせない。ライブラリを使うことで、コードを短く直感的に書ける。よって、ライブラリが何を提供するかを知っておくことがとても重要。 確かにRuby公式を学んでいるときにもサラッとメソッドに目を通しておく良いと推奨されていたが、ここに紐づくんだお感じた。

印象的だった言葉は下記のもので、胸が痛いなと感じた😅

問題や設計をうまく言葉にできないのであれば、何か見落としているか、詳細が明確になっていないということ

第十三章 短いコードを書く

ここでのポイントは、できるだけコードを書かないようにするという点。新しいコードを書くということは、テストや文書や保守が必要になるし、コードを理解してもらう量が増えることになる。なので、根本的にコードを書かない(短いコード)のが良いと言える。 じゃあ、新しいコードを書かないようにするにはどうするか?ってことだけ、本では下記が紹介されていた。

ポイント 説明
機能を過剰にしない 要求を詳しく調べて、要求のコアを見つけ、そこに対して最も簡単に問題を解決できる方法を考える
コードを小さく保つ コードを小さく軽量に維持するために下記を意識する
・汎用的な『ユーティリティ』コードを作って、重複を削除
・未使用のコードを削除
・プロジェクトをサブプロジェクトに分割
ライブラリに親しむ ライブラリを使うことで、時間とコードが節約できる。そのために、ライブラリの機能についてあらかじめ目を通して、何ができるかを知っておくことが大切。
CLIも使う コードがダメなら、Unixコマンドラインなどの方法も検討する

リーダブルコード 第四部:選抜テーマ

第四部では、これまでに学んできたコードを理解しやすくするための技法を、実際に適応する例が紹介されている。リーダブルなコードにしていく際にどういう流れで適応していくかを思い出すときに読むといいと思った。

第十四章 テストと読みやすさ

ここでのポイントは、テストコードも読みやすさが大切という点。テストが読みやすければ、テストを書きやすいし、他の人もテストを追加しやすい状態になる。また、テストしやすいコードというのは、コードの設計自体も改善されているものになりやすい。

じゃあ、読みやすいテストコードにするために何をしないといけないかというと、下記を意識すると良いと記述されていた。

  • テストのトップレベルは簡潔にする
    入出力のテストは、一行のコードで記述できているとベター
  • エラーメッセージを読みやすくする
    テストが失敗したときにバグや修正がわかるようなエラーメッセージが出力されるようにする。そのために、テストに役立つライブラリやフレームワークを知っておく必要がある。いいのがなければ手作りのアサートを作るなどして、役立つエラーメッセージを作る。
  • テストに有効な最も単純な入力値を使う
    入力値には、コードを完全にテストする最も単純な入力値の組み合わせにする必要がある。複雑な値や目を引く値で入力を作ってしまうと、何をテストしたいかがぼやけてしまうため。また、1つの機能に複数の小さなテストを用意した方が、簡単・効果的・読みやすいテストになりやすい。
  • テストの機能に名前をつける
    テスト関数に説明的な名前をつけて、何をテストしているかを明らかにする。例えば、Test1()ではなく、Test1_<関数名>_<状況>のような名前。テスト自体は他のコードから呼び出されるものでないので、名前が長くなってしまったも問題なし!

テストは重要だけれど、テストを意識しすぎてやりすぎてはダメ。以下に注意とのことだった。

  • テストのために、テスト対象のコードにゴミを入れない
    テストを読みやすくするために、テスト対象を読みにくくするような対応はしてはダメ。意識するのは、テスト対象は単純で疎結合テストは読み書きしやすく
  • カバレッジ100%にこだわる 重要度に応じて、カバレッジを考える。どうでもいいような機能のところに力を入れすぎない。
  • 目的を見失わない
    テストはあくまでもプロジェクトの一部。ある種の儀式的な位置付けとして、多大な時間かけてやるようになってきたら、何かずれていると感じて本当にやりたかったことができているかを見直す。

第十五章 『分/時間カウンタ』を設計・実装する

第十四章よりもさらに実務的な解説の章であった。内容自体は、どうリーダブルなコードにしていくかの流れを実務例として紹介している感じのものなので、現職であったり、プラクティスを進めるときに参考にすればいいかなと思った。

参考

Gitまとめ

いつも呪文のように唱えていたgitのコマンドだけど、ようやく学ぶことができたのでメモ。

言葉の定義

  • レポジトリ
    Gitがファイルの履歴を保存している場所
  • インデックス
    リポジトリに保存されている情報とワークツリー(作業している場所)との差(変更箇所)を記録する場所
  • ワークツリー
    リポジトリの内容をファイルとして展開する場所

コマンド一覧

コマンド 内容
git init レポジトリを作成する
git add コミット対象として登録する
-u:変更したファイル全てをインデックに登録
-A:全てのファイルをインデックスに登録
git commit インデックスの履歴をレポジトリに登録
git commit --amend 直前のコミット漏れしたファイルを後で追加
git commit --amend -m 直前コミットのコメント内容を``に変更
git revert ``というコミットの取り消し
git rebase -i HEAD~~ 過去のコミットをまとめたり、修正したりする。
左記はHEADから2つ前まで。コミットをまとめるときは、
エディタが開いたら2つ目のpicksquashに変更。
コミットを修正するときはpickeditに変更する
詳細
git rebase ``ブランチに現在いるブランチで行った全コミットを適応
git rebase baseブランチに`ブランチで行った全コミットを適応<br>(git checkout && git rebase `と同じ意味)
git rm --cached -r . git init直後の、git addを全て取り消し
git rm --cached -r git init直後の、git addfnameというファイルのみ取り消し
git reset --mixed HEAD 2回目以降にてgit addした内容を取り消し
git reset --mixed HEAD 2回目以降にてgit addしたfnameというファイルのみ取り消し
git stash 変更内容の退避。インデックス以下の変更全てが退避される。
git stash save "コメント" コメントを付けて変更内容を退避。
git stash apply 退避した内容をステージング前の状態として取り出す。
取り出してもstashリストから削除しない
--indexをつけるとステージング後の状態として取り出す
git stash pop 基本applyと同じだが、取り出したらstashリストから削除する
git stash clear stashリストを全て削除
git stash show 退避した内容の詳細を見る
git status ワークツリーの状態を表示する
git diff ワークツリーとインデックスの差分を表示する
git diff --cached インデックスとレポジトリの差分を表示する
git diff HEAD ワークツリーとレポジトリ差分を比較する
git log 履歴を表示する
git log --graph ブランチやマージの歴史を、ログ出力とともにアスキーグラフで表示する
git branch ブランチの一覧を表示する
-rをつけるとリモート追跡ブランチを表示
git branch `という新しいブランチを作る<br>-d`をつけるとブランチを削除する
git branch -m ブランチ名変更(へ)
git checkout ``ブランチに切り替える
git checkout -b ``ブランチを新しく作って、ブランチを切り替える
git checkout -b / ブランチが、リポジトリの``ブランチを追跡するように設定
git merge ``ブランチを現在のブランチにマージ。
git push
:
変更履歴を送る
git push --delete リポジトリのブランチを削除
git clone レポジトリを複製する
git remote add リモートレポジトリに別名をつける
git remote -v レポジトリの別名を一覧表示する
git remote rename リモートレポジトリの別名を変更したい
git fetch 他レポジトリの変更履歴を取込む
変更反映はmerge
git pull 別名の``というブランチを
現在のブランチに取り込む
git tag タグ一覧を表示する
-nをつけてコメント表示
git tag 現在のHEADが差しているコミットに``という軽量タグをつける
git tag -a 注釈付きタグをつける。-amでタグ名とコメント追加を一緒に行う
git tag -a 昔のコミットにタグを付ける。
check sumgit log --pretty=onelineで確認できる
git tag -d タグの削除
git push に``というタグ名でpush

Git ローカルレポジトリへのcommit、リモートレポジトリへのpush

上に書いたコマンド一覧だけだと、後で見たときに『結局どういうふうに使うんだっけ?😅』となりそうなので、大まかな流れと実際に試した例を載せておく。

  1. git initで空レポジトリを作成
  2. git initしたディレクトリで、必要なファイル作成やコピーを行う
  3. git addで2.で更新したファイル群をワークツリーからインデックスへ追加
  4. git commitでインデックスの内容をローカルレポジトリへ追加
  5. git remoteでリモートレポジトリに別名をつけてgit push時の入力手間軽減
  6. git pushでローカルレポジトリの内容をリモートレポジトリへ反映
$ git init
Initialized empty Git repository in /home/goruchan/git/hoge/.git/
$ git branch -m main   &lt;--デフォルトブランチ名をmainに設定
$ git branch           &lt;--レポジトリが空なのでbranchは出てこない
$ ls -la
total 12
drwxr-xr-x 3 goruchan goruchan 4096 Dec 27 22:11 .
drwxr-xr-x 3 goruchan goruchan 4096 Dec 27 22:10 ..
drwxr-xr-x 7 goruchan goruchan 4096 Dec 27 22:13 .git&lt;--レポジトリ
$ touch readme.md
$ git add readme.md     &lt;---リポジトリに履歴にとして追加
$ git status
On branch main

No commits yet

$ git branch
$ git commit -m &quot;add readme.md&quot;
[main (root-commit) 0e4504d] add readme.md
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 readme.md
$ git branch
* main
$ git branch develop   &lt;--developブランチ作成
$ git checkout develop  &lt;--developブランチへ切り替え
Switched to branch &#039;develop&#039;
$ touch hoge.md
$ git add -A
$ git commit -m &#039;add hoge.md&#039;
[develop 4260a4d] add hoge.md
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 hoge.md
$ git checkout main    &lt;--mainブランチへ切り替え
Switched to branch &#039;main&#039;
$ git branch
  develop
* main
$ git merge develop    &lt;--developブランチをmainブランチへ取り込む
Updating 4a14ed8..4260a4d
Fast-forward
 hoge.md | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 hoge.md
$ ls
hoge.md  readme.md
$ git branch -d develop &lt;--developブランチの削除
Deleted branch develop (was 4260a4d).
$ git remote add origin git@github.com:goruchanchan/gitPractice.git  &lt;--originをリポジトリパスとして設定(この場合、Github上のレポジトリ)
$ git push -u origin main   main
Branch 'main' set up to track remote branch 'main' from 'origin'.

あと、大雑把なワークフローのイメージをまとめてみた。全体的な流れを大雑把に理解して、あとは今後のプラクティスで定着させていこう😀 gitwork.png

fetchについてもう少し細かく書くと、リモートレポジトリからのfetchでやっているのは、リモートレポジトリの最新状況をローカル内に引っ張ってくるところまでで、現在作業しているレポジトリに対してのマージは実施しない。参考

fetch.png

また、コミットの取り消しについては、こちらの内容が参考になった。 reset.png

競合時の解決方法

  1. git fetch
  2. git merge
  3. 競合の修正
  4. 後はいつもの手順(addcommitpush)
$ git push origin tutorial3:tutorial3
error: failed to push some refs to 'github.com:goruchanchan/gitPractice.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
$ git fetch 
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 2 (delta 1), reused 2 (delta 1), pack-reused 0
Unpacking objects: 100% (2/2), 299 bytes | 299.00 KiB/s, done.
From github.com:goruchanchan/gitPractice
   f59c3b9..6ba99fe  tutorial3  -&gt; origin/tutorial3
$ git merge origin/tutorial3 
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.
$ vim test.txt 
$ git add .
$ git commit
[tutorial3 c65231e] Merge remote-tracking branch 'origin/tutorial3' into tutorial3
$ git push 
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 629 bytes | 629.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:goruchanchan/gitPractice.git
   6ba99fe..c65231e  tutorial3 -&gt; tutorial3

競合時のイベントシーケンスはここの内容がとてもわかりやすいので、記載しておく。 sequence.png

同じところにチームで機能開発している場合のワークフローもあったので、参考として載せておく。workflow.png

Git用のエリアスの設定

大きく2つのやり方でGit用のエイリアスを設定できる。

  • コマンドで追加

    $ git config --global alias.br branch
    $ git config --global alias.ci commit
    
  • .gitconfigファイルに直接記入

コマンド追加を実行したときには、結局.gitconfigに追加してくれているだけっぽいので、直接そのファイルに書き込んでしまっても設定できる。[alias]部分にエイリアスを設定してあげれば良い。ちなみにbrstは上のコマンドで追加したままのもの。

  # This is Git's per-user configuration file.
  [user]
  # Please adapt and uncomment the following lines:
    name = goruchan 
    email = xxx@xxx.xxx.xxx
  [color]
    ui = auto
  [core]
    editor = vim
  [alias]
    br = branch
    st = status
    last = log -1 HEAD