🙄

開発現場でよく使うGit コマンドシリーズ

2022/03/30に公開約7,000字

ファイルの変更を保存する系

ワークツリーからインデックスにファイルの変更内容を移動する。

$ git add -A 

インデックスに置かれたファイルの変更内容をコメットメッセージを添えて保存する。

$ git commit -m 'message'

現在チェックアウトしているブランチの最新の状態をgitlab、もしくはgithubのリモートリポジトリにpushする。

$ git push origin HEAD

ワークツリー

自分が作業している場所

現在checkoutしているブランチの先頭

commitの履歴閲覧系

コミット履歴を見ることができる。

$ git reflog
8645cbf (HEAD -> test) HEAD@{0}: commit: test
9656c9d (origin/master, typescripts, master) HEAD@{1}: checkout: moving from test2 to test
f0698c6 (test2) HEAD@{2}: commit: test
9656c9d (origin/master, typescripts, master) HEAD@{3}: checkout: moving from test to test2
9656c9d (origin/master, typescripts, master) HEAD@{4}: checkout: moving from master to test
9656c9d (origin/master, typescripts, master) HEAD@{5}: checkout: moving from typescripts to master

特定のcommitまで戻す系

上の git reflog で出力されたコミット一覧の中に、 HEAD@{番号} の表記があるので、これを使って特定のコミットまで戻ることができる。
ちなみに、 --hard オプションをつけると、HEADの位置、ワークツリー、インデックスの全てを HEAD@{0} の位置に移動することができる。

$ git reset --hard HEAD@{0}

addした内容、つまりインデックスにある内容を取り消したい場合は --mixed オプションをつける。

$ git reset --mixed HEAD@{0}

index( git add . した変更内容)にある更新内容を、ワーキングディレクトリに戻す

git reset .

参考サイト

https://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe

一時待避系

ファイルの変更内容を一時的に退避させる。

$ git stash save

退避させた内容をワークツリーに戻す。

$ git stash pop

退避させた変更内容の一覧を表示する。

$ git stash list
stash@{0}: WIP on typescripts: 9656c9d yaml修正
stash@{1}: WIP on typescripts: 9656c9d yaml修正
stash@{2}: WIP on typescripts: 9656c9d yaml修正

退避させた変更内容をワークツリーに適用する。

$ git stash apply stash@{1}

以前のcommitとの差分を見る

差分を見る系

以前のcommitとの差分を見る。

$ git diff /var/www/html/sample_project/index.html

ブランチ間で差分を見る。

$ git diff [branchA] [branchB]

ブランチ操作系

新規ブランチを作成する

$ git branch -b example-branch

指定したブランチにチェックアウトする

$ git checkout example-branch

新規ブランチを作成した上でチェックアウトする。

$ git checkout -b example-branch

remoteリポジトリにあるブランチをローカルに持ってくる

remoteリポジトリの状態をローカルリポジトリに反映する

$ git remote update

リモートリポジトリのブランチをローカルリポジトリに持ってくる。

$ git checkout -b example-branch origin/example-branch

ブランチ名を変更する。

git branch -m <古いブランチ名> <新しいブランチ名>

不要なブランチを削除する

merge済みのブランチを削除

git branch --merged|egrep -v '\*|develop|master'|xargs git branch -d

mergeされていないブランチを削除

git branch |egrep -v '\*|develop|master'|xargs git branch -D

別ブランチからcommitをピックアップする系

git cherry-pick [commit ID]

commitをピックアップする手順

1. git chekcout develop でピックアップされるブランチに移動
2. git log でcommit IDを確認する
3. git checkout featureでピックアップ先のブランチに移動
4. git cherry-pick [commit ID]

コンフリクト解消系

test1ブランチにtest2ブランチを取り込む場合。

$ git checkout test1
$ git merge test2

test1ブランチとtest2ブランチで同様の箇所を修正していた場合にコンフリクト(衝突)が発生し、開発者自身がコンフリクトの解消を行わなければいけない。

コンフリクト発生画面
localhost@root:laravel_project $ git merge test2
CONFLICT (add/add): Merge conflict in app/Http/Controllers/conf copy.php
Auto-merging app/Http/Controllers/conf copy.php
Automatic merge failed; fix conflicts and then commit the result.

VSCodeにてコンフリクトを解消する

VSCodeのファイル一覧を見ると、コンフリクトが発生しているファイル名のところに「C」のマークがついているのがわかる。

このファイルにてコンフリクトが発生している。

ea11279847e06625f7c47634fd8b9d68.png

コンフリクトが起きているファイルを開くと、2つのブランチ間での差分が表示される。

