採点されません。匿名です。 間違えることは学習の一部です。読むだけでもかまいません。

GitHub にコードを上げる

テクノロジ系 / psc-day28 — PSC 案件 Day28 配布版 (Git/GitHub ハンズオン)

GitHub にコードを上げる

ローカル Git から PR・マージ・チーム協働まで

やることリスト

やること既知なら飛ばせるか
1GitHub で空リポジトリを作る
2初回 push の認証 (GCM / PAT)△ (PAT 発行手順だけ確認)
3git initcommitremote addpush -u origin main
4feature ブランチを切って push → Compare バナーから PR
5PR 画面の読み方 (Open / No conflicts / Files changed)
6Merge pull request → Confirm → git pull で手元に反映
7詰まったとき (認証・エディタ・改行コード)
8演習 3 問 (第 2 PR / 衝突解決 / revert)(演習なので飛ばさない)
9演習の解答例(詰まったら見る)
10招待 / Fork / cross-repo PR / Review△ (cross-repo の base/head 切替だけ確認)

章 1. リモートリポジトリを作る

GitHub にログインしてフォームを開く

右上の 「+」 → New repository を押すとこの画面になる。

!w:680

入力する 3 項目

Repository name : git-handson-demo
Visibility      : Public
Initialize      : (何もチェックしない)

> リポジトリ名は何でもよい。 以降のスクショは git-handson-demo で進める。

> Add README を ON にすると、 ローカルとの初回 push で衝突する。 練習中は 空っぽで作る のが安全。

入力できたら Create repository を押す。

章 2. 認証セットアップ (最初の 1 回だけ)

push で認証を聞かれたら

初めて git push を叩くと、 ほぼ確実に GitHub の認証ダイアログが出る。

出方は環境で 2 通りある。

経路 A — ブラウザが自動で開く (Git Credential Manager)

  • 「Sign in with your browser」 を押す
  • 開いた GitHub のページでログイン → 「Authorize」 を押す
  • ブラウザを閉じてターミナルに戻ると push が続行する

経路 B — ブラウザが開かない

  • パスワード欄に GitHub のパスワードは入らない (2021 年から廃止)
  • 代わりに Personal Access Token (PAT) を発行して貼る (次のスライド)

fine-grained PAT の発行手順

  1. https://github.com/settings/personal-access-tokens → Generate new token
  2. Token name: git-handson / Expiration: 30 日
  3. Repository access: Only select repositories → 自分の git-handson-demo を選ぶ
  4. Permissions → Repository permissions → Contents: Read and write にする
  5. Generate token → 表示された文字列を 1 回だけコピー (再表示不可)

ターミナルに戻ったら、 Username 欄は GitHub のユーザー名、 Password 欄に いまコピーしたトークン を貼る。

章 3. ローカルから push する

手元のターミナルで打つ

mkdir git-handson-demo && cd git-handson-demo
git init
echo "# はじめての GitHub" > README.md
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin <ここに GitHub の Code ボタンからコピーした URL を貼る>
git push -u origin main

> <...> の山括弧ごと書き換える。

> URL は GitHub のリポジトリページ → 緑の Code ボタン → HTTPS タブからコピー。

> 図 01 の Owner 欄に映っているアカウントは撮影者のもの。 自分のアカウント名で OK。

push が成功するとこう見える

ブラウザをリロードすると、 README.md がトップに表示される。

!w:680

ここまでで「自分の PC のコードが GitHub に乗った」 状態になる。

章 4. ブランチで作業して PR を出す

直接 main にコミットしない

feature/greeting ──●──●──●
                         ↓ merge(即時)
main            ───────────●  ← 誰も差分を見ていない

1 人で書いているリポジトリでも、 main には自分で確認したコードだけ入れるように癖をつけておく。

後で人が増えたとき、 そのまま運用が乗る。

ブランチを切って push する

git switch -c feature/greeting
echo "Hello, world!" > greeting.txt
git add greeting.txt
git commit -m "add greeting"
git push -u origin feature/greeting

push したあと、 GitHub のリポジトリページに戻るとこのバナーが出る。

!w:680

黄色の Compare & pull request を押すと PR 作成フォームに飛ぶ。

章 5. PR の画面を読む

