<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Git on AIによる技術記事 備忘録</title><link>https://ai.hack-le.com/tags/git/</link><description>Recent content in Git on AIによる技術記事 備忘録</description><generator>Hugo -- gohugo.io</generator><language>ja</language><lastBuildDate>Sat, 22 Aug 2026 10:31:20 +0900</lastBuildDate><atom:link href="https://ai.hack-le.com/tags/git/index.xml" rel="self" type="application/rss+xml"/><item><title>Giteaへの既存コードpushでrejectedエラーを解決する方法</title><link>https://ai.hack-le.com/gitea%E3%81%B8%E3%81%AE%E6%97%A2%E5%AD%98%E3%82%B3%E3%83%BC%E3%83%89push%E3%81%A7rejected%E3%82%A8%E3%83%A9%E3%83%BC%E3%82%92%E8%A7%A3%E6%B1%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/</link><pubDate>Thu, 11 Sep 2025 17:45:22 +0900</pubDate><guid>https://ai.hack-le.com/gitea%E3%81%B8%E3%81%AE%E6%97%A2%E5%AD%98%E3%82%B3%E3%83%BC%E3%83%89push%E3%81%A7rejected%E3%82%A8%E3%83%A9%E3%83%BC%E3%82%92%E8%A7%A3%E6%B1%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/</guid><description>&lt;p&gt;既存のローカルプロジェクトをGiteaサーバーにpushしようとした際、「Updates were rejected because the remote contains work that you do not have locally」エラーが発生した。このエラーの原因と解決方法について記録する。&lt;/p&gt;&#10;&lt;h2 id="再現環境"&gt;再現環境&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;ローカル環境：macOS&lt;/li&gt;&#10;&lt;li&gt;Git：既存のローカルリポジトリ（masterブランチ）&lt;/li&gt;&#10;&lt;li&gt;リモート：Giteaサーバー（プライベートネットワーク内）&lt;/li&gt;&#10;&lt;li&gt;接続方式：SSH&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="エラーの発生状況"&gt;エラーの発生状況&#10;&lt;/h2&gt;&lt;p&gt;実行したコマンド&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# リモートリポジトリを追加&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote add origin user@xxx.xxx.xxx.xxx:org/repository-name.git&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# pushを実行&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push -u origin master&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;発生したエラー&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;To xxx.xxx.xxx.xxx:org/repository-name.git&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ! [rejected] master -&amp;gt; master (fetch first)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;error: failed to push some refs to &amp;#39;xxx.xxx.xxx.xxx:org/repository-name.git&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hint: Updates were rejected because the remote contains work that you do not&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hint: have locally. This is usually caused by another repository pushing to&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hint: the same ref. If you want to integrate the remote changes, use&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hint: &amp;#39;git pull&amp;#39; before pushing again.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hint: See the &amp;#39;Note about fast-forwards&amp;#39; in &amp;#39;git push --help&amp;#39; for details.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="エラーの原因分析"&gt;エラーの原因分析&#10;&lt;/h2&gt;&lt;p&gt;このエラーが発生する主な原因は、リモートリポジトリとローカルリポジトリの履歴が一致していないことである。具体的には以下のケースが考えられる。&lt;/p&gt;&#10;&lt;h3 id="最も一般的な原因"&gt;最も一般的な原因&#10;&lt;/h3&gt;&lt;p&gt;Giteaでリポジトリを作成する際に「Initialize with README」オプションを有効にしたため、リモートリポジトリに初期コミット（README.md）が存在していた。一方、ローカルでは既存のプロジェクトを独立してgit管理していたため、両者に共通の祖先コミットが存在しない状態となった。&lt;/p&gt;&#10;&lt;h3 id="その他の原因"&gt;その他の原因&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;他の開発者が既にコミットをプッシュしている&lt;/li&gt;&#10;&lt;li&gt;複数の場所から同じリポジトリにプッシュを試行している&lt;/li&gt;&#10;&lt;li&gt;リモートリポジトリが予期せず変更されている&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="解決方法"&gt;解決方法&#10;&lt;/h2&gt;&lt;h3 id="手順1-リモートの変更を確認"&gt;手順1: リモートの変更を確認&#10;&lt;/h3&gt;&lt;p&gt;まず、リモートにどのような変更があるかを確認する。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git fetch origin&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log origin/master --oneline&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="手順2-無関係な履歴をマージしてpull"&gt;手順2: 無関係な履歴をマージしてpull&#10;&lt;/h3&gt;&lt;p&gt;以下のコマンドを実行して、無関係な履歴を統合する。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git pull origin master --allow-unrelated-histories --no-rebase&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="手順3-競合の解決必要な場合"&gt;手順3: 競合の解決（必要な場合）&#10;&lt;/h3&gt;&lt;p&gt;README.mdなどでマージ競合が発生した場合は、手動で解決する。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# 競合ファイルを編集後&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add .&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &amp;#34;Resolve merge conflicts&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="手順4-最終的なpush"&gt;手順4: 最終的なpush&#10;&lt;/h3&gt;&lt;p&gt;競合を解決できたら、改めてpushを実行する。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push origin master&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="予防方法"&gt;予防方法&#10;&lt;/h2&gt;&lt;p&gt;既存コードをpushする予定がある場合は、Giteaでリポジトリを作成する際に以下の自動生成オプションを無効にする。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;README.mdの自動生成&lt;/li&gt;&#10;&lt;li&gt;.gitignoreの自動生成&lt;/li&gt;&#10;&lt;li&gt;ライセンスファイルの自動生成&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;新規プロジェクトを開始する場合は、以下の手順を推奨する。&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Giteaで空のリポジトリを作成&lt;/li&gt;&#10;&lt;li&gt;ローカルでgit cloneを実行&lt;/li&gt;&#10;&lt;li&gt;cloneしたディレクトリ内で開発を開始&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;この方法により、最初から履歴が一致した状態で開発を進められる。&lt;/p&gt;&#10;&lt;h2 id="技術的背景"&gt;技術的背景&#10;&lt;/h2&gt;&lt;h3 id="allow-unrelated-historiesオプションについて"&gt;&amp;ndash;allow-unrelated-historiesオプションについて&#10;&lt;/h3&gt;&lt;p&gt;Gitは通常、共通の祖先を持たないブランチ同士のマージを拒否する。&lt;code&gt;--allow-unrelated-histories&lt;/code&gt;オプションは、この制限を解除して無関係な履歴同士をマージすることを可能にする。&lt;/p&gt;&#10;&lt;h3 id="プルストラテジーの選択"&gt;プルストラテジーの選択&#10;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;git pull&lt;/code&gt;コマンド実行時に以下のエラーが発生する場合がある。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hint: You have divergent branches and need to specify how to reconcile them.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この場合は、マージ戦略を明示的に指定する必要がある。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# マージ戦略を使用（推奨）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git pull origin master --allow-unrelated-histories --no-rebase&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# またはリベース戦略を使用&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git pull origin master --allow-unrelated-histories --rebase&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;マージ戦略を選択することで、両方の履歴が保持されたマージコミットが作成される。&lt;/p&gt;&#10;&lt;h2 id="まとめ"&gt;まとめ&#10;&lt;/h2&gt;&lt;p&gt;このエラーは、Git初心者が既存コードをリモートリポジトリにpushする際によく遭遇する問題である。根本的な原因は履歴の不一致であり、&lt;code&gt;--allow-unrelated-histories&lt;/code&gt;オプションを使用することで解決できる。&lt;/p&gt;&#10;&lt;p&gt;今後は、リポジトリ作成時の設定に注意を払い、適切なワークフローを選択することで、このような問題を予防できる。特に、既存プロジェクトをGitで管理し始める際は、リモートリポジトリを完全に空の状態で作成することが重要である。&lt;/p&gt;&#10;</description></item><item><title>一度コミットしたファイルを .gitignore に追加して追跡から外す手順</title><link>https://ai.hack-le.com/gitignore-cached/</link><pubDate>Sat, 21 Sep 2024 10:05:06 +0900</pubDate><guid>https://ai.hack-le.com/gitignore-cached/</guid><description>&lt;p&gt;プロジェクトの開発中に、一時的なファイルやビルドアーティファクトを誤って Git にコミットしてしまうことがあります。通常、これらのファイルは &lt;code&gt;.gitignore&lt;/code&gt; に追加してリポジトリに含めないようにするのが一般的ですが、既にコミットされている場合、追跡から外す必要があります。&lt;/p&gt;&#10;&lt;h2 id="手順"&gt;手順&#10;&lt;/h2&gt;&lt;h3 id="gitignore-にファイルやフォルダを追加する"&gt;&lt;code&gt;.gitignore&lt;/code&gt; にファイルやフォルダを追加する&#10;&lt;/h3&gt;&lt;p&gt;まず、追跡したくないファイルやフォルダを &lt;code&gt;.gitignore&lt;/code&gt; に追加します。たとえば、ビルドアーティファクトや一時ファイルを無視する場合は、以下のように記述します。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# 追跡しないファイルやフォルダを指定&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;build/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;temp/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;.env&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;.gitignore&lt;/code&gt; に追加することで、今後これらのファイルやフォルダは新たに Git の追跡対象から外されますが、既にコミットされたものは追跡されたままです。&lt;/p&gt;&#10;&lt;h3 id="既に追跡されているファイルやフォルダをインデックスから削除"&gt;既に追跡されているファイルやフォルダをインデックスから削除&#10;&lt;/h3&gt;&lt;p&gt;既にコミットされているファイルやフォルダを Git の追跡から外すには、以下のコマンドを実行してインデックスから削除します。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git rm -r --cached &amp;lt;ファイル名またはフォルダ名&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;&amp;lt;ファイル名またはフォルダ名&amp;gt;&lt;/code&gt; の部分には、追跡から外したいファイルやフォルダのパスを指定します。&lt;code&gt;--cached&lt;/code&gt; オプションを付けることで、ローカルのファイルは削除されず、Git の追跡からのみ外れます。&lt;/p&gt;&#10;&lt;p&gt;例として、ビルドディレクトリ &lt;code&gt;build/&lt;/code&gt; を追跡から外す場合は次のようにします。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git rm -r --cached build/&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="変更をコミット"&gt;変更をコミット&#10;&lt;/h3&gt;&lt;p&gt;インデックスから削除したファイルやフォルダの変更をコミットします。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &amp;#34;Remove build directory from tracking&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで、指定したファイルやフォルダは Git で追跡されなくなります。&lt;/p&gt;&#10;&lt;h3 id="リモートにプッシュ"&gt;リモートにプッシュ&#10;&lt;/h3&gt;&lt;p&gt;最後に、変更をリモートリポジトリにプッシュします。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push origin &amp;lt;your-branch&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;&amp;lt;your-branch&amp;gt;&lt;/code&gt; の部分には作業中のブランチ名を指定します。&lt;/p&gt;&#10;&lt;h2 id="まとめ"&gt;まとめ&#10;&lt;/h2&gt;&lt;p&gt;誤ってコミットしてしまった一時ファイルやビルドアーティファクトを Git の追跡から外す際は、次の手順を覚えておくと便利です。&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;code&gt;.gitignore&lt;/code&gt; に無視するファイルやフォルダを追加&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;git rm --cached&lt;/code&gt; コマンドでインデックスから削除&lt;/li&gt;&#10;&lt;li&gt;変更をコミットしてリモートにプッシュ&lt;/li&gt;&#10;&lt;/ol&gt;&#10;</description></item><item><title>ディレクトリベースで複数のGitHubアカウントを管理する方法</title><link>https://ai.hack-le.com/directory-github/</link><pubDate>Thu, 04 Jul 2024 18:56:23 +0900</pubDate><guid>https://ai.hack-le.com/directory-github/</guid><description>&lt;p&gt;この記事では、個人用と仕事用のGitHubアカウントを、プロジェクトディレクトリごとに自動的に切り替えて使用する方法を詳しく解説します。具体的には、&lt;code&gt;~/projects/personal&lt;/code&gt; ディレクトリ下のプロジェクトでは個人のGitHubアカウントを使用し、&lt;code&gt;~/projects/work&lt;/code&gt; ディレクトリ下では仕事用のアカウントを使用する状況を想定します。コマンドラインでのGit操作だけでなく、VSCodeなどのIDEでも適用されるようにします。&lt;/p&gt;&#10;&lt;h2 id="前提条件"&gt;前提条件&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;Gitの基本的な知識があること。&lt;/li&gt;&#10;&lt;li&gt;アカウントごとにSSHキーを生成しており、それぞれのGitHubアカウントに登録していること。&lt;/li&gt;&#10;&lt;li&gt;基本的なGit操作に慣れていること。&lt;/li&gt;&#10;&lt;li&gt;Git 2.13以降であること。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="git設定の基本"&gt;Git設定の基本&#10;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;.gitconfig&lt;/code&gt;ファイルはGitの設定を管理するための中心的なファイルで、ユーザ名やメールアドレス、エイリアス、スクリプトの実行設定などを含みます。全体的なユーザー設定（グローバル設定）は通常、ユーザのホームディレクトリに位置する&lt;code&gt;.gitconfig&lt;/code&gt;ファイルに記述されます。&lt;/p&gt;&#10;&lt;h3 id="ディレクトリごとのgit設定"&gt;ディレクトリごとのGit設定&#10;&lt;/h3&gt;&lt;p&gt;Git 2.13以上では、&lt;code&gt;includeIf&lt;/code&gt;ディレクティブを使用して、特定のディレクトリに基づいてGit設定を動的に適用することができます。これを利用して、異なるプロジェクトディレクトリで異なるGitHubアカウントを使い分ける設定を行います。&lt;/p&gt;&#10;&lt;h4 id="基本的なgitconfig設定"&gt;基本的な&lt;code&gt;.gitconfig&lt;/code&gt;設定&#10;&lt;/h4&gt;&lt;p&gt;ホームディレクトリの&lt;code&gt;.gitconfig&lt;/code&gt;に以下の設定を追加します。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[user]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; name = default_name&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; email = default_email@example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[includeIf &amp;#34;gitdir:~/projects/personal/&amp;#34;]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; path = ~/.gitconfig-personal&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[includeIf &amp;#34;gitdir:~/projects/work/&amp;#34;]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; path = ~/.gitconfig-work&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="各ディレクトリ用のgitconfigファイル"&gt;各ディレクトリ用の&lt;code&gt;.gitconfig&lt;/code&gt;ファイル&#10;&lt;/h4&gt;&lt;p&gt;&lt;code&gt;~/.gitconfig-personal&lt;/code&gt;ファイルには次のように記述します：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[user]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; name = personal_username&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; email = personal_email@example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[core]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sshCommand = &amp;#34;ssh -i ~/.ssh/id_rsa_personal -F /dev/null&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;~/.gitconfig-work&lt;/code&gt;ファイルには次のように記述します：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[user]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; name = work_username&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; email = work_email@example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[core]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sshCommand = &amp;#34;ssh -i ~/.ssh/id_rsa_work -F /dev/null&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="まとめ"&gt;まとめ&#10;&lt;/h2&gt;&lt;p&gt;ディレクトリベースでGitHubアカウントを管理することで、複数のアカウントを効率的かつ安全に運用することが可能です。設定は初めに少し時間がかかりますが、一度設定してしまえば、その後は自動で適切なアカウントが使用されるため、非常に便利です。&lt;/p&gt;&#10;</description></item><item><title>pre-commitでGitのコミットメッセージのプレフィックスをチェックする</title><link>https://ai.hack-le.com/pre-commit-git/</link><pubDate>Wed, 15 Nov 2023 17:11:39 +0900</pubDate><guid>https://ai.hack-le.com/pre-commit-git/</guid><description>&lt;h2 id="はじめに"&gt;はじめに&#10;&lt;/h2&gt;&lt;p&gt;現代のソフトウェア開発では、コードの品質を維持することが非常に重要です。そのためには、バージョン管理システムであるGitを効果的に活用し、特にコミットプロセスを最適化する必要があります。このブログ記事では、&lt;code&gt;pre-commit&lt;/code&gt;を使用してコミットメッセージにプレフィックスを確認する方法について解説します。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;pre-commit&lt;/code&gt;は、Gitのコミット前に自動的に実行されるフックを設定するためのツールです。これにより、コードのスタイルチェック、テストの実行、その他の重要な検証が可能となります。特に、コミットメッセージに適切なプレフィックス（例えば&lt;code&gt;feat&lt;/code&gt;、&lt;code&gt;fix&lt;/code&gt;、&lt;code&gt;docs&lt;/code&gt;など）が含まれているかどうかを自動的に確認することは、プロジェクトの整理と追跡を容易にし、チームメンバー間のコミュニケーションを明確にします。&lt;/p&gt;&#10;&lt;p&gt;この記事では、&lt;code&gt;pre-commit&lt;/code&gt;の基本的なセットアップからカスタムスクリプトの作成、そして実際の統合に至るまでのプロセスを段階的に説明します。&lt;/p&gt;&#10;&lt;h2 id="コミットメッセージのプレフィックスの重要性"&gt;コミットメッセージのプレフィックスの重要性&#10;&lt;/h2&gt;&lt;h3 id="コミットメッセージの役割"&gt;コミットメッセージの役割&#10;&lt;/h3&gt;&lt;p&gt;コミットメッセージは、ソフトウェア開発におけるコミュニケーションの基本的な要素です。これらのメッセージは、変更内容を要約し、他の開発者や将来の自分自身がコードの変更点を理解しやすくするために使われます。良いコミットメッセージは、プロジェクトの履歴を追跡しやすくし、特定の変更を見つけ出す際の手がかりとなります。&lt;/p&gt;&#10;&lt;h3 id="プレフィックスの役割"&gt;プレフィックスの役割&#10;&lt;/h3&gt;&lt;p&gt;コミットメッセージにプレフィックスを含めることは、変更の種類を明確にし、プロジェクトの管理を効率化します。例えば、&lt;code&gt;feat&lt;/code&gt;は新機能を、&lt;code&gt;fix&lt;/code&gt;はバグ修正を、&lt;code&gt;docs&lt;/code&gt;はドキュメントの更新を示します。これらのプレフィックスは、コードレビューや履歴の追跡を行う際に、どのような種類の変更が含まれているかを瞬時に理解するのに役立ちます。&lt;/p&gt;&#10;&lt;h3 id="一般的なプレフィックス"&gt;一般的なプレフィックス&#10;&lt;/h3&gt;&lt;p&gt;プロジェクトによって異なることはありますが、一般的には以下のようなプレフィックスが使われます：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;feat&lt;/code&gt;: 新機能の追加&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;fix&lt;/code&gt;: バグの修正&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;docs&lt;/code&gt;: ドキュメントの変更&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;style&lt;/code&gt;: コードのフォーマットやスタイルの変更&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;refactor&lt;/code&gt;: コードのリファクタリング&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;test&lt;/code&gt;: テスト関連の変更&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;これらのプレフィックスを使うことで、コミットメッセージがより情報豊かで、プロジェクトの管理がより容易になります。次のセクションでは、&lt;code&gt;pre-commit&lt;/code&gt;をセットアップし、これらのプレフィックスを自動的にチェックする方法について詳しく説明します。&lt;/p&gt;&#10;&lt;h2 id="pre-commitのセットアップ"&gt;&lt;code&gt;pre-commit&lt;/code&gt;のセットアップ&#10;&lt;/h2&gt;&lt;h3 id="pre-commitのインストール"&gt;&lt;code&gt;pre-commit&lt;/code&gt;のインストール&#10;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;pre-commit&lt;/code&gt;は、開発プロセスを自動化し、コード品質を維持するための強力なツールです。まずは、&lt;code&gt;pre-commit&lt;/code&gt;をインストールする必要があります。Pythonがシステムにインストールされている場合、以下のコマンドで&lt;code&gt;pre-commit&lt;/code&gt;をインストールできます：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install pre-commit&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このコマンドは、&lt;code&gt;pre-commit&lt;/code&gt;をグローバルにインストールし、任意のGitリポジトリで使用できるようにします。&lt;/p&gt;&#10;&lt;h3 id="pre-commit-configyamlファイルの設定"&gt;&lt;code&gt;.pre-commit-config.yaml&lt;/code&gt;ファイルの設定&#10;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;pre-commit&lt;/code&gt;を使用するには、リポジトリのルートに&lt;code&gt;.pre-commit-config.yaml&lt;/code&gt;ファイルを作成し、必要な設定を記述する必要があります。このファイルは&lt;code&gt;pre-commit&lt;/code&gt;フックの動作を定義し、どのフックをいつ実行するかを指定します。&lt;/p&gt;&#10;&lt;p&gt;ここでは、例として、基本的な&lt;code&gt;pre-commit&lt;/code&gt;設定を以下に示します：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- &lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://github.com/pre-commit/pre-commit-hooks&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rev&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.4.0 &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# フックのバージョンを指定&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;check-yaml&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;end-of-file-fixer&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この設定例では、公式の&lt;code&gt;pre-commit-hooks&lt;/code&gt;リポジトリからいくつかの基本的なフックを使用しています。各フックは特定のタスクを実行し、コードの品質を向上させるのに役立ちます。&lt;/p&gt;&#10;&lt;h3 id="pre-commitフックのインストール"&gt;&lt;code&gt;pre-commit&lt;/code&gt;フックのインストール&#10;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;.pre-commit-config.yaml&lt;/code&gt;ファイルを設定した後、次のコマンドを使用して&lt;code&gt;pre-commit&lt;/code&gt;フックをリポジトリにインストールします：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pre-commit install&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このコマンドは、Gitの&lt;code&gt;pre-commit&lt;/code&gt;フックとして&lt;code&gt;pre-commit&lt;/code&gt;を設定し、コミットを行う際に自動的にこれらのフックが実行されるようにします。&lt;/p&gt;&#10;&lt;p&gt;次のセクションでは、コミットメッセージのプレフィックスをチェックするためのカスタムスクリプトの作成について詳しく説明します。&lt;/p&gt;&#10;&lt;h2 id="カスタムスクリプトの作成"&gt;カスタムスクリプトの作成&#10;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;pre-commit&lt;/code&gt;を使用してコミットメッセージのプレフィックスをチェックするためには、カスタムスクリプトを作成し、それを&lt;code&gt;pre-commit&lt;/code&gt;設定に組み込む必要があります。&lt;/p&gt;&#10;&lt;h3 id="スクリプトの作成"&gt;スクリプトの作成&#10;&lt;/h3&gt;&lt;p&gt;プレフィックスをチェックするスクリプトは、シェルスクリプト（Bashスクリプトなど）で書くことができます。以下は、コミットメッセージが特定のプレフィックスで始まっているかどうかをチェックする簡単なスクリプトの例です：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;commit_regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;^(feat|fix|docs|style|refactor|test|chore):&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;error_msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;エラー: コミットメッセージは &amp;#39;feat|fix|docs|style|refactor|test|chore:&amp;#39; のいずれかで始まる必要があります。&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; ! grep -qE &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$commit_regex&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$error_msg&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このスクリプトは、コミットメッセージが&lt;code&gt;feat&lt;/code&gt;, &lt;code&gt;fix&lt;/code&gt;, &lt;code&gt;docs&lt;/code&gt;, &lt;code&gt;style&lt;/code&gt;, &lt;code&gt;refactor&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;, &lt;code&gt;chore&lt;/code&gt;のいずれかで始まっていることを確認します。そうでない場合、エラーメッセージを表示し、コミットを拒否します。&lt;/p&gt;&#10;&lt;h3 id="スクリプトのテスト"&gt;スクリプトのテスト&#10;&lt;/h3&gt;&lt;p&gt;スクリプトを作成したら、適切に動作するかどうかをテストすることが重要です。スクリプトをリポジトリのルートに保存し（例：&lt;code&gt;commit-msg-lint.sh&lt;/code&gt;）、実行可能にします：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod +x commit-msg-lint.sh&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;そして、異なるコミットメッセージを使ってスクリプトが正しく動作するかを確認します。&lt;/p&gt;&#10;&lt;h3 id="pre-commitにスクリプトを組み込む"&gt;&lt;code&gt;pre-commit&lt;/code&gt;にスクリプトを組み込む&#10;&lt;/h3&gt;&lt;p&gt;カスタムスクリプトを&lt;code&gt;pre-commit&lt;/code&gt;に組み込むには、&lt;code&gt;.pre-commit-config.yaml&lt;/code&gt;ファイルにスクリプトを追加します。以下はその設定例です：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- &lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;commit-msg-lint&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Check commit message format&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./commit-msg-lint.sh&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;script&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;commit-msg]&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この設定により、&lt;code&gt;pre-commit&lt;/code&gt;がコミットメッセージをチェックする際にカスタムスクリプトが実行されます。&lt;/p&gt;&#10;&lt;p&gt;次のセクションでは、&lt;code&gt;pre-commit&lt;/code&gt;の使用において遭遇する可能性がある一般的なトラブルシューティングについて説明します。&lt;/p&gt;&#10;&lt;h2 id="pre-commitにおけるトラブルシューティング"&gt;&lt;code&gt;pre-commit&lt;/code&gt;におけるトラブルシューティング&#10;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;pre-commit&lt;/code&gt;を使用する際には、いくつかの一般的な問題に直面することがあります。ここでは、これらの問題のいくつかとその解決策について説明します。&lt;/p&gt;&#10;&lt;h3 id="スクリプトが実行不可能な場合"&gt;スクリプトが実行不可能な場合&#10;&lt;/h3&gt;&lt;p&gt;時折、&lt;code&gt;pre-commit&lt;/code&gt;がカスタムスクリプトを実行不可能と認識することがあります。この問題は、スクリプトに適切な実行権限が設定されていない場合に発生することが多いです。スクリプトに実行権限を与えるには、次のコマンドを使用します：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod +x commit-msg-lint.sh&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで、スクリプトは実行可能になります。しかし、これだけでは不十分な場合もあります。Gitのインデックスとファイルシステムの間で実行権限の不一致が生じている場合、&lt;code&gt;git update-index&lt;/code&gt;コマンドを使用してこの問題を解決することができます：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git update-index --chmod&lt;span class="o"&gt;=&lt;/span&gt;+x commit-msg-lint.sh&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="他の一般的な問題"&gt;他の一般的な問題&#10;&lt;/h3&gt;&lt;p&gt;他にも、設定ファイルの誤りや、&lt;code&gt;pre-commit&lt;/code&gt;フックの不適切な設定など、さまざまな問題が発生する可能性があります。これらの問題を解決するには、以下のステップを試みてください：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;.pre-commit-config.yaml&lt;/code&gt; ファイルの設定を再確認し、構文エラーがないかチェックします。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;pre-commit&lt;/code&gt;フックを再インストールします：&lt;code&gt;pre-commit install&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;詳細なエラーメッセージを確認し、具体的な問題の原因を特定します。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;これらの一般的なトラブルシューティング手法を試みることで、ほとんどの問題は解決できるはずです。&lt;/p&gt;&#10;&lt;p&gt;次のセクションでは、&lt;code&gt;pre-commit&lt;/code&gt;の使用におけるベストプラクティスと結論について説明します。&lt;/p&gt;&#10;&lt;h2 id="結論とベストプラクティス"&gt;結論とベストプラクティス&#10;&lt;/h2&gt;&lt;h3 id="pre-commitの有効活用"&gt;&lt;code&gt;pre-commit&lt;/code&gt;の有効活用&#10;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;pre-commit&lt;/code&gt;を使用することで、コードの品質を維持し、開発プロセスを効率化することが可能です。特に、コミットメッセージのプレフィックスを自動的にチェックすることにより、プロジェクトの整理と追跡が容易になります。以下は&lt;code&gt;pre-commit&lt;/code&gt;を最大限に活用するためのいくつかのベストプラクティスです：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;明確なプレフィックスの規則を設定する&lt;/strong&gt;：プロジェクトのニーズに合わせて、明確なプレフィックスの規則を設定し、チーム全体で共有します。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;カスタムフックを適切にテストする&lt;/strong&gt;：新しいフックを追加する際は、適切にテストを行い、予期しない挙動がないことを確認します。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;ドキュメントを整備する&lt;/strong&gt;：&lt;code&gt;pre-commit&lt;/code&gt;の設定や使用するフックに関するドキュメントを整備し、新しいチームメンバーが迅速に理解できるようにします。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="コード品質の維持の重要性"&gt;コード品質の維持の重要性&#10;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;pre-commit&lt;/code&gt;は、コードレビューの負担を軽減し、品質を一定の水準で保つのに役立ちます。自動化されたチェックを導入することで、コーディング規約の遵守、バグの早期発見、一貫性のあるコミットメッセージの作成など、多くの利点があります。&lt;/p&gt;&#10;&lt;h3 id="最後に"&gt;最後に&#10;&lt;/h3&gt;&lt;p&gt;この記事では、&lt;code&gt;pre-commit&lt;/code&gt;を使用してコミットメッセージのプレフィックスをチェックする方法について解説しました。適切なツールとプロセスを取り入れることで、開発プロジェクトの効率と品質を同時に高めることが可能です。これらのプラクティスを活用して、より良いソフトウェア開発を目指しましょう。&lt;/p&gt;&#10;</description></item><item><title>Gitの”Executable … not executable”エラー: 原因と解決法</title><link>https://ai.hack-le.com/git-executable-xxx-not-executable/</link><pubDate>Wed, 15 Nov 2023 16:21:47 +0900</pubDate><guid>https://ai.hack-le.com/git-executable-xxx-not-executable/</guid><description>&lt;h2 id="はじめに"&gt;はじめに&#10;&lt;/h2&gt;&lt;p&gt;Gitと&lt;code&gt;pre-commit&lt;/code&gt;は、現代のソフトウェア開発プロセスにおいて中心的な役割を果たしています。これらのツールを使うことで、開発の効率を高めながらもコードの品質を維持することができます。しかし、これらを日常的に使用する中で、予期しない問題に遭遇することもあります。今回の記事では、そんな一つの典型的な問題、「Executable &lt;code&gt;/path/to/your-script.sh&lt;/code&gt; is not executable」というエラーメッセージに遭遇した際の解決方法を掘り下げます。&lt;/p&gt;&#10;&lt;p&gt;この問題は、Gitリポジトリ内のスクリプトファイルに適切な実行権限が設定されているにも関わらず、&lt;code&gt;pre-commit&lt;/code&gt;フックがそのファイルを実行不可能とみなす状況を指します。それでは、このエラーがどのような状況で発生するのか、見ていきましょう&lt;/p&gt;&#10;&lt;h2 id="背景"&gt;背景&#10;&lt;/h2&gt;&lt;h3 id="gitとpre-commitの基本"&gt;Gitと&lt;code&gt;pre-commit&lt;/code&gt;の基本&#10;&lt;/h3&gt;&lt;p&gt;Gitは、ソースコードのバージョン管理に広く使用されているシステムです。それに対して&lt;code&gt;pre-commit&lt;/code&gt;は、Gitのコミットプロセスにフック（カスタムスクリプト）を組み込むためのツールで、コードの品質を確保するための自動化されたチェックを提供します。これらのフックは、コードがリポジトリにコミットされる前に様々なタイプの検証を行います。&lt;/p&gt;&#10;&lt;h3 id="実行権限の重要性"&gt;実行権限の重要性&#10;&lt;/h3&gt;&lt;p&gt;UNIX系オペレーティングシステム（LinuxやmacOSを含む）では、ファイルの実行権限は非常に重要です。スクリプトやプログラムが実行されるためには、適切な実行権限が設定されている必要があります。この権限は、ファイルシステム上で&lt;code&gt;chmod&lt;/code&gt;コマンドを使って設定されます。&lt;/p&gt;&#10;&lt;h3 id="gitの実行権限の取り扱い"&gt;Gitの実行権限の取り扱い&#10;&lt;/h3&gt;&lt;p&gt;Gitは、ファイルの内容と共に、その実行権限の状態も追跡します。しかし、Gitのインデックス（ステージングエリア）とローカルファイルシステムの間で実行権限の状態に不一致が生じることがあります。特に、異なる環境やファイルシステム間でGitリポジトリが共有される場合、この問題はより複雑になることがあります。&lt;/p&gt;&#10;&lt;h3 id="問題の全体像"&gt;問題の全体像&#10;&lt;/h3&gt;&lt;p&gt;この背景において、&lt;code&gt;Executable not executable&lt;/code&gt;というエラーメッセージは、Gitがスクリプトファイルの実行権限を正しく認識していない場合に発生します。これは、&lt;code&gt;pre-commit&lt;/code&gt; などのツールがスクリプトを実行しようとした際に特に顕著になります。この問題を解決するためには、Gitのインデックスとローカルファイルシステムの間の実行権限の状態を同期させる必要があります。&lt;/p&gt;&#10;&lt;h2 id="問題の詳細"&gt;問題の詳細&#10;&lt;/h2&gt;&lt;p&gt;開発者として、私たちは頻繁にコードの品質を確保し、バグを未然に防ぐために&lt;code&gt;pre-commit&lt;/code&gt;フックを利用します。ある日、私は自分のプロジェクトにカスタムの&lt;code&gt;pre-commit&lt;/code&gt;フックを追加しようとしました。このフックは、コミットメッセージが特定のフォーマットに従っているかどうかをチェックするものでした。&lt;/p&gt;&#10;&lt;p&gt;しかし、このフックを追加した後、コミットしようとすると次のようなエラーメッセージが表示されました：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Executable `/path/to/your-script.sh` is not executable&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このエラーメッセージは、私のスクリプトが実行不可能とみなされていることを示していました。しかし、ファイルには明らかに実行権限が与えられていました。これは、特に混乱を招く問題でした。&lt;/p&gt;&#10;&lt;h2 id="最初のトラブルシューティングの試み"&gt;最初のトラブルシューティングの試み&#10;&lt;/h2&gt;&lt;p&gt;問題の解決に取り組むため、まずは基本的なトラブルシューティングから始めました。最初のステップとして、スクリプトファイルの実行権限を確認しました。ターミナルで以下のコマンドを実行しました：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -l /path/to/your-script.sh&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;結果は、ファイルが実行権限を持っていることを示していました（&lt;code&gt;-rwxr-xr-x&lt;/code&gt;）。次に、Gitの&lt;code&gt;core.fileMode&lt;/code&gt;設定がファイルの実行権限を正しく追跡しているかどうかを確認しました。この設定は、Gitがファイルの実行権限の変更を検出するかどうかを決定します。&lt;/p&gt;&#10;&lt;p&gt;しかし、これらの基本的なチェックにも関わらず、問題は解決しませんでした。ファイルには明らかに実行権限が付与されているにもかかわらず、&lt;code&gt;pre-commit&lt;/code&gt;は依然としてスクリプトを実行不可能と認識していました。この時点で、問題がもう少し複雑なものであることが明らかになりました。&lt;/p&gt;&#10;&lt;h2 id="解決策git-update-index---chmodx"&gt;解決策：&lt;code&gt;git update-index --chmod=+x&lt;/code&gt;&#10;&lt;/h2&gt;&lt;p&gt;最初のトラブルシューティングのステップが効果を示さなかった後、さらに深く問題を掘り下げました。調査の結果、Gitのインデックスとファイルシステムの間で実行権限の状態に不一致が生じている可能性が浮上しました。この不一致を解消するために、&lt;code&gt;git update-index --chmod=+x&lt;/code&gt; コマンドを使用することにしました。&lt;/p&gt;&#10;&lt;p&gt;このコマンドは、Gitに対して特定のファイルに実行権限があることを明示的に指示します。コマンドを実行することで、Gitのインデックスが更新され、ファイルが実行可能として認識されるようになります。以下のコマンドを実行しました：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git update-index --chmod&lt;span class="o"&gt;=&lt;/span&gt;+x /path/to/your-script.sh&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このコマンドを実行した後、再びコミットを試みると、今度は成功しました。エラーメッセージは消え、&lt;code&gt;pre-commit&lt;/code&gt; フックが正常に実行されました。&lt;/p&gt;&#10;&lt;h2 id="なぜこのコマンドが効果的だったのか"&gt;なぜこのコマンドが効果的だったのか&#10;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git update-index --chmod=+x&lt;/code&gt; コマンドが効果的だった理由は、Gitのインデックスがローカルのファイルシステムの状態と同期していなかったためです。通常、Gitはファイルの内容とメタデータ（この場合は実行権限）を追跡しますが、特定の状況下ではこれらの情報が不一致になることがあります。このコマンドによって、Gitの内部状態が強制的に更新され、スクリプトが実行可能であるという情報がGitのインデックスに正しく反映されました。&lt;/p&gt;&#10;&lt;p&gt;この経験から、特に複数の環境やファイルシステムを跨いで作業する場合には、Gitのインデックスとローカルのファイルシステムの間で生じる可能性のある不一致に注意が必要であることがわかりました。&lt;/p&gt;&#10;&lt;h2 id="他の関連する問題への適用"&gt;他の関連する問題への適用&#10;&lt;/h2&gt;&lt;p&gt;この問題とその解決策は、特定の状況に限定されるものではありません。実際、異なるオペレーティングシステムやGitの設定、さらには異なるバージョンのGitを使用する際にも類似の問題が発生する可能性があります。特に、チーム内で複数の開発環境が混在している場合、Gitのインデックスとファイルシステム間の不一致は一般的な問題となり得ます。&lt;/p&gt;&#10;&lt;p&gt;また、この問題は&lt;code&gt;pre-commit&lt;/code&gt;フックに限定されず、他のGitフックやスクリプト実行の文脈でも発生する可能性があります。そのため、Gitの実行権限に関連するエラーに直面した場合は、&lt;code&gt;git update-index --chmod=+x&lt;/code&gt; コマンドの使用を検討することが有益です。&lt;/p&gt;&#10;&lt;h2 id="結論"&gt;結論&#10;&lt;/h2&gt;&lt;p&gt;この経験から、私たちはGitと&lt;code&gt;pre-commit&lt;/code&gt;の使用におけるいくつかの重要な教訓を学びました。最も重要なのは、Gitのインデックスとローカルのファイルシステムの間に生じる可能性のある不一致に注意を払うことです。また、標準的なトラブルシューティング手法が効果を示さない場合でも、Gitのより高度な機能やコマンドを使用して問題を解決する方法が存在することを理解することも重要です。&lt;/p&gt;&#10;&lt;p&gt;最後に、この問題は、開発者が遭遇する可能性のある一連の問題の一例に過ぎません。技術的な問題に直面した際には、根気強く原因を探求し、コミュニティやドキュメントからのサポートを活用することが不可欠です。このような経験は、技術的スキルの向上だけでなく、より良い開発者に成長するための道の一部です。&lt;/p&gt;&#10;&lt;h2 id="参考リンク"&gt;参考リンク&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a class="link" href="https://github.com/asottile" target="_blank" rel="noopener"&#10; &gt;&amp;ldquo;Executable &amp;hellip; is not executable&amp;rdquo; error · Issue #1514 · pre-commit/pre-commit&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;</description></item><item><title>メタデータを含まないGitHub.comからGitHub Enterpriseへのリポジトリ移行ガイド</title><link>https://ai.hack-le.com/github-com-github-enterprise/</link><pubDate>Tue, 14 Nov 2023 13:29:37 +0900</pubDate><guid>https://ai.hack-le.com/github-com-github-enterprise/</guid><description>&lt;p&gt;&lt;strong&gt;導入&lt;/strong&gt;: GitHubからGitHub Enterpriseへのリポジトリ移行の際は、まずメタデータの移行をするかどうかが重要な判断となります。GitHubリポジトリのメタデータ（Issueやプルリクエストなど）の移行を行うかどうかを判断する際に考慮すべきポイントは以下の通りです：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;プロジェクトの歴史の重要性&lt;/strong&gt;: 過去のIssueやプルリクエストが将来のプロジェクト運営に重要な情報を含んでいる場合、これらのデータを移行する価値があります。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;プロジェクトの継続性&lt;/strong&gt;: 新しい環境でのプロジェクトの継続性を保つために、過去の議論や決定の履歴を参照できることが重要な場合は、メタデータの移行を検討すべきです。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;リソースと技術力&lt;/strong&gt;: メタデータの移行は複雑で時間とリソースを要するプロセスです。十分な技術力とリソースがあるかどうかを評価してください。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;プロジェクトの将来計画&lt;/strong&gt;: プロジェクトが新しいフェーズに入っており、過去のデータがそれほど関連性を持たない場合、メタデータの移行は必要ないかもしれません。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;これらの要素を総合的に検討し、プロジェクトのニーズとリソースに基づいて決定を下すことが重要です。&lt;/p&gt;&#10;&lt;p&gt;Issueやプルリクエスト（PR）などのメタデータを含まなくてよい場合、移行は比較的簡単なプロセスです。ここでは、コードとコミット履歴のみを移行する手順を詳細に説明します。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;手順&lt;/strong&gt;:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;新しいリポジトリの作成&lt;/strong&gt;:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;GitHub Enterpriseにログインし、新しいリポジトリを作成します。このリポジトリは空である必要があります。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ol start="2"&gt;&#10;&lt;li&gt;&lt;strong&gt;ローカルリポジトリの準備&lt;/strong&gt;:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;移行するローカルリポジトリで作業している場合、最新の状態に更新しておきます（&lt;code&gt;git pull&lt;/code&gt;）。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ol start="3"&gt;&#10;&lt;li&gt;&lt;strong&gt;リモートURLの変更&lt;/strong&gt;:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;リポジトリのリモートURLをGitHub Enterpriseの新しいリポジトリURLに変更します。これには&lt;code&gt;git remote set-url origin [新しいURL]&lt;/code&gt;コマンドを使用します。（ &lt;code&gt;.git/config&lt;/code&gt;を参照することで変更を確認できます）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ol start="4"&gt;&#10;&lt;li&gt;&lt;strong&gt;コードのプッシュ&lt;/strong&gt;:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;git push -u origin master&lt;/code&gt;（または対象のブランチ名）を使用して、コードを新しいリポジトリにプッシュします。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;チームメンバーへの指示&lt;/strong&gt;:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;チームの他のメンバーも、自分のローカルリポジトリで同じリモートURLの変更を行う必要があります。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;注意点&lt;/strong&gt;:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;この方法では、コードとコミット履歴のみが移行されます。GitHubのメタデータ（Issue、PRなど）は移行されません。これらの情報を移行したい場合は、追加の手順が必要です。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;結論&lt;/strong&gt;: GitHub.comからGitHub Enterpriseへのリポジトリ移行は、上記の手順を実行することで、簡単かつ効率的に行うことができます。ただし、プロジェクトの要件に応じて、メタデータの移行も検討してください。&lt;/p&gt;&#10;</description></item></channel></rss>