バージョン管理の個人的な考え方
基本的に歴史は改変したくないタイプ。タイポの修正もわざわざrebase
しないで普通にcommit
します。
初回のpush
までは色々試行錯誤もあるので、ローカルのコミットはしばらく放置していますが、目処が立ったらステージングしコミットを付けていきます。
Gitでやらかした時に使える19個の奥義がよく検索ヒットしますが、個人的にはあまり実務で使ってないんです。
そこで、ビギナー〜中級の人向けに役に立つコマンドを以下にまとめます。
という書き出しで当初はまとめていましたが、実は考えが変わってきました。
rebaseからのforced pushはやっても良い派になりました。ただし、forkからのPull Requestもしくはレビュー前のコミットの場合に限ります。自分のリポジトリのブランチなんだからキレイにした後にマージしてもらう方が親切だったり、レビューワーを意識したまとまりにしておく方が親切かなっと。
脱Git初心者のための参考書
-
Gitのリポジトリの中身をなるべく正確に理解する
- これはマジで一回読んだほうがいい
- A successful Git branching model
実務でよく使うGitコマンド
変更点を部分的にステージングしたいとき
最初は試行錯誤し、目処が付いたらコミットを開始するんですが、同じファイルの一部だけをコミットしたい場合が多発します。そんなときはこれ。
$ git add -p [ファイル]
概要
変更点の塊=ハンク(Hunk)を指定してステージングすることができます。
ハンクごとにどうするのかを聞かれ、回答に以下のオプションを入力してステージングするかどうか決めていく。
ちなみに、p
はpatch
のことです。
-p, --patch
Interactively choose hunks of patch between the index and the work tree and add them to the index. This gives the user a chance to
review the difference before adding modified contents to the index.
This effectively runs add --interactive, but bypasses the initial command menu and directly jumps to the patch subcommand. See
"Interactive mode" for details.
オプション
オプション | 意味(原文) | 意味 |
---|---|---|
y | stage this hunk | このハンクをステージングする(インデックスに移す) |
n | do not stage this hunk | このハンクは無視する |
q | quit; do not stage this hunk or any of the remaining ones | このハンク以降は無視して終了する |
a | stage this hunk and all later hunks in the file | このハンクとそれ以降のハンク全部ステージングする |
d | do not stage this hunk or any of the later hunks in the file | このハンク以降はステージングしない |
g | select a hunk to go to | ステージングするハンクを選択する |
/ | search for a hunk matching the given regex | 正規表現に一致するハンクを探す |
j | leave this hunk undecided, see next undecided hunk | このハンクは保留して次の未操作ハンクに移る |
J | leave this hunk undecided, see next hunk | このハンクは保留して次のハンクに移る |
k | leave this hunk undecided, see previous undecided hunk | このハンクは保留して前の未操作ハンクに移る |
K | leave this hunk undecided, see previous hunk | このハンクは保留して前のハンクに移る |
s | split the current hunk into smaller hunks | このハンクを自動で分割する(分割されたハンクごとに同じように操作していく) |
e | manually edit the current hunk | このハンクを手動で分割する(別の画面へ) |
? | print help | ヘルプを表示 |
勢いでステージングしたハンクをワークツリーに戻したい
さっきのgit add -p
で追加間違いしたらこれで戻します。
$ git reset -p [ファイル名]
概要
基本的にはgit add -p
と同じ使い方ですが、オプションe
で手動で各行の操作を実行する場合は固有の操作が必要です。
e
を選択した場合は以下のような表示でvi等のエディタが起動します。
追加部分+
をワークツリーに戻す場合は、行頭の+
をスペースに置き換えてあげます。
削除部分-
をワークツリーに戻す場合は、その行を削除。
編集が完了したら上書き保存してエディタを終了します。
# Manual hunk edit mode -- see bottom for a quick guide.
@@ -21,6 +25,6 @@ class UsersController < ApplicationController
private
def method
- params.require(:user).permit(:name)
+ params.require(:user).permit(:name, :avator)
end
end
# ---
# To remove '+' lines, make them ' ' lines (context).
# To remove '-' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for unstaging.
# If it does not apply cleanly, you will be given an opportunity to
# edit again. If all lines of the hunk are removed, then the edit is
# aborted and the hunk is left unchanged.
プルリクエストをレビューしたいからローカルに落としたい
レビューを依頼されたら、そのプルリクの変更が反映された環境をローカルで動作確認したい場合があります。
そんなときはこれ。
$ git fetch [remoteリポジトリ名(originなど)] pull/[id]/head:[ブランチ名]
$ git branch
* master
[ブランチ名]
$ git checkout [ブランチ名]
概要
ローカルに該当プルリクエストのブランチをfetchし、そのブランチにcheckoutします。
例えば、以下のようなプルリクがあったとすれば、git fetch origin pull/4893/head:check-confirmation-token-present
となります。
![スクリーンショット 2018-07-05 23.43.53.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F249168%2Ff61ce915-6e74-2db0-42bd-dc5bcc580511.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=9b3486519ae696652b457007d33abf69)
参考
インデックスの内容の差分を確認
コミットする直前で、今から何のコミットだっけ?ってど忘れをすることが多い方にはこれ。
$ git diff --cached
概要
ステージングエリア(インデックス)の内容と最新コミット時点の差分を表示します。
ワークツリーの内容の差分を確認
これからどの変更をステージングしようかな?と悩んだときはこれ。
$ git diff
概要
ワークツリーの内容と最新コミット時点の差分を表示します。
ローカルとリモートのmasterブランチに差異があるので、リモートの内容に強制同期
なぜかリモートと差異があった場合にはコレでリモートの内容に合わせます。
$ git fetch origin
$ git reset --hard origin/master
過去のコミットメッセージを変更したい
以下の方法は、今更気づいた場合かつ、pushしていない場合のみ有効な方法です。
ちなみに、n
はHEADを1としたときに何番目のコミットかを表す数字。つまり、git log --oneline
で上から数えた値です。
$ git log --oneline
0237ff3 (HEAD -> hoge)
98071c1 途中のコミット
8d99250 大切なコミットっ
$
$ git rebase -i HEAD~n
## コミットがコミット順の昇順でならんだviが開くので、変更したいコミット(今は8d99250とします)の行でpickをeditに変更して上書き保存します。
## すると...
Stopped at 8d99250... 大切なコミットっ
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
$
$ git commit --amend -m '大切なコミット'
[detached HEAD 2b6a3d2] 大切なコミット
Date: Thu Feb 14 14:52:37 2019 +0900
1 file changed, 84 insertions(+), 4 deletions(-)
$
$ git rebase --continue
Successfully rebased and updated refs/heads/feature/AL-809.
$
概要
つまりはただのrebase
です。rebase
なのでpush
していないときに使うようにします。