セットアップと設定
プロジェクトの取得と作成
基本的なスナップショット
ブランチとマージ
プロジェクトの共有と更新
検査と比較
パッチ適用
デバッグ
メール
外部システム
サーバー管理
- 2.46.1 → 2.50.1 変更なし
-
2.46.0
2024-07-29
- 2.34.1 → 2.45.4 変更なし
-
2.34.0
2021-11-15
- 2.29.1 → 2.33.8 変更なし
-
2.29.0
2020-10-19
- 2.27.1 → 2.28.1 変更なし
-
2.27.0
2020-06-01
説明
この FAQ の例は、bash
や dash
のような標準的な POSIX シェルと、ホスティングプロバイダー git.example.org
に author
アカウントを持つユーザー A U Thor を想定しています。
設定
user.name
には何を入れるべきですか?-
一般的に、与えられた名前と姓を使った形式で、あなたの個人名を入れるべきです。例えば、Git の現在のメンテナは「Junio C Hamano」を使用しています。これは、あなたが行うすべてのコミットに保存される名前の部分になります。
この設定はリモートサービスへの認証には影響しません。それについては、git-config[1] の
credential.username
を参照してください。
http.postBuffer
は実際には何をするのですか?-
このオプションは、Git が HTTP または HTTPS 経由でリモートにデータをプッシュする際に使用するバッファのサイズを変更します。データがこのサイズより大きい場合、Git の HTTP サポートを処理する libcurl は、プッシュされるデータのサイズが事前にわからないため、チャンク転送エンコーディングを使用します。
リモートサーバーまたは途中のプロキシが HTTP/1.1 (チャンク転送エンコーディングを導入したもの) をサポートしていないか、チャンクデータで壊れていることが分かっている場合を除き、この値をデフォルトのサイズにしても問題ありません。これは一般的なプッシュの問題に対する解決策として (誤って) 提案されることが多いですが、ほとんどすべてのサーバーとプロキシが少なくとも HTTP/1.1 をサポートしているため、この値を大きくしてもほとんどのプッシュの問題は解決しません。HTTP/1.1 とチャンク転送エンコーディングを正しくサポートしていないサーバーやプロキシは、今日のインターネットでは多くのトラフィックを破壊するため、あまり有用ではありません。
この値を増やすと、Git が HTTP または HTTPS 経由で行うすべての関連プッシュで消費されるメモリが増えることに注意してください。これは、バッファ全体が使用されるかどうかに関わらず割り当てられるためです。したがって、異なる値が必要だと確信している場合を除き、デフォルトのままにしておくのが最善です。
- 別のエディターを設定するにはどうすればよいですか?
-
Git にエディターを特に指定していない場合、デフォルトでは
VISUAL
またはEDITOR
環境変数で設定したエディターが使用されます。どちらも指定されていない場合は、システムのデフォルト (通常はvi
) が使用されます。vi
を使いにくいと感じる人や、別のエディターを好む人もいるため、使用するエディターを変更することが望ましい場合があります。ほとんどのプログラムで必要な汎用エディターを設定したい場合は、シェル設定 (例:
~/.bashrc
または~/.zshenv
) を編集して、EDITOR
またはVISUAL
環境変数に適切な値を設定する行を含めることができます。例えば、nano
エディターを好む場合は、次のように記述できます。export VISUAL=nano
Git 専用のエディターを設定したい場合は、
core.editor
設定値またはGIT_EDITOR
環境変数を設定できます。これらのオプションが参照される順序の詳細については、git-var[1] を参照してください。どの場合でも、エディターの値はシェルに渡されるため、スペースを含む引数は適切に引用符で囲む必要があることに注意してください。さらに、エディターが通常呼び出し時に端末からデタッチされる場合、そうしないようにする引数を指定する必要があります。そうしないと、Git は変更を認識しません。Windows でこれらの両方の問題に対処する設定の例は、ファイル名をスペースで引用符で囲み、プロセスをバックグラウンド化しないように
--nofork
オプションを指定する設定 "C:\Program Files\Vim\gvim.exe" --nofork です。
認証情報
- HTTP 経由でプッシュする際に認証情報を指定するにはどうすればよいですか?
-
最も簡単な方法は、
credential.helper
設定を介して認証ヘルパーを使用することです。ほとんどのシステムは、システム認証マネージャーと統合するための標準的な選択肢を提供します。例えば、Git for Windows はwincred
認証マネージャーを提供し、macOS にはosxkeychain
認証マネージャーがあり、標準のデスクトップ環境を持つ Unix システムはlibsecret
認証マネージャーを使用できます。これらはすべて、パスワードやトークンを安全に保つために、暗号化されたストアに認証情報を保存します。さらに、ホームディレクトリのファイルに保存する
store
認証マネージャーや、認証情報を永続的に保存しないが、一定期間プロンプトを表示しないcache
認証マネージャーも使用できます。プロンプトが表示されたときにパスワードを入力することもできます。パスワード (パーセントエンコードする必要がある) を URL に含めることも可能ですが、これは特に安全ではなく、認証情報の偶発的な漏洩につながる可能性があるため、推奨されません。
- 環境変数からパスワードやトークンを読み取るにはどうすればよいですか?
-
credential.helper
設定オプションは、標準出力に認証プロトコルを出力する任意のシェルコマンドも受け入れることができます。これは、例えば、認証情報をコンテナに渡す場合に便利です。このようなシェルコマンドは、オプション値を感嘆符で始めることで指定できます。パスワードまたはトークンが
GIT_TOKEN
に保存されている場合、次のコマンドを実行して認証ヘルパーを設定できます。$ git config credential.helper \ '!f() { echo username=author; echo "password=$GIT_TOKEN"; };f'
- HTTP を使用して同じホスティングプロバイダーで複数のアカウントを使用するにはどうすればよいですか?
-
通常、これらのアカウントを区別する最も簡単な方法は、URL でユーザー名を使用することです。例えば、
git.example.org
にauthor
とcommitter
のアカウントがある場合、https://author@git.example.org/org1/project1.git と https://committer@git.example.org/org2/project2.git の URL を使用できます。これにより、認証ヘルパーを使用すると、アカウントの正しい認証情報を自動的に検索しようとします。すでにリモートが設定されている場合は、git
remote
set-url
origin
https://author@git.example.org/org1/project1.git
のように URL を変更できます (詳細については git-remote[1] を参照してください)。
- SSH を使用して同じホスティングプロバイダーで複数のアカウントを使用するにはどうすればよいですか?
-
SSH をサポートするほとんどのホスティングプロバイダーでは、単一のキーペアがユーザーを一意に識別します。したがって、複数のアカウントを使用するには、各アカウントにキーペアを作成する必要があります。比較的新しい OpenSSH バージョンを使用している場合は、
ssh-keygen
-t
ed25519
-f
~/.ssh/id_committer
のようにして新しいキーペアを作成できます。その後、公開キー (この場合、~/.ssh/id_committer.pub
;.pub
に注意) をホスティングプロバイダーに登録できます。ほとんどのホスティングプロバイダーはプッシュに単一の SSH アカウントを使用します。つまり、すべてのユーザーは
git
アカウント (例:git@git.example.org
) にプッシュします。プロバイダーがその場合、SSH で複数のエイリアスを設定して、どのキーペアを使用するかを明確にすることができます。例えば、~/.ssh/config
に次のように記述し、適切な秘密キーファイルを置き換えることができます。# This is the account for author on git.example.org. Host example_author HostName git.example.org User git # This is the key pair registered for author with git.example.org. IdentityFile ~/.ssh/id_author IdentitiesOnly yes # This is the account for committer on git.example.org. Host example_committer HostName git.example.org User git # This is the key pair registered for committer with git.example.org. IdentityFile ~/.ssh/id_committer IdentitiesOnly yes
次に、プッシュ URL を
git@example.org
の代わりにgit@example_author
またはgit@example_committer
を使用するように調整できます (例:git
remote
set-url
git@example_author:org1/project1.git
)。
転送
- 複数のシステム間で作業ツリーを同期するにはどうすればよいですか?
-
まず、そもそもこれを実行するかどうかを決定してください。Git は、通常の
git
push
およびgit
fetch
コマンドを使用して作業をプッシュまたはプルするときに最も効果を発揮し、システム間で作業ツリーを共有するように設計されていません。これは潜在的にリスクがあり、場合によってはリポジトリの破損やデータ損失を引き起こす可能性があります。通常、そうすると
git
status
が作業ツリー内のすべてのファイルを再読み込みする必要が生じます。さらに、Git のセキュリティモデルは、信頼できないユーザー間での作業ツリーの共有を許可しないため、すべてのマシンで単一のユーザーのみが使用する場合にのみ作業ツリーを安全に同期できます。Git リポジトリのいかなる部分もクラウド同期サービスを使用して同期しないことが重要です。オブジェクトの欠落、ファイルの変更や追加、壊れた参照、その他さまざまな問題など、破損を引き起こす可能性があるためです。これらのサービスは、継続的にファイルごとに同期する傾向があり、Git リポジトリの構造を理解していません。これは、リポジトリが更新中に同期される場合に特に悪く、不完全な更新や部分的な更新、したがってデータ損失を引き起こす可能性が非常に高いためです。
発生しうる破損の種類の例として、参照の状態に関する競合があり、両側が互いが持っていないブランチ上で異なるコミットを持つことになる場合があります。これにより、重要なオブジェクトが参照されなくなり、
git
gc
によってプルーニングされる可能性があり、データ損失につながります。したがって、作業を他のシステムまたは中央サーバーに通常のプッシュおよびプルメカニズムを使用してプッシュする方が良いでしょう。ただし、これはstashのような重要なデータを常に保持するわけではないため、システム間で作業ツリーを共有することを好む人もいます。
これを行う場合、推奨されるアプローチは、リポジトリのルートで
rsync
-a
--delete-after
(理想的にはssh
のような暗号化された接続を使用) を使用することです。これを行う際には、いくつかのことを確認する必要があります。-
追加の作業ツリーまたは個別の Git ディレクトリがある場合、それらはメインの作業ツリーおよびリポジトリと同時に同期する必要があります。
-
宛先ディレクトリがソースディレクトリと正確に同じコピーになることを許容できること、既にそこにあるデータはすべて削除されることを許容できること。
-
転送中は (すべての作業ツリーと Git ディレクトリを含む) リポジトリが静止状態であること (つまり、
git
gc
のようなバックグラウンド操作やエディターによって呼び出される操作を含め、いかなる種類の操作も行われていないこと)。これらの推奨事項に従っても、この方法での同期にはGitの通常のリポジトリ整合性チェックをバイパスするため、リスクがあることに注意してください。そのため、バックアップを取ることをお勧めします。同期後、宛先システムでデータの整合性を検証するために
git
fsck
を実行することも検討してください。
-
一般的な問題
- 追跡対象ファイルの変更を無視するにはどうすればよいですか?
-
Git にはこれを行う方法がありません。その理由は、Git がこのファイルを上書きする必要がある場合(チェックアウト時など)、ファイルへの変更が貴重で保持すべきなのか、それとも無関係で安全に破棄できるのかがわからないためです。したがって、安全な方法を取り、常にそれらを保持する必要があります。
git
update-index
の特定の機能、すなわち assume-unchanged および skip-worktree ビットを使用しようとすると、この目的のために正しく機能せず、このように使用すべきではありません。設定ファイルを変更することが目的の場合、リポジトリにチェックインされたファイルをテンプレートまたはデフォルトのセットとして持ち、それを横にコピーして適切に修正できることが役立つことがよくあります。この2番目の修正されたファイルは、誤ってコミットされるのを防ぐために通常は無視されます。
- Git に様々なファイルを無視するよう指示しましたが、それらがまだ追跡されています。
-
gitignore
ファイルは、Git によって追跡されていない特定のファイルが追跡されないようにします。しかし、.gitignore
に追加する前に特定のファイルが追跡されていた場合、それらはまだ追跡されたままになります。ファイルを追跡解除して無視するには、git rm --cached <ファイル/パターン> を使用し、<ファイル> に一致するパターンを.gitignore
に追加します。詳細については、gitignore[5] を参照してください。
- フェッチとプル、どちらを行うべきかどうやって判断すればよいですか?
-
フェッチは、リモートリポジトリからの最新の変更を、作業ツリーや現在のブランチを変更せずにコピーして保存します。その後、自由に上流の変更を検査、マージ、リベース、または無視することができます。プルは、フェッチの直後にマージまたはリベースを実行するものです。git-pull[1] を参照してください。
- Git でプロキシを使用できますか?
-
はい、Git はプロキシの使用をサポートしています。Git は Unix で一般的に使用される標準の
http_proxy
、https_proxy
、no_proxy
環境変数を尊重し、HTTPS 用のhttp.proxy
と同様のオプションでも設定できます ( git-config[1] を参照)。http.proxy
および関連オプションは、URL パターンごとにカスタマイズできます。さらに、Git は理論上、ネットワーク上に存在する透過型プロキシと正常に連携できます。SSHの場合、GitはOpenSSHの
ProxyCommand
を使ってプロキシをサポートできます。netcat
やsocat
といったツールが一般的に使われます。ただし、これらは標準入力でEOFを見ても終了しないように設定する必要があります。これは通常、netcat
には-q
が必要で、socat
には-t
10
のようなタイムアウトが必要であることを意味します。これは、Git SSHサーバーがこれ以上リクエストがないことを知る方法は標準入力のEOFですが、その時点でサーバーが最終リクエストをまだ処理していない可能性があり、その時点で接続を切断するとそのリクエストが中断されるためです。~/.ssh/config
の HTTP プロキシを含む設定エントリの例は次のようになります。Host git.example.org User git ProxyCommand socat -t 10 - PROXY:proxy.example.org:%h:%p,proxyport=8080
すべての場合において、Git が正しく機能するためには、プロキシが完全に透過的である必要があります。プロキシは、接続を変更、改ざん、またはバッファリングしてはならず、そうしないと Git はほぼ確実に機能しなくなります。多くのプロキシ、多くの TLS ミドルボックス、Windows Defender および Windows Firewall 以外の Windows のアンチウイルスおよびファイアウォールプログラム、およびフィルタリングプロキシは、この標準を満たしておらず、その結果 Git を破損させることに注意してください。多くの問題報告とその貧弱なセキュリティ履歴のため、これらの種類のソフトウェアおよびデバイスの使用は推奨しません。
マージとリベース
- スクワッシュマージで長期間のブランチをマージする際に、どのような問題が発生する可能性がありますか?
-
一般的に、スクワッシュマージを使用して2つのブランチを複数回マージする場合、さまざまな問題が発生する可能性があります。これには、
git
log
出力、GUI、または範囲を表す ... 記法を使用するときに余分なコミットが表示されることや、競合を繰り返し再解決する必要がある可能性などが含まれます。Git が2つのブランチ間で通常のマージを行う場合、3つの点だけを考慮します。つまり、2つのブランチと、通常はコミットの共通の祖先である*マージベース*と呼ばれる3番目のコミットです。マージの結果は、マージベースと各ヘッド間の変更の合計です。通常のコミットで2つのブランチをマージすると、新しい共通の祖先ができたため、再度マージするときにその結果が新しいマージベースになります。Git はマージベースより前に発生した変更を考慮する必要がないため、以前に解決した競合を再解決する必要はありません。
スクワッシュマージを実行すると、マージコミットは作成されません。代わりに、一方の変更が通常のコミットとして他方に適用されます。これは、これらのブランチのマージベースが変更されていないことを意味するため、Git が次のマージを実行するときに、前回考慮したすべての変更と新しい変更を考慮します。つまり、競合を再解決する必要がある場合があります。同様に、
git
diff
、git
log
、または GUI で ... 記法を使用すると、元のマージベース以降のすべての変更が表示されます。結果として、2つの長期間のブランチを繰り返しマージしたい場合は、常に通常のコミットを使用するのが最善です。
- 2つのブランチで変更を行い、そのうち1つで元に戻した場合、なぜそれらのブランチのマージにその変更が含まれるのですか?
-
デフォルトでは、Git はマージを行う際に、洗練されたスリーウェイマージを行う
ort
戦略を使用します。このような場合、Git はマージを実行する際に、2つのヘッドと、通常はそれらのコミットの共通の祖先である*マージベース*と呼ばれる3番目の点のちょうど3つの点を考慮します。Git は、それらのブランチで発生した履歴や個々のコミットを一切考慮しません。その結果、両方の側で変更があり、一方の側でその変更が元に戻された場合、結果はその変更を含めることになります。これは、コードが一方の側で変更され、他方の側では実質的な変更がないためであり、このシナリオでは Git は変更を採用します。
これが問題となる場合、代わりにリベースを行うことができます。元に戻したブランチをもう一方のブランチにリベースします。このシナリオでのリベースは、リベースが個々のコミット(元に戻すコミットを含む)を適用するため、変更を元に戻します。リベースは履歴を書き換えるため、公開されたブランチをリベースすることは、それに慣れていることを確信している場合を除き避けるべきであることに注意してください。詳細については、git-rebase[1] の NOTES セクションを参照してください。
フック
- ユーザーが特定の変更を行うのを防ぐには、フックをどのように使用すればよいですか?
-
これらの変更を行う唯一安全な場所は、リモートリポジトリ (つまり Git サーバー) であり、通常は
pre-receive
フックまたは継続的インテグレーション (CI) システム内です。これらはポリシーを効果的に強制できる場所です。これらのことをチェックするために
pre-commit
フック (またはコミットメッセージの場合はcommit-msg
フック) を使用することが一般的ですが、これは単独の開発者として作業していてツールに助けてもらいたい場合に非常に役立ちます。ただし、開発者マシンでフックを使用することは、ポリシー制御としては効果がありません。なぜなら、ユーザーは--no-verify
を使用して (その他さまざまな方法で) これらのフックを気づかれずにバイパスできるためです。Git は、ユーザーが自分のローカルリポジトリを制御していると仮定しており、これを阻止したり、ユーザーの密告を試みたりしません。さらに、一部の高度なユーザーは、作業中のものをステージングするための仮コミットや修正コミットを作成するワークフローにとって
pre-commit
フックが妨げになると感じているため、これらの種類のチェックはとにかくサーバーにプッシュする方が良いでしょう。
クロスプラットフォームの問題
- 私は Windows を使用しており、テキストファイルがバイナリとして検出されます。
-
Git はテキストファイルを UTF-8 で保存するときに最も効果を発揮します。Windows の多くのプログラムは UTF-8 をサポートしていますが、一部のプログラムはサポートしておらず、Git がバイナリとして検出するリトルエンディアン UTF-16 形式のみを使用します。プログラムで UTF-8 を使用できない場合でも、リポジトリにこれらのファイルを UTF-8 で保存しながら、ファイルがチェックアウトされるエンコーディングを示す作業ツリーエンコーディングを指定できます。これにより、git-diff[1] などのツールが期待どおりに機能し、同時にツールも機能します。
これを行うには、
working-tree-encoding
属性を持つ gitattributes[5] パターンを指定します。例えば、次のパターンはすべての C ファイルを UTF-16LE-BOM (Windows で一般的なエンコーディング) を使用するように設定します。*.c working-tree-encoding=UTF-16LE-BOM
これを有効にするには
git
add
--renormalize
を実行する必要があります。これらの変更を複数のプラットフォームで使用されるプロジェクトで行う場合、リポジトリ内の.gitattributes
ファイルでこれを行うと、リポジトリのすべてのユーザーに適用されるため、ユーザーごとの設定ファイルまたは$GIT_DIR/info/attributes
内のファイルでこれを行うのが望ましいでしょう。改行コードの正規化に関する情報も次のエントリを参照し、属性ファイルの詳細については gitattributes[5] を参照してください。
- 私は Windows を使用しており、git diff でファイルが末尾に
^M
を持っていると表示されます。 -
デフォルトでは、Git はファイルを Unix スタイルの改行コードで保存することを想定しています。そのため、Windows の改行コードの一部であるキャリッジリターン (
^M
) は、後続の空白文字と見なされるため表示されます。Git はデフォルトで、既存の行ではなく新しい行にのみ後続の空白文字を表示します。ファイルをリポジトリに Unix 改行コードで保存し、プラットフォームの改行コードに自動的に変換することができます。これを行うには、設定オプション
core.eol
をnative
に設定し、ファイルをテキストまたはバイナリとして設定する方法については、推奨される保存設定に関する質問を参照してください。行末のキャリッジリターンを削除したくない場合は、
core.whitespace
設定でこの動作を制御することもできます。
- なぜ常に変更されているファイルがあるのですか?
-
内部的には、Git は常にファイル名をバイトシーケンスとして保存し、エンコーディングや大文字・小文字の畳み込みは行いません。しかし、Windows と macOS はデフォルトでファイル名の大文字・小文字の畳み込みを行います。その結果、名前が大文字・小文字のみが異なる複数のファイルやディレクトリが存在する可能性があります。Git はこれを問題なく処理できますが、ファイルシステムはこれらのファイルのうちの1つしか保存できないため、Git が他のファイルを読み込んでその内容を確認しようとすると、変更されているように見えます。
ファイルは1つだけになるように、いずれかのファイルを削除するのが最善です。これは、他にクリーンな作業ツリーで次のようなコマンド(2つのファイル
AFile.txt
とafile.txt
を仮定)を使用して行えます。$ git rm --cached AFile.txt $ git commit -m 'Remove files conflicting in case' $ git checkout .
これはディスクに触れずに、追加のファイルを削除します。プロジェクトでは、この問題が再発するのを避けるために、すべて小文字の名前などの命名規則を採用することを好むかもしれません。このような規則は、
pre-receive
フックを使用するか、継続的インテグレーション(CI)システムの一部としてチェックできます。システムでスマッジまたはクリーンフィルターが使用されているにもかかわらず、以前にスマッジまたはクリーンフィルターを実行せずにコミットされたファイルがある場合にも、どのプラットフォームでも永続的に変更されたファイルが発生する可能性があります。これを修正するには、他にクリーンな作業ツリーで次を実行します。
$ git add --renormalize .
- Git でファイルを保存する推奨される方法は何ですか?
-
Git はあらゆる種類のファイルを保存および処理できますが、他の設定よりも効果的な設定がいくつかあります。一般的に、テキストファイルはバイトオーダーマーク (BOM) なしで LF (Unix スタイル) の改行コードを持つ UTF-8 で保存することを推奨します。コミットメッセージでも UTF-8 (BOM なし) の使用を推奨します。これらは、複数のプラットフォームや
git
diff
やgit
merge
などのツールで最も効果的に機能する設定です。さらに、テキストベースのストレージ形式と非テキストベースのストレージ形式を選択できる場合、ファイルをテキスト形式で保存し、必要に応じて他の形式に変換することを推奨します。例えば、1行に1レコードのテキストベースの SQL ダンプは、実際のデータベースファイルよりも diffing とマージにはるかに適しています。同様に、Markdown や AsciiDoc などのテキストベースの形式は、Microsoft Word や PDF などのバイナリ形式よりも優れています。
同様に、バイナリ依存関係 (共有ライブラリや JAR ファイルなど) やビルド生成物をリポジトリに保存することは、一般的に推奨されません。依存関係やビルド生成物は、アーティファクトまたはパッケージサーバーに保存し、リポジトリには参照、URL、ハッシュのみを保存するのが最善です。
また、どのファイルがテキストでどのファイルがバイナリかを明示的にマークするために、gitattributes[5] ファイルを設定することも推奨します。Git に推測させたい場合は、属性
text=auto
を設定できます。テキストファイルの場合、Git は通常、リポジトリ内で LF 終端が使用されることを保証します。
core.autocrlf
およびcore.eol
設定変数は、テキストファイルがチェックアウトされるときにどの改行コード規則に従うかを指定します。eol
属性 (例:eol=crlf
) を使用して、どのファイルがどの改行コード処理を受けるかを上書きすることもできます。例えば、一般的にシェルファイルはLF終端を、バッチファイルはCRLF終端を持たなければならないため、いくつかのプロジェクトでは次の設定が適切かもしれません。
# By default, guess. * text=auto # Mark all C files as text. *.c text # Ensure all shell files have LF endings and all batch files have CRLF # endings in the working tree and both have LF in the repo. *.sh text eol=lf *.bat text eol=crlf # Mark all JPEG files as binary. *.jpg binary
これらの設定は、パッチなどの出力に適切な形式をツールが選択するのに役立ち、ファイルがプラットフォームに適した改行コードでチェックアウトされる結果となります。
GIT
git[1]スイートの一部