kakakakakku blog

Weekly Tech Blog: Keep on Learning!

今だからこそ読み直す「エンジニアのための時間管理術」

2006年に出版された「エンジニアのための時間管理術」を2009年(大学院時代)にはじめて読んだ.本書はエンジニアを対象にした書籍であり,その後 SIer でシステムエンジニアとして働きながら何度も読み直した.もともとプロダクティビティを追求することに興味があり,今も続くスタイルの一部は本書から学んだことを参考にしている.それほどに「個人的に影響を受けた1冊」と言える.今までブログに書評記事を書いてなく,最近また読み直す機会があったため,書評記事を書くことにした.

本書のタイトルは「エンジニアのための」と書いてあるけど,原著のタイトルは「Time Management for System Administrators」となり,明確に「システム管理者」を対象に書かれている.本書の冒頭にも「プログラマを対象としていない」と書かれている.とは言え,現在では文化面も技術面も変化し,DevOps や SRE という言葉も浸透した.システム管理者に限らず,エンジニアなら誰でも読める内容になっていると思う.2006年に出版されたこともあり,当然ながら技術的なたとえ話に古さを感じたりするため,そのあたりは読み替えながら読む.

目次

  • 1章「タイムマネジメントの原則」
  • 2章「集中と割り込み」
  • 3章「ルーチン」
  • 4章「サイクルシステム」
  • 5章「サイクルシステム : 作業リストとスケジュール」
  • 6章「サイクルシステム : カレンダーの管理」
  • 7章「サイクルシステム : 人生の目標」
  • 8章「優先順位」
  • 9章「ストレスの管理」
  • 10章「電子メールの管理」
  • 11章「時間の浪費」
  • 12章「文書化」
  • 13章「自動化」

1章「タイムマネジメントの原則」

1章「タイムマネジメントの原則」では,6種類の原則が載っている.

  • タイムマネジメント情報を1つの「データベース」にまとめる
  • 能力は重要な作業のために温存しておく
  • 日課を定め,それらに従う
  • 習慣やモットーを養う
  • 「プロジェクトタイム」の間は集中力を保つ
  • 日常生活の管理にも,仕事で使用するのと同じツールを使用する

例えば,最初に載っている原則の「データベース」の例として PDA (Personal Digital Assistant)PAA (Personal Analog Assistant) が紹介されている.Palm など時代を感じる内容だけど,現在ならスマホを使えば良いし,Trello や Google Calendar など,ツールも多くある.アナログ派ならメモ帳を持ち歩くのも良いと思う.他にも「習慣化の話」「頭の中を整理する必要性」など,今でも重要な原則と言える.

4章「サイクルシステム」

4章「サイクルシステム」を読むと,原著者が考えた「タイムマネジメント戦略」を学べる.大前提として「自分の記憶力を信用するな!」というメッセージがあり,とても共感できる.実際には,先ほど載せた PDA or PAA で以下の4点を管理すると書いてある.

  • 365日分の作業リスト(ほぼ日手帳のような?)
  • 今日のスケジュール
  • 約束のカレンダー
  • メモ(人生目標を書いたりする)

そして,毎日を以下のサイクルで繰り返す.

  • 今日のスケジュールを作成する
  • 今日の作業リストを作成する
  • 優先順位を付け,スケジュールを調整する
  • 予定に取り組む
  • 1日の終わり
  • 会社を出る
  • 繰り返す

「サイクルシステム」は完璧にタイムマネジメントをしながら記録を残すため,いざ試そうとすると比較的重いと思う.昔に試したこともあったけど,現在は守破離のように自分なりに取捨選択している.例えば,朝起きたらすぐに作業リストを作ったり,割り込みが入ったら優先順位を入れ替えたりするのは,今でも実践している.数年前からは朝ではなく,寝る前に翌日の作業リストを作っていたりもする.

7章「サイクルシステム:人生の目標」

「サイクルシステム」の素晴らしい点は,構成要素に「人生目標」が入っていることで,目標を立てないと「単純に作業をうまく進められるようになるだけ」になってしまう.7章「サイクルシステム : 人生の目標」を読むと,以下のように具体的な目標を立てる必要性を学べる.

  • "何を" 実現したいのか
  • "いつ" それを実現したいのか

