SYNOPSIS
gitfaq
DESCRIPTION
このFAQの例では、 bash
や dash
などの標準のPOSIXシェルと、ホスティングプロバイダー git.example.org
にアカウント author
を持つユーザー A U Thor を想定しています。
Configuration
-
user.name
には何を入れるべきですか? -
個人名、通常は名前とファミリーネームを使用した形式を入力する必要があります。たとえば、Gitの現在のメンテナは "Junio C Hamano" (濱野 純)を使用しています。 これは、コミットするたびに保存される名前の部分になります。
この構成は、リモートサービスへの認証には影響しません。 そのためには、 git-config(1) の
credential.username
を参照してください。 -
http.postBuffer
は実際には何をしますか? -
このオプションは、HTTPまたはHTTPSを介してデータをリモートにプッシュするときにGitが使用するバッファーのサイズを変更します。データがこのサイズより大きい場合、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でこれらの問題の両方に対処する構成の例は、構成 "C:\Program
Files
\Vim\gvim.exe"--nofork
です。これは、空白を含んだファイル名をクォートし、プロセスのバックグラウンド実行を回避するため--nofork
オプションを指定します。
Credentials
- 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'
- 資格情報マネージャーに保存したパスワードまたはトークンを変更するにはどうすればよいですか?
-
通常、パスワードまたはトークンが無効な場合、Gitはそれを消去し、新しいものを要求します。ただし、これが常に発生するとは限りません。パスワードまたはトークンを変更するには、既存の資格情報を消去してください。そうすればGitが新しい資格情報の入力を求めます。資格情報を消去するには、以下の構文を使用します(ユーザー名(「author」の部分)とホスト名(「git.example.org」の部分)をあなた自身のに置き換えてください):
$ echo url=https://author@git.example.org | git credential reject
- HTTPを使用して同じホスティングプロバイダーで複数のアカウントを使用するにはどうすればよいですか?
-
通常、これらのアカウントを区別する最も簡単な方法は、URLでユーザー名を使用することです。 たとえば、
git.example.org
にアカウントauthor
とcommitter
がある場合、URLに https://author@git.example.org/org1/project1.git と https://committer@git.example.org/org2/project2.git を使用できます。このように、資格情報ヘルパーを使用すると、アカウントの正しい資格情報が自動的に検索されます。すでにリモートを設定している場合は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
) 。
Transfers
- How do I sync a working tree across systems?
-
First, decide whether you want to do this at all. Git works best when you push or pull your work using the typical
git
push
andgit
fetch
commands and isn’t designed to share a working tree across systems. This is potentially risky and in some cases can cause repository corruption or data loss.Usually, doing so will cause
git
status
to need to re-read every file in the working tree. Additionally, Git’s security model does not permit sharing a working tree across untrusted users, so it is only safe to sync a working tree if it will only be used by a single user across all machines.It is important not to use a cloud syncing service to sync any portion of a Git repository, since this can cause corruption, such as missing objects, changed or added files, broken refs, and a wide variety of other problems. These services tend to sync file by file on a continuous basis and don’t understand the structure of a Git repository. This is especially bad if they sync the repository in the middle of it being updated, since that is very likely to cause incomplete or partial updates and therefore data loss.
An example of the kind of corruption that can occur is conflicts over the state of refs, such that both sides end up with different commits on a branch that the other doesn’t have. This can result in important objects becoming unreferenced and possibly pruned by
git
gc
, causing data loss.Therefore, it’s better to push your work to either the other system or a central server using the normal push and pull mechanism. However, this doesn’t always preserve important data, like stashes, so some people prefer to share a working tree across systems.
If you do this, the recommended approach is to use
rsync
-a
--delete-after
(ideally with an encrypted connection such as withssh
) on the root of repository. You should ensure several things when you do this:-
If you have additional worktrees or a separate Git directory, they must be synced at the same time as the main working tree and repository.
-
You are comfortable with the destination directory being an exact copy of the source directory, deleting any data that is already there.
-
The repository (including all worktrees and the Git directory) is in a quiescent state for the duration of the transfer (that is, no operations of any sort are taking place on it, including background operations like
git
gc
and operations invoked by your editor).Be aware that even with these recommendations, syncing in this way has some risk since it bypasses Git’s normal integrity checking for repositories, so having backups is advised. You may also wish to do a
git
fsck
to verify the integrity of your data on the destination system after syncing.
-
Common Issues
- 前回のコミットでミスをしました。どうすれば変更できますか?
-
作業ツリーに適切な変更を加え、必要に応じて
git
add
<file> またはgit
rm
<file> を実行してステージングしてから、git
commit
--amend
を実行できます。変更はコミットに含まれ、コミットメッセージを再度編集するように求められます。元のメッセージをそのまま使用したい場合は、--no-edit
オプションを伴っててgit
commit
を使用するか、または、エディタが開いたら何もせず保存して終了して済ませることもできます。 - バグで変更を加えましたが、それは既にメインブランチに含まれてしまっています。どうすれば元に戻すことができますか?
-
これに対処する通常の方法は、
git
revert
を使用することです。これにより、元の変更が行われて貴重な貢献であった、という履歴が保持されるとともに、元の変更に問題があったためにそれらの変更を元に戻す新しいコミットも導入されます。revertのコミットメッセージは、復帰(revert)されたコミットを示し、通常、復帰(revert)が行われた理由に関する説明を含むように編集されます。 - 追跡されているファイルへの変更を無視するにはどうすればよいですか?
-
Gitはこれを行う方法を提供していません。 その理由は、チェックアウト中など、Gitがこのファイルを上書きする必要がある場合、ファイルへの変更が貴重で保持されるべきかどうか、または無関係で安全に破棄できるかどうかがわからないためです。したがって、安全なルートを取り、常にそれらを保存する必要があります。
git
update-index
の特定の機能、つまり、assume-unchangedビットとskip-worktreeビットを使おうとするのは魅力的ですが、これらはこの目的には適切に機能しないため、このように使用しないでください。あなたの目的が構成ファイルを変更することの場合は、テンプレートまたはデフォルトのセットであるファイルをリポジトリにチェックインして、一緒にコピーして必要に応じて変更できると便利なことがよくあります。この場合の変更されたファイルは、誤ってコミットすることを防ぐために、通常は無視されます。
- さまざまなファイルを無視するようにGitに依頼したはずなのに、それらはまだ追跡されています
-
gitignore
ファイルは、Gitによって追跡されていない特定のファイルが追跡されないままであることを保証します。ただし、特定のファイルが.gitignore
に追加される前に追跡されている場合は追跡されたままになります。ファイル/パターン を追跡解除して無視するには、git
rm
--cached
<file/pattern> を使用し、 <file> に一致するパターンを.gitignore
に追加します。詳細については gitignore(5) を参照してください。 - フェッチまたはプルのどちらを実行すればよいか知るにはどうすればよいですか?
-
フェッチは、作業ツリーや現在のブランチを変更せずに、リモートリポジトリからの最新の変更のコピーを保存します。その後、自由に、アップストリームの変更を検査、マージ、リベース、または無視することができます。プルは、フェッチとその直後のマージまたはリベースで構成されます。 git-pull(1) を参照してください。
- Can I use a proxy with Git?
-
Yes, Git supports the use of proxies. Git honors the standard
http_proxy
,https_proxy
, andno_proxy
environment variables commonly used on Unix, and it also can be configured withhttp.proxy
and similar options for HTTPS (see git-config(1)). Thehttp.proxy
and related options can be customized on a per-URL pattern basis. In addition, Git can in theory function normally with transparent proxies that exist on the network.For SSH, Git can support a proxy using OpenSSH’s
ProxyCommand
. Commonly used tools includenetcat
andsocat
. However, they must be configured not to exit when seeing EOF on standard input, which usually means thatnetcat
will require-q
andsocat
will require a timeout with something like-t
10
. This is required because the way the Git SSH server knows that no more requests will be made is an EOF on standard input, but when that happens, the server may not have yet processed the final request, so dropping the connection at that point would interrupt that request.An example configuration entry in
~/.ssh/config
with an HTTP proxy might look like this:Host git.example.org User git ProxyCommand socat -t 10 - PROXY:proxy.example.org:%h:%p,proxyport=8080
Note that in all cases, for Git to work properly, the proxy must be completely transparent. The proxy cannot modify, tamper with, or buffer the connection in any way, or Git will almost certainly fail to work. Note that many proxies, including many TLS middleboxes, Windows antivirus and firewall programs other than Windows Defender and Windows Firewall, and filtering proxies fail to meet this standard, and as a result end up breaking Git. Because of the many reports of problems and their poor security history, we recommend against the use of these classes of software and devices.
Merging and Rebasing
- 寿命の長いブランチをスカッシュマージとマージすると、どのような問題が発生する可能性がありますか?
-
一般に、スカッシュマージを使用して2つのブランチを複数回マージすると、さまざまな問題が発生する可能性があります。これには、GUIを使用した場合、または
...
`表記を使用して範囲を表す場合に、 `gitlog
出力で追加のコミットが表示されることや、競合を何度も再解決する必要がある可能性が含まれます。Gitが2つのブランチ間で通常のマージを行う場合、正確に3者が考慮されます。2つのブランチと、通常は2つのコミットの共通の祖先である「マージベース」(merge base)と呼ばれる3番目のコミットです。マージの結果は、マージベースと各headの間の変更の合計です。2つのブランチを通常のマージコミットでマージすると、新しい共通の祖先を持つ、新しいコミットが発生し、再度マージされるときはそれが最終的なマージベースになります。そうすると、Gitは、マージベースの前に発生した変更を考慮する必要がないため、以前に解決した競合を再解決する必要がありません。
スカッシュマージを実行する場合、マージコミットは作成されません。代わりに、一方の側からの変更は、もう一方の側への通常のコミットとして適用されます。つまり、これらのブランチのマージベースは変更されないため、Gitが次のマージを実行するときに、前回考慮したすべての変更と新しい変更が考慮されます。つまり、競合を再解決する必要があるかもしれません。 同様に、
git
diff
またはgit
log
またはGUIで ... 表記を使用すると、元のマージベース以降のすべての変更が表示されます。結果として、2つの長期間有効なブランチを繰り返しマージする場合は、常に通常のマージコミットを使用するのが最善です。
- 2つのブランチに変更を加えた後、それを1つに戻した場合、それら2つのブランチのマージに変更が含まれるのはなぜですか?
-
デフォルトでは、Gitがマージを行うとき、それは「ort」戦略と呼ばれる戦略を使用します。これは、派手な3者間マージ(fancy three-way merge)を行います。 このような場合、Gitはマージを実行するときに、正確に3つのポイントを考慮します。2つのheadと、通常はこれらのコミットの共通の祖先である「マージベース」(merge base)と呼ばれる3番目のポイントです。 Gitは、これらのブランチで発生した履歴や個々のコミットをまったく考慮しません。
その結果、両方の側に変更があり、一方の側がその変更を元に戻した場合、結果には変更が含まれます。 これは、コードが一方の側で変更され、もう一方の側では正味の変更がないためです。このシナリオでは、Gitが変更を採用します。
これが問題になる場合は、代わりにリベースを実行して、ブランチを他のブランチに戻すことでリベースすることができます。このシナリオでのリベースは変更を元に戻します。これは、リベースが元に戻すことを含め、個々のコミットを適用するためです。リベースは書き換え履歴(rewrite history)をリベースするため、問題がない場合を除いて、公開されたブランチのリベースは避けてください。詳細については、 git-rebase(1)のNOTESセクションを参照してください。
Hooks
- フックを使用して、ユーザーが特定の変更を行うのを妨げるにはどうすればよいですか?
-
これらの変更を行うための唯一の安全な場所は、リモートリポジトリ(つまり、Gitサーバー)で、通常は
pre-receive
フックまたは継続的インテグレーション(CI)システムです。これらは、ポリシーを効果的に実施できる場所です。pre-commit
フック(または、コミットメッセージの場合はcommit-msg
フック)を使用してこれらをチェックするのが一般的です。これは、単独の開発者として作業していて、ツールが役立つことを望んでいる場合に最適です。ただし、開発者のマシンでフックを使用することは、ユーザーが(他のさまざまな方法の中でも)気付かれることなく--no-verify
でこれらのフックをバイパスできるため、ポリシーコントロールとしては効果的ではありません。 Gitは、ユーザーがローカルリポジトリを管理していることを前提としており、これを防止したり、ユーザーを攻撃したりすることはありません。さらに、一部の上級ユーザーは、「pre-commit」フックが、一時的なコミットを使用して進行中の作業をステージングしたり、修正コミットを作成したりするワークフローの障害であると感じているため、とにかくこれらの種類のチェックはサーバーに押しやることをお勧めします。
Cross-Platform Issues
- Windowsを使用していますが、テキストファイルがバイナリとして検出されます。
-
Gitは、テキストファイルをUTF-8として保存する場合に最適に機能します。Windows上の多くのプログラムはUTF-8をサポートしていますが、Gitがバイナリとして検出するリトルエンディアンのUTF-16形式を使用していないプログラムもあります。プログラムでUTF-8を使用できない場合は、これらのファイルをUTF-8としてリポジトリに保存しながら、ファイルをチェックアウトするエンコードを示す作業ツリーエンコーディング(working tree encoding)を指定できます。これにより、 git-diff(1) などのツールを期待どおりに機能させながら、ツールを機能させることができます。
これを行うには、
working-tree-encoding
属性を使用して gitattributes(5) パターンを指定できます。たとえば、以下のパターンは、Windowsで一般的なエンコーディングである UTF-16LE-BOM を使用するようにすべてのC言語ファイルを設定します:*.c working-tree-encoding=UTF-16LE-BOM
これを有効にするには、
git
add
--renormalize
を実行する必要があります。プラットフォーム間で使用されるプロジェクトでこれらの変更を行う場合は、ユーザーごとの構成ファイルまたは$GIT_DIR/info/attributes
の構成ファイルで行う必要があることに注意してください。リポジトリ内の.gitattributes
ファイルは、リポジトリのすべてのユーザーに適用されます。行末の正規化については以下のエントリを参照してください。属性ファイルの詳細については、gitattributes(5) を参照してください。
-
Windowsの git diff はファイルの最後に
^M
があると表示します。 -
デフォルトでは、GitはファイルがUnixの行末で保存されることを想定しています。そのため、Windowsの行末の一部であるキャリッジリターン(
^M
)は、末尾の空白と見なされるため、表示されます。Gitはデフォルトで、既存の行ではなく、新しい行にのみ末尾の空白を表示します。You can store the files in the repository with Unix line endings and convert them automatically to your platform’s line endings. To do that, set the configuration option
core.eol
tonative
and see the question on recommended storage settings for information about how to configure files as text or binary.行末からキャリッジリターン(CR;\x0d)を削除したくない場合は、
core.whitespace
設定を使用してこの動作を制御することもできます。 - 常に変更されるファイルがあるのはなぜですか?
-
内部的には、Gitは常にファイル名をバイトのシーケンスとして保存し、エンコードや大文字と小文字の区別は行いません。 ただし、WindowsとmacOSはどちらも、デフォルトでファイル名に対して大文字と小文字を区別します。その結果、大文字と小文字が区別される場合にのみ名前が異なる複数のファイルまたはディレクトリが作成される可能性があります。Gitはこれを問題なく処理できますが、ファイルシステムはこれらのファイルの1つしか保存できないため、Gitが他のファイルを読み取ってその内容を確認すると、変更されているように見えます。
ファイルが1つだけになるように、ファイルの1つを削除することをお勧めします。これは、以下のようなコマンド(2つのファイル
AFile.txt
と`afile.txt` を想定)を使用して、他の点ではクリーンな作業ツリーで実行できます:$ git rm --cached AFile.txt $ git commit -m 'Remove files conflicting in case' $ git checkout .
これにより、ディスクへの変更は回避され、追加のファイルは削除されます。プロジェクトでは、この問題が再発しないように、すべて小文字の名前などの命名規則を採用することをお勧めします。このような規則は、
pre-receive
フックを使用して、または継続的インテグレーション(CI)システムにてチェックできます。システムでスマッジまたはクリーンフィルター(a smudge or clean filter)が使用されているが、スマッジまたはクリーンフィルターを実行せずにファイルが以前にコミットされた場合、任意のプラットフォームで永続的に変更されたファイルが発生する可能性もあります。これを修正するには、他の点ではクリーンな作業ツリーで以下を実行します:
$ git add --renormalize .
- Gitにファイルを保存するための推奨の方法は何ですか?
-
Gitはあらゆるタイプのあらゆるファイルを保存および処理できますが、他の設定よりもうまく機能する設定がいくつかあります。一般に、テキストファイルは、LF(Unixスタイル)で終わるバイト順マーク(BOM)なしでUTF-8に保存することをお勧めします。また、コミットメッセージでUTF-8(ここでもBOMなし)を使用することをお勧めします。これらは、プラットフォーム間や
git
diff
やgit
merge
などのツールで最適に機能する設定です。さらに、テキストベースまたは非テキストベースのストレージ形式を選択できる場合は、ファイルをテキスト形式で保存し、必要に応じて他の形式に変換することをお勧めします。たとえば、1行に1つのレコードを持つテキストベースのSQLダンプは、実際のデータベースファイルよりも差分とマージにはるかに適しています。同様に、MarkdownやAsciiDocなどのテキストベースの形式は、MicrosoftWordやPDFなどのバイナリ形式よりもうまく機能します。
同様に、バイナリ依存関係(共有ライブラリやJARファイルなど)を格納したり、リポジトリに製品をビルドしたりすることは、通常はお勧めしません。依存関係とビルド製品は、リポジトリに保存されている参照、URL、ハッシュのみを使用して、アーティファクトサーバーまたはパッケージサーバーに保存するのが最適です。
We also recommend setting a gitattributes(5) file to explicitly mark which files are text and which are binary. If you want Git to guess, you can set the attribute
text=auto
.With text files, Git will generally ensure that LF endings are used in the repository. The
core.autocrlf
andcore.eol
configuration variables specify what line-ending convention is followed when any text file is checked out. You can also use theeol
attribute (e.g.,eol=crlf
) to override which files get what line-ending treatment.For example, generally shell files must have LF endings and batch files must have CRLF endings, so the following might be appropriate in some projects:
# 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
Part of the git(1) suite