コンテンツにスキップ

コマンド@Git

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


add

--all

変更した全てのファイルをaddする。


branch

branch --all

作業中のローカルブランチとリモート追跡ブランチを取得する。


branch -M

現在のブランチを新しい名前に変更する。

$ git branch -M main


clone

認証

▼ HTTPS接続

Basic認証でGitHubにログインし、クローンする。

GitHubのユーザー名とパスワードが必要になる。

$ git clone https://github.com/<組織名>/<GitHubリポジトリ名>.git

ユーザー名とパスワードの入力は、ターミナルに手動で入力する方法と、自動的に入力する方法がある。

後者の場合、1個目にURLに設定する方法がある。

$ git clone https://<ユーザー名>:<パスワード>@github.com/<組織名>/<GitHubリポジトリ名>.git

もう1個の方法として、~/.netrcファイルに定義しておく。

machine github.com
login <ユーザー名>
password <パスワード>

▼ SSH公開鍵認証

SSH公開鍵認証でGitHubにログインし、クローンする。

GitHubの自身の公開鍵を登録する必要がある。

サーバー接続名は、SSH公開鍵認証の設定ファイル (~/.ssh/config) に記載されている。

デフォルトでは、GitHubの接続名は、『github.com』になっている。

$ git clone git@<ssh-configファイルでのサーバー接続名>:<組織名>/<GitHubリポジトリ名>.git

▼ アクセストークン

アクセストークンを使用して、クローンする。

$ git clone https://<ユーザー名>:<トークン>@github.com/<GitHubリポジトリ名>.git


オプション

▼ 名前指定

リポジトリのクローンを別名でクローンする。

# fooという名前でクローン
$ git clone https://github.com/hiroki-hasegawa/foo-repository.git foo

▼ --recursive

リポジトリがサブモジュールを含む場合、サブモジュールも合わせてクローンする。

$ git clone --recursive https://github.com/hiroki-hasegawa/foo-repository.git

▼ --depth

最近コミットのみをクローンする。

処理速度が求められる場合 (例:CIの実行コンテナなど) に役立つ。

$ git clone --depth 1 https://github.com/hiroki-hasegawa/foo-repository.git


config

設定の影響範囲の種類

影響範囲 意味 上書き順 設定ファイルの場所
system 全PCユーザーの全リポジトリ 1 /etc/gitconfig
global 現在のPCユーザーの全リポジトリ 2 ~/.gitconfig
local 現在のリポジトリ 3 <GitHubリポジトリ名>/.git/config


--<影響範囲> --list

指定した影響範囲で適用されている設定値を取得する。--localで設定されていない項目は、--globalの設定値が適用される。

$ git config --local --list

Macでは、1個のマシンで2個のGutHubアカウントを使用する場合、キーチェーンという機能で設定が必要になる。


--<影響範囲> user.name

AuthorとCommitterの名前を設定する。

localが一番最後に上書きされ、適用される。

$ git config --local user.name "hiroki.hasegawa"


--<影響範囲> user.email

AuthorとCommitterのメールアドレスを設定する。

localが一番最後に上書きされ、適用される。

$ git config --local user.email "example@gmail.com"

Authorの情報は、コミット時に反映される (Committerは表示されない) 。

$ git log

commit ee299250a4741555eb5027ad3e56ce782fe90ccb
Author: hiroki.hasegawa <example@gmail.com>
Date:   Sat Sep 12 00:00:00 2020 +0900

    add ◯◯を実装した。


--global core.autocrlf

改行コードを、特定のタイミングで自動変換するように設定する。

inputとしておくのが良い。

$ git config --global core.autocrlf <値>
設定値 チェックアウト時 コミット時
input 変換しない CRLF ➡︎ LF
true LF ➡︎ CRLF CRLF ➡︎ LF
false 変換しない 変換しない


--global core.editor

gitのデフォルトエディタを設定する。

ここでは、Vimをデフォルトとする。

$ git config --global core.editor "vim -c "set fenc=utf-8""


init

initとは

ローカルマシンのディレクトリとGitHubリポジトリを紐付ける。

エディタにGitHubリポジトリを再反映するためにも使用できる。

