kiyasuの日記

ハッピーうれピーよろしく哀愁

gitメモ

なんかちょっと前からプライベートリポジトリへのアクセスのたびに毎回パスワード聞かれるなーと思いつつもやりすごしていたら、UPMからgithubリポジトリへアクセスする際にエラーが出てついに困ったことになりました。なあなあで続けてきたgitと僕の関係を見直す時が来たようです。ついでにSourceTreeもアンインストールしてコマンドラインで生きていきます。

これらのことはググってたら出てきますが時間が経つと当然のように忘れるので、ここに自分のためにまとめておきます。自分用メモというやつです。こんな私にも「いまさらgitの記事書くの恥ずかしいな・・・」などというプライドがあるのですが、そんなものは捨てておきます。

なんかgitは「git自体の使い方」「gitの設定」「リポジトリの設定」「認証」「git使う時のマナーや標準的なフロー」あたりが混在しているのがわかりにくい原因な気がする。


インストール

gitの現状の確認、整理

where git

windowsのコマンド です。これ使うと手元に複数gitがあったりしてびっくりしました。SourceTreeに同梱されてるgitがあったんですねえ。後述しますがSourceTreeはちゃんとアンインストールしないといろいろ残るようです。これらを一回全部消すことにします。

gitのアンインストール

windowsの「設定/アプリと機能」からアンインストールすればOK。この後再インストールしようとするとgitフォルダが残っていると言われるが無視してそこにインストールしても問題なかったです。

SourceTreeの削除

これもgitと同じく「設定/アプリと機能」からアンインストールできるんですが、それだけでは不十分なようです。上記のようにgitなどの関連ファイルが残ります。

SourceTree関連ファイルの削除

C:\Users[username]\AppData\Local\Atlassian 配下の SourceTree という名前が含まれているフォルダを全削除しましょう。

Windows の SourceTree を完全にアンインストールする方法 - 約束の地

SourceTreeクレデンシャル情報の削除

過去使用していた接続先やユーザーの認証情報がオプションの認証タブに残っています。

これは以前souretreeを再インストールしたときに見た問題です。今回はSourceTree消したままにするので確認はしてないのですが、対策を残しておきます。

Windowsの場合、SourceTreeの認証情報は「コントロール パネル\すべてのコントロール パネル項目\資格情報マネージャー」で管理しているようです。 資格情報マネージャーにアクセスの上sourecetree- で始まる資格情報の削除をお願いします。 削除後 sourecetreeからも削除されます。

SourceTreeの認証情報を削除することができない - RS アトラシアン製品 ユーザーコミュニティ

これで環境はクリーンになったので、次はインストールです。

Gitのインストール

Git - Downloading Package

ここからインストールします。途中の認証ヘルパーのoptionには「Git Credential Manager Core」(以下GCM Core)を選んでおきます。あまり使いこなせてないけど次のデファクトらしい。

確認

$git --version

でインストールしたバージョンと突き合わせて確認。

パスの確認

いまちょうどコミット済みのブランチがあるのでpushしてみます。

$git push
git: 'remote-https' is not a git command. See 'git --help'

おっと。これはremote-httpsというhttps通信するためのサブプログラムが見つからない、ということのようです。いかにも最初から入ってそうな機能なので見つからないのはおかしい。windowsで「git-remote-https.exe」をファイル検索すると普通に見つかりました。

C:\Program Files\Git\mingw64\libexec\git-core パスが通ってないようです。

サブプログラムのパスは以下のコマンドで確認します。

$git --exec-path
C:\Program Files (x86)\Git Credential Manager Core

この作業をやる前にいろいろやってた影響でここの値がおかしなことになってました。「Git Credential Manager Core」フォルダは今はもうないので(これはgitコマンドとは別にGCM Coreを入れたときに作られるフォルダ)、ここのパスを上記のgit-coreフォルダにします。これはWindowsの環境設定でGIT_EXEC_PATHに設定すればOKです。

Git - 環境変数

これでpushできました。インストールはこれでいいと思います。

Gitの設定ファイル

あまり見ることはないですが、概観書き記しておきます。

local, global, systemの3つのレベルがあってこの順番で優先されます。それぞれは以下のコマンドで一覧が見られます。

$git config --local -l
$git config --global -l
$git config --system -l

項目の設定方法は、

$git config --global credential.interactive true

でglobalレベルのcredential.interactiveがtrueになります。

Gitの認証

Git Credential Manager Core

これは現状使いこなせてないのですが、調べたことだけ書いておきます。

そもそもGCM Coreがインストールされているかどうかは

$ git-credential-manager-core version

