tech-memo

Git/GitHub

MacのGit

git version
brew install git

始め方

  1. ローカルでプロジェクトを作る

以下でローカルフォルダにgitのローカルプロジェクトが作成される

git init
git add .
git commit -m 'first create'
  1. GitHub上でリポジトリを作る(README.mdファイルを作成しないで作成)

ローカルで、画面に表示される以下のコマンドを実行すればよい

git remote add origin https://github.com/[ユーザ名]]/[プロジェクト名].git
git branch -M main	# ←ブランチ名をmainに変更
git push -u origin main

既存のディレクトリにソースがあってそれをリモートリポジトリに接続する方法

git init
git remote add origin https://~.git
git fetch
git reset --hard origin/main  # 強制的にリモートブランチの最新のコミット状態にリセットする
git pull origin develop

git push -u origin mainでAuthentication errorになる場合

既存のプロジェクトを使用する場合

git pullではなくgit cloneすることで、自動的にgit remote add originされたことになり、接続が生成される

ブランチ指定でcloneする

git clone -b [branch name] [url]

接続の確認

git remote -v

ブランチの表示/作成

git branch
git branch -r
git branch [ブランチ名]

ブランチを作成してから空コミット | commit -a

git commit -a

ブランチの切り替え

release-1.39のブランチからmasterに切り替える(masterに最新化する)場合

git checkout master
git checkout -b ローカルブランチ名 origin/リモートブランチ名

ブランチの削除

git branch -d [ブランチ名]

ブランチのマージ

git checkout develop 	# developに移動
git pull origin develop	# developブランチを最新にする
git checkout feature/1	# feature/1に移動
git merge develop 		# developをfeature/1にマージする...このあとコンフリクトを解消する作業を行う
git push origin feature/1	# feature/1をリモートにプッシfュする

つまり、pull requestでdevelopとfeature/1を同期させた上でdevelopにマージするために、まずはfeature/1に対してdevelopを適用する必要がある

マージの取り消し

git merge --abort

特定のコミットの反映 | cherry-pick

git cherry-pick [c2b9b96907b7~などのcommit hash値]
git cherry-pick fe87c8ab11638c6c73db6374fb47c02236a5720a..4d270af741fc5d3fdcc4247fe1c8f2f9b8f10d12

このとき、開始点のcommitは含まれないので注意.
逆に言えば、指定するのは反映済のcommitを指定すればよい.
開始点を含めたい場合は、

git cherry-pick fe87c8ab11638c6c73db6374fb47c02236a5720a^..4d270af741fc5d3fdcc4247fe1c8f2f9b8f10d12

で、^をつける

commitを調べる | log

git log

特定ブランチのcommitを知りたい場合は、続けてブランチ名でよい.

commitされたファイルの一覧を出力する | show

git show --pretty=oneline --name-only <commit_hash>

--pretty=oneline: コミットのハッシュとメッセージを1行で表示します。–name-only と組み合わせることで、ファイルリストの前にコミット情報が付加されます。
--name-only: 変更されたファイルの名前だけを表示し、実際の差分(diff)は表示されません。

変更を退避する | stash

ローカルソースを変更中に、別のcommitを取り込みたいとき、変更内容が破棄されてしまうので、一旦退避して戻すことができる.

git stash -u

-u: untrackedファイルも含めて保存. -uなしならuntrackedファイルは無視

git stash push -m "メモ"

で退避して、

git stash apply stash@{n}

で戻す. stash@{n}はstashした履歴のどれを戻すか指定する.

git stash list

で表示される先頭の文字.

stashしたファイルを表示するには、

git stash show -p stash@{0}

特定のファイルのみ戻したい場合は、

git checkout stash@{0} -- path/to/file

とする.

stashリストは消えないので、

git stash drop stash@{n}

で削除できる. もしくはapplyではなくpopでもいいらしい.

コミットを戻す(コミットの取り消し) | reset / revert

git reset [commit hash値]
git revert [commit hash値]

その後リモートリポジトリにもそれを反映させるには以下を実行

git push origin [ブランチ名] --force

逆にリモートブランチでローカルを強制的に合わせるには以下

git reset --hard origin/[ブランチ名]

commit hash値のところはHEAD^とすることで、直前のcommitを取り消すことができる.
resetには--soft--hard--mixedのオプションがある.

例えば上記の例として、最新から5個のcommitがあって、4番目まで戻して、1番目のコミットだけ適用したいみたいな場合、