74cfadc026d72851716be28275069b4f.png

HEAD (Current Change) の部分が、現在チェックアウトしているブランチにて加えられている変更内容である。

test2 (Incoming Change) の部分が、チェックアウトしているブランチに取り込みたいブランチにて加えられた変更内容である。

この2つのブランチにて加えられた変更内容のどちらを採用するのかを開発者自身が選択する。

ee9374a3ac7b5e630549f0e01084caf0.png

上記の画像のように、VSCode上の各ボタンを選択することで、コンフリクトを解消することができるようになっている。

Accept Current Change は 現在チェックアウトしているブランチの内容を採用する。

Accept Incoming Change` は取り込まれる側のブランチの内容を採用する。

Compare Changes を選択すると、以下のように差分を見ることができる。

Accept Both Changes は現在チェックアウトしているブランチと、取り込まれるブランチの両方をブランチの変更内容を採用する。

8b886157373395eab01828acfb5e125e.png

コンフリクトを解消した後は、解消した内容をcommitする必要がある。

$ git add -A
$ git commit -m 'resove conflict'

以上で、test2ブランチの内容をtest1に取り込んだ上で、その際に発生したコンフリクトを解消することができた。

fast-forward とは

developブランチをmasterブランチにマージするときに、masterに変更がなかったときに、行われるマージをfast-forwardマージとする。

Gitコマンドのショートカットを登録する方法

アプリ開発などをしていると、1日に何回も打つことになるであろうGitコマンドのショートカットがあれば便利だと思って、設定してみることにした。

ちなみに、設定するにあたって以下の記事を参考にした。
Gitコマンドラインショートカット

実践

ローカルの開発環境で、.bash_profileを開いて、以下のように追記をする。

~/.bash_profile
--------------
Git Aliases
--------------
alias gaa='git add .'
alias gcm='git commit -m'
alias gl='git log'
alias gs='git status'
alias gpom='git push origin master'
alias gpfom='git push -f origin master'

これで、以下のようにターミナルで設定したショートカットコマンドを打つと、楽にGitの操作ができるようになる。

ターミナル
$ gaa
$ gcm
$ gl

git pull origin masterがうまくいかない時

ローカル環境からgithubにpushをし、EC2からpullをしたときにエラーが出たのでメモを残します。

以下の記事を参考にして対処しました。
本番環境でpullしたらコンフリクト?解決法3パターン!【Please commit your changes or stash them before you merge】

エラーの内容

$ git pull origin master
From https://github.com/user-name/app-name
     * branch      master       ->   FETCH_HEAD 
Updating e05c05f..050505
error: Your local changes to the following files would be overwritten by merge: 
         Gemfile.lock
         config/initializers/devise.rb
Please commit your changes or stash them before you merge.
Aborting

私が実践した対処法

terminal
$ git fetch origin master

$ git reset --hard origin/master

これで無事にgithubの内容がEC2上に反映されました。

# Git config設定時に気をつけること
同じサーバでほかの開発者が別ディレクトリで開発をしている場合のgitの設定についてまとめる。

globalhomeディレクトリ内にあるユーザディレクトリ全体に反映させる

対象リポジトリだけに設定を反映させたい場合は、以下の通り。

git config --local user.name
git config --local user.email

Masterブランチへのmergeを取り消して再度mergeする手順

###Git revert

commitを打ち消す

$ git revert <commit ID>

参考サイト
【gitコマンド】いまさらのrevert

開発環境で

$ git pull origin revert-branch

問題のあるコードを修正し、

$ git push origin rever-branch

GitLab or Github上で

revert-branchのMergeRequestからmasterにmergeする。

GithubやGitLabにpushしたディレクトリやファイルを削除する方法

GitHubなどのリモートリポジトリで管理する必要のないファイルを削除したいときの操作方法をまとめる。

以下の記事を参考にした。

gitの管理対象から特定のファイル、ディレクトリを削除する

手順

1.任意のディレクトリもしくはファイルを管理対象から外す

以下のコマンドを実行することで、GitHubで管理するファイルから除外することができる。
(ローカルにファイルを残したまま、GitHubにはpushしないようにできる。)

$ git rm --cached [削除したいファイル]

2. .gitignoreにGitHubにはpushしたくないファイルを記述する。

.gitignore
[任意のディレクトリもしくはファイル]

3.ローカルでの変更をGitHubのリモートレポジトリに反映する。

$ git add .
$ git commit '[任意のディレクトリを削除]
$ git push origin master

以上の手順で、一度GitHubにpushしてしまったディレクトリやファイルを削除することができる。

Discussion

ログインするとコメントできます