を実行してみましょう。この結果が"bash: git-credential-manager-core: command not found"なら、インストールされていないか、されているがパスが通っていないか、です。インストールされている場合は" C:\Program Files (x86)\Git Credential Manager Core"にあると思います。

Credential Manager Core not a git command. See `git --help` . · Issue #144 · GitCredentialManager/git-credential-manager · GitHub


GCM Coreの概観、httpssshの違い、ファーストステップについてはこちら↓のページ

Git Credential Manager Core: Building a universal authentication experience | The GitHub Blog

具体的な使い方はこちら↓のページ

git-credential-manager/configuration.md at main · GitCredentialManager/git-credential-manager · GitHub

とりあえず最初の段落だけ読んでみました。

  • GCM Coreの設定はgit標準の設定ファイル(git config --local -lで見られるやつ)に記述される
  • その場合「credential.***」となっているのがGCM Coreの設定変数
  • local>global>system に加えて、各リモートurl別に設定もあるようだ
  • ほかにもGCM特有の変数があり、これはconfigurationファイルよりも優先される。GCM_*** という名前のようだが、どこに記述されるものか不明

$git config --global credential.helper manager-core

でGCM Coreをcredential helperとして設定することができる。

$git config credential.helper

で現在のcredential helperを確認できます、とのこと。

git自体の使い方

最初にやること

$git init

なにはともあれ

.gitignoreの作成

普通にテキストファイルを作って.gitignoreにリネームして中身を書く/コピペして持ってくる

gitignoreは変更した後、基本的には手動で反映処理とかはしなくていいっぽい。ただすでにgitの管理下に入っているファイルについてはキャッシュが残っているらしく、その場合はgitignoreの更新に合わせてキャッシュの削除をする必要がある。

$ git rm -r --cached . //ファイル全体キャッシュ削除

または

$ git rm -r --cached [ファイル名] //ファイル指定してキャッシュ削除

$ git add .

.gitignoreに記載したのに反映されない件 - Qiita

ケースバイケースなのかもしれませんが。

.gitignoreメモ

.gitignoreは複数のディレクトリに設置でき、それぞれ設置場所をカレントディレクトリとしてそこからの相対場所に設置できる。

/[Lli]brary/

.gitignoreが置かれたフォルダ上にあるLibraryフォルダしかignoreされない。

[Lli]brary/

.gitignoreが置かれたフォルダ以下、すべての場所でlibraryフォルダがignoreされる。

[Git] .gitignoreの仕様詳解 - Qiita

現状確認

$git log

今のブランチのコミットログを表示する。

$git status

変更済みファイル、gitの管理下にないファイルなど、現状を一覧する。新規追加してまだステージングされていないファイルなどをこれで確認する。

$git diff
$git diff --name-only

git diffは変更箇所もまとめてバーっとでる。--name-onlyオプションで変更のあったファイル名のみ表示する。

$git branch

ローカルのブランチ一覧。現在地には*が付く。

ブランチ操作

$git checkout <ブランチ名>

ブランチ切り替え

$git checkout -b <ブランチ名>

新規ローカルブランチを作りそのブランチに移動する

Gitコマンド(ブランチの作成) - Qiita

$git checkout .

これで現ブランチで前コミットからの変更内容を取り消しできる。

$git checkout --force <ブランチ名>

自動生成ファイルとかでどうしても変更点が残ってしまいcheckoutがうまくいかないときは--forceを付ける

↓はほかの人がプッシュしたなどで、remoteにあるけどlocalにないbranchにcheckoutしたいときに行う。

$git fetch origin <ブランチ名>

$git checkout <ブランチ名>

リモート追跡ブランチ作成してからローカルに作る

【Git】リモートブランチをチェックアウトしたいときは「git fetch origin <ブランチ名>」と「git checkout <ブランチ名>」を実行すれば良い | DevelopersIO

ステージング

$git add <ファイルパス>

modifiedをまとめてコミットしたいときは

git ls-files -z --modified | xargs -0 git add

こう。(多分。未確認)

git diff --cached --name-only

add済みのファイル一覧。--name-onlyが無ければファイルの中身のdiffまで表示

コミット

$git commit -m "メッセージ本文"

コミット取り消し

git reset --hard HEAD^

[Git]コミットの取り消し、打ち消し、上書き - Qiita

プッシュ

$git push --set-upstream origin feature/hoge

リモートリポジトリに対応したブランチがない時の方法。

削除

$ git rm ファイル名

ファイルを削除して、gitの管理から外す。
ファイルが残っていて、前回のcommitから変更されていたらエラーになる。この時は

