🖥️

Gitのコマンドについて

2021/09/11に公開

畑田です。自分がよく使う、よく調べ直すコマンドを日本語でまとめました。

clone

remoteのリポジトリをcloneする。
cloneするリポジトリのために自動生成されるディレクトリの名前(下ではREPOSITORY_NAME)を指定しないと、リポジトリ名と同じになる。

$ git clone REPOSITORY_URL DIRECTORY_NAME

remote repositoryの追加

# after creating remote repository in GitHub
$ git remote add origin REMOTE_REPOSITORY_PATH
$ git remote -v

staging

stagingする。

$ git add FILE_PATH

ディレクトリ内の全てのファイルをstagingする。

$ git add .

unstagingする。
indexの内容を破棄する。

$ git reset

commit

commitする。
以下のコマンドでvimが起動するので、iでinsertモードにしてコミットメッセージを追加し、escキー、:wqでcommitを完了できる。
:q!でcommitをabortできる。

$ git commit

コミットメッセージ付きでcommitする。

$ git commit -m 'COMMIT_MESSAGE'

最新のcommitを現在のindexを踏まえて修正する。
remoteへの反映後にこれを行うのは忌避すべきである。

$ git add . # staging
$ git commit --amend

log

logを見る。

$ git log

1行ずつのlogを見る。

$ git log --oneline

push

上流ブランチにpushする。

$ git push

pushする前に、pushしたときの挙動を確認する。

$ git push --dry-run
# or
$ git push -n

push先を明示してpushする。

$ git push REMOTE_NAME BRANCH_NAME

上流ブランチを設定しながらpushする。

$ git push --set-upstream REMOTE_NAME BRANCH_NAME
# or
$ git push -u REMOTE_NAME BRANCH_NAME

pull

pullはfetchとmergeを組み合わせた操作です。
今checkoutしているブランチの上流ブランチからpullする。

$ git pull

remote branchを明示してpullする。

$ git pull REMOTE_NAME BRANCH_NAME

pullするときのlocalでのbranch名を明示してpullする。

$ git pull REMOTE_NAME BRANCH_NAME:TARGET_NAME

difference

基本的な使い方。
..の前のブランチを時系列的に前のブランチ、後のブランチを後のブランチとして差分を表示する。
--の後にpathを書くと、そのファイルについての差分を表示する。これは以下のコマンドの末尾に追加しても有効である。

$ git diff PREVIOUS_BRANCH..NEXT_BRANCH -- FILE_PATH

git pull する前にリモートとの差分を表示する。

$ git diff HEAD..REMOTE_NAME/BRANCH_NAME

git push する前にリモートとの差分を表示する

$ git diff REMOTE_NAME/BRANCH_NAME..HEAD

一つ前のcommit (HEAD^)との差分を表示する。

$ git diff HEAD^
# or
$ git diff HEAD^..HEAD

stagingする前に最新のcommitとwork tree (現状)の差分を表示する。

$ git diff

stagingした後に最新のcommitとindexの差分を表示する。

$ git diff --cached
# or
$ git diff --staged

差分のstatusを表示する。

$ git diff --stat

branchを表示

ローカルのブランチを表示する。

$ git branch

リモートのブランチを表示する。

$ git branch -r

上流ブランチを表示する。

$ git branch -vv

local branchに上流ブランチを設定する。

$ git branch --set-upstream-to=REMOTE_BRANCH
# or
$ git branch -u REMOTE_BRANCH

branchを削除する。

$ git branch -d BRANCH_NAME

branchを強制削除する。

$ git branch -D BRANCH_NAME

branchの名前を変更する。

$ git branch -m CURRENT_BRANCH_NAME NEW_BRANCH_NAME # CURRENT_BRANCH_NAME is optional.

branchを切り替える

branchを切り替える。

$ git checkout BRANCH_NAME
# or
$ git switch BRANCH_NAME

branchを新しく生成しながら、そのbranchに切り替える。
このとき、commitしていないindexやwork treeの変更はそのbranchに移行される。

$ git checkout -b NEW_BRANCH_NAME
# or
$ git switch -c NEW_BRANCH_NAME # -c stands for --create

