Git

提供: ArchWiki
2015年10月9日 (金) 19:54時点におけるKusakata (トーク | 投稿記録)による版
ナビゲーションに移動 検索に移動

関連記事

Git は Linux カーネルの創設者である Linus Torvalds によって設計・開発されたバージョン管理システム (VCS) です。現在 Git は Linux カーネルのソースの管理だけでなく、様々な他のプロジェクトにも使われており、Arch Linux プロジェクトもそれに含まれます。

インストール

git パッケージをインストールしてください。

Git の補助ツールを使いたい場合は、必要に応じて任意の依存パッケージもインストールしてください。GUI ツール (例: gitkgit gui) は tk パッケージを必要とし、インストールしていない場合エラーで起動できません:

/usr/bin/gitk: line 3: exec: wish: not found.

また、GUI ツールは gsfonts を必要とし、インストールしていない場合セグメンテーション違反でクラッシュします。

Git SVN ブリッジ (git svn) を使いたい場合は perl-term-readkey も必要です。インストールしていない場合、次のエラーが表示されます:

Can't locate Term/ReadKey.pm in @INC (you may need to install the Term::ReadKey module)

基本設定

Git を使うには少なくとも名前とメールアドレスを設定する必要があります:

$ git config --global user.name  "John Doe"
$ git config --global user.email "johndoe@foobar.com"

他の設定については #高度な設定 を見て下さい。

基本的な使い方

このチュートリアルでは Git によるプロジェクトの基本的な分散バージョン管理について説明します。典型的な Git のワークフローは以下の通りです:

  1. 新しいプロジェクトを作成、またはリモートのプロジェクトを複製する。
  2. ブランチを作成して変更を加え、変更をコミットする。
  3. コミットを統合して上手くまとめて分かりやすくする。
  4. メインのブランチにコミットをマージする。
  5. (任意) 変更をリモートサーバーにプッシュする。

ローカルリポジトリ

ステージング

新しいリポジトリを作成:

$ git init

リポジトリの変更を記録するには、先にインデックスまたはステージングエリア (ステージングとも呼ばれます) に変更を追加する必要があります。ファイルを追加するには:

$ git add file1 file2

ファイルを全て追加:

$ git add .
ヒント: git add . などのコマンドでファイルを無視するようにしたい場合、.gitignore ファイルを作成してください:
.gitignore
# File I'll likely delete
test-script

# Ignore all .html files, except 'important.html'
*.html
!important.html

