自分用 Git事例集

自分用ゆるふわ事例集

# 間違っちゃった系
### 間違って違うブランチにPUSHしてしまった！
事例：案件ごとにブランチを切っていたのに、間違ってdevelopブランチにプッシュしてしまった！
対応：ローカル上のコミットを残しつつ、github のpush を取り消す。
参考：http://hylom.net/2011/03/01/how-to-reset-remote-git-branch/

```
$ git push -f origin HEAD~:develop
```
HEADは最新のコミット、HEAD~はその1つ前のコミットを指す。
-f　オプションを付けることで1つ前のコミットを強制的にpushし、最新のコミットを取り消している。

### 作業自体間違ったブランチで作業していた！
事例：案件ごとの開発を、普通にdevelopブランチで行ってしまった！commitもしてしまい、push前に気付いた場合。

```
# 現在、巻き戻しをしたいブランチにいるかを確認
$ git branch
 
# 巻き戻し先のcommit番号を確認
$ git log
 
# gitのcommitを巻き戻す ファイルは巻き戻さない
$ git reset  <commit id>
Unstaged changes after reset:
M       hoge.txt # ここに自分が間違ったブランチで作業をしたブランチが表示される
 
# 適切なブランチへ移動
$ git  checkout <branch_name>
 
# この際、ファイルの修正はそのまま残っている状態なのでcommit
$ git commit -a 
```
これで、間違ったブランチでの作業を巻き戻した上で、本来のブランチに反映させることができた。

### 不要なファイルをgitに上げてしまった！（↑の事後対応）
いずれかの方法でgit上から削除する

```
$ git rm -f hoge.html # ローカル、リモート共にに削除
 
$ git rm --cached -f foo.html # リモートのみ削除 
```
誤ってaddでステージングしてしまったファイルについても、'git rm --cached'にてアンステージング可能

# 取り消したい系
### コミットを取り消したい

```
# コミットの取り消し、ワークディレクトリはそのまま
$ git revert ---soft f60f24d
 
# コミットの取り消し、およびワークディレクトリも戻す（保存してても作業内容が失われる）
$ git revert ---hard f60f24d
```
取り消したいcommit番号を指定する。

### マージを取り消したい
```
 git revert -m 1 f60f24d
```
-m 1を付ける

### revertを取り消したい
```
git reset --hard HEAD~
```
http://qiita.com/awakia/items/5fad0c454ddc7b478ff1


# 修正、手直し系
### 過去のコミットのコメントを修正したい、または追加で修正を含めたい
##### 直前の場合
```
# 修正を反映するファイルを選択
$ git add hoge.txt

# 選択したファイルをコミット →ammendにより直前のコミットにaddした修正が追加される
$ git commit --amend
```
-aオプションを使う場合

```
$ git commit --amend -a
```

##### 直前でない場合
rebaseを使う

```
# 例えば、3つ前に含めたい場合
$ git rebase -i HEAD~3

#実行すると、エディタが開かれる（以下、例）
pick <コミット1のhash> hogeファイルを修正
pick <コミット2のhash> fugaファイルを修正
pick <コミット3のhash> piyoファイルを修正
↓ #ここで、修正を含めたいコミットのpickをeditに書き換え
edit <コミット1のhash> hogeファイルを修正
pick <コミット2のhash> fugaファイルを修正
pick <コミット3のhash> piyoファイルを修正

# ワーキングディレクトリが選択したコミット1になるので、ammendが使える
$ git add hoge2.txt
$ git commit --amend 
 
# その後、以下を実行しコミット1以降を再度コミット
$ git rebase --continue
```
参考：http://qiita.com/zaneli@github/items/8d519a229653a2ed9ec6

### rebaseで複数のコミットを統合する
```
# コミット履歴を修正したい範囲を指定
$ git rebase -i HEAD~3
 
#実行すると、エディタが開かれる（以下、例）
pick <コミット1のhash> hogeファイルを修正
pick <コミット2のhash> fugaファイルを修正
pick <コミット3のhash> hogeファイルを修正(修正漏れ)
↓以下の様に変更
pick <コミット1のhash> hogeファイルを修正
s <コミット3のhash> hogeファイルを修正(修正漏れ)
pick <コミット2のhash> fugaファイルを修正

 
# すると再度エディタが開くので、1行目にコメントを記入
 
# git log で確認してみる
$ git log 
 
# pushする、既にpush済みの場合は-fが必要 または1人作業のときはリモートブランチ削除→再プッシュも可
git push
```
ただし、rebaseはコミット履歴を修正する行為なので、複数人で同じブランチで作業しているときは注意が必要。**少なくとも、Push済みのコミット履歴の修正は避けるべき。**