目標の粒度としては,書籍「How to Get Control of Your Time and Your Life」を引用して,以下のような表が載っている.「仕事の目標」「プライベートの目標」をどちらも立てる点がとても良い.

  • 短期(1ヶ月)
  • 中期(1年)
  • 長期(5年)

個人的には2014年頃から本格的に「人生目標」を運用していて,粒度は以下のように変えている.

  • 短期(3ヶ月)
  • 中期(1年)
  • 長期(2年)

基本的に非公開だけど「中期(1年)目標」の一部はブログにも載せている(意図的に抽象的に書いている).「長期(2年)目標」に関しては,例えば 2017年 から「技術支援を仕事にする or 講師になる」という目標があり,実際に現在の仕事は技術講師だし,その前はプログラミング講師の仕事も経験した.さらに2年以上も継続している「ブログメンタリング活動」「習慣化を支援すること」を強く意識している.よって長期目標をある程度は達成できているように思うし,今後も目標は運用し続けていく.

11章「時間の浪費」

プロダクティビティを追求することに興味があるため,11章「時間の浪費」と類似した書籍も読んでいるけど,時間を捻出するために「時間の浪費を減らす」ことは本当に重要だと思う.何を「時間の浪費」と定義するかは価値観にもよるけど,本書だと「費やした時間に対する利益率が低いこと」と書かれている.具体的に以下の項目に興味があれば(自覚症状があれば)読んでみると良さそう.とは言え,項目だけだとミスリードも起きるため,本書を読んでもらえればと!ただ「時間の浪費」を意識しすぎているからこそ,よく「せっかちすぎる」と揶揄される.

  • 一般的な時間の浪費
    • 作業リストのくだらない項目
    • 大量のメーリングリスト
    • 掲示板や Usenet
    • チャットシステム
    • オフィスへの「立ち寄り」
    • セールスと人材スカウト業者
    • 手動プロセス
  • オフィスでの交流
  • 無駄な会議
  • レンタルビデオで迷う
  • つまらない番組を観ない
  • 洗濯と掃除
  • ハードウェアとソフトウェアのインストール

特徴的な項目としては「レンタルビデオで迷う」という「時間の浪費」が挙げられる.ビデオショップで何を借りようか迷う時間が無駄であるという話で,2006年に出版された書籍だけど,今でも動画配信サービスで同じことが起きる.僕自身は Amazon Prime Video でダラダラ迷わないように「Trello に観る予定の作品名をチケット化」している.まさに本書から学んだ Tips と言える.さらに Trello の Checklist を使ってエピソードの進捗まで管理してる話はポッドキャストでも話した.

omoiyarifm.github.io

13章「自動化」

エンジニアを対象にした本書だからこそ,13章「自動化」もある.「自動化をするべきか見極める方法」「自動化のステップ」など,一般的に参考になる内容から,Shell の alias~/. ssh/configMakefile など,もともと対象だった「システム管理者」のためになる内容も載っている.このあたりは技術面の変化もあるため,参考になるものもあれば,今ならもっと便利なツールがあったりもする.

まとめ

2009年から何度も読み直している「エンジニアのための時間管理術」の書評記事を今さらながら書いた.プロダクティビティ関連の本は多くあるけど,本書はエンジニアを対象にした書籍となる.たとえ話などは古さを感じる面もあるけど,2020年になった今でも読める.リモートワークになりタイムマネジメントに悩んでいるという相談を受けることもあり,参考になる1冊だと思う.全ての章を紹介していないため,興味があったら読んでみてもらえればと!仕事も家庭環境も日々変わるけど,定期的に習慣を見直して,タイムマネジメントを楽しもう!

Next.js 9.3 で使えるようになった getStaticProps と getServerSideProps

2020年3月にリリースされた Next.js 9.3 から,アプリケーションをビルドする戦略として以下3種類の API が使えるようになった.Next.js Blog では「Next-gen Static Site Generation (SSG) Support」と紹介されていた.

  • getStaticProps
    • 「ビルド時」にデータを取得する
  • getStaticPaths
    • 「ビルド時」にデータを取得する(Dynamic Routing を作る)
  • getServerSideProps
    • 「リクエスト時」にデータを取得する

