フリーキーズ | 独学プログラミング

Git/Githubをもっと便利に!エンジニア中級者向けgitのテクニック

最終更新日
【画像】Git/Githubをもっと便利に!エンジニア中級者向けgitのテクニック

これは入門編の続きです。

GitやGithubを利用していると、どう操作すべきかわかりづらい難しい状況に陥ることもしばしば起きます。
そういったときに使えるテクニックをいくつか紹介するので、ぜひ参考にしてください。

GitとGitHubを効率的に使うためのヒントとコツ

GitとGitHubを使いこなすには基本的なコマンドを理解するだけではありません。
より効率的にGitを使うためには、コミットログの表示や以前のバージョンへのチェックアウト、.gitignoreファイルの使用など、さまざまなテクニックを熟知しておく必要があります。

コミット履歴が見たい

例えば、git logを使えばコミットの詳細な履歴を見ることができます。これは、変更を追跡し、どこでエラーが発生したかを特定するのに便利です。

$ git log
commit e346a905178da2596312a32413dc5a81eb46a8c4 (HEAD -> main)
Author: XXXXXXX
Date:   Sat Jun 10 11:49:35 2023 +0900

    2nd commit

commit 156451701ee1e5d57419117dc956bce278139a82
Author: XXXXXXX
Date:   Fri Jun 9 20:12:20 2023 +0900

    init

.gitignoreでgitの対象外にしたいファイルを管理

.gitignoreは、Gitにどのファイルやディレクトリを無視し、追跡しないことを設定する目的でリポジトリに作成する特別なファイルです。
ログファイルや一時ファイル、コンパイル済みのコード(Pythonの.pycファイルなど)、環境固有の設定ファイルなど、他の人と共有する必要のないファイルに対して有効です。

以下はPythonプロジェクトにおける.gitignoreファイルの例です。

# すべてのコンパイル済コードを無視
*.pyc
__pycache__/

# すべてのログファイルを無視
*.log

# 環境変数や仮想環境関連を無視
.env
.venv/
*.egg-info/

# データベースファイルを無視
*.db
*.sqlite3

# キャッシュと一時ファイルを無視
*.cache
*.tmp

この例では、Pythonのコンパイル済みファイル、ログファイル、環境関連ディレクトリ、データベースファイル、キャッシュファイル、一時ファイルはすべてGitに無視されます。
つまり、git statusを実行しても表示されず、git add .を実行しても含まれないということです。

.gitignoreのパターンはglobのような形式であることに注意してください。
ワイルドカードとして*を使うことができ、ディレクトリを指定するために/を使い、コメントを追加するために行頭へ#を使うことができます。ディレクトリを指定した場合はそのディレクトリ内のすべてのファイルも無視されます。

Gitによってすでに追跡されているファイルは.gitignoreの影響を受けないということに注意してください。無視させたい場合はgit rm --cached /path/to/fileで明示的に追跡対象から削除する必要があります。

マージコンフリクトに対処する

マージコンフリクトは、Gitが2つのコミット間のコードの相違を自動的に解決できない場合に発生します。
マージコンフリクトが発生するとマージプロセス中に警告を発します。コンフリクトが発生した場合は手動で解決しなければ先に進めません。

$ git merge new-feature
# コンフリクトしている箇所の警告が出る

コンフリクトは<<<<<======>>>>という記号で表示されます。<<<<<======の間のコードはあなたの現在のブランチのコードで、======>>>>の間のコードは他のブランチのコードです。どのコードを残すかを手動で決める必要があります。
また、<<<<<======>>>>のような記号も手動で削除してから再度pushします。

コミットが迷子

git reflogはGitの強力なコマンドで、リポジトリのHEADに加えられたすべての変更の一覧を表示し、Gitリポジトリで行ったすべてのアクションの記録として効果的に機能します。
これは変更を取り消したり前の状態に戻したりしたいときに特に便利です。

いくつかのコミットを行った後、git reset --hard HEAD~3を使って3コミット前に戻したとします。git reflogを使えば、そのコミットを復元できます。

まず、reflogを確認します。

$ git reflog
0d1a7b6 (HEAD -> master) HEAD@{0}: reset: moving to HEAD~3
347fad4 HEAD@{1}: commit: Add feature Z
a6f5f3f HEAD@{2}: commit: Add feature Y
b9c0224 HEAD@{3}: commit: Add feature X

出力では、HEAD@{1}HEAD@{2}HEAD@{3}がハードリセットを行った際に失われるコミットであることがわかります。
各行には、コミットハッシュ(347fad4の箇所)、その時点でHEADが指していたもの、そして実行されたコマンドが表示されています。

