Git よく使うコマンドまとめ

✍🏼 作成日 2016年04月21日   
❗️ 注意:この記事が作成されてから既に 日が経過しています。情報の鮮度にご注意ください

はじめに

Gitを頻繁に使っていますが、ずっと書く時間がありませんでした。今やっと時間ができたので、よく使うコマンドをまとめてみます。

本文

新しいブランチを作成し、そのブランチに切り替える:

1
git checkout -b branch_name

ブランチを切り替える:

1
git checkout branch_name

ブランチを削除する(先に別のブランチにcheckoutする必要がある):

1
git branch -d branch_name

注意:ローカルで新しいブランチを作成したが、git pushしていない場合、以下のコマンドでブランチを削除しようとすると警告が表示されます

1
2
error: The branch 'test' is not fully merged.
If you are sure you want to delete it, run 'git branch -D test'.

本当に不要な場合は、指示に従って強制削除してください。

ファイルをコミットする流れは:

1
git add ==> git commit ==> git push

git addでよく使うパラメータは3つあります:

  1. git add -A すべての変更記録(新規追加、削除、変更)をステージングエリアに追加します。
  2. git add . ファイルの追加記録と変更をステージングエリアに追加しますが、削除されたファイルは含まれません。
  3. git add -u ファイルの削除と変更記録をステージングエリアに追加しますが、新規追加されたファイルは含まれません。

人生に後悔薬はありませんが、gitにはあります。誤ったファイルをコミットしてしまった場合やコミットメッセージを間違えた場合は、状況に応じて以下のコマンドを実行できます。

まずgit statusでバージョン状態を確認します(私はzshを使っています)。赤いファイルはステージングエリアにgit addされていない状態、緑のファイルはすでにgit addされており、git commitを待っている状態です。

この時、git addをキャッシュエリアに行きたくない場合は、git reset HEADですべてのファイルを未git addの元の状態に戻せます。特定のファイルだけgit addをキャッシュエリアに行きたくない場合は、ファイル名を指定します:

1
git reset HEAD filename

時には、変更したファイルをgit addキャッシュエリアに移動したくないだけでなく、そのファイルに行ったすべての変更を無視したい(つまり未変更状態に戻したい)場合もあります。その場合は再チェックアウトすればよいです:

1
git checkout -- filename

ここでスペルミスがないことに注意してください。checkoutfilenameの間には左右にスペースを挟んだハイフンがあります。

git addの後はgit commitです。-mパラメータを付けてコミットメッセージを書くことができます。これは良い習慣であり、強制されています。-mパラメータがない場合は、vim編集モードに入り、メッセージを追加するよう促されます:

1
git commit -m '这是一个提交说明'

この時、コミットメッセージを間違えたことに気づき、commitしたくない場合(HEADはすでに変更されています)、2つの方法があります:

1つはcommitを削除することです(これはまだpushされておらず、ローカルリポジトリにcommitされているだけです):

まずgit logし、誤ってcommitする前のcommit idをメモします。これはhash(SHA)で、例えば73cf3bfc3419a85e959d7ecfcb917d9cdc24b3c9、または直近のpushHEADでも構いません:

1
git reset 73cf3bfc3419a85e959d7ecfcb917d9cdc24b3c9

(この時はgit addの時にgit reset HEADを使うことができません。git commitの後HEADはすでに変更されているため(つまりgit logでコミット履歴を確認できる状態になっているため)です)

ここでgit resetコマンドの3つのパラメータについて補足します:--mixed,--soft,--hard:

ネット上には多くのチュートリアルがあり、図解や公式ブランチ説明の引用などがありますが、複雑です。私は簡単に説明します。

シンプルに、例を挙げて簡単に説明しましょう。 —Xheldon

git resetのデフォルトはmixedパラメータで、git reset xxxxを実行します(xxxはSHAまたは未commitの場合はHEADを表します)。これはgit reset --mixed xxxxを実行するのと同じで、ファイルを変更した後、gitコマンドを実行していない状態(ファイルが赤い状態)に戻します。

--softパラメータは、ファイルを単にコミット前の状態に戻すだけで、ファイルはまだgit addされています(緑のままです)。

--hardはより強力で、指定したコミット記録の状態に完全にファイルを復元します。addしたかcommitしたか、ファイルを変更したかに関係なく、すべて無視します。git reset --hard xxxを実行するのはある程度危険で、現在の変更がローカルから削除されることに注意してください。