参考：http://qiita.com/takke/items/3400b55becfd72769214

### rebaseの別の使い方
ローカルのmasterブランチが最新の状態、かつ開発ブランチにいるときに、以下のコマンドでmasterブランチの内容を反映することができる。

```
$ git rebase master
```
詳細はこちら。http://sota1235.com/blog/2015/03/19/git-rebase.html

# 戻す、持ってくる系
### 指定したコミットIDの状態にしたい
```
$ git checkout 8cc97c1  hoge.php # 指定したファイルのみを変更
$ git checkout 8cc97c1  . #　全部変更
``` 
### 他リポジトリの特定のコミットだけ反映させたい
git cherry-pick なるコマンドでいける模様（使ったことない）
http://rfs.jp/server/git/gite-tech/git-cherry-pick.html



### リモートブランチをそのままローカルに持って来たい
```
# ブランチnew-branchをローカルに持って来たい
git branch new-branch origin/new-branch
 
# ローカルに持って来て、ついでにブランチも切り替えたい
git checkout -b new-branch origin/new-branch
 
------------------------------------------------
# 仮に以下のエラーが表示された場合
$ git checkout -b hoge origin/hoge
fatal: git checkout: updating paths is incompatible with switching branches.
Did you intend to checkout 'origin/hoge' which can not be resolved as commit?
 
# リモートも含めてブランチを確認する
$ git branch -a
...
 
# ここでリモートから持って来たいブランチがなかった場合は、一度fetchを挟む
$ git fetch
* [new branch] 
...
 
# 再度リモートも含めてブランチを確認
$ git branch -a
remote/origin/hoge

# 持って来たいブランチがあることを確認したら、再度チェックアウト
$ git checkout -b hoge origin/hoge
Branch hoge set up to track remote branch hoge from origin.
Switched to a new branch 'hoge'
```
参考：http://blog.inouetakuya.info/entry/20120826/1345979787
http://d.hatena.ne.jp/yuheiomori0718/20130701/1372688497

### 特定のブランチの特定のファイルのみを持って来たい
```
# 持って来たいファイルのあるブランチをローカルに持ってくる  cf.「リモートブランチをそのままローカルに持って来たい」
$ git checkout -b <target_branch> origin/<target_branch>
 
# 持って来たいブランチとファイルを指定してcheckout
$ git checkout <target_branch> <target_file>
```


### ローカルリポジトリをリモートリポジトリに上げたい
ローカルリポジトリにて、以下を実行。

```
$ git init
$ git add .
$ git commit -m 'commit message'
```
リモートでリポジトリを作成、リモートリポジトリのSSHをコピーする。

その後、ローカルにて以下を実行。

```
$ git remote add origin [リモートリポジトリのSSHのcopy]
$ git push --set-upstream origin master
```

# 痒いところに手が届く系
### 不要なファイルをgitに上げたくない！
http://www.omakase.org/misc/gitignore.html
トップディレクトリにある.gitignoreに、gitに上げたくないファイル名、ディレクトリ名を記述する。

### 部分的にaddしたい

-pオプションを指定してaddしたいファイルを指定すると、そのファイル内のハンク（変更のかたまり）ごとにaddをするかを指定することができる。

```
$ git add -p
``` 

# 設定系
### forkしてきた本家ブランチをupstreamに設定する
```
# 本家ブランチを
$ git remote add upstream git://github.com/DQNEO/Renshu.git （clone時に指定するURL）

# 確認
$ git remote -v
```

# トラブル系
### (no branch)状態になった！
```
$ git checkout 8cc97c123
Note: checking out '8cc97c123'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
  git checkout -b new_branch_name
HEAD is now at 8cc97c1... for version 1.0.1
```
checkoutで特定のコミットを指すと、detached HEAD状態になる。これは、いずれのブランチからも切り離された状態。ここで加えた変更はどのブランチにも影響を与えない。変更箇所を破棄することも別ブランチに反映させることも可能。

##### 変更を破棄する場合
後で書く

##### 変更を別ブランチに反映させる場合
```
git branch XXX(branch_name) (commit_id)
```
参考：http://devlights.hatenablog.com/entry/20130417/p1