nextjs.org

今までの getInitialProps は?

レンダリング時に API からデータを取得するなど,今まで使ってきた getInitialProps はどうなるの?と気になると思う.ドキュメントに書いてある通り,Next.js 9.3 以降は getInitialProps ではなく getStaticPropsgetServerSideProps を使うことが推奨 (Recommended) になっている.とは言え,今までの getInitialProps も非推奨とまでは書いてなく,引き続き使える.今後実装するなら,getStaticPropsgetServerSideProps を使っていくと良さそう.

nextjs.org

なお,getStaticPropsgetServerSideProps は Node.js コンテキスト(サーバサイド)で実行される.よって,今まではフロントエンドにも対応した fetch API として,例えば isomorphic-unfetch などを使っていたけど,サーバサイドだけなら node-fetch を使える.Next.js 9.3 に対応したサンプルコードも node-fetch を使うように更新されていたりする.

data-fetch テンプレート

実際に getStaticPropsgetServerSideProps を試しながら理解を深めるため,create-next-app で使える data-fetch テンプレートの実装を参考に試した.既に getStaticProps を使った実装に更新されている.さらに今回は TypeScript を使うために with-typescript テンプレートをベースにした.create-next-app に関しては先週の記事にまとめた.

kakakakakku.hatenablog.com

検証環境

今回は Next.js 9.3.5 を使う.

$ npm view next version
9.3.5

また,動作確認をするサンプルコードを pages 直下に実装した.

$ tree pages
pages
├── get-server-side-props.tsx
└── get-static-props.tsx

サンプルコード : get-static-props.tsx

まず,getStaticProps を使ったサンプルコード get-static-props.tsx を載せる.ビルド時に GitHub API から Next.js の Star⭐️ 件数を取得する.また Link コンポーネントを使って遷移できるように /get-server-side-props へのリンクも実装した.

import React from 'react'
import Link from 'next/link'
import fetch from 'node-fetch'

type Props = {
  stars: number
}

function Index({ stars }: Props) {
  return (
    <div>
      <p>Next.js has {stars} ⭐️</p>
      <Link href="/get-server-side-props">
      <a>Go to getServerSideProps</a>
      </Link>
    </div>
  )
}

export async function getStaticProps() {
  const res = await fetch('https://api.github.com/repos/zeit/next.js')
  const json = await res.json()
  return {
    props: {
      stars: json.stargazers_count,
    },
  }
}

export default Index

サンプルコード : get-server-side-props.tsx

次に,getServerSideProps を使ったサンプルコード get-server-side-props.tsx を載せる.リクエスト時に GitHub API から Next.js の Star⭐️ 件数を取得する.また Link コンポーネントを使って遷移できるように /get-static-props へのリンクも実装した.

import React from 'react'
import Link from 'next/link'
import fetch from 'node-fetch'

type Props = {
  stars: number
}

function Index({ stars }: Props) {
  return (
    <div>
      <p>Next.js has {stars} ⭐️</p>
      <Link href="/get-static-props">
        <a>Go to getStaticProps</a>
      </Link>
    </div>
  )
}

export async function getServerSideProps() {
  const res = await fetch('https://api.github.com/repos/zeit/next.js')
  const json = await res.json()
  return {
    props: {
      stars: json.stargazers_count,
    },
  }
}

export default Index

ビルド

yarn build を実行すると,実装された getStaticPropsgetServerSideProps を参考に判定される./get-static-props「● (SSG)」となり /get-server-side-props「λ (Server)」となる.

$ yarn build

(中略)

Page                            Size     First Load JS
┌ ○ /                           1.8 kB         59.9 kB
├ ○ /404                        2.61 kB        60.7 kB
├ λ /get-server-side-props      1.84 kB        59.9 kB
└ ● /get-static-props           1.85 kB        59.9 kB

(中略)

λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerSideProps)(Static)  automatically rendered as static HTML (uses no initial props)(SSG)     automatically generated as static HTML + JSON (uses getStaticProps)

✨  Done in 5.0s.