feature Zを追加したばかりのプロジェクトの状態に戻るにはコミットハッシュを利用できます。

$ git reset --hard 347fad4

これで失われたと思っていたコミットが復元されました。

git reset --hardを使用する場合は、コミットを永久に破棄してしまうので注意が必要です。破壊的なコマンドを使う前に、必ずコードのバックアップを取っておくか、コードをリモートリポジトリにプッシュしておくようにしてください。

不正確なコミットメッセージ

間違ったコミットメッセージや不完全なコミットメッセージで変更をコミットした場合、git commit --amendを使ってメッセージを変更できます。
テキストエディタが開き、コミットメッセージを編集できます。

ただしすでに公開リポジトリにプッシュされているコミットを修正する場合は注意が必要です。

誤ってプッシュしたコミット

間違ってGitHubにプッシュしてしまった場合は、git revert <commit_id>を使って新しいコミットを作成し、間違ったコミットで行われたすべての変更を取り消すことができます。
これは既存のコミット履歴を変更しないので比較的安全な方法です。

より高度なGitコマンドを試す

Gitに慣れてきたらより高度な機能を持つコマンドを試すことをおすすめします。
例えば、git rebaseはブランチのベースをあるコミットから別のコミットに変更し、あたかも別のコミットからブランチを作成したかのように見せることができる強力なコマンドです。

$ git checkout feature-branch
$ git rebase main

もうひとつの便利なコマンドはgit stashで、すぐにコミットしたくない変更を一時的に保存しておきます。
このコマンドによって任意のタイミングで変更を適用できます。

$ git stash
# 別の変更を加える
$ git stash apply

高度なコマンドは強力ですが、注意深く使用しないと破壊的な力を発揮することがあります。
コマンドを実行する前に常にコマンドを理解していることを確認してください。

GitとGitHubの高度なコンセプトの探求

GitとGitHubの理解を深めれば、コーディングのワークフローを効率化するための豊富な機能をさらに多く発見できます。
例えば、Gitにはインタラクティブなステージング環境があり、次のコミットに選択的に変更を追加できます。このモードに入るにはgit add -iコマンドを使用します。この環境を使うことで、変更点の塊を直接編集できます。

$ git add -i
# 以下のようなプロンプトが表示されインタラクティブに操作できる
           staged     unstaged path
  1:    unchanged        +1/-1 sample.txt

*** Commands ***
  1: status	  2: update	  3: revert	  4: add untracked
  5: patch	  6: diff	  7: quit	  8: help
What now>

GitHubも基本的な機能だけでなく多くの機能を提供しています。
たとえば、GitHub Actionsを活用してCI/CDパイプラインなどのソフトウェアワークフローを自動化できます。また、GitHubのREST APIやGraphQL APIを使って、プログラム的にプラットフォームと対話することでニーズに合わせて機能拡張も可能です。

Star、Issues、Actions、GitHub PagesでGitHubを最大限に活用

GitHubは、Gitの機能をコラボレーションツールで拡張しています。

Starは、気になるリポジトリへ☆をつけることで最新の情報を受け取りやすくできます。 Issuesは、バグ、タスク、機能のディスカッションフォーラムとして機能します。
Actionsは、コードのテストからアプリケーションのデプロイまで、タスクの自動化を可能にします。
GitHub Pagesは、あなたのリポジトリから直接静的なWebサイトをホストします。

# Github Actionsのワークフロー例
name: CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run tests
        run: |
          make test

これらの機能を使いこなすことで、GitHubのプロジェクトを効率とコラボレーションの新たなレベルへと引き上げることができます。

Gitのワークフローとベストプラクティスを理解する

GitとGitHubのメリットを最大限に活かすには、確立されたベストプラクティスに従うことが肝要です。
一般的に、開発チームはFeature Branch WorkflowGitflow WorkflowForking Workflowなどのワークフローを採用して作業を整理しています。

# Feature Branch Workflowの例
$ git checkout -b feature_branch
# 作業する
$ git checkout main
$ git merge feature_branch

優れたコミットメッセージも重要です。
優れたコミットメッセージは簡潔で、何が変更されたかを含み、なぜその変更が必要だったのかを説明するものです。

リモートリポジトリから定期的にアップデートをpullして、常に最新の状態を保つことも推奨されます。これらのベストプラクティスを実践してGitとGitHubを使いこなし、ストレスフリーな開発体制を整備してください。

関連するコンテンツ