check out

work treeの変更をなかったことにする。(check outする。)
.の部分を特定のファイルにすれば、そのファイルのみに適用できる。

$ git checkout .

fetch

fetchとはremoteのbranchの最新のcommitを取得することで、取得されたcommitは無名のブランチとして管理され、FETCH_HEADという仮の名前でcheck outすることができる。

$ git fetch

remote repositoryを明示してfetchする。

$ git fetch REMOTE_NAME

削除されたブランチなどの変更を取りえれてfetchする。

$ git fetch --prune

merge

今checkoutしているブランチに指定したブランチからmergeする。
BRANCH_NAMEとしているところにはorigin/developなどが入る。

$ git merge BRANCH_NAME

変更をなかったことにする

resetコマンドを使うと、指定したコミットログのcommitの状態に戻すというような作業が行える。
コミットログを明示しないと、一つ前のcommitの状態に戻る。
代表的なoptionには--soft--mixed--hardがあり、それぞれ何を戻すのかが変わる。
何もoptionをつけないと--mixed optionをつけたときの挙動を示す。
以下にメモしていく。
HEADだけを指定したcommitの状態に戻し、indexとwork treeは戻さず今の状態を保持する。

$ git reset --soft COMMIT_LOG

HEADとindexを指定したcommitの状態に戻し、work treeは戻さずに今の状態を保持する。
unstageにも使える。

$ git reset --mixed COMMIT_LOG
# or
$ git reset COMMIT_LOG

HEADとindexとwork treeを指定したcommitの状態に戻し、現状の変更を全て破棄する。

$ git reset --hard COMMIT_LOG

restoreコマンドを使うと、check outと同じような挙動で変更の破棄を行える。
.の部分を特定のファイルにすれば、そのファイルのみに適用できる。

$ git restore .

git rmとかrmとかgit rm --cachedとか、、、

まずgit rmrmですが、この二つのコマンドに本質的な違いはありません。
以下のコマンドでは、指定したファイルがwork treeから削除され、その変更がindexにstagingされます。

$ git rm FILE_PATH

一方、以下は普通のファイル削除コマンドですから、work treeでは指定されたファイルは削除されますが、stagingされません。

$ rm FILE_PATH

ところで、--cached optionについて、その正確な仕組みがわかっていなかったので記録しておきます。
このコマンドはgitの管理から指定したファイルを除外するものです。
とよく言われますが、次のように実現されています。

  • work treeの指定ファイルは削除されずに、indexにだけ指定ファイルが削除されたとstagingされます。
  • これ以降、work treeの指定ファイルは新しく生成されたファイルとして扱われます。
  • .gitignoreに指定ファイルを追加すると、そのファイルはgitから見えなくなり、生成されたことが記録されません。

以上によって、gitにとってはファイルは削除されているが、work treeにのみそのファイルが存在し、変更が記録されないという状況が実現されます。
一応簡単にコマンドを載せておきます。

$ git rm --cached FILE_PATH
$ echo FILE_PATH >> .gitignore
$ git add -- .gitignore
$ git commit -m 'untrack FILE_PATH' -- FILE_PATH .gitignore

変更をcommitせずに保存しておく

変更をcommitしたくないけど、branchを切り替えたいというときに、変更を保持しておけるのがstashです。
stashはindexの内容をスタック空間に保持しておける機能です。
まずはstashに変更をpushするコマンドです。

$ git stash push
# or
$ git stash
# with a message
$ git stash push -m 'MESSAGE'

stashした内容を確認する。
ここではgit logと同じoptionが使えます。--oneline-pなどです。

$ git stash list

stashした内容を復元する。

$ git stash apply STASH_NAME

stashを削除する。

$ git stash drop STASH_NAME

stashを復元させながら、スタック空間から削除する。

$ git stash pop STASH_NAME

コンフリクト解決

コンフリクトの解決はファイルを確認しながら手動でやった方が良いことが多いが、一応コマンドもある。
merge元のbranchを優先する

$ git checkout --theirs -- FILE_PATH

merge先のbranchを優先する

$ git checkout --ours -- FILE_PATH

Discussion