動作確認

実際に画面にアクセスして確認した.ビルド時の Star⭐️ 件数は 46914 だった(動作確認中にどんどん増えてて驚いた!).ビルド時と変化させるために Star⭐️ を付けたり消したりした.以下にイメージ画像を載せておく.

f:id:kakku22:20200420102656p:plain

1. /get-static-props

getStaticProps の場合はビルド時にデータを取得しているため,素早く表示された.5ms ~ 10ms 程度.直接 http://localhost:3000/get-server-side-props にアクセスすると Content-Typetext/html で返ってきた.Link コンポーネントをクリックしてフロントエンド側で画面遷移をすると Content-Typeapplication/json で以下のように返ってきた.

{
  "pageProps": {
    "stars": 46914
  },
  "__N_SSG": true
}

2. /get-server-side-props

getServerSideProps の場合はリクエスト時にデータを取得しているため,少し時間がかかる.getStaticProps と同じく,直接 http://localhost:3000/get-server-side-props にアクセスすると Content-Typetext/html で返ってきた.Link コンポーネントをクリックしてフロントエンド側で画面遷移をすると Content-Typeapplication/json で以下のように返ってきた.

{
  "pageProps": {
    "stars": 46918
  },
  "__N_SSP": true
}

まとめ

Next.js 9.3 で使えるようになった getStaticPropsgetServerSideProps の理解を整理するためにサンプルコードを実装しながら試した.getStaticProps はビルド時にデータを取得し,getServerSideProps はリクエスト時にデータを取得する.詳しくは Data fetching のドキュメントにも載っている.Static Site Generation (SSG) を使っていくぞー!

nextjs.org

Next.js に入門するのに便利な create-next-app の with-typescript テンプレート

最近 Next.js Learn を使って Next.js に入門した.今度は Next.js でプロトタイプを実装しながら学ぶため,プロジェクトの初期構築として create-next-app を使うことにした.少し調べたところ,create-next-app はもともと Segment 社で実装されて,現在は Next.js を管理する ZEIT 社に譲渡されている.さらに2019年10月に再実装された create-next-app もリリースされている.

nextjs.org

with-typescript テンプレート

create-next-app にテンプレートを指定するオプションがある.試しに Next.js と TypeScript 組み合わせた with-typescript テンプレートを指定したところ,Next.js を学ぶのに便利な構成になっていた.Next.js 9.3 にも対応している.今回は create-next-appwith-typescript テンプレートを使って学べる「計6点」を紹介する.コードを書きながら試行錯誤するなら Next.js Learn よりも使える.

  1. ディレクトリ構造
  2. Link コンポーネント
  3. Layout コンポーネント
  4. getStaticProps 関数
  5. getStaticPaths 関数と Dynamic Routes 機能
  6. API Routes 機能

なお with-typescript 以外のテンプレートは以下にある.

準備

まず npx create-next-app--example オプションを使ってプロジェクトを構築する.構築後に yarn dev を実行すると,すぐに http://localhost:3000 にアクセスできるようになる.

$ npx create-next-app --example with-typescript sandbox-create-next-app-ts
$ cd sandbox-create-next-app-ts
$ yarn dev

f:id:kakku22:20200413214932p:plain

1. ディレクトリ構成

create-next-app を実行した直後は以下のようなディレクトリ構成になっている.node_modules 以外を載せた.議論の余地はあるかもしれないけど,pages/ 以外にコンポーネントを管理する components/ や,型定義を管理する interfaces/ など,最低限このあたりは分割しておこう!という指針になる.

$ tree -I node_modules
.
├── README.md
├── components
│   ├── Layout.tsx
│   ├── List.tsx
│   ├── ListDetail.tsx
│   └── ListItem.tsx
├── interfaces
│   └── index.ts
├── next-env.d.ts
├── package.json
├── pages
│   ├── about.tsx
│   ├── api
│   │   └── users
│   │       └── index.ts
│   ├── index.tsx
│   └── users
│       ├── [id].tsx
│       └── index.tsx
├── tsconfig.json
├── utils
│   └── sample-data.ts
└── yarn.lock

7 directories, 16 files