# Ignore all files recursively in 'DoNotInclude'
DoNotInclude/**

詳しくは gitignore(5) を参照。

ステージングからファイルを削除 (--cached を付けるとファイルを実際には削除しません):

$ git rm (--cached) file

ファイルを全て削除:

$ git rm --cached -r .

または:

$ git reset HEAD -- .

上記の HEAD は現在の版の「シンボル参照」です。

ファイルの名前を変更:

$ git mv file1 file2

ファイルのリストを表示:

$ git ls-files

上記のコマンドはデフォルトでステージングエリアのファイルを表示します (--cached ファイル)。

変更をコミット

コンテンツをステージングに記録したら、次のコマンドでコミットします:

$ git commit -m "First commit."

-m, --message オプションを使うことで短いメッセージを残せます: オプションを省略した場合、事前に設定していたエディタが起動して長いメッセージを書くことができます。

ヒント:
  • 小さい変更でも頻繁にコミットを行ってちゃんとしたメッセージを書くようにしましょう。
  • 編集を加えたファイルを全てインデックスに追加して、それらをコミットするのは一つのコマンドで実行できます (-a--all の略式):
$ git commit -am "First commit."

過去に戻ってコミットメッセージを編集:

$ git commit --amend -m "Message."

この記事で使われるコマンドの多くはコミットを引数として指定します。コミットは以下の形式のどれかで指定することが可能です:

  • 40文字の SHA-1 ハッシュ (大抵は最初の7文字くらいで一意に識別できます)。
  • ブランチやタグの名前といったコミットのラベル。
  • HEAD ラベルはチェックアウトされた最新のコミットを示します (git checkout を使って古いコミットまで歴史を戻していない限り、ブランチの頭になります)。
  • 上記に加えて ~ を付けることで前のコミットを指定できます。例えば、HEAD~HEAD の一つ前のコミット、HEAD~5HEAD の五つ前のコミットを指します。

変更を閲覧

コミット間の差分を表示:

$ git diff HEAD HEAD~3

ステージングエリアと作業ツリーの差分を表示:

$ git diff

変更の要点を表示:

$ git status

変更の履歴を表示 ("-N" は表示する直近のコミット数):

$ git log (-N)

ブランチの作成

基本的に、修正や新しい機能などはブランチでテストします。変更が問題ないようだったら、デフォルトのブランチ (master) にマージします。ブランチを作成するときは、目的に適った名前を付けて下さい:

$ git branch help-section-addition

ブランチを一覧:

$ git branch

ブランチを切り替え:

$ git checkout branch

ブランチを作成して切り替え:

$ git checkout -b branch

ブランチを master ブランチにマージ:

$ git checkout master
$ git merge branch

変更が衝突しない場合はマージされます。衝突する場合は衝突箇所が記録されます。git diff を使ってどこで衝突しているのか確認することができるので、手動で衝突の解消をする必要があります。

ブランチが不要になったら、次のコマンドで削除します:

$ git branch -d branch

共同作業

エチケット

  • 既存のプロジェクトに貢献しようと考えた場合、プロジェクトのライセンスを確認しましょう。コードの変更についてかなり制限がかけられている場合もあります。ライセンスによっては、コードの所有権について論争が生まれることも考えられます。
  • プロジェクトのコミュニティを観測してどうやったら適合できるか考えましょう。プロジェクトの方向性を理解するために、ドキュメントやリポジトリのログを読むのも大切です。
  • コミットを pull するようにリクエストしたり、パッチを送るときは、できるかぎりパッチを短くして説明を付加するようにしましょう。メンテナがあなたの変更箇所を理解するための手助けとなり、マージするか、もしくは修正を加えるよう要求すべきか判断する基準にもなります。
  • If a contribution is rejected, do not get discouraged, it is their project after all. If it is important, discuss the reasoning for the contribution as clearly and as patiently as possible: with such an approach a resolution may eventually be possible.

リポジトリを複製

To begin contributing to a project, clone its repository:

$ git clone location folder

location can be either a path or network address. Also, when cloning is done, the location is recorded so just a git pull will be needed later.

プルリクエスト

After making and committing some changes, the contributor can ask the original author to merge them. This is called a pull request. To pull:

$ git pull location master

The pull command combines both fetching and merging. If there are conflicts (e.g. the original author made changes in the same time span), then it will be necessary to manually fix them.

Alternatively, the original author can pick the changes wanting to be incorporated. Using the fetch option (and log option with a special FETCH_HEAD symbol), the contents of the pull request can be viewed before deciding what to do:

$ git fetch location master
$ git log -p HEAD..FETCH_HEAD
$ git merge location master

リモートの使用

Remotes are tracked repositories, a label defining a location. They are commonly used for frequently accessed repositories. Create a remote:

$ git remote add label location

Fetch a remote:

$ git fetch label

Show differences between master and a remote master:

$ git log -p master..label/master

View remotes for the current repository:

$ git remote -v

When defining a remote that is a parent of the fork (the project lead), it is defined as upstream.

リポジトリにプッシュ

After being given rights from the original authors, push changes with:

$ git push location branch

When git clone is performed, it records the original location and gives it a remote name of origin. So what typically is done is this:

$ git push origin master

If the --set-upstream option is used, the location is recorded so the next time just a git push is necessary.

マージの対処

See Basic Merge Conflicts in the Git Book for a detailed explanation on how to resolve merge conflicts. Merges are generally reversible. If wanting to back out of a merge one can usually use the --abort command (e.g. git merge --abort or git pull --abort).

メーリングリストにパッチを送信

メーリングリストに直接パッチを送る場合、次のパッケージをインストールする必要があります: perl-authen-sasl, perl-net-smtp-ssl, perl-mime-tools

ユーザー名とメールアドレスを設定したか確認してください、#基本設定を参照。

メールアドレスを設定:

$ git config --global sendemail.smtpserver smtp.gmail.com
$ git config --global sendemail.smtpserverport 587
$ git config --global sendemail.smtpencryption tls
$ git config --global sendemail.smtpuser foobar@gmail.com

これでメーリングリストにパッチを送信することができます (OpenEmbedded:How to submit a patch to OpenEmbedded#Sending patches を参照):

$ git add filename
$ git commit -s
$ git send-email --to=openembedded-core@lists.openembedded.org --confirm=always -M -1

履歴とバージョニング

履歴の検索

git log では履歴とコミットのチェックサムや作者、日付、ショートメッセージを表示します。チェックサムはコミットオブジェクトのオブジェクト名であり、通常は40文字の SHA-1 ハッシュになります。履歴とロングメッセージを表示するには ("checksum" は一意であるかぎり短く省略できます):

$ git show (checksum)

追跡されているファイルをパターン検索:

$ git grep pattern

.c.h ファイルを検索:

$ git grep pattern -- '*.[ch]'

バージョニングとリリース

Tag commits for versioning:

$ git tag 2.14 checksum

Tagging is generally done for releasing/versioning but it can be any string. Generally annotated tags are used, because they get added to the Git database. Tag the current commit with:

$ git tag -a 2.14 -m "Version 2.14"

List tags:

$ git tag -l

Delete a tag:

$ git tag -d 2.08

Update remote tags with a separate:

$ git push --tags

コミットの修正

Before submitting a pull request it may be desirable to consolidate/organize the commits. This is done with the git rebase interactive option:

$ git rebase -i checksum

This will open the editor with a summary of all the commits in the range specified; in this case including the newest (HEAD) back to, but excluding, commit checksum. Or to use a number notation, use for example HEAD~3, which will rebase the last three commits:

pick d146cc7 Mountpoint test.
pick 4f47712 Explain -o option in readme.
pick 8a4d479 Rename documentation.

Editing the action in the first column will dictate how the rebase will be done. The options are:

  • pick — Apply this commit as is (the default).
  • edit — Edit files and/or commit message.
  • reword — Edit commit message.
  • squash — Merge/fold into previous commit.
  • fixup — Merge/fold into previous commit discarding its message.

The commits can be re-ordered or erased from the history (but be very careful with these). After editing the file, Git will perform the specified actions; if prompted to resolve merge problems, fix them and continue with git rebase --continue or back out with the git rebase --abort command.

ノート: Squashing commits is only used for local commits, it will cause troubles on a repository that is shared by other people.

高度な設定

Git は INI タイプの設定ファイルから設定を読み込みます:

  • 各リポジトリにはリポジトリごとの設定を記述した .git/config ファイルが含まれます。
  • 各ユーザーの $HOME/.gitconfig ファイルがフォールバックとして使われます。
  • システム全体のデフォルト設定としては /etc/gitconfig が使われます。

These files can be edited directly, but the usual method is to use git config, as shown in the examples below.

List the currently set variables:

$ git config {--local,--global,--system} --list

デフォルトエディタを vim から nano に設定:

$ git config --global core.editor "nano -w"

Set the default push action:

$ git config --global push.default simple

git difftool で使用するツールを設定 (デフォルトでは meld になっています):

$ git config --global diff.tool vimdiff

See git-config(1) and Git Configuration for more information.

SSH の高速化

Often if you find yourself pushing constantly to a few common servers, you may wish to remove the hassle of setting your username for each repository.

If you do not already have the keys created, make them now.

$ ssh-keygen -N ’’ -b 4096 -t rsa -f ~/.ssh/aur -C "user@domain.com"
$ ssh-keygen -N ’’ -b 4096 -t rsa -f ~/.ssh/github -C "user@domain.com"

Add the resulting public keys to your accounts.

Additionally, reusing the same SSH connection will drastically improve the time git push takes.

$ mkdir -p ~/.ssh/sockets/

You may wish to adjust the ServerAliveInterval depending on your connection.

~/.ssh/config
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 8760h
ServerAliveInterval 5
ServerAliveCountMax 1
TCPKeepAlive yes

Host aur-dev.archlinux.org
IdentityFile ~/.ssh/aur
User aur
Port 2222

Host github.com
IdentityFile ~/.ssh/github
User [username here]

デフォルトプロトコル

上述のように SSH で多重接続することで、Git over SSH の方が HTTPS よりも高速になります。また、(AUR など) サーバーによっては SSH を介して push することもできます。例えば、以下の設定をすると AUR でホストされているリポジトリで Git over SSH を設定します。

~/.gitconfig
[url "ssh://aur@aur.archlinux.org/"]
	insteadOf = https://aur.archlinux.org/
	insteadOf = http://aur.archlinux.org/
	insteadOf = git://aur.archlinux.org/

Bash 補完

Bash の補完を有効にするには、Bash のスタートアップファイル/usr/share/git/completion/git-completion.bash を source してください。もしくは、bash-completion をインストールしてください。

Git プロンプト

Git パッケージにはプロンプトスクリプトが付属しています。プロンプトを有効にするには、シェルのスタートアップファイル/usr/share/git/completion/git-prompt.sh スクリプトを source して、%s パラメータでカスタムプロンプトを設定してください:

  • Bash の場合: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
  • zsh の場合: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '

Git リポジトリのディレクトリに移動すると、プロンプトはブランチの名前を表示するようになります。他の情報もプロンプトに表示させるよう設定できます:

シェル変数 情報
GIT_PS1_SHOWDIRTYSTATE + for staged, * if unstaged.
GIT_PS1_SHOWSTASHSTATE $ if something is stashed.
GIT_PS1_SHOWUNTRACKEDFILES % if there are untracked files.
GIT_PS1_SHOWUPSTREAM <,>,<> behind, ahead, or diverged from upstream.

GIT_PS1_SHOWUPSTREAM will need to be set to auto for changes to take effect.

ノート: If you experience that $(__git_ps1) returns ((unknown)), then there is a .git folder in your current directory which does not contain any repository, and therefore Git does not recognize it. This can, for example, happen if you mistake Git's configuration file to be ~/.git/config instead of ~/.gitconfig.

高度な使い方

変更量を視覚的に表示するには:

$ git diff --stat

git log with forking representation:

$ git log --graph --oneline --decorate

git log graph alias (i.e. git graph will show a decorated version):

$ git config --global alias.graph 'log --graph --oneline --decorate'

Reset to previous commit (very dangerous, erases everything to specified commit):

$ git reset --hard HEAD^

If a repository address gets changed, its remote location will need to be updated:

$ git remote set-url origin git@address:user/repo.git

Signed-off-by line append (a name-email signature is added to the commit which is required by some projects):

 $ git commit -s

Signed-off-by automatically append to patches (when using git format-patch commit):

$ git config --local format.signoff true

Commit specific parts of files that have changed. This is useful if there are a large number of changes made that would be best split into several commits:

$ git add -p

マスター以外のブランチで作業

Occasionally a maintainer will ask that work be done on a branch. These branches are often called devel or testing. Begin by cloning the repository.

To enter another branch beside master (git clone only shows master branch but others still exist, git branch -a to show):

$ git checkout -b branch origin/branch

Now edit normally; however to keep the repository tree in sync be sure to use both:

$ git pull --all
$ git push --all

Git サーバー

様々なプロトコルによるリポジトリへの接続を設定する方法。

SSH

SSH プロトコルを使うには、まず SSH 公開鍵を設定します。SSH 鍵のガイドに従って設定してください。SSH サーバーを設定する方法は、SSH を見て下さい。

With SSH working and a key generated, paste the contents of ~/.ssh/id_rsa.pub to ~/.ssh/authorized_keys (be sure it is all on one line). Now the Git repository can be accessed with SSH by doing:

$ git clone user@foobar.com:my_repository.git

You should now get an SSH yes/no question, if you have the SSH client setting StrictHostKeyChecking set to ask (the default). Type yes followed by Enter. Then you should have your repository checked out. Because this is with SSH, you also have commit rights now.

To modify an existing repository to use SSH, the remote location will need to be redefined:

$ git remote set-url origin git@localhost:my_repository.git

Connecting on a port other than 22 can be configured on a per-host basis in /etc/ssh/ssh_config or ~/.ssh/config. To set up ports for a repository, if the repository is in ~/ and using 443 for the port:

~/.git/config
[remote "origin"]
    url = ssh://user@foobar.com:443/~my_repository/repo.git

Smart HTTP

Git is able to use the HTTP(S) protocol as efficiently as the SSH or Git protocols, by utilizing the git-http-backend. Furthermore it is not only possible to clone or pull from repositories, but also to push into repositories over HTTP(S).

The setup for this is rather simple as all you need to have installed is the Apache web server (apache, with mod_cgi, mod_alias, and mod_env enabled) and of course, git.

Once you have your basic setup running, add the following to your Apache configuration file, which is usually located at:

/etc/httpd/conf/httpd.conf
<Directory "/usr/lib/git-core*">
    Require all granted
</Directory>
 
SetEnv GIT_PROJECT_ROOT /srv/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

This assumes your Git repositories are located at /srv/git and that you want to access them via something like: http(s)://your_address.tld/git/your_repo.git.

ノート: Make sure that Apache can read and write to your repositories.

For more detailed documentation, visit the following links:

Git

ノート: Git プロトコルでは読み取りアクセスだけが許可されます。

git-daemon.socket起動・有効化してください。

The daemon is started with the following options:

ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git

Repositories placed in /srv/git/ will be recognized by the daemon. Clients can connect with something similar to:

$ git clone git://location/repository.git

アクセス権限の設定

To restrict read and/or write access, use standard Unix permissions. Refer to http://sitaramc.github.com/gitolite/doc/overkill.html[リンク切れ 2013-11-06] (archive.org mirror) for more information.

より細かいアクセス管理については、gitolitegitosis を参照してください。

参照