gitコマンド 備忘録

# はじめに

タイトル通り、「あれって何だったっけな？」の時のための自分用メモ。
記載コマンドは `-help` した時の表記となるべく同じようになるように記述しておく。

更新は随時行っていく。

# ブランチ操作

## リモートブランチを作成/更新

### チェックアウト中のローカルブランチをそのままpushする場合

`git push <repository> <refspec>`

### リモートブランチを指定してpushする場合

`git push <repository> <localbranch>:<remotebranch>`

## ローカルブランチの作成

### ブランチを作成すると同時にチェックアウト

`git checkout -b <branch> [<repository>/]<branch>`

:warning: `git checkout -B` **で実行すると、同名のブランチが既に存在していた場合は上書きされてしまうので注意**:bangbang:

### upstreamの設定をしながらブランチを作成する

`git branch -t <branchname> [<repository>/]<target_branchname>`

### 空のブランチを作成する

`git checkout --orphan <newbranch>`

## ブランチの削除

### ローカルブランチを削除

`git branch -d <branchname>`

### ローカルブランチを強制的に削除

`git branch -D <branchname>`

### リモートリポジトリーからブランチを削除

`git push --delete <repository> <refspec>`

## ブランチにupstreamを設定する

`git branch -u <target_branchname>`

## ブランチのリネーム

### 通常

`git branch -m <oldbranch> <newbranch>`
:memo: コミットしていない変更がある場合はリネームできない

### 強制的にリネーム

`git branch -M <oldbranch> <newbranch>`


# リモート操作

## 現在のリモートリポジトリーの状態を表示

`git remote show <repository>`

## リモートリポジトリーに関する情報を更新

### テスト実行

`git remote prune --dry-run <repository>`

### 反映

`git remote prune <repository>`

## リモートブランチの情報を更新

## 通常

`git fetch <repository>`

## ブランチの削除情報も含めて更新

`git fetch --prune <repository>`

# tag

## 作成

### コメント付き

`git tag -a <tag_name> (<target_branch>)`

## リモートリポジトリーに反映

`git push <repository> (<tagname>|refs/tags/<tagname>)`

# 対話的ステージング

`git add -i`


# commit

## ステージされている変更をコミット

`git commit`

## 全ての変更をコミット

`git commit -a`


# stash

## 保存

`git stash save <message>`
:warning: コマンドラインからの入力になってしまうので、日本語が化ける

## 一覧表示

`git stash list`

## 反映

### current branchに反映してstashを削除

`git stash pop stash@{0}`

### current branchに反映してstashを保持

`git stash apply stash@{0}`

## 削除

### 指定したstashを削除

`git stash drop stash@{0}`

### 全てのstashを削除

`git stash clear`


# 既にバージョン管理されているファイルの変更を無視したい(update-index)

## assume-unchanged

### 設定する

`git update-index --assume-unchanged <target_file>`

### 元に戻す

`git update-index --no-assume-unchanged <target_file>`

### 設定状態の確認

`git ls-files -v | grep ^h`
:memo: *assume-unchanged* 設定のファイルは状態が **小文字** で表示される

## skip-worktree

### 設定する

`git update-index --skip-worktree <target_file>`

### 元に戻す

`git update-index --no-skip-worktree <target_file>`

### 設定状態の確認

`git ls-files -v | grep ^S`
:memo: *skip-worktree* 設定のファイルは状態が **S** と表示される

## **※assume-unchanged と skip-worktree の違い※**

### assume-unchanged

そのファイルが作業ツリー上で変更されている場合でも git はその変更を無視して変更されていないとみなす。

* merge の時にマージ元の内容で上書きされる。
* `reset --hard`した時も上書きされる。

### skip-worktree

そのファイルが作業ツリー上で変更されている場合には git はその変更を保つ。

* merge の時にローカルの状態が優先されて保持される。
* `reset --hard`したとしても状態は保持される。

# その他のコマンド

## コミットしてあるけどキャッシュから削除して最初から存在しなかったことにする

`git rm --cached ./`

## 特定のモジュールを存在しなかったことにする

### ファイル

`git filter-branch --tree-filter 'rm -f <file>' HEAD`

### ディレクトリ

`git filter-branch --tree-filter 'rm -rf <dir>' HEAD`

## graph

`git log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all`

## conflict発生時に、コマンドラインからサクッとマージ

:memo: マージをするというよりは、競合が起きたモジュールをどちらかのコミットに完全に寄せてしまう対処の仕方

### マージ元を採用

`git checkout --theirs .`

### マージ元を採用 -ファイル単位-

`git checkout --theirs <file>`

### マージ先(workディレクトリ)を採用

`git checkout --ours .`

### マージ先(workディレクトリ)を採用 -ファイル単位-

`git checkout --ours <file>`