2. Link コンポーネント

まず,トップページの実装を確認するため pages/index.tsx を読む.すると Link コンポーネントを使って /about へのリンクが実装されている.React Router などを使わずに簡単に実装できる.

import Link from 'next/link'
import Layout from '../components/Layout'

const IndexPage = () => (
  <Layout title="Home | Next.js + TypeScript Example">
    <h1>Hello Next.js 👋</h1>
    <p>
      <Link href="/about">
        <a>About</a>
      </Link>
    </p>
  </Layout>
)

export default IndexPage

3. Layout コンポーネント

画面の1番上には Users ListUsers API など,他にもリンクが実装されている.既に載せた pages/index.tsx を読むと,独自実装の Layout コンポーネントがあり,title 属性が指定されている.コンポーネントの実装を確認するため components/Layout.tsx を読むと,画面共通のレイアウトが実装されている.ここにまた Link コンポーネントがあったり,{children} を使ってコンテンツを受け渡していたり,ベーステンプレートの実装として参考になる.

import * as React from 'react'
import Link from 'next/link'
import Head from 'next/head'

type Props = {
  title?: string
}

const Layout: React.FunctionComponent<Props> = ({
  children,
  title = 'This is the default title',
}) => (
  <div>
    <Head>
      <title>{title}</title>
      <meta charSet="utf-8" />
      <meta name="viewport" content="initial-scale=1.0, width=device-width" />
    </Head>
    <header>
      <nav>
        <Link href="/">
          <a>Home</a>
        </Link>{' '}
        |{' '}
        <Link href="/about">
          <a>About</a>
        </Link>{' '}
        |{' '}
        <Link href="/users">
          <a>Users List</a>
        </Link>{' '}
        | <a href="/api/users">Users API</a>
      </nav>
    </header>
    {children}
    <footer>
      <hr />
      <span>I'm here to stay (Footer)</span>
    </footer>
  </div>
)

export default Layout

4. getStaticProps 関数

次にトップページから Users List をクリックすると,一覧画面に遷移する.

f:id:kakku22:20200413215057p:plain

一覧画面を実装した pages/users/index.tsx を読むと,Next.js 9.3 でリリースされた新機能 getStaticProps 関数を使って実装されている.getStaticProps 関数を使うと,Next.js のビルド時に静的ファイルを生成できるため,不要な SSR (Server-Side Rendering) を減らせる.今回は API ではなく,ファイルデータ utils/sample-data.ts を読み込む実装になっている.当然ながら,全ての一覧画面を静的ファイルにするべきという意味ではなく,あくまでサンプルとして.

なお,AliceBob など,一覧部分は,独自実装の List コンポーネント (components/List.tsx) と ListItem コンポーネント (components/ListItem.tsx) に実装されている.

export const getStaticProps: GetStaticProps = async () => {
  // Example for including static props in a Next.js function component page.
  // Don't forget to include the respective types for any props passed into
  // the component.
  const items: User[] = sampleUserData
  return { props: { items } }
}

5. getStaticPaths 関数と Dynamic Routes 機能

一覧画面で Alice など,特定のユーザーをクリックすると,詳細画面に遷移する.

f:id:kakku22:20200413215135p:plain

詳細画面は pages/users/[id].tsx に実装されている.詳細画面はユーザーごとに異なるため,Next.js の「Dynamic Routes 機能」を使って,任意の id に対応する.そのために Next.js 9.3 でリリースされた新機能 getStaticPaths 関数を使って実装されている.まず getStaticProps 関数で,URL から取得した id を使ってファイルデータを検索し,ビルド時に静的ファイルを生成する.さらに getStaticPaths 関数で,Dynamic Routes 機能に必要なパスのリストを生成する.簡単な実装ではあるけど,参考になる.

import React from 'react'
import { GetStaticProps, GetStaticPaths } from 'next'

import { User } from '../../interfaces'
import { sampleUserData } from '../../utils/sample-data'
import Layout from '../../components/Layout'
import ListDetail from '../../components/ListDetail'

type Props = {
  item?: User
  errors?: string
}