git reset --hard xxxの後、ファイルはローカルから削除され、すべての変更も削除されていますが、hardで削除したファイルの変更記録を復元したい場合はどうすればよいでしょうか?git reflogを使います

あなたが行ったすべてのcommitreset操作は、gitによって記録が生成されます。この記録はgit reflogで見つけることができ、各記録の前に短いhashがあります。この短いhashをコピーして、git reset --hard short_hashを再度実行すればよいです。

注意:git commitを実行した後、HEADはすでにコミットしたファイルの変更状態になっています。そのため、git reset --mixed HEADgit reset --soft HEADを実行しても効果がありません(現在のHEADcommit後のポイントだからです(pushしていなくても))。git add後の状態に戻りたい場合、git commit前の状態に戻るにはgit reset --soft commit_idが必要です。git add前の状態に戻るにはgit reset --mixed commit_id、または直接git reset commit_idします。

git commit後悔薬の別名は--amendです。コミット後に後悔し、メッセージを間違えたことに気づいた、またはファイルをさらに変更した場合、commit記録を生成したくない(見た目が悪く、あなたがコミットメッセージを間違えるような初心者に見えるため)、次のコマンドを実行します:

1
git commit --amend change_file_name_after_commit -m "新的msg"

これで完了です。

後悔薬を飲んだ後、git commitして問題がなければgit pushできます。この時、現在のブランチから分岐したリモートブランチに他の人が更新をコミットしていない場合は、fast forwardモード(ファストフォワードモード)を使用して直接マージできます。マージ状況を視覚的に確認するには:

1
git log --graph --pretty=oneline

ブランチを分岐している間に他の誰かもブランチをコミットした場合、衝突がなければそのままマージできます。まずgit pullを行い、その後git pushを実行する必要があります。
衝突がある場合、他の人の変更とあなたの変更の間にどのような衝突があるかが通知されます。これは手動で解決する必要があり、解決後はgit addgit commitを行います。

ブランチのマージ:

1
git merge another_branch_name

ここでの状況は非fast forwardモードです。つまり、ブランチBがブランチAから分岐した後、親ブランチであるAブランチが変更され、ブランチBも何らかの変更を加えた状態で、再度Aブランチにマージしようとした場合に現在の状況が発生します。
注意:あなたがブランチAにいる場合、mergeする必要があるのはブランチBです。この場合、mergされるブランチBはgit pushされている必要があります。ブランチBが単にgit commitされているだけではマージされません。なぜなら、git merge branch_namebranch_namebranch_nameのリモートoriginからmergeされており、commitはローカルのHEADのみを変更し、pushがないためリモートoriginは変更されていないからです。
ブランチBがすでにgit pushをリモートにプッシュし、ローカルのブランチAもgit addをローカルリポジトリにコミットしている場合、ブランチAでgit merge Bを実行すると(変更されたファイルがconfig.jsだと仮定して)以下のようになります:

1
2
3
4
Updating 474cfbf..9c94d0c
error: Your local changes to the following files would be overwritten by merge:config.js
Please commit your changes or stash them before you merge.
Aborting

これは、2つのブランチをマージする際にエラーが発生して中断されたことを意味します。現在のブランチの変更を一時保存(git stash)するか、変更をコミット(git commit)するように促されます。その後、git mergeを行い、衝突が発生したら手動で修正して再度コミットします。
では、まず現在の変更をgit commitし、再度git merge Bを実行します。この時(衝突ファイルがconfig.jsだと仮定して)以下のようになります:

1
2
3
Auto-merging config.js
CONFLICT (content): Merge conflict in config.js
Automatic merge failed; fix conflicts and then commit the result.

手動で解決した後、再度git addgit commitを行います。

注意:あるブランチでファイルを変更し、checkoutで別のブランチに移動する際に衝突が発生しなかった場合、何の通知もなくファイルの変更は保持されます。したがって、ファイルを1つのブランチで変更した後、別のブランチにコミットすることができます。しかし、1つのブランチでファイルを変更した後、checkoutで他のブランチに移動する際に衝突が発生した場合(例えば他のブランチがgit pullされた、または他のブランチが同じファイルの同じ部分をgit commitした場合):

1
2
3
4
error: Your local changes to the following files would be overwritten by checkout:
config.js
Please commit your changes or stash them before you switch branches.
Aborting