$ git init


GitHubへの公開鍵の登録方法

GitHubとSSH公開鍵認証を実行するために、秘密鍵と公開鍵は次の方法で作成し、GitHubアカウント設定画面のSSHの項目に登録する。

(1)

ssh-keygenコマンドで、秘密鍵と効果鍵のセットを作成する。

# 鍵を保管するディレクトリに移動
$ cd ~/.ssh/github

$ ssh-keygen -t rsa

# 秘密鍵と公開鍵の名前はGitHubのユーザー名にしておくとわかりやすい
Enter file in which to save the key: hiroki-it
# 鍵の使用時にパスワードの入力を要求するか否かは任意である。
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
(2)

このうち、公開鍵をクリップボードにコピーする。

# Mac
$ pbcopy < ~/.ssh/github/<鍵名>.pub

# Windows
$ clip < ~/.ssh/github/<鍵名>.pub
(3)

コピーした公開鍵を、GitHubアカウント設定画面のSSHの項目 ( https://github.com/settings/ssh ) にペーストする。sshコマンドで接続を確認する。

$ ssh -T <接続名>

Hi hiroki.hasegawa! You've successfully authenticated, but GitHub does not provide shell access.



ignore

global ignore

gitignoreファイルとして、~/.config/git/ignoreファイルを作成する。

このgitignoreファイルで指定したファイルは、グローバルにバージョン管理から無視される。

# IDEA
*.idea/*

# VSCode
*.code-workspace
.vscode/

# Mac
*.DS_Store


remote

add origin

プライベートリポジトリのURLを登録し、プッシュ/プル可能にする。

*実行例*

Basic認証の場合、以下の通りである。

$ git init

# Basic認証
$ git remote add origin https://github.com/hiroki-hasegawa/example.git

# 登録されたGitHubリポジトリ
remote.origin.url=https://github.com/hiroki-hasegawa/example.git

*実行例*

SSH公開鍵認証の場合、以下の通りである。

$ git init

# SSH公開鍵認証
$ git remote add origin git@github.com:<組織名またはgitユーザー名>/<GitHubリポジトリ名>.git

# 登録されたGitHubリポジトリ
remote.origin.url=git@github.com:<組織名またはgitユーザー名>/<GitHubリポジトリ名>.git


set-url origin

プライベートリポジトリのURLを変更し、プッシュ/プル可能にする。

configファイルに記述されたユーザー名と接続名を設定する。

1個のマシンで複数のGitHubアカウントを使用している場合、設定が必須である。

プロジェクトをクローンした時、SSH URLはデフォルトで『git@github.com:<組織名またはgitユーザー名>/<プロジェクト名>.git』となっている。

使用頻度の高いアカウントで所有するリポジトリでは、SSH URLを変更することが手間なので接続名を『github.com』としておく。

一方で、使用頻度の低いアカウントで所有するリポジトリでは、標準のSSH URLを異なる接続名で再設定する。

*実行例*

Basic認証の場合、以下の通りである。

# Basic認証
$ git remote set-url origin https://github.com/hiroki-hasegawa/example.git

# 登録されたGitHubリポジトリ
remote.origin.url=https://github.com/hiroki-hasegawa/example.git

$ git config --local --list

# 変更されたURL
remote.origin.url=https://github.com/hiroki-hasegawa/example.git

*実行例*

SSH公開鍵認証の場合、以下の通りである。

# SSH公開鍵認証
# 使用頻度の高いアカウントで所有するリポジトリ
$ git remote set-url origin git@github.com:<組織名またはgitユーザー名>/<GitHubリポジトリ名>.git

# 使用頻度の低いアカウントで所有するリポジトリ
$ git remote set-url origin git@<任意の接続名>:<組織名またはgitユーザー名>/<GitHubリポジトリ名>.git

$ git config --local --list

# 変更されたURL
remote.origin.url=git@<任意の接続名>:<組織名またはgitユーザー名>/<GitHubリポジトリ名>.git
# 使用頻度の高いアカウント
Host github.com
    User git
    Port 22
    HostName github.com
    IdentityFile <秘密鍵へのパス>

# 使用頻度の低いアカウント
Host <任意の接続名>
    User git
    Port 22
    HostName github.com
    IdentityFile <秘密へのパス>

# その他Gitlabなど
Host gitlab.com
    User git
    Port 22
    HostName gitlab.com
    IdentityFile <秘密へのパス> # GitHabとは別の鍵を作成した方が良い。

リポジトリに対してコミットをプッシュし、エラーが出た場合、異なる接続名が選択されている場合は、URLの『接続名』の部分が正しく設定されているか否かを確認する。

$ git push

ERROR: Permission to hiroki-hasegawa/*****.git denied to Foo.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.


submodule

サブモジュールとは

リポジトリ内の特定のディレクトリで他のリポジトリをリモート参照可能にする。

フォークと似た仕組みであり、git submodule updateコマンドを実行しないと、サブモジュールの更新を取り込めない。

また、git cloneコマンドの実行時には--recursiveオプションを有効化しないと、サブモジュールも合わせてクローンできない。

そのため、更新頻度の高いリポジトリをサブモジュールにすると、取り込む作業が大変になる。


add

カレントディレクトリにサブモジュールを作成する。

$ git submodule add --branch main https://github.com/hiroki-hasegawa/foo-sub-module.git ./modules/foo-sub-module

コマンドを実行すると、.gitmodulesファイルが作成される。

[submodule "modules/foo-sub-module"]
    path = modules/foo-sub-module
    url = https://github.com/hiroki-hasegawa/foo-sub-module.git
    branch = main


update

参照先のリポジトリで更新があった場合、それを取り込む。

参照先の更新を自動的に取り込むことはできないため、以下のコマンドを必要なタイミングで実行する必要がある。

上記を実行すると、サブモジュールのコミット情報が更新されて差分が生じるため、それをプッシュする。

$ git submodule update --remote <.gitmodulesに定義されたサブモジュール名>


--contains

現在にいるブランチを取得する。

$ git branch --contains

* main

--delete --force

プッシュとマージの状態に関係なく、ローカルブランチを削除する。

$ git branch --delete --force <ローカルブランチ名>


--move

作業中のローカルブランチの名前を変更する。

$ git branch --move <ローカルブランチ名>


--delete --remote

$ git branch --delete --remote origin/<ローカルブランチ名>

リモート追跡ブランチを削除する。

(1)

まず、branch --allで作業中のローカルブランチとリモート追跡ブランチを取得する。

$ git branch --all

* main
  remotes/origin/2019/Symfony_Nyumon/main
  remotes/origin/main
(2)

remotes/origin/2019/Symfony_Nyumon/mainを削除する。

$ git branch -d -r origin/2019/Symfony_Nyumon/main

Deleted remote-tracking branch origin/2019/Symfony_Nyumon/main (was 18a31b5).
(3)

再び、branch --allで削除されたことを確認。

$ git branch --all
* main
  remotes/origin/main


checkout -b

指定のコミットから新しいブランチを生やせる。

$ git branch checkout -b <新しいローカルブランチ名> <コミット番号>
$ git checkout -b feature/3 d7e49b04


cherry-pick

cherry-pickとは

現在のブランチに対して、指定したコミットそれ単体をマージする。

$ git cherry-pick <コミットID>

*例*

$ git cherry-pick 1d0ddeb9e52

プルリクエストのマージによるマージコミットを指定すると、そのプルリクエストで変更されたファイルのみがコミットの内容として取得できる。

これにより、developブランチ上の必要な変更のみをリリースできる。

ただし、マージコミットを指定する時は-mオプションを有効化しないとエラーになってしまうことに注意する。

また、マージコミットには2個の親がおり、マージ先の基点ブランチで変更されたファイルが被るコミットと作業ブランチの最後のコミットである。

前者は1番、また後者は2番となっており、1番を選択すること。

# mainブランチ上でreleaseブランチを作成し、チェックアウトする
$ git checkout -b release

# mオプションがないとエラー
$ git cherry-pick d7e49b04
error: commit d7e49b04 is a merge but no -m option was given.
fatal: cherry-pick failed

# mオプションを有効化する
$ git cherry-pick -m 1 d7e49b04

[main a9ebcb4] Merge pull request #276 from feature/123
 Author: hiroki.hasegawa <*****@users.noreply.github.com>
 Date: Wed Sep 15 00:00:00 2021 +0900
 1 file changed, 7 insertions(+)

# 指定したコミットのみがマージされているか否かを確認する。
$ git log

# releaseブランチをmainブランチにマージする。
$ git checkout main
$ git merge release


diff

結果に応じた終了コードをを出力する。

空文字をtrueとして判定する。

too many argumentsのエラーにならないように、ダブルクオーテーションをつける。

DIFF=$(git diff origin/main --name-only --relative ./...)

# 空文字かどうかを検証する
if [ -z "$DIFF" ] ; then
  echo "差分なし";
  exit 0
fi

echo "差分あり";

空文字でないことをtrueとして判定することもできる。

ダブルクオーテーションをつける。

DIFF=$(git diff origin/main --name-only --relative ./...)

# 空文字でないかどうかを検証する
if [ -n "$DIFF" ] ; then
  echo "差分あり";
  exit 1
fi

echo "差分なし";
EXIT_CODE=$(git diff origin/main --quiet)

# 終了コードを検証する
case $EXIT_CODE in
  0) echo "差分なし" ;;
  1) echo "差分あり" ;;
  128) echo "パラーメーターが誤っている" ;;
  *) echo "予期せぬエラー" ;;
esac


stash

stashとは

ファイルが、『インデックス』 (=add) あるいは『HEAD』 (=コミット) に存在している状態で、異なるローカルブランチをcheckoutしようとすると、以下のエラーが出る。

$ git checkout 2019/Symfony2_Ny

umon/main
error: Your local changes to the following files would be overwritten by checkout:
        app/config/config.yml
        src/AppBundle/Entity/Inquiry.php
Please commit your changes or stash them before you switch branches.
Aborting

この場合、一度stashを行い、『インデックス』 (=add) あるいは『HEAD』 (=コミット) を横に置いておく必要がある。

--include-untracked

トラッキングされていないファイルも含めて、全てのファイルを退避させる。

git statusをしたところ、修正ファイルが3個、トラックされていないファイルが1個ある。

$ git status

On branch 2019/foo-repository/feature/6
Your branch is up to date with "origin/2019/foo-repository/feature/6".

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   app/Resources/views/Inquiry/index.html.twig
        modified:   app/config/config.yml
        modified:   src/AppBundle/Entity/Inquiry.php

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        app/Resources/views/Toppage/menu.html.twig

no changes added to commit (use "git add" and/or "git commit -a")

これを、stash -uする

$ git stash -u

Saved working directory and index state WIP on 2019/foo-repository/feature/6: 649995e update #6 *****

これらのファイルの変更点を一時的に退避できる。

-- <パス>

特定のディレクトリやファイルのみstashできる。

git stash -- ./

list

退避している『ファイル番号ブランチ親コミットとコミットメッセージ』の一覧を取得する。

$ git stash list

stash@{0}: WIP on 2019/foo-repository/feature/6: 649995e update #6 *****

pop

退避している指定のファイルを復元する。

$ git stash pop stash@{<番号>}
$ git stash pop stash@{0}

On branch 2019/foo-repository/feature/8
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   app/Resources/views/Inquiry/index.html.twig
        modified:   app/config/config.yml
        modified:   src/AppBundle/Entity/Inquiry.php

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        app/Resources/views/Toppage/menu.html.twig

no changes added to commit (use "git add" and/or "git commit -a")

drop

退避している指定のファイルを復元せずに削除する。

$ git stash drop stash@{<番号>}
$ git stash drop stash@{0}

Dropped refs/stash@{0} (1d0ddeb9e52a737dcdbff7296272080e9ff71815)

clear

退避している全てのファイルを復元せずに削除する。

$ git stash clear


status

statusとは

addステージやcommitステージにファイルが存在しているか否かを取得する。

--porcelain

git statusコマンドを他のコマンドに入力できる形式で出力する。

CIの自動化で使用することが多い。

 $ git status --porcelain

 M foo
 M bar
 M baz
#!/bin/bash

git add .

if [ -z "$(git status --porcelain)" ]; then
  echo "変更点がないため、終了しました。"
  exit 0;
fi

git commit -m "CIツールが自動的にプッシュしました。"

git pull

git push origin HEAD


revert

revertとは

作業中のローカルブランチで、指定の履歴を削除する。

revert


<コミットID> --no-edit

指定したコミットのみを打ち消す新しいコミットを作成する。

コミットメッセージは、打ち消すコミットと同じものになる。

リリース後に元に戻したい時に役立つ。

$ git revert <コミットID> --no-edit


<コミットID> --edit

指定したコミットのみを打ち消す新しいコミットを作成する。

vimが起動するため、コミットメッセージを新しいものに変更する。

$ git revert <コミットID> --edit


-m <マージナンバー> <マージコミットID>

指定したマージコミットのみを打ち消す新しいコミットを作成する。

コミットメッセージは、打ち消すコミットと同じものになる。

マージナンバーを事前に確認しておく必要がある。

$ git show

commit xyz
Merge: 1a1a1a 2b2b2b    #ここに注目
Author: xxxx xxxx
Date:   Thu Jul 13 09:00:00 2017 +0000

    Merge commit

$ git revert -m 1 xyz


reset

resetとは

作業中のローカルブランチで、指定の履歴まで戻し、それ以降を削除する。

reset


インデックスから、指定したファイルを削除する。

$ git reset HEAD <ファイル名/パス>


--soft <コミットID>

作業中のブランチで、最新のHEAD (=コミット後) を指定の履歴まで戻し、それ以降を削除する。

コミットのみを取り消したい場合はこれ。

$ git reset --soft <コミットID>


--mixed <コミットID>

作業中のローカルブランチで、インデックス (=add後) 、HEAD (=コミット後) を指定の履歴まで戻し、それ以降を削除する。

addとコミットを取り消したい場合はこれ。

$ git reset --mixed <コミットID>


--hard <コミットID> (ブランチ)

作業中のローカルブランチで、最新のワークツリー (=ディレクトリ) 、インデックス (=add後) 、HEAD (=コミット後) を指定の履歴まで戻し、それ以降を削除する。

ワークツリー (=ディレクトリ) 内のファイルの状態も戻ってしまうため、取り扱い注意!!

$ git reset --hard <コミットID>
$ git reset --hard <ブランチ名>


resetの使用例

(1)

まず、logコマンドで、作業中のローカルブランチにおけるコミットIDを確認。

$ git log

commit f17f68e287b7d84318b4c49e133b2d1819f6c3db (HEAD -> main, 2019/foo-repository/main)
Merge: 41cc21b f81c813
Author: hiroki.hasegawa <example@gmail.com>
Date:   Wed Mar 20 22:56:32 2019 +0900

    Merge remote-tracking branch "refs/remotes/origin/main"

commit 41cc21bb53a8597270b5deae3259751df18bce81
Author: hiroki.hasegawa <example@gmail.com>
Date:   Wed Mar 20 20:54:34 2019 +0900

    add #0 fooさんのREADME_2を追加

commit f81c813a1ead9a968c109671e6d83934debcab2e
Author: hiroki.hasegawa <example@gmail.com>
Date:   Wed Mar 20 20:54:34 2019 +0900

    add #0 fooさんのREADME_1を追加
(2)

指定のコミットまで履歴を戻す。

$ git reset --soft f81c813a1ead9a968c109671e6d83934debcab2e
(3)

logコマンドで、正しく変更されているか確認。

$ git log

commit f81c813a1ead9a968c109671e6d83934debcab2e (HEAD -> main)
Author: Hiroki Hasegawa <example@gmail.com>
Date:   Wed Mar 20 20:54:34 2019 +0900

    add 新しいREADMEを追加
(4)

push --forceでローカルリポジトリの変更をリモートリポジトリに強制的に反映する。 『強制的にプッシュした』というログも、リモート側には残らない。

$ git push --force

Total 0 (delta 0), reused 0 (delta 0)
To github.com:hiroki-hasegawa/foo-repository.git
 + f0d8b1a...f81c813 main -> main (forced update)


強制的にpullする

$ git reset --hard origin/<ブランチ名>


rebase

rebaseとは (注意点あり)

作業中のローカルブランチで、ブランチの派生元を変更する。

例えば、作業ブランチで基点ブランチのコミットを取り込みたい場合に使用する。

リモートブランチにプッシュした後は使用してはならず、他のコマンドを使用する。

処理結果がgit mergeコマンドと似ているが、git rebaseコマンドはマージコミットを作らず、ない。


--interactive <コミットID>

派生元を変更する機能を応用して、過去のコミットのメッセージ変更、削除、統合などを実行する。

*例 (コミットメッセージの変更) *

(1)

まず、logコマンドで、作業中のローカルブランチにおけるコミットIDを確認。

$ git log

commit f17f68e287b7d84318b4c49e133b2d1819f6c3db (HEAD -> main, 2019/foo-repository/main)
Merge: 41cc21b f81c813
Author: Hiroki Hasegawa <example@gmail.com>
Date:   Wed Mar 20 22:56:32 2019 +0900

    Merge remote-tracking branch "refs/remotes/origin/main"

commit 41cc21bb53a8597270b5deae3259751df18bce81
Author: Hiroki Hasegawa <example@gmail.com>
Date:   Wed Mar 20 20:54:34 2019 +0900

    add #0 fooさんのREADME_2を追加

commit f81c813a1ead9a968c109671e6d83934debcab2e
Author: Hiroki Hasegawa <example@gmail.com>
Date:   Wed Mar 20 20:54:34 2019 +0900

    add #0 fooさんのREADME_1を追加
(2)

指定した履歴の削除

$ git rebase --interactive 41cc21bb53a8597270b5deae3259751df18bce81

とすると、タブが表示され、指定のコミットIDの履歴が表示される

pick b1b5c0f add #0 *****

『挿入モード』に変更し、この1行のpickeditに変更。

その後、

:w

として保管。

その後、エディタ上で『Ctrl+C』を押し、

:qa!

で終了。

(3)

git commit --amend-mオプションを付けて、メッセージを変更する。

$ git commit --amend -m="<変更後のメッセージ>"
(4)

git rebase --continueコマンドを実行することにより、変更を反映させる。

$ git rebase --continue

Successfully rebased and updated refs/heads/develop.
(5)

プッシュしようとすると、![rejected] develop -> develop (non-fast-forward)とエラーが出るため、

$ git merge <ブランチ名> --allow-unrelated-histories

で解決し、プッシュする。

*例 (Author名とCommiter名の変更) *

(1)

ハッシュ値を指定して、git rebaseコマンドを実行する。

$ git rebase --interactive 41cc21bb53a8597270b5deae3259751df18bce81
(2)

git commit --amendコマンドに--reset-authorオプションを付けて、configで設定した名前をAuthor名とComitter名に適用する。

$ git commit --amend --reset-author
(3)

git rebase --continueコマンドを実行し、変更を反映させる。

$ git rebase --continue
Successfully rebased and updated refs/heads/develop.

過去の全てのコミットに対して、Author名とCommitter名を適用するコマンドもある。

しかし、危険な方法であるため、個人利用のリポジトリのみで使用するようにする必要がある。

#!/bin/bash

git filter-branch -f --env-filter "
    # Author名かCommitter名のいずれかが誤っていれば適用します。
    if [ ${GIT_AUTHOR_NAME}="hiroki.hasegawa" -o ${GIT_COMMITTER_NAME}="hiroki.hasegawa" ] ; then
    export GIT_AUTHOR_NAME="hiroki.hasegawa"
    export GIT_AUTHOR_EMAIL="example@gmail.com"
    export GIT_COMMITTER_NAME="hiroki.hasegawa"
    export GIT_COMMITTER_EMAIL="example@gmail.com"
fi"


--onto <派生元にしたいローカルブランチ名> <誤って派生元にしたローカルブランチ名> <派生元を変更したいローカルブランチ名>

作業中のローカルブランチの派生元を変更する。

$ git rebase --onto <派生元にしたいローカルブランチ名> <誤って派生元にしたローカルブランチ名> <派生元を変更したいローカルブランチ名>


--interactive --root

一番古い、最初の履歴を削除する。

(1)

変更タブの表示

$ git rebase --interactive --root

とすると、最初の履歴が記述されたタブが表示される

pick b1b5c0f add #0 *****
(2)

pick b1b5c0f add #0 *****の行を削除して保管し、タブを閉じ、エディタ上で『Ctrl+C』を押す。

:qa!

ここで未知のエラー

CONFLICT (modify/delete): README.md deleted in HEAD and modified in 37bee65... update #0 README.mdに本レポジトリのタイトルと引用を記載した
した. Version 37bee65... update #0 README.mdに本レポジトリのタイトルと引用を記載した of README.md left in tree.
error: could not apply 37bee65... update #0 README.mdに本レポジトリのタイトルと引用を記載した

Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

Could not apply 37bee65... update #0 README.mdに本レポジトリのタイトルと引用を記載した


--abort

やりかけのrebaseを取り消し。

作業中のローカルブランチにおける(main|REBASE-i)が、(main)に変更されていることからも確認可能。

hiroki.hasegawa@PC /var/www/foo (main)
$ git rebase --interactive

hiroki.hasegawa@PC /var/www/foo (main|REBASE-i)
$ git rebase --abort

hiroki.hasegawa@PC /var/www/foo (main)
$


pull

コマンド組み合わせ

全てのリモートブランチをpullする。

$ git branch -r \
    | grep -v "\->" \
    | grep -v main \
    | while read remote; do git branch --track "${remote#origin/}" "$remote"; done

$ git fetch --all

$ git pull --all


push

-u origin <作成したブランチ名>

ローカルで作成したブランチを、リモートにプッシュする。

コミットは無くても良い。

$ git push -u origin <作成したブランチ名>


origin <コミットID>:main

トラウマコマンド。

$ git push origin <コミットID>:main


--delete origin <バージョンタグ>

リモートブランチのタグを削除する。

$ git push --delete origin <バージョンタグ>

*例*

$ git push --delete origin v1.0.0

注意点として、ローカルマシンのタグは別に削除する必要がある。

$ git tag -d v1.0.0


--tags

ローカルマシンのコミットに付与したタグをリモートにプッシュする。

$ git push --tags


show-branch

作業ブランチの派生元になっているブランチを確認。

$ git show-branch \
    | grep "*" \
    | grep -v "$(git rev-parse --abbrev-ref HEAD)" \
    | head -1 \
    | awk -F"[]~^[]" "{print $2}"


filter-branch

-f --env-filter

指定した名前とメールアドレスを上書きする。

$ git filter-branch --force --env-filter '
    # GIT_AUTHOR_NAMEの書き換え
    if [ "$GIT_AUTHOR_NAME"="<変更前のコミッター名>" ];
    then
      GIT_AUTHOR_NAME="<変更後のコミッター名>";
    fi

    # GIT_AUTHOR_EMAILの書き換え
    if [ "$GIT_AUTHOR_EMAIL"="<変更前のコミッターメールアドレス>" ];
    then
      GIT_AUTHOR_EMAIL="<変更後のコミッターメールアドレス>";
    fi

    # GIT_COMMITTER_NAMEの書き換え
    if [ "$GIT_COMMITTER_NAME"="<変更前のコミッター名>" ];
    then
      GIT_COMMITTER_NAME="<変更後のコミッター名>";
    fi

    # GIT_COMMITTER_EMAILの書き換え
    if [ "$GIT_COMMITTER_EMAIL"="<変更前のコミッターメールアドレス>" ];
    then
      GIT_COMMITTER_EMAIL="<変更後のコミッターメールアドレス>";
    fi
    ' -- --all


-f --tree-filter

全てのコミットに対して、指定した処理を実行する。

*例*

全てのコミットに対して、特定のファイルを削除する処理を実行する。

加えて、ローカルリポジトリに対してガーベジコレクションを実行すると、ローカルリポジトリから完全に削除できる。

$ git filter-branch -f --tree-filter \
    'rm -f <パス>' \
    HEAD

# ガベージコレクションを実行する
$ git gc --aggressive --prune=now