$ git rm -f ファイル名

で変更内容ごと削除する。自分が使う時はこれで問題なさそう。

$ git ls-files -z --deleted | xargs -0 git rm -f

これは状態がdeletedのものを全てgit rmする。これも良く使いそう。ファイルがdeletedされたらそれ以降はgit管理から外すのが自然(だよね?)

"git ls-files -z"のzオプションとxargsの-0オプションは「デリミタにヌル文字を使うよ」という約束。これでファイル名にスペースが含まれていても大丈夫。

マージ

masterマージにdevの変更を取り込みたい場合、

git checkout master

まずmasterに移動してから

git merge dev

devを指定する。特にしていなければこのまま。

特定のコミットだけマージ

(あくまで前コミットとの差分だけマージするときに使う)

$git cherry-pick <コミットハッシュ>

現在地でないブランチのログを調べるには

$git log <ブランチ名>

特定のブランチのある地点の状態をマージしたい場合

git checkout <コミットハッシュ> -b <新ブランチ名>

でブランチ作ってから、マージする。

コンフリクト

CONFLICT (modify/delete):... といくつか出た。これは最新版でいくつかファイルが追加されているけど、もとのブランチにこのファイルは存在しないからdelete、みたいな感じのようだ。

素直に各ファイルを

git add "xxx"

してコンフリクト解消したら

git cherry-pick --continue

すればOK。コミットメッセージの編集画面(vi)に自動的に遷移したけど編集せずにそのまま出した。

もしくは、全部相手側の変更を優先したい、となった場合は(自分はこのパターンが多い)

$ git checkout --theirs .

こうすればよい。そのあと

$ git add .
$ git commit

などとやる。

[git]マージ時のコンフリクトで片側の変更だけ適用する方法 - Qiita

取り消しあれこれ

addしたファイルを取り消したい

$git diff --cached --name-only

addしたファイル一覧を見る。

$git rm --cached -r ファイル名

ファイル名を指定してindexから取り消す。

変更箇所を全て取り消す

$git checkout .

ただし新規追加したファイルは削除されない

忘れやすい人のための git diff チートシート - Qiita

Git で特定のコミットをマージする方法メモ - Qiita

【Git】特定のブランチの git log を見たい - Qiita

submodule

基本的にはこの辺

自分が必要とする最低限の git submodule の知識 - Qiita

Git submodule の基礎 - Qiita

  • まず.gitmoduleがあるか確認する。あればcatなどで中身を見てみる
  • なければ自分で作る

git submodule add "git:xxxxxxxxxxxx.git" {path}
git submodule update --init

必要なら--recursiveもつけてサブモジュールのサブモジュールも対象にする

git submodule update --init --recursive

あとはサブモジュール管理下になっているフォルダに移動してgitコマンドを試してみる

git status

または

git log

など。これで親になっているリポジトリの情報が出てくるならサブモジュールになっていない

git submodule update --init

を忘れているかも

その他

detached HEAD

HEADというのは「今自分がどこを見ているか」なわけですが、本来

HEAD -> (branch) -> (commit)

となるはずのところ

HEAD -> (commit)

になっているのがdetached HEADの状態。自分がdetached HEADになるときは大体「現在のブランチの過去コミットに戻るとき、git chenckout (commit)」にしたとき。なのでここではHEADを本来のブランチに戻す操作を書き残しておきます。

まず自分が今見ているcommitのハッシュ値を調べる

λ git rev-parse HEAD
λ [ハッシュ値]

もしくは

λ cat .git/HEAD
λ [ハッシュ値]

でも良い。次にこのコミットが含まれるブランチ名を調べる

λ git name-rev [ハッシュ値] λ [ハッシュ値] dev

どうやらdevブランチのようだ。

λ git checkout dev

あとはこれでOK

参考 :

detached HEAD から脱出する方法を git の内部構造から探る - Qiita

configまわり

プロジェクトごとに手元のPCからコミットするアカウントを変えたい

configの設定確認は以下で行う

git config -l # 現在有効になっている設定一覧
git config --local -l # 現在いるプロジェクトのlocalファイル(.git/config)に書かれている設定一覧
git config --global -l # global(~/.gitconfig)に書かれている設定一覧
git config --system -l # systemに書かれている設定一覧

ファイルの編集は"-e"を付ける

git config -e # ローカルの設定を変更
git config --global -e
git config --system -e

項目別作業

git config --local user.name # local設定に書かれたuser.nameを表示 git config --local user.name nobu2 # local設定に書かれたuser.nameをnobu2に変更

Gitの設定をgit configで確認・変更 | note.nkmk.me

随時更新。