PR を作るとこの画面に来る

!w:680

  • タイトルと #番号 が一番上にある
  • Open のうちはマージ前
  • No conflicts with base branch と出ていれば衝突なし → そのままマージしてよい

差分を読む

Files changed タブに切り替えると、 自分が何を変えたかが行単位で見える。

!w:680

  • 緑の + 行 = 追加した行
  • 赤の 行 = 削除した行

今回は 新規ファイル (greeting.txt) を追加しただけなので、 画面には + の行しか出ない。

既存ファイルを修正した PR では、 行と + 行が並んで表示される。

章 6. マージする

Merge pull request ボタン

Conversation タブの下のほうに緑のボタンがある。

!w:680

押すと、 コミットメッセージ入力欄がその場で展開される。

中身はそのまま Confirm merge を押せば OK。

マージ後はこの状態になる

!w:680

紫の Merged バッジに変わり、 Delete branch でブランチを片付けられる。

ローカルに反映する

GitHub 側で main が進んだので、 手元の main も追いつける。

git switch main
git pull origin main
git branch -d feature/greeting   # ローカルブランチも削除

履歴を確認する

git log --oneline --graph --all
*   9bc39a8 Merge pull request #1 from <USER>/feature/greeting
|\
| * 4ca572d add greeting
|/
* 5e6ea0a first commit

<USER> には自分の GitHub ユーザー名が入る。 hash 値 (9bc39a8 等) は環境ごとに違う文字列になるが、 *|\分岐 → 統合の形 が同じなら OK。

分岐して戻ってきた跡が log にそのまま残る。 後から「何をどこで入れたか」 を追える。

章 7. 詰まったときに見る場所

よく出るエラー

出たものやること
commit で Please tell me who you aregit config --global user.name "..." && git config --global user.email "..." を実行
Authentication failed章 2 の認証手順をやり直す (ブラウザが出ない → PAT 発行 → パスワード欄に貼る)
Repository not foundgit remote -v で URL を確認。 <USER> を書き換え忘れていないか / リポ名のスペル一致を見る
remote origin already existsgit remote set-url origin <正しい URL> で上書き、 または git remote remove origin してから add し直す
non-fast-forward で push 拒否git pull origin main --rebase で最新を取り込んでから git push
LF will be replaced by CRLF 警告Windows の改行コード自動変換。 そのまま進んで OK (警告で失敗ではない)

エディタが閉じられない

git commit-m 無しで打つと、 環境ごとに違うエディタが新規ウィンドウで開く。

  • VS Code: 1 行目にメッセージを書く → Ctrl+S で保存 → タブ (COMMIT_EDITMSG) を Ctrl+W で閉じる
  • vim が開いた場合: ESC:wq → Enter
  • 画面がぐちゃぐちゃになったら: ESC:q! → Enter で 保存せずに 抜けて、 git commit -m "..." のように -m を付けて打ち直す

-m を付けておけばそもそもエディタは開かない。

章 8. 演習 — 1 人で回す

演習の進め方

章 1〜7 で作った git-handson-demo リポジトリをそのまま使う。

3 問のドリルを順番に解く。 1 問ごとに GitHub の画面で結果を確認 してから次に進む。

  • 採点テストは無い。 自分の目で GitHub の画面 / ターミナル出力 を見て確認する
  • 各ドリルに 実施前 / 実施後 のスクショと ヒント が付いている
  • 詰まったらヒントを読む。 それでも分からなければ章 9 の解答例を見る

3 問共通で守ること:

  • リポジトリ名は章 1 で決めたものから変えない
  • main へ直接 commit しない (= 全部ブランチ → PR を通す)
  • PR の説明欄に「何をしたか」 を 1 行書く

ドリル一覧

#タイトルタイプ難易度
12 つ目の PR を作って merge する🛠️ 反復
2わざと衝突を起こして解決する⚠️ 衝突★★
3直前の commit を取り消す↩️ 取消★★

全部終わったら、 手元で git log --oneline --graph --all を打って分岐 → 統合の網目を眺めてみる。

ドリル 1 — 2 つ目の PR を作って merge する