export default class StaticPropsDetail extends React.Component<Props> {
  render() {
    const { item, errors } = this.props

    if (errors) {
      return (
        <Layout title={`Error | Next.js + TypeScript Example`}>
          <p>
            <span style={{ color: 'red' }}>Error:</span> {errors}
          </p>
        </Layout>
      )
    }

    return (
      <Layout
        title={`${
          item ? item.name : 'User Detail'
        } | Next.js + TypeScript Example`}
      >
        {item && <ListDetail item={item} />}
      </Layout>
    )
  }
}

export const getStaticPaths: GetStaticPaths = async () => {
  // Get the paths we want to pre-render based on users
  const paths = sampleUserData.map(user => ({
    params: { id: user.id.toString() },
  }))

  // We'll pre-render only these paths at build time.
  // { fallback: false } means other routes should 404.
  return { paths, fallback: false }
}

// This function gets called at build time on server-side.
// It won't be called on client-side, so you can even do
// direct database queries.
export const getStaticProps: GetStaticProps = async ({ params }) => {
  try {
    const id = params?.id
    const item = sampleUserData.find(data => data.id === Number(id))
    // By returning { props: item }, the StaticPropsDetail component
    // will receive `item` as a prop at build time
    return { props: { item } }
  } catch (err) {
    return { props: { errors: err.message } }
  }
}

6. API Routes 機能

最後は Next.js で API を実装する「API Routes 機能」で,pages/api/users/index.ts のように pages/api 配下にファイルを置く.すると http://localhost:3000/api/users で API にアクセスできるようになる.

$ curl -s http://localhost:3000/api/users | jq .
[
  {
    "id": 101,
    "name": "Alice"
  },
  {
    "id": 102,
    "name": "Bob"
  },
  {
    "id": 103,
    "name": "Caroline"
  },
  {
    "id": 104,
    "name": "Dave"
  }
]

今回はファイルデータ utils/sample-data.ts をそのまま JSON で返すだけになっているけど,例えば NextApiRequest で HTTP メソッドを判定したり,API Middlewares を使って拡張もできる.最低限の API 実装という観点で参考になる.

import { NextApiRequest, NextApiResponse } from 'next'
import { sampleUserData } from '../../../utils/sample-data'

export default (_: NextApiRequest, res: NextApiResponse) => {
  try {
    if (!Array.isArray(sampleUserData)) {
      throw new Error('Cannot find user data')
    }

    res.status(200).json(sampleUserData)
  } catch (err) {
    res.status(500).json({ statusCode: 500, message: err.message })
  }
}

まとめ

create-next-appwith-typescript テンプレートから Next.js プロジェクトを初期構成すると,Next.js の主要な機能を学べる.一通りの機能を試せる点や Next.js 9.3 をサポートしている点など,Next.js Learn よりも便利だなと感じた.機能ごとに学びたかったら Next.js Learn を使って,コードを書きながら試行錯誤したかったら create-next-app で新規プロジェクトを作ってしまうと良さそう.Next.js Learn の紹介記事も載せておく!

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

Chrome DevTools で「オフライン環境」をエミュレートする

例えば「オフライン対応」のアプリケーションを実装して動作確認をするときなど「オフライン環境」が必要になる場合もある.単純に WiFi をオフにすれば良いこともあるけど,WiFi をオフにせず,部分的にオフライン環境をエミュレートできると便利.具体的には,先週とあるライブコーディングを自宅から配信したときに,WiFi をオフにせず「オフライン環境のテスト」をする必要があった.

Chrome DevTools を使う

developers.google.com

Chrome DevTools を使えば,簡単にオフライン環境をエミュレートできる.Network タブを開き Disable cache の右側にあるプルダウンから「Offline」を選ぶ.すると,設定したタブはオフライン環境になる.

f:id:kakku22:20200410235002p:plain

ネットワーク設定は「計4種類」から選べる.さらに Add... から自由に Network Throttling Profiles を作れる.Download (kb/s)Upload (kb/s)Latency (ms) を自由に設定できるため,低速ネットワーク環境におけるフロントエンドのレンダリング確認などに使える.

  • Online(デフォルト)
  • Fast 3G
  • Slow 3G
  • Offline

f:id:kakku22:20200410235217p:plain