git reset --soft [4番目の前のcommit hash値]  # これで最新から4番目までのコミットがなくなる
git log  # 確認する
# vscode上は1番目から4番目の変更がステージングされているので、必要なものだけにする
git commit -m "message" # 1番目の変更内容をコミットする
git push origin [ブランチ名] --force # リモートと同期する

これでリモートブランチとローカルブランチは戻る。 このリモートブランチを他の人がgit pullするとコンフリクトしてしまうので、

git fetch origin
git reset --hard origin/<branch-name>

として今度はリモートブランチと強制的に同期をとる

resetの別クライアントでの反映

resetとすると、別のクライアントでresetする前のコミットを取得済の場合、git pullしても取り消したcommitは取得できなくなってしまう。そのクライアント側でもresetする必要がある。

resetして、

git checkout -- [ファイル名]

としてリモートリポジトリのファイルを再取得する必要がある。

最新をpullしたらバグってたので任意のコミット箇所に戻す

この場合もresetでよい

git reset --hard [commit hash値]

直前のコミットメッセージを間違えたのでやり直す

git reset --soft HEAD~1
# リモートに反映済みの場合
git push --force-with-lease origin [ブランチ名]

--softは変更は保持するオプション。変更も取り消すのは--hard
--force-with-leaseは、他の人がpushしていたら防ぐオプション。気にしない場合は、--force

git pull=git fetch & git merge

git pullはfetchしてmergeすること。
git fetchは、リモートリポジトリの最新の変更(コミット、ブランチ、タグなど)をローカルリポジトリにダウンロードしますが、現在の作業ブランチの作業ツリー(ワーキングディレクトリ)やインデックス(ステージングエリア)は変更しません。
git mergeは作業ツリーやインデックスに統合すること。

別ブランチの特定のファイルを取り込む

作業中(取り込み先)のブランチで

git checkout [別ブランチ名] -- /path/file.js

git pullなどでSSL certificate problem: unable to get local issuer certificateエラー

一時的にSSL認証を無視するオプションを付けて実行

git -c http.sslVerify=false pull

基本的にgitのバージョンが古いケース。gitをバージョンアップする。

git pullの強制 | reset –hard

ローカルファイルを変更していて、git pullが効かないが、リモートリポジトリで強制的に上書きしたい場合、 (masterブランチを上書きする)

git fetch origin master
git reset --hard origin/master

ディレクトリのみリポジトリに入れるgitignoreの書き方

[log]ディレクトリのみリポジトリに入れる場合、log/.gitkeepファイルを作成して以下の記述

log/*
!.gitkeep

!は直前ルールの否定.

git worktree

git worktree add -b feature/foo /mydir/feature-foo
git worktree add /mydir/feature-foo feature/foo
git worktree list
git worktree remove /mydir/feature-foo   # 片付け
git worktree prune                       # 孤児掃除

.gitignoreでgitの追跡を解消する

すでにgit管理済みのファイルをあとから.gitignoreにファイルを追加しても、対象外にできない。 その場合は以下の手順が必要。

git rm --cached [ファイル名] 	# gitのcacheを削除する(ファイルはそのままになる)
git commit -m "ファイルを削除などのメッセージ" 	# コミット

このあと、.gitignoreファイルに対象ファイルを記載する

git アカウント

一つのPCで複数のgitアカウントを使う場合は、グローバル設定がデフォルトになるので要注意。 グローバル設定を変更するには

git config --global user.name "change name"
git config --global user.email "change email"

git difftool

別ブランチの同一ファイルをビジュアルに比較できるツール

git config --global diff.tool vscode
git config --global difftool.vscode.cmd "code --wait --diff $LOCAL $REMOTE"
git difftool ブランチ1 ブランチ2 -- path/to/file

Git CLIでissueを出力

以下でタブ区切りのリストを出力できる https://cli.github.com/manual/gh_issue_list

gh issue list -s all -a [ユーザ名] -L 100

-s: open | closed | all
-a: アサインユーザー名
-L: 出力行数(デフォルト30件)

コンソール表示では、タイムスタンプがabout 5 days agoなどとなるが、標準出力すればタイムスタンプになる。
タイムスタンプはclose issueならcloseした日付。

Macの場合

↓に従ってghで認証情報を作成する
https://docs.github.com/ja/get-started/getting-started-with-git/caching-your-github-credentials-in-git

brew install gh
gh auth login

すると選択式で進む
GitHub.com/GitHub Enterprise https/SSH→https
??/GitHub CLI→GitHub CLI
でGitHubにブラウザからログインして、表示されている認証コードを入力する

macの場合キーチェーンアプリにGitHub.comの認証情報が追加される