この場合、まずgit stashで変更を一時保存(このstash储藏git add暂存ではありません。stashはファイルを特定の領域に保存し、ブランチを切り替えた後、パッチのようにこのstashを切り替えたcheckoutブランチに適用するか、またはstashを適用せず、切り替えたブランチでの作業が終わってから再度このstashを適用することができます。もちろん、stashをずっと適用したくない場合は適用しなくても問題ありません)。
ここでgit stashについて説明します。このコマンドは、2つのブランチの変更を同時に行う必要がある場合に使用されます。1つのブランチで作業を途中まで進めた状態で、別のブランチも変更する必要がある場合、途中までの作業を破棄することはできず、またcommitすることもできません。なぜなら、checkoutするとconflictが発生する可能性があるため、stashを一時保存する必要があります。
まず現在の状態を確認します。git status

1
2
3
4
5
6
7
8
9
On branch optimize
Your branch is up-to-date with 'origin/optimize'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: config.js

no changes added to commit (use "git add" and/or "git commit -a")

変更を一時保存します。git stash

1
2
Saved working directory and index state WIP on optimize: 24bf0e1 test add
HEAD is now at 24bf0e1 这是一个提交

その後、再度git statusを確認します:

1
2
3
On branch optimize
Your branch is up-to-date with 'origin/optimize'.
nothing to commit, working tree clean

これで安心して他のブランチに切り替えることができます。ここで注意すべきは、他のブランチに切り替える際に、保存したブランチの変更を現在のブランチに適用することもできるということです(衝突を恐れなければ)。保存リストを確認します。git stash list

1
stash@{0}: WIP on optimize: 24bf0e1 test add

これは先ほどstashした変更です。git stash applyを使用してこの最新の変更を適用できます。stashの変更が複数ある場合は、stashの名前を指定します:

1
git stash apply stash@{0}

適用後、このstashは保存領域から削除されます。削除したくない場合は:

1
git stash apply stash_name --index

後で削除したい場合は:

1
git stash drop stash_name

上記の2つのコマンドでstash_nameを指定しない場合、デフォルトで最新のstashが削除されます。

とりあえず思いつくのはこれくらいです。慣れていない場合は、Sourcetreeを使用することをお勧めします。

更新

git revert/reset/rebase 説明を読むだけでは理解できません。自分でコマンドを入力してテストする必要があります。

私はクリーンで整理されたコミット履歴のためにgit rebaseを使用するのが好きですが、このコマンドは危険で、いくつかの使用シナリオに注意が必要です。git rebaseよりもさらに危険なのはgit resetで、これは現在のプロジェクトを特定のコミットにリセットします。git revertは比較的安全ですが、revertする前にキャッシュ領域が空であることを確認する必要があります。そうでないとエラーメッセージが表示されます。

もちろん、gitコマンドは数え切れないほどあります(誇張)。いくつかのコマンドは特定のシナリオ向けであり、遭遇するまでその使用方法を理解できないこともあります。これは正常です。

例えば、git reset commitIdHEADcommitIdの場所に移動します。これを見て「HEADを移動して何の意味があるのか?このコマンドの目的は何か?」と疑問に思うかもしれません。また、git revert commitIdcommitIdのコミットを削除しますが、HEADのポインタは移動しません。

コードを見る(d0b9defcommit -m 'reset/revert test 3' のコミットに対応、現在 HEAD'reset/revert test 4' 上):

git revert d0b9def の後、あなたのコードはこのようになっているかもしれません:

1
2
3
4
5
6
7
reset/revert test 1
reset/revert test 2
<<<<<<< HEAD
reset/revert test 3
reset/revert test 4
=======
>>>>>>> parent of d0b9def... reset/revert test

同じ HEAD 上で git reset d0b9def を実行した後、あなたのワークスペースはこのようになっているかもしれません:

1
2
3
4
 reset/revert test 1
reset/revert test 2
reset/revert test 3
+reset/revert test 4

HEAD を移動させるかどうかの違いが分かりましたか? revert は必ず手動でコンフリクトを解決させるよう要求します。なぜなら、それは commitId 前の親 commit から現在の HEAD までの、d0b9def を除くすべての変更を保持するからです。一方 reset はコンフリクトを解決させず、黙って HEAD を移動させ、d0b9def 以降のすべての変更をファイル変更として表示し、手動で git add/commit する必要があります。もちろん push --force も欠かせません。

したがって、revert公开 のコミットを安全に取り消すように設計されており、reset本地 の変更をリセットするように設計されています。両コマンドの目的が異なるため、実装も異なります: リセットは一連の変更を完全に削除しますが、取り消しは元の変更を保持し、新しいコミットで取り消しを実現します。

- EOF -
この記事の初出: Git よく使うコマンドまとめ - Xheldon Blog