likes: 0
困ったとき→環境を作って実験しよう。
# リモートブランチを指定して削除。機能開発が完了したら削除する。 git switch dev git push origin --delete <remote-branch> # マージ済みリモートブランチ数のカウント git branch -r --merged | grep -vE '^\*|master$' | wc -l # WARNING: 全てのマージ済みリモートブランチを削除 git branch -r --merged | grep -vE '^\*|master$' | sed -e 's% *origin/%%' | xargs -I% git push origin :%
git branch -d <local-branch>
git fetch -p && git branch --merged | grep -v '*' | xargs git branch -d
# untracked fileを一覧表示 git clean -n # untracked directoryを一覧表示 git clean -dn # untracked fileを全て削除 git clean -f # untracked directoryを全て削除 git clean -df
# github側で、マージする際にsquash mergeを選べばOK。 # コミットが1つにまとめられるので、見やすくなる。
# 何も指定しないと全てになる git pull # 指定しないととんでもない量を取得する場合があるので注意 git pull origin main git pull origin dev git pull origin feat
# そもそもブランチを切るべき。 # しかし例えば、actionsで1つのブランチに定刻実行する場合などは以下の考慮が必要。 ' 1. pushする前: リモートとローカルの共有部Aを出発点としてリモートの更新部分Bをローカルに加えて、 ローカルの更新部分Cをその後に加える。 ローカルでA-CだったものをローカルでA-B-Cにする。 ' git pull --rebase ' 2. conflictなどが生じた際には: abortすればrebaseを取り消せる ' git rebase --abort ' 3. pushする: ' git push origin <branch-name>
# チャンクごとに[y/n]でaddするかを選べる。 git add -p <file-name> # チャンクをさらに細かくするには、オプションで s を選択。 ⭐️ VScodeならサイドバーからGUIでやれる
オプションの意味:https://qiita.com/cotton_desu/items/bf08ac57d59b37dd5188
# コミットメッセージのみ git log -p # コミット内容も表示 --oneline # 1行で表示 -n {n} # 指定数のコミットのみ表示 --author=<author-name> # 指定者のみ --since=<date> # それ以降のみ <branchname> # そのブランチで飲み --<filename> # そのファイルのみ --graph # ネットワーク図 --no-merges # マージコミット除く
git config --global push.default current ' この設定をしておけば、 git push だけで、今いるブランチのリモートブランチにpushできる。 - git push origin main - git push origin feat/temp-dl などと同義になる!楽! '
# ex) 前にいたブランチに移動: 「-」を使用する git switch - # - の表現はブランチだけでなくディレクトリなどでも同じ。
merge(pull) -> ローカル親ブランチにリモートリポジトリの内容を反映する rebase -> ローカル作業ブランチにローカル親ブランチの内容を反映する(根元に反映する) # フロー: 1. ローカル作業ブランチで add,commitする 2. ローカル親ブランチに切り替える 3. ローカル親ブランチにリモートリポジトリの内容を反映 (pull) 4. ローカル作業ブランチに切り替える 5. ローカル親ブランチをローカル作業ブランチにリベース git rebase <parent-branch> 6. コンフリクトが起きたら、解消して、addしたのちに git rebase --continue (途中でリベースを取り消したい場合は git rebase --abort) 7. プッシュ前にローカル親ブランチの変更内容が取り込まれていることを確認しておく git log 8. リモートリポジトリにプッシュ(2つのオプションはorigin <name> の後ろにつけること!) git push origin <work-branch> --force-with-lease --force-if-includes この2つのオプションによってリベース後でも安全にプッシュしている。-fはしないこと。
1. コミットをindexまで戻す。 git reset --mixed @~n 2. 選択的にaddしてcommitすれば、上手いコミット履歴の出来上がり。
# 例えばlogがこうだったとき 6b35b56 (HEAD -> dev) fixup! fix lec14 9e60951 (origin/dev) add syo-test14 28a879f fix lec14 4910d56 add lec14 860d25d update .gitignore a25d618 🐛 fix prac11 HEAD 現在(fixup!: fix lec14) HEAD~ 1つ前(add syo-test14) HEAD~~ 2つ前 HEAD~4 3つ前 # HEADのエイリアスに@がある。 @ @~ @~~ @~4 # ちなみにコミットログをreset --softしても、コミットがなくなるだけなので、ステージされた内容はステージされた状態で残っている。つまり消えないので安心。
1. git rebase -i @~~ 2. 対象のコミットをeditにして閉じる。 3. そこで加えたい修正を普通に加えて、git add <file> 4. git rebase —continue 5. (conflictしたら手で解決して、git rebase —continueを繰り返す。)
https://qiita.com/kzmasa/items/b430bc528d117a7a4493#1%E3%81%A4%E3%81%AE%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%82%922%E3%81%A4%E4%BB%A5%E4%B8%8A%E3%81%AB%E5%88%86%E5%89%B2%E3%81%99%E3%82%8B
editで任意の粒度のコミットを作り直す、ということ。
git rebase -i @~{n} # change pick -> edit git reset (--mixed) @~ # 直前コミットに戻り現コミット内容をステージ前に戻す # ここからコミットを分割してadd, commitしていく git rebase --continue # コミット分割が終わったら、これで完了
editによるコミット分割、squashによるコミット吸収を使えば、めっちゃ便利。
ex) コミット1+2+3+5とコミット4+6がある。コミット1+2+3+5をコミット1+2+3, コミット4に分割して、コミット4をコミット4+6に吸収させる。すると、コミット1+2+3とコミット4+5+6を作れる。
1. git rebase -i @~~ 2. BをCにまとめたかったら以下のようにする pick A pick B s C pick D 下のコメントアウトされてる説明を読めばわかるので大丈夫。squashにしたコミットは、1つ前のコミットに溶け込む。 3. 問題なかったらそのままgit rebase —continueで完了。
git rebase -i --root
git commit --allow-empty # ちなみに、一番最初のコミットはプロジェクトと関係ないコミットが良いと言われる。 # なぜなら、一番最初のコミットは上記の通り--rootをつけないとrebase対象に出来ず、面倒だから(だと思われる)。
あるコードの意図を知りたい時、いつ作られたのかを知りたい時。「なんでわざわざこう書いてるんだろう?」と思ったら調べよう。
- git log -S “{該当コード}” でコミットハッシュを得る
- githubのPRタブの検索バーでコミットハッシュを検索
git mv {old-file} {new-file}
こうしないと、new fileとして認識されてしまい、今までの編集履歴がパーになる。
// -u は --include-untracked の略です。 // 新規作成ファイル(追跡対象に含まれていないファイル)も退避できる。 git stash -u // 一覧を見る git stash list // 退避した変更の詳細をみる git stash show stash@{n} // さらに詳細(コード)を見る git stash show -p // 最新の退避の差分を詳しく見る git stash show -p stash@{n} // 指定した退避の差分を詳しく見る // 退避したものを戻す(適用する): nはlist表示した時の対象の番号 git stash apply stash@{n} // 退避したものを消す git stash drop stash@{n}
https://qiita.com/chihiro/items/f373873d5c2dfbd03250
https://qiita.com/yoichi22/items/ee1801d0c274ffe781e3
# 過去コミットに戻す git checkout <commitId> # 最新コミットに戻す git checkout <branchName>
https://envader.plus/article/395
git switch -c --track origin/<リモートブランチ名>
これで問題なし!
1. mainから新ブランチ作成(git switch -c <new-branch>) 2. mainで作業したコミットを削除(下記参照) 3. 新ブランチで普通に作業すればOK git rebase -i @~~~~ (4つコミットしちゃった場合) エディタでdropに設定 これだけでOK〜 (コミットもしてないなら git reset --hard @ でOK)
一度addしたファイルをgitignoreするためには、一度git rmが必要!
git restore <file>
# そもそも、ローカルは3段階に分けられる。 # 1. 作業ツリー -> まだaddしてないもの # 2. インデックス -> addしてステージングしたもの # 3. HEAD -> commitしたもの # つまりこのコマンドでは、インデックスを取り消している。 git restore --staged <対象ファイル名,ディレクトリ名>
参考:
$ git commit --amend --no-edit
# <<<まだpushしておらず>>>単に直近のコミットメッセージを変更したいとき git commit --amend
git reflog # 打ち消したいコミットのハッシュ値を調べる # revertして色々消えても、そのrevertをrevertすれば戻る。 git revert <打ち消したいコミットID> git push origin <branch> # 「コミットを打ち消すコミット」がrevertによって作られるので、それをプッシュしてやればOK.
# git reset (基本はsoftを使用する) そもそもresetは、ある時点「まで」巻き戻したい時に使用。 ある個別のコミットをうち消したい場合はrevertを使用する(履歴が残る)。 resetするときは、消したいコミットの1つ前のハッシュ値を指定する。 「指定した時点まで」巻き戻るから。 --hardはプッシュ前のローカルにのみ使用しよう。他者に影響が出る。 # ex) A,B,Cをコミットしてプッシュした。 この時、Aまで戻ってDをコミットしたい。ただし、今はDの作業中(addしてない)で、Dの内容がB,Cの内容と混ざらないようにしたい。 1. Aまでreset (stagedにB,C、worktreeにDがある状態になる) git reset --soft @~2 # @の例: @~なら、HEAD(つまりC)の1つ前を表すのでBまで戻る # @の例: @なら、HEADを表すので、何も戻らない(Cまで戻る) # --soft: リセットされた内容はstaged(addされた状態)まで戻る 2. indexを確認後、B,Cをworktreeに下す git restore --staged . 3. Dを選択的にadd サイドバーのgitアイコンから行単位でaddする。 4. worktreeのB,Cを削除する git restore . 5. Dの残りの作業をやって普通にadd,commit,push pushできなかったらforce-push(オプション付き)する。
git branch -m <old-name> <new-name> # 今いるブランチの名称を変更する場合 git branch -m <new-name>
やるべきではない。PRの内容とかコメントが消えるから。
# ローカルを変更 -> 変更したブランチをリモートへpush -> 元のリモートブランチを削除 # リモートブランチ名を変えるのではなく、旧リモートブランチを消して新リモートブランチを作っている。 git branch -m <old> <new> git push origin :<old(リモートのブランチ名)> # : をつける。 git push origin <new(現在のブランチ名)>
入力側(主にリモート側)と現在の方(主にローカル側)のどちらかを丸々反映させたい場合:
- サイドパネルのgitマークへ。
- 「変更のマージ」欄で、ファイルを複数選択して右クリック
- 「現在の方をすべて取り込む」「入力側をすべて取り込む」のいずれかをクリック
- add, commit, pushでOK。
該当ファイル.git/refs/headsにある参照用ファイルを消せばOK
# エラー例 fatal: bad object refs/heads/get-specified-period-data-in-order 2 error: github.com:hirata-lab-nit/my-repo.git did not send all necessary objects
https://qiita.com/D_suke/items/56060e0dba9a0ec557a7
# プロジェクト用ディレクトリを作成しておく git clone <URL> git remote add origin <URL> # ふつう、masterではなくdevが最新ブランチになるので注意。masterからブランチ切らないこと。
※ branch -M main は「現在のブランチ名をmainに強制変更」するコマンド。
# Githubでリポジトリを作成 # ...or create a new repository on the command line # にあるコマンドをコピペすればOK(例として以下に記述) # git init <dir-name> すれば、最初のgit initと同じ処理が行われる。 git init git remote add origin https://github.com/username/reponame.git # 次にdevブランチを作る git switch -c dev git status git add . git status git commit -m "commit-message" git push origin master # github上でdefault-branchをdevに変更しておく # devからブランチ切って開発開始
git remote -v #現在のリモートURL確認 git remote set-url origin <URL>
- main (master)
- release
- dev (develop)
- feat (feature)
- hotfix
参考:
- feat: 新しい機能
- fix: バグの修正
- docs: ドキュメントのみの変更
- style: 空白,フォーマット,セミコロン追加など
- フロントデザインのことではない。
- refactor: 仕様に影響がないコード改善(リファクタ)
- perf: パフォーマンス向上関連
- test: テスト関連
- chore: ビルド、補助ツール、ライブラリ関連
運用方法はチーム方針による。
自分のローカルでsquash mergeする場合(レビュアーが見やすくするため):
- featブランチをローカルにpullする。
- ローカルのfeatブランチからfeat/somefeatブランチを切る。
- feat/somefeatからfeat/somefeat/devを切る(これはローカルのみで使用)。
- feat/somefeat/devで開発する。addやcommitする。
- feat/somefeatへ移動してfeat/somefeat/devからmerge —squash。
- feat/somefeatでcommitしてリモートへpush。
- feat/somefeat/devへ戻って、feat/somefeatのコミットを(普通の)merge。
- github上でプルリク出してレビューをお願いする。
- 修正依頼きたら、リモートの最新状態をfetchしてローカルのfeat/somefeatにmerge。(merge origin feat/somefeat)
- feat/somefeat/devに移動してfeat/somefeatをmerge。
- 4 ~ 8 と同様。
- OK出たら(大体は)レビュアーがfeatにfeat/somefeatをマージする。
注意
- バイナリファイルは追跡するべきではない!!! gitは更新されるたびにdiffが走るが、バイナリファイルは元ファイルが少し編集されるだけで大きく変わるため、重くなってしまう。
- github上のコミットログは下の方が新しい。
- 「リモートリポジトリ」は普通originで、origin masterはリモートのmasterブランチという意味。同様にorigin test-01はリモートのtest-01ブランチという意味。
- プルリクでマージに成功すると、Delete branchボタンをGithubは表示してくれる。そのブランチでの開発が終了したら消すことを忘れずに。
- Aと全く同じ内容で名前は違うBを作成し、Aを消したとする。すると、gitは”deleted: A, new file: B”ではなく”renamed: A→B”と判定する。いつかこれで困る日が来るかもしれない(多分ない)。
- Githubプルリク時の差分は画面下にある。
- Question 24
Gitで特定のコミットの変更内容を確認するためのコマンドはどれですか?
X git log commit_hash
O git show commit_hash
git show commit_idは特定のコミット(`commit_id`で指定)についての詳細を表示するコマンドで、コミットメッセージ、変更されたファイル、行の追加や削除などが含まれます。Reference link Git Show Documentation
- Question 26
特定のリモートブランチをローカルに追跡ブランチとして作成するためのコマンドはどれ?
X git track origin/branchname
O git checkout -t origin/branchname
git checkout -t origin/branchnameはリモートブランチ`origin/branchname`をローカルに追跡ブランチとしてチェックアウトするためのコマンドです。 Reference link Git Checkout Documentation。-tはTrack追跡なんだろうね。