おまけ : Chrome Dino Game も遊べる

オフライン環境をエミュレートすれば Chrome Dino Game も遊べる!とは言え,実はオフライン環境をエミュレートしなくても,直接 chrome://dino/ にアクセスすれば遊べる.気分転換に便利!

f:id:kakku22:20200411000247p:plain

まとめ

今回は Chrome DevTools の小ネタを書いた.Chrome でオフライン環境をエミュレートする場合は Network タブを開き「Offline」を選ぼう!

git checkout の代替としてリリースされた git switch と git restore

2019年8月にリリースされた Git 2.23 から,Experimental(実験的機能)として新コマンド git switchgit restore が使える.今までずっと使ってきた git checkout は機能が多すぎたため,機能を分割し git checkout の代替としてリリースされた.個人的にリリースされてから,できる限り git switchgit restore を使うようにしてるけど,まだ無意識に git checkout を使ってしまうこともある.最近 git switch を教える機会があったため,ブログにまとめておく.

github.blog

なお,以下の検証は Git 2.26.0 を使った.

$ git --version
git version 2.26.0

1. git switch を使う

git switch を使って「ブランチ操作」を行なう.ドキュメントを網羅的に紹介するのではなく,よく使う操作を中心に git checkout などと比較しながら紹介する.詳細はドキュメントを参照してもらればと.

git-scm.com

ブランチを作る

git switch -c でブランチを作れる.今までは git checkout -b を使っていた.

$ git checkout -b my-git-checkout

$ git switch -c my-git-switch

ブランチを切り替える

git switch という名前の通り,ブランチ名を指定すると切り替えられる.

$ git checkout master

$ git switch master

1個前のブランチに切り替える

Linux の cd - と同じく,- を使って git switch - とすると,1個前のブランチに切り替えられる.

$ git checkout -

$ git switch -

リモートブランチを取得する

「ブランチを作る」と同じく git switch -c を使って,origin/xxx など,リモートブランチを指定する.

$ git fetch
$ git checkout -b my-github-branch origin/my-github-branch

$ git fetch
$ git switch -c my-github-branch origin/my-github-branch

"強制的に" ブランチを作る

個人的にあまり使う機会はなさそうだし,誤って使うと危険な気もするけど,git switch-C オプション(大文字)もしくは --force-create オプションを使うと,もし同じ名前のブランチが存在していても強制的に作り直す.-c-C は区別しにくそう...!

$ git switch -C my-git-switch

2. git restore を使う

git restore を使って「変更を戻す操作」を行なう.ドキュメントを網羅的に紹介するのではなく,よく使う操作を中心に git checkout などと比較しながら紹介する.詳細はドキュメントを参照してもらればと.

git-scm.com

Unstaging な変更を戻す(git add をする前)

今まで git checkout を使って変更を戻していたけど,git restore で戻せる.とは言え,個人的に1番無意識に使ってしまうのが git checkout . で,今もまだ git restore . には慣れていない.

$ git checkout README.md
$ git checkout .

$ git restore README.md
$ git restore .

実際に git status を使うと,git restore を使うリファレンスも出る.

$ git status

(中略)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   README.md

Staging な変更を戻す(git add をした後)

git add で Staging にした変更を戻す場合,今までは git reset を使っていたけど,git restore --staged を使う.

$ git reset README.md

$ git restore --staged README.md

実際に git add をした後に git status を使うと,git restore --staged を使うリファレンスも出る.

$ git status

(中略)

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   README.md

指定した Commit に戻す

指定した Commit に戻す場合は git restore -s を使う.ただし,git checkoutStaging な状態に戻り,git restore -sUnstaging な状態に戻るため,単純比較ではなく,注意すること.

$ git checkout ${HASH} .
$ git checkout master~2 .

$ git restore -s ${HASH} .
$ git restore -s master~2 .

まとめ

Git 2.23 から,Experimental(実験的機能)として使えるようになった新コマンド git switchgit restore の中でよく使う操作を中心に紹介した.プログラミング講師の仕事をしていたときに git checkout の説明に苦労した経験もあり,今後は Git 初学者は git switchgit restore から学べば良さそう.