> 🛠️ 【タイプ: 反復】 章 4〜6 の流れをもう 1 度自分で通す。

  1. main から 新しいブランチ feature/update-readme を切る
  2. README.md に「## 学んだこと」 のセクションを追加して、 何を学んだか 1 行書く
  3. ブランチを push して GitHub で PR を作成 → マージ → ブランチ削除 まで通す
  4. 手元 main を git pull で最新化する

ドリル 1 — 実施前 (main トップ)

!w:680

1 Commit / 1 Branch / Pull requests バッジは 1 (= 章 7 で作った PR #1 だけがマージ済)。

ここから 2 つ目の PR を作りに行く。

ドリル 1 — 実施後 (Closed PR が 2 つ)

!w:680

Pull requests タブ → Closed フィルタで #1#2 の 2 つがマージ済として並ぶ。

ターミナルで git log --oneline --graph --all を打つと、 分岐 → 統合の山が 2 つ並ぶ形になる。

ドリル 1 — ヒント

> ⚠️ 自力で考えてから読んでください

  • ブランチを切るコマンドは章 4 と同じ (git switch -c <ブランチ名>)
  • README.md の編集はエディタで開いて末尾に追記すればよい
  • PR を出すまでの流れは章 4〜6 と完全に同じ
  • 手元 main を更新するのは git pull origin main

ドリル 2 — わざと衝突を起こして解決する

> ⚠️ 【タイプ: 衝突】 同じファイルを 2 経路で編集して衝突状態を作る。

  1. main から feature/conflict-a を切って、 README.md の冒頭行を # Hello A に書き換えて commit + push + PR を作る (まだ merge しない)
  2. main に戻って feature/conflict-b を切って、 README.md の同じ冒頭行を # Hello B に書き換えて commit + push + PR を作る
  3. 先に feature/conflict-a を merge する (これは普通にマージできる)
  4. feature/conflict-b の PR ページを開く と「This branch has conflicts」 と赤い表示が出る
  5. ターミナルで feature/conflict-b ブランチに居る状態で git pull origin main を打つと衝突メッセージが出る
  6. README.md を開き、 <<<<<<<>>>>>>> の間を見て どちらかを残す形に編集 する
  7. git add README.md && git commit && git push で解決を反映 → GitHub で merge

ドリル 2 — 実施前 (PR が衝突状態)

!w:680

PR ページ右上が 「Merge conflicts」 の赤バッジに変わり、 下に 「This branch has conflicts that must be resolved」 の警告。 Merge ボタンはグレーアウトして押せない。

ドリル 2 — 実施後 (Merged)

!w:680

ローカルで衝突を解決 → push すると赤バナーが消え、 マージ可能になる。 マージ後は紫の Merged バッジ。

ドリル 2 — ヒント

> ⚠️ 自力で考えてから読んでください

  • 衝突マーカーの構造:
  <<<<<<< HEAD
  # Hello B          ← 自分のブランチ側
  =======
  # Hello A          ← main から取り込んだ側
  >>>>>>> origin/main
  
  • マーカー (<<<<<<< ======= >>>>>>>) は 3 本とも削除する
  • 残す側の行だけ残して、 不要な側の行とマーカーを消す
  • git commit で開いたエディタは中身そのままで保存・終了して OK (Git が merge メッセージを用意してくれている)

ドリル 3 — 直前の commit を取り消す

> ↩️ 【タイプ: 取消】 ドリル 2 で main に入れた変更を 後から取り消す 練習。 revert は履歴を残したまま打ち消す方法。

  1. git log --oneline直前の merge commit の hash を確認する
  2. main から feature/revert ブランチを切る
  3. git revert -m 1 <その merge commit の hash> を実行する
  4. エディタが開いたら、 そのまま保存して閉じる (Git が revert 用のメッセージを用意してくれている)
  5. 出来た commit を push して PR を作成 → merge する

> -m 1 は「merge commit を revert するときに、 main 側 (1 番目の親) を残す」 という意味のフラグ。 通常の commit を revert するときは不要。

ドリル 3 — 実施前 (git log --oneline -n 5)

afa06cf Merge pull request #4 from <USER>/feature/conflict-b
e831e51 Merge branch 'main' of github.com:<USER>/git-handson-demo into feature/conflict-b
8ca7976 Merge pull request #3 from <USER>/feature/conflict-a
6f7d7b4 rename heading to Hello B
26a014c rename heading to Hello A

1 行目の hash がドリル 2 で merge した PR のコミット。 この hash を git revert -m 1 で指定する。

ドリル 3 — 実施後 (git log --oneline --graph --all)

*   5061897 Merge pull request #5 from <USER>/feature/revert
|\
| * 2ebd4c4 Revert "Merge pull request #4 from <USER>/feature/conflict-b"
|/
*   afa06cf Merge pull request #4 from <USER>/feature/conflict-b
|\
...
* ddd3a47 first commit

元の merge commit は 消えずに履歴に残ったまま、 後ろに Revert "..." commit が追加される。 「打ち消した記録」 が残るのが revert。

ドリル 3 — ヒント

> ⚠️ 自力で考えてから読んでください

  • git log --oneline の出力 1 行目が直前の commit (= ドリル 2 の最終 merge)
  • hash は 7 文字あれば指定できる (例: git revert -m 1 8288712)
  • git reset は履歴を 巻き戻して消す ので、 push 済の場所では使わない。 代わりに revert で「打ち消し commit を足す」
  • 失敗したら git revert --abort でやり直せる

章 9. 解答例

ドリル 1 解答

git switch main && git pull origin main
git switch -c feature/update-readme

cat >> README.md <<'EOF'

## 学んだこと

- git の add → commit → push の流れ
- Pull Request の作り方とマージの仕方
EOF

git add README.md
git commit -m "add learnings section"
git push -u origin feature/update-readme

# GitHub で PR を作成 → Merge pull request → Delete branch

git switch main
git pull origin main

ドリル 1 確認結果

git log --oneline --graph --all (hash は環境ごとに異なる):

*   abcdef1 Merge pull request #2 from <USER>/feature/update-readme
|\
| * 1234567 add learnings section
|/
*   8288712 Merge pull request #1 from <USER>/feature/greeting
|\
| * 7812060 add greeting
|/
* ddd3a47 first commit

merge commit が 2 つある (#1#2)。 分岐 → 統合の山が 2 つ並ぶ。

ドリル 2 解答 — ブランチを 2 本作る

# ブランチ A
git switch main && git pull origin main
git switch -c feature/conflict-a
# README.md の冒頭を `# Hello A` に書き換え
git add README.md
git commit -m "rename heading to Hello A"
git push -u origin feature/conflict-a   # PR を作る (まだ merge しない)

# ブランチ B (main は A 取り込み前)
git switch main
git switch -c feature/conflict-b
# README.md の冒頭を `# Hello B` に書き換え
git add README.md
git commit -m "rename heading to Hello B"
git push -u origin feature/conflict-b   # PR を作る

ドリル 2 解答 — 衝突解決の流れ

# 先に conflict-a を GitHub でマージ → conflict-b 側でローカル衝突解決
git switch feature/conflict-b
git pull origin main
# → Auto-merging README.md
# → CONFLICT (content): Merge conflict in README.md

README.md を開くと衝突マーカー:

<<<<<<< HEAD
# Hello B
=======
# Hello A
>>>>>>> origin/main

どちらかを残す (例: B を残す) → マーカー 3 行を全削除して # Hello B だけにする。

ドリル 2 解答 — 解決の commit

git add README.md
git commit            # エディタが開くがそのまま :wq で閉じる
git push origin feature/conflict-b
# GitHub に戻ると PR が緑になっている → Merge pull request

よくある詰まり

  • マーカー (<<<<<<< ======= >>>>>>>) を消し忘れる

→ push 後に PR が緑にならない / merge できても README が壊れて表示される

  • 両方を残してしまう → 両方の見出しが README に出る
  • git commit でエディタが開いて閉じられない → :wq (vim) / Ctrl+SCtrl+W (VS Code)

ドリル 3 解答 — revert を打つ

git switch main && git pull origin main
git log --oneline -n 5
# 1 行目の hash をメモ (例: 8288712)

git switch -c feature/revert
git revert -m 1 8288712
# エディタが開く → そのまま保存して閉じる

git push -u origin feature/revert
# GitHub で PR を作る → Merge pull request

ドリル 3 解答 — なぜ -m 1

merge commit には 親が 2 つ ある (main 側 と feature 側)。

revert するとき「どちらの親を残すか」 を Git に教える必要がある。

*   8288712 Merge pull request #4   ← 親が 2 つ
|\
| * xxx     conflict-b の変更         ← parent 2 (打ち消したい側)
|/
* yyy       直前の main の状態        ← parent 1 (残したい側)

-m 1 = 「parent 1 (main 側) を正として残し、 もう片方を打ち消す」 という意味。

通常の単独 commit を revert するときは -m は不要。

章 10. 他の人のリポジトリと協働する

共同作業には 2 つのモデルがある

モデル何をするか使う場面
Collaborator (招待)自分が相手のリポジトリに 直接 push できる権限 をもらう同じチームのメンバー間。 信頼関係あり
Fork & PR相手のリポジトリを コピー (fork) して、 自分のコピーで作業 → 本家に PR を出す顔の見えない相手 (OSS など)。 権限を渡さない

→ どちらの場合も、 本家 main に入れる前に PR でレビューを通す。 ここは 1 人で書くときと同じ。

モデル A — 招待する側 (Add people)

リポジトリの Settings → Collaborators → Add people で相手の GitHub ユーザー名を入力する。

!w:680

検索ボックスに入力するとアカウントがサジェストされ、 緑の Add <username> ボタンで招待が送られる。

モデル A — Collaborator として登録された

相手が招待を Accept すると、 Settings → Collaborators の Manage access にユーザーが並ぶ。

!w:620

権限レベルは Organization リポでは Read / Triage / Write / Maintain / Admin から選べる (個人リポでは Write 固定)。 開発メンバーの標準は Write (push 可)、 レビュアーだけ任せたいなら Triage (push 不可・PR 整理は可)、 見せるだけなら Read

モデル A — 招待される側 (Accept invitation)

招待されると GitHub の通知 (https://github.com/notifications) に届く。 リポジトリ URL を直接開いてもこの画面に来る。

!w:680

緑の Accept invitation を押すと、 push 権限を持った Collaborator になる。 あとは git clone で章 4 と同じ流れ。

モデル B — Fork して PR を返す

OSS など権限をもらえない / もらうほどでもない場合。 相手のリポジトリページの 右上 Fork ボタン を押す。

!w:680

Fork ボタンの横の数字が現在の fork 数。 押すと「Create fork」 確認画面 → 自分のアカウント配下にコピーが作られる。

モデル B — Fork が作られた

自分のアカウント配下に同名のリポジトリが出来る。 ヘッダの下に forked from <OWNER>/<REPO> と表示される。

!w:680

Sync fork で本家の最新を取り込める。 Contribute ボタンが本家へ PR を出す入口。

モデル B — fork からの cross-repo PR

fork の中でブランチを切って push したあと、 Compare changes ページに行くとリポジトリを跨いだ PR の画面が出る。

!w:620

base repository = 本家 (取り込んでもらう先) / head repository = 自分の fork (送り出す側)。 4 つのドロップダウンで方向を切り替えられる。 緑の Create pull request で本家にレビュー依頼が飛ぶ。

モデル B — fork で本家を最新化する

本家 (upstream) が先に進んだら、 自分の fork も追いつかせる必要がある。

# 一度だけ: 本家を upstream という名前で追加
git remote add upstream https://github.com/<OWNER>/<REPO>.git
git remote -v
# origin     https://github.com/<自分>/<REPO>.git    (自分の fork)
# upstream   https://github.com/<OWNER>/<REPO>.git   (本家)

# 本家の main を取り込む
git switch main
git fetch upstream
git merge upstream/main
git push origin main   # 自分の fork も最新に

GitHub UI 上の Sync fork ボタンでも同じことができる (図 34 参照)。

他の人の PR をレビューする

相手から PR が来たら、 Files changed タブで差分を読んで Submit review ボタンを押す。

!w:680

ダイアログで 3 つから選ぶ:

  • Comment — 意見だけ残す (承認 / 却下しない)
  • Approve — マージしてよい
  • Request changes — 修正してから出し直してほしい

Approve すれば PR ページに戻って Merge pull request → Confirm でマージできる。

ブランチ運用の典型 (一言だけ)

チームで使われているブランチ運用には名前が付いているものがある。

  • GitHub Flow — main 1 本 + feature ブランチ。 PR で main に merge してすぐ deploy。 この資料がやってきた形がこれ
  • Git Flowdevelop / release / hotfix などのブランチを使い分ける重い運用。 リリース日が決まったプロダクト向け
  • Trunk-based development — main にどんどん commit していく (ブランチをほぼ作らない)。 強い CI と feature flag が前提

今は GitHub Flow だけ覚えておけば十分。 必要になったら名前で検索する。

章 10 のまとめ

場面やること
同じチームに招待されたAccept invitation → clone → ブランチ → push → PR
OSS に貢献したいFork → clone → ブランチ → push → 本家に cross-repo PR
自分のリポに PR が来たFiles changed で差分 → Submit review → Approve → Merge
本家が進んだ (fork)git fetch upstream && git merge upstream/main または UI の Sync fork

1 人で回すときと同じ「ブランチ → PR → merge」 の流れ がそのまま通用する。

資料を片手に、 1 章ずつ手を動かす

このページに戻ってきたら、 章 1 から順に試していく。

資料の図と自分の画面を見比べながら進めて、 詰まったら章 7 と章 9 を開く。

ハンズオン

演習ガイド

Git / GitHub ハンズオン ドリル集

演習の進め方 (読んでから始めてください)

章 1〜7 で作った git-handson-demo リポジトリをそのまま使う。

3 問のドリルを順番に解く。 1 問ごとに GitHub の画面で結果を確認 してから次に進む。

ドリルのタイプ

  • 採点テストは無い。 自分の目で GitHub の画面 / ターミナル出力 を見て確認する
  • 各ドリルの 「実施前 / 実施後」 に「ここに何が表示されれば OK」 が写真で載っている
  • 詰まったら ヒント を読む

3 問共通で守ること

  • リポジトリ名は章 1 で決めたものから変えない
  • main へ直接 commit しない (= 全部ブランチ → PR を通す)
  • PR の説明欄に「何をしたか」 を 1 行書く

このガイドのドリル一覧

#ドリル名タイトルタイプ難易度
101-second-pr2 つ目の PR を作って merge する🛠️ 反復
202-conflictわざと衝突を起こして解決する⚠️ 衝突★★
303-revert直前の commit を取り消す↩️ 取消★★

> 全部終わったら、 手元で git log --oneline --graph --all を打って分岐 → 統合の網目を眺めてみる。

ドリル 1: 2 つ目の PR を作って merge する

ドリル名: 01-second-pr

> 🛠️ 【タイプ: 反復】 章 4〜6 の流れをもう 1 度自分で通す。

問題

git-handson-demo リポジトリで以下を実行せよ。

  1. main から 新しいブランチ feature/update-readme を切る
  2. README.md に「## 学んだこと」 のセクションを追加して、 何を学んだか 1 行書く
  3. ブランチを push して GitHub で PR を作成 → マージ → ブランチ削除 まで通す
  4. 手元 main を git pull で最新化する

実施前 — main トップ

!w:880

1 Commit / 1 Branch / Pull requests バッジは 1 (= 章 7 で作った #1 だけがマージ済)。

ここから 2 つ目の PR を作りに行く。

実施後 — Closed PR が 2 つ並ぶ

!w:880

Pull requests タブ → Closed フィルタで #1#2 の 2 つがマージ済として並ぶ。

ターミナルで git log --oneline --graph --all を打つと、 分岐 → 統合の山が 2 つ並ぶ形になる。

ドリル 1: ヒント

ドリル名: 01-second-pr

> ⚠️ 自力で考えてから読んでください

  • ブランチを切るコマンドは章 4 と同じ (git switch -c <ブランチ名>)
  • README.md の編集はエディタで開いて末尾に追記すればよい
  • PR を出すまでの流れは章 4〜6 と完全に同じ
  • 手元 main を更新するのは git pull origin main

ドリル 2: わざと衝突を起こして解決する

ドリル名: 02-conflict

> ⚠️ 【タイプ: 衝突】 同じファイルを 2 経路で編集して衝突状態を作る。

問題

git-handson-demo で以下を順番にやって、 わざと 衝突 を作る。

  1. main から feature/conflict-a を切って、 README.md の冒頭行を # Hello A に書き換えて commit + push + PR を作る (まだ merge しない)
  2. main に戻って feature/conflict-b を切って、 README.md の同じ冒頭行を # Hello B に書き換えて commit + push + PR を作る
  3. 先に feature/conflict-a を merge する (これは普通にマージできる)
  4. feature/conflict-b の PR ページを開く と「This branch has conflicts」 と赤い表示が出る
  5. ターミナルで feature/conflict-b ブランチに居る状態で git pull origin main を打つと衝突メッセージが出る
  6. README.md を開き、 <<<<<<<>>>>>>> の間を見て どちらかを残す形に編集 する
  7. git add README.md && git commit && git push で解決を反映 → GitHub で merge

実施前 — PR が衝突状態 (赤バナー)

!w:880

PR ページ右上が 「Merge conflicts」 の赤バッジに変わり、 下に 「This branch has conflicts that must be resolved」 の警告。 Merge ボタンはグレーアウトして押せない。

実施後 — 衝突を解決して Merged

!w:880

ローカルで衝突を解決 → push すると赤バナーが消え、 マージ可能になる。 マージ後は紫の Merged バッジ。

ドリル 2: ヒント

ドリル名: 02-conflict

> ⚠️ 自力で考えてから読んでください

  • 衝突マーカーの構造:
  <<<<<<< HEAD
  # Hello B          ← 自分のブランチ側
  =======
  # Hello A          ← main から取り込んだ側
  >>>>>>> origin/main
  
  • マーカー (<<<<<<< ======= >>>>>>>) は 3 本とも削除する
  • 残す側の行だけ残して、 不要な側の行とマーカーを消す
  • git commit で開いたエディタは中身そのままで保存・終了して OK (Git が merge メッセージを用意してくれている)

ドリル 3: 直前の commit を取り消す

ドリル名: 03-revert

> ↩️ 【タイプ: 取消】 ドリル 2 で main に入れた変更を 後から取り消す 練習。 revert は履歴を残したまま打ち消す方法。

問題

git-handson-demo の main で以下を実行せよ。

  1. git log --oneline直前の merge commit の hash を確認する
  2. main から feature/revert ブランチを切る
  3. git revert -m 1 <その merge commit の hash> を実行する
  4. エディタが開いたら、 そのまま保存して閉じる (Git が revert 用のメッセージを用意してくれている)
  5. 出来た commit を push して PR を作成 → merge する

> -m 1 は「merge commit を revert するときに、 main 側 (1 番目の親) を残す」 という意味のフラグ。 通常の commit を revert するときは不要。

実施前 — git log --oneline -n 5 の出力

afa06cf Merge pull request #4 from <USER>/feature/conflict-b
e831e51 Merge branch 'main' of github.com:.../git-handson-demo into feature/conflict-b
8ca7976 Merge pull request #3 from <USER>/feature/conflict-a
6f7d7b4 rename heading to Hello B
26a014c rename heading to Hello A

1 行目の hash がドリル 2 で merge した PR のコミット。 この hash を git revert -m 1 で指定する。

実施後 — git log --oneline --graph --all

*   5061897 Merge pull request #5 from <USER>/feature/revert
|\
| * 2ebd4c4 Revert "Merge pull request #4 from <USER>/feature/conflict-b"
|/
*   afa06cf Merge pull request #4 from <USER>/feature/conflict-b
|\
...
* ddd3a47 first commit

元の merge commit は 消えずに履歴に残ったまま、 後ろに Revert "..." commit が追加される。 「打ち消した記録」 が残るのが revert。

ドリル 3: ヒント

ドリル名: 03-revert

> ⚠️ 自力で考えてから読んでください

  • git log --oneline の出力 1 行目が直前の commit (= ドリル 2 の最終 merge)
  • hash は 7 文字あれば指定できる (例: git revert -m 1 8288712)
  • git reset は履歴を 巻き戻して消す ので、 push 済の場所では使わない。 代わりに revert で「打ち消し commit を足す」
  • 失敗したら git revert --abort でやり直せる

おつかれさまでした

3 問通したら、 git log --oneline --graph --all の網目を眺めてみる。

add / commit / push / PR / merge / 衝突解決 / revert を一通り経験したことになる。