Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Git/GitHub入門

 Git/GitHub入門

研究室のB3への講義資料.
あまり踏み込んだところまではやってませんが,基本的な概念と操作は習得できるかと思います.

Tai YAMADA

April 16, 2024
Tweet

Other Decks in Programming

Transcript

  1. こんな経験ありませんか?ない?多分これから経験します 最新版どれ?何が違うの? (つーかyamadaって誰だよ......) コメント内に変更内容と その担当者が直接書かれている 名前と日付から 一概に判断できない 1人が変更コメントつけ忘れるだけで 全く意味を為さなくなる チーム制作で各自が編集した

    ファイルを統合するとき 統合する人が大変すぎる → Gitを使えば全て解決! mina, Git入門, https://speakerdeck.com/silmin_/gitru-men JOB SUPPORT, “新人SE・PG教育にも使える!ソースコード(Java)のコメントの書き方 ①”, https://job-support.ne.jp/blog/java-training/howto3
  2. ざっくりしすぎた説明の例 GitやGitHubの名前を聞く機会は増えているが, 「ソースコードをやりとりする感じのサイトなんだよね?」ぐらいの認識の人が多い. 研究開発を行う上では避けて通れないので今日 学ぼう. まずGitとGitHubは混同されることも多いが,別モノ. Git/GitHubとは Gitは元々Linux(macOSやUbuntu,Androidなど Windows以外のほとんどのOSの骨格)の開発に用いられていた. オープンソースであることも相まって急速に普及し,

    この種のツールとしてはデファクトスタンダード. (他にApache Subversionなどもあるが触れません) Git: GitHub: ファイルのバージョンを管理・共有するツール. Gitのリポジトリ(ソースコード等の保存場所)を Web上で管理・公開するWebサービス. Gitの利便性を高めるためのものとして捉えると良い. クローズドな開発に特化したGitLabというツールも ありますが,今回は特に触れません. 今日使われるほとんどのOSの基礎となっているLinuxだが,Linus Torvaldsによる修士論文に端を発する. Linus率いるチームは元々BitKeeperというバージョン管理ツールを用いてLinuxを開発していたが, 法的なトラブルにより使えなくなってしまったため,Gitの開発に着手することとなった. TIPS IT media NEWS, “GitHubは「設計図共有サイト」? 日経記事の見出しが話題に その後修正”, https://www.itmedia.co.jp/news/articles/1806/05/news069.html
  3. 「別にDropboxとかGoogle Driveとかでもチームメイトとファイル共有できるやん」と 言う人も多いが,本日の講義を聞けば「ソースコード管理はGit/GitHubしか勝たん 」になる. ファイル共有サービス Git/GitHub ファイルのやりとり フォルダに保存したものが自動的に クラウド上のストレージと同期. 明示的にプル/プッシュという操作を行うことで

    同期. 変更履歴の保存 誤ってファイルを上書き・削除することも あるが,期間(サービスによるが30~90日) 内であればゴミ箱から復活できる. ゴミ箱からもデータが消えてたら,ほぼ詰み. 変更して同期する都度に,その変更内容を記録 (コミット)するので, 誰がいつ変更したか・どれぐらい前のバージョン まで戻すかをファイル内の行単位で管理できる. 変更が食い違った場合 新しい方で上書きするか,(1)(2)など 連番形式で別ファイルが作成される. 自動的に両者の変更を生かし,無理そう(行単位 で内容が被る等)な場合には,どちらの変更を採 用するか明示的に指定する. 複数人の作業を支援する機能 サービスにより異なる. かなり多様な操作に対応. バイナリファイルの扱い テキストファイルと同等. テキストファイルは細かく変更を追跡できるが バイナリファイルの内容は管理できない. 巨大なファイルの扱い 比較的大きなサイズのファイルも扱える. 基本的に1つのファイルは100MB程度が限界で, それ以上のファイルを扱うには特別な設定が必要. あくまでもソースコード特化型のバージョン管理・共有ツール
  4. ・ブランチ(branch) Git/GitHubを扱う上で覚えとくべき概念 ・リポジトリ(repository) ・ステージ(stage) ・ステータス(status) ・プッシュ(push) ・プル(pull) ・クローン(clone) ファイルやディレクトリの状態(ソースコード, 変更履歴,コメント)を管理する場所.

    ファイルに対する変更をブランチに記録すること. 記録した情報自体もコミットと呼ぶことがある. コミット対象のファイルを登録すること. ・フォーク(Fork) 他のユーザーが公開するリモートリポジトリを丸ごと 自分のアカウントにコピーすること.(GitHub特有の機能) リモートリポジトリを元に ローカルリポジトリを複製すること. メインの開発ラインから独立した開発ラインを 作成し,別ルートで作業する機能. 「どのファイルがステージ状態にあるか」など, 現在の開発ラインの状態を表示する機能. ・マージ(merge) ローカル側からリモート側へ リポジトリの内容を送ること. リモート側からローカル側へ リポジトリの内容を取り込むこと. 複数のブランチの内容を統合すること. ・コンフリクト(conflict) コードの統合時にGitから自動で解決できない「変更の衝突」 ・プルリクエスト(Pull Request, PR) 開発者がコードに対して行った変更を採用してもらうよう, 他の開発者へ依頼すること.(GitHub特有の機能) ・フェッチ(fetch) リモートリポジトリの内容を参照すること. ・コミット(commit)
  5. リポジトリ(repository) ファイルの変更履歴を管理する場所. リモートリポジトリをユーザーの ローカルストレージ(=各自のPC)へ複製したもの. リポジトリのデータを各所へ分散させる構造から 分散型と言われる(⇔集中型) リモートリポジトリが吹き飛んでも 誰かのローカルリポジトリから復元できる ユーザー1 (ノートPC)

    ユーザー2 (ノートPC) ユーザー3 (デスクトップPC) ローカルリポジトリ リモートリポジトリ インターネット(Gitサーバ)上で 管理されるリポジトリ. GitHubやGitLabなどは リモートリポジトリの実装の1つ. Version data Version data Version data Version data サーバー
  6. フォーク(Fork) ユーザーA (GitHubアカウント) ユーザーB (GitHubアカウント) ユーザーAさんが 公開してる リポジトリの 使い心地がしっくり こないんだよなぁ...

    俺が改造したろ! 他のユーザーが公開しているリモートリポジトリを 丸ごと自分のアカウントにコピーすること(GitHub特有の機能)
  7. フォーク(Fork) 他のユーザーが公開しているリモートリポジトリを 丸ごと自分のアカウントにコピーすること(GitHub特有の機能) Q. 他人の成果物を勝手にコピーしちゃっていいの!?しかも改造や再配布とか流石にダメでは......? A. 元のプロジェクトにオープンソースライセンスが記されていれば 大抵の場合はOK.(ライセンスによっては改変等が許可されていないのでよく調べること) そもそもLinuxやGit,VSCodeを含む多くのソフトウェアは「プロジェクトのソースコードは誰でも 触れるよう(=オープンソース)にして,みんなでドシドシ改善していこう」という文化で発展してきた.

    むしろ誰かにフォークしてもらえる方が名誉であるとされる. (科学も論文というプラットフォームで,ある意味同じことをやっている) MITライセンスがおそらく最もオーソドックス. 「著作権の表示は必要だが,商用利用, 修正, 配布, サブライセンス全部やってOK」という緩めの内容. TIPS 筆者が個人的に好きなのはWTFPLライセンス. ”Do What The Fuck You Want To Public License”の略で,文字通り「どうぞお好きなようにしやがれ」 ただし,大幅な根本的改変でなく,機能の追加程度の変更内容であれば,後述するプルリクエストにより 元の開発者に還元することが推奨される.
  8. 小話: ソースコードのパクり? 「放置少女 ~百花繚乱の萌姫たち~」を運営する会社(原告)が 「戦姫コレクション ~戦国乱舞の乙女たち~」の運営会社(被告)に対し 著作権侵害の訴訟を起こした事件 「放置少女」事件 事実関係として ・利用規約が会社名以外同一

    ・特定機能のプログラムのソースコードの類似度が90.66% ・「戦姫コレクション」(被告ゲーム)のソースコード上に 「放置少女」(原告ゲーム)の開発担当者の名前が残されていた などあったものの,著作権法上の権利侵害が無いとされた →ソースコードはあくまでシステムを成立させるための「アイデア」であり, 表現上の創作性がないため著作権侵害とはいえない 2024年現在,生成AIの学習元が問題になりがちだが,他にも「任意の イラストレーターの絵柄を模倣する生成AI」を取り巻く議論も尽きない. 法的に著作性が肯定されるのはあくまで「絵」そのものである. 「絵柄」はアイデアに該当するため,著作権法による保護対象に当たらない. しかしイラストレーターにとっては「絵柄」こそアイデンティティ. 長年かけて培ってきた技術を生成AIによってコモディティ化されることが 是となる状況への不満から,AI規制を掲げるイラストレーターも多い. どこからどこまでがパクり判定か等に興味があれば 「〈ケース研究〉著作物の類似性判断: ビジュアルアート編」という本がオススメです クリエイターとプログラマーの文化の違いを表すミーム reddit, thanksForTheFork, https://www.reddit.com/r/ProgrammerHumor/comments/14qohwj/thanksforthefork/
  9. プッシュ(push) プル(pull) ローカルリポジトリ内の現在のブランチ (チェックアウトしているブランチ)の内容を 送信すること. ブランチ(branch)は次ページにて解説. ローカルリポジトリ リモートリポジトリ Version data

    Version data プル プッシュ リモートリポジトリ内の現在のブランチ (チェックアウトしているブランチ)の内容を 取り込むこと. リモートリポジトリの内容が更新された際に行う.
  10. ブランチ(branch) 元々メインのブランチ名は「master」だったが,「奴隷制度を彷彿とさせる」との指摘から近年「main」に改められた.工学分野で長く 用いられてきた「マスター(master)/スレーブ(slave)」呼称は減りつつあり,電子工作でのSPI通信では「SDO(Serial Data Out)/SDI(Serial Data In)」,ロボットの遠隔制御では「リーダー(Leader)/フォロワー(Follower)」呼称が推奨されている. コミット(commit) マージ(merge) ファイルに対する変更を

    ブランチに記録すること. 記録した情報そのものを指すこともある. メインの開発ラインから独立した開発ラインを作成し,別ルートで作業する機能. ブランチを切る(=枝分かれを行う)ことにより,互いに干渉しない並行世界線をつくるイメージ. ブランチの内容を統合すること. mainブランチは「いつでもコードを動かせる」 状態に保つ必要があり, 中途半端な開発ブランチをマージしてはダメ. mainのbranch func1開発のための branch func2開発のための branch HEAD マージ コミット (コミットオブジェクト) コミットオブジェクト 記録した情報そのものの正式名称 HEAD チェックアウトしているブランチの先頭のコミットオブジェクト. Gitはここからブランチの各コミットの差分を読んで最新コミットの内容を算出する. チェックアウト 特定ブランチへ移動すること チェック アウト TIPS
  11. プルリクエスト(Pull Request, PR) 開発者がコードに対して行った変更を採用してもらうよう,他の開発者へ依頼すること(GitHub特有の機能) 個人開発ではまず使わないが,チーム開発で使うかもしれんので一応知っておくと良い. TIPS 「こっちの変更をプッシュしているのに”プル”リクエスト?」と思うかもしれないが,元々GitはLinux開発に用いられており,世界中の開発者たち がLinus Torvaldsに対して「こういう機能を開発したから是非ともアンタのLinuxに統合(=プル)してくれよ」とリクエストしたことに由来. あくまで主語は「プッシュする開発者側」でなく「それをプルする元リポジトリやmainブランチ側」なので,プルリクエストという名称となる.

    フォーク後にコード(機能)を追加して プルリクエスト(PR)を出す事で,元リポジトリの プロジェクトに貢献できる. オープンソースソフトウェア(OSS)開発で主流の方式. レビュアーはPRの内容をチェック(コードレビュー)し, バグや悪意あるコードなどの問題が無ければプルする. 2024年3月末,Linux開発において悪意あるコードがPRを通過し, Linuxの一部にバックドアが仕込まれる事件が発生した. 不特定多数が関わるオープンソースのプロジェクトは,たびたびハッカーを 寄せ付けるので,PRは特に慎重に行う必要がある. (オープンソースだからこそ大衆の目に晒されて発覚した事件ともいえるので 必ずしもOSS=悪でもない) メインとなるブランチと他のブランチで分け, 権限を持つ者へPRして 承認を受けないとmainブランチへマージをできないようにする手法. 企業等が機密を保持するためにリポジトリを 非公開(=フォーク出来ない設定)とする際に主流となる方式. メイン用・開発用の2種のブランチを用いる「GitHub Flow」と, 用途や緊急度などに応じ5種類のブランチを用いる「git-flow」がある. ・小規模~中規模開発 → GitHub Flow ・大規模開発 → git-flow
  12. コミットツリー コミットの履歴を木構造で表現したもの ステージ(stage) コミット対象のファイルを登録すること(ステージングともいう) ステージ ワークツリー 実際にファイル編集の作業を 行うディレクトリ コミットオブジェクト 変更A

    変更B 変更B 変更A ステージング コミット TIPS 「Gitってブランチを切るたびにファイルが増えて,めちゃくちゃデータを食うのでは?」と思うかもしれないが, ブランチが保持するのはコミットオブジェクトであり,あくまで変更内容(差分)やコミットメッセージ等のメタデータのみ. ファイルの内容でなく差分を保存するだけなので,ブランチをドンドコ切ってもリポジトリのサイズが大幅に増えたりしない.
  13. 小話: コミットオブジェクトの中身って? コミット = ステージされた変更内容を40文字のSHA1(発音: シャーワン)ハッシュに変換したもの コミット + メタデータ= コミットオブジェクト

    変更後のハッシュ値 変更前のハッシュ値 変更担当者 タイムスタンプ コミットコメント 393e373424ec28e112a29f94a7f6f63218cc1bce 38988eef0331afb9f374ccc124ebfbaf4ae2e7bf ハッシュ値によりファイルを一意に識別している. 各コミットのハッシュ値の差を見ることで,数学的に高い効率性でファイルの差分を管理できる(かしこい...) コミット 各種情報 (メタデータ) TIPS SHA-1は「Secure Hash Algorism 1」の略で,任意長の文字列を160ビット(16進数では40文字)長の文字列に変換する暗号化アルゴリズム. 1995年にSHA-0の後継として米国国家安全保障局(NSA)により設計された.ファイルの真正性や改ざんを検知することを目的として 開発されたが,その後に衝突攻撃による脆弱性が指摘されたことから米国国立標準技術研究所(NIST)はSHA-2やSHA-3への移行を推奨している.
  14. ① SSHのリンクをコピー リポジトリをクローンし,ファイルをコミット ② <ソース管理>をサイドバーに 開き,リポジトリの複製 ③ SSHのリンクを張り付け, <リポジトリのURL>をクリック ④

    リポジトリの保存先を選択. 「第1回」の授業フォルダとか. ⑤ <新しいウィンドウで開く>を選択 ⑥ 適当なファイルを作成する ⑦ <すべての変更をステージ> (ファイル名にマウスホバーすると 表示される<+>マークから 任意ファイル単体でもステージ可) ⑧ 作成したファイルが 「ステージされている変更」に移動する (何か操作する必要なし) ⑨ 適当なコメントを書く ⑩ < コミット>を押す
  15. 作業ブランチを作成 ① GitHubリポジトリの 「main」をクリックする ② 「Branches」に 「main」しかないことを確認 (何も操作しなくてOK) ④ 新しいブランチ名を適当に決める

    ③ 三点リーダーから 「ブランチ」 →「ブランチの作成...」 ⑤ 「Branchの発行」を選択 ⑦ GitHubリポジトリに 新たなブランチが追加されてる ⑥ アクティビティバー左に 表示されるブランチ名が変わる
  16. 作業ブランチでコミット ① 作業ブランチをチェックアウト ② 適当なファイルを作成 ③ ファイルをステージする ④ コミットコメントを書いて<コミット> ⑤

    <変更の同期>をクリック (書いてある数字は未プッシュのコミット数) ⑥ GitHubリポジトリの 表示ブランチを変更 ⑦ 作業ブランチにだけ ファイルが追加されてる
  17. さらにファイルを変更してコミット ① VSCodeの作業ブランチで なんか変更を加える. 変更を加えた行の初めに 青いラインが追加されるはず (ここをクリックすると 変更内容が確認可能) ② 「ソース管理」の

    「変更」タブにある ファイル名の部分を直接クリック ③ 差分エディターが展開される. 左が旧ファイルで右が新ファイル. 赤くハイライトされた行が「削除された行」 緑にハイライトされた行が「追加された行」 ⑤ < コミット>を押し変更をコミット. <変更の同期>をクリックすることで リモートリポジトリの内容が変わる. ④ ファイルをステージして 適当なコミットコメントを書く
  18. リモートリポジトリの更新内容をプルする リモートリポジトリを編集 ① メインブランチをチェックアウト ② 編集対象のファイルをクリックして選択 ③ 右側のペンのアイコン<Edit this file>をクリック

    ④ 適当に文章を加えて右上の<Commit changes...>を押す ⑤ コミットメッセージが自動生成されるので 特に何も変更せず<Commit changes> これで「リモートリポジトリが他人によりアップデートされた」 状況が出来たので,プルしてローカルリポジトリも更新します
  19. リモートリポジトリの更新内容をフェッチしてマージする リモートリポジトリを編集 ローカルリポジトリにプル ② mainブランチにいることを確認する ① 2ぺージ前と同様に リモートリポジトリの mainブランチでファイルを編集 ③

    ソース管理タブの 三点リーダーから<フェッチ> ④ ソース管理タブから「origin/main」ブランチの内容が 変わっていることが確認できる. 「受信」タブにあるファイル名をクリックすると 差分エディタが出て「どう変わったのか」が分かる. 変更内容に問題が無ければ<変更の同期>を押す事で 「main」ブランチに内容がマージされる.
  20. 無視ファイルの設定 ① 「hate_git.csv」「private_file」「日本語でOK.py」を作成する コミットしたくないファイルやフォルダ,拡張子などを指定できる機能. キャッシュやセキュリティ上共有したくないファイルをGitの管理下から除外できる. ただし,一度コミットして追跡対象となったファイルは無視できなくなる点に注意 ② 「.gitignore」 という拡張子オンリーのファイルを作成する. (隠しファイルとなる)

    TIPS 「*」は正規表現と混同されることもあるが,正しくはワイルドカードというもの. Gitの追跡対象をもっと複雑に表現したい場合は,このサイトで確認するのがおすすめ. Uマークがついていたら Unmodifiedであり,追跡対象 ③ 「.gitignore」の中身を以下のように編集し,保存する. (「*」は半角アスタリスクで「任意の文字列」の意味) ④ さっき作成したファイル名からUマークが消え 追跡対象から除外される. フォルダなど細かな指定も 可能なので色々試してみよう ⑤ .gitignoreファイルを <コミット>して <変更の同期>も行う
  21. ブランチのコミットツリーを確認する ① 一番下のアクティビティバー左側にある <Git Graph>をクリック ② エディタに「Git Graph」タブが出て, 過去のコミットが一覧表示される ③

    適当なコミットをクリックして詳細パネルを出す. ファイル名をクリックすると変更の詳細が出る. このGit Graphにより ・過去のコミットを修正 ・過去のコミットを削除 ・複数コミットを合体 など複雑で便利な操作が簡単にできるようになる!. マジで便利なので必ずこのサイトに目を通しておこう.
  22. コンフリクトを解決する 変更内容が異なるコミットを 各ブランチで作成 ① mainブランチで「conflict.txt」を作成する ② 「conflict_branch_1」と 「conflict_branch_2」ブランチをそれぞれ作成する ③ Git

    Graphでコミットツリーを見ると 最新(一番上)に新たなブランチが追加されてる ④ 各作業ブランチで「conflict.txt」の内容が異なるように 編集し,それぞれコミットしておく
  23. 過去のコミットに戻る ① mainブランチでGit Graphを開き,過去のコミットを 右クリック(画像では「.gitignoreの作成」のコミットを選択) リセット(reset)という機能で「この頃のコミットに戻したいなぁ。。。」という要望を叶えられる. ② <Reset current branch~>を選択し,

    モードは「Mixed」として <Yes, reset>を選択 ④ ソース管理タブの「変更」に未ステージファイル がある状態だとマージできないので,conflict.txt の右にある<変更を破棄>を押す. 「ファイルを削除するか」的なメッセージにOK ⑤ <変更の同期>を押して「origin/main」をマージする ことで,リセット操作が取り消される. これで過去に戻れた. 新たな作業ブランチを作るなりご自由に. 今回は何もせず,リセット前の状態に戻す (=リセット操作を無かったことにする)
  24. 特定コミットだけmainブランチに取り込む 複数段階に分けてコミットする ② 新たなブランチで 「memo_1.md」~「memo_4.md」の 連番形式でファイルを作成する ③ 「memo_1.md」の右側にある <+>マークから,このファイルのみをステージ. ④

    「memo 1作成」のように分かりやすい コミットコメントを書き,< コミット>. ⑤ 他の連番ファイルも同様に”単体で”,それぞれ区別がつく コミットコメントを付けて< コミット>をする. チェリーピック(cherry-pick)で特定コミットだけマージできる. 「開発ブランチの最新コミットは未完成だけど,少し前のこのコミットだったら今すぐリリース可能」という場面で役立つ ① mainブランチから新たなブランチを切る
  25. 特定コミットだけmainブランチに取り込む ⑧ mainブランチでGit Graphを開く. <Show Remote Branches>の は外しておく. ⑨ 「memo_2.md」のコミットを右クリックして

    <Cherry Pick...>を選択 普通にマージしたら「memo_4.md」までの全てのファイル がmainブランチに取り込まれてしまうが, 今回は「memo_2.md」のコミットだけを取り入れる ⑩ 何もチェックをつけずそのまま<Yes, cherry pick>を選択. オプションの内容はココから確認してください.
  26. ・mina, Git入門, https://speakerdeck.com/silmin_/gitru-men ・IT media NEWS, “GitHubは「設計図共有サイト」? 日経記事の見出しが話題に その後修正”, https://www.itmedia.co.jp/news/articles/1806/05/news069.html

    ・JOB SUPPORT, “新人SE・PG教育にも使える!ソースコード(Java)のコメントの書き方①”, https://job-support.ne.jp/blog/java-training/howto3 ・reddit, thanksForTheFork, https://www.reddit.com/r/ProgrammerHumor/comments/14qohwj/thanksforthefork/ ・THE LINUX FOUNDATION, The Greatness of Git, https://www.linuxfoundation.org/blog/blog/the-greatness-of-git ・wann, “【初心者向け】git fetch、git merge、git pullの違いについて”, https://qiita.com/wann/items/688bc17460a457104d7d ・Git, Recording Changes to the Repository, https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository 参考文献・URL ・リブロワークス (2023) ,『ノンプログラマーのためのVisual Studio Code 実線活用ガイド』, 株式会社技術評論社