20200914のGitに関する記事は11件です。

Gitチートシート(サクッと調べたいとき用)

ローカルリポジトリを新規作成

$ git init
Initialized empty Git repository in ~~~~~~

上記のコマンドでワークツリー上にリポジトリが新規作成されます。

変更をステージに追加する

#ファイルを追加
$ git add <ファイル名>
#ディレクトリを追加
$ git add <ディレクトリ名>
#変更すべて追加
$ git add .

変更をリポジトリに反映する

$ git commit -m "コミットメッセージ"

mオプションでgitのエディターを立ち上げることなく、コミットメッセージをつけることが出来ます。

現在の変更状況を確認する

$ git status
#現在いるブランチ
On branch master

No commits yet
#ステージに追加されているファイル
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
    new file:   index.html
#ステージに追加されていないファイル
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    main.css

変更差分を確認する(ステージ前)

$ git diff
diff --git a/index.html b/index.html 
index cef45f3..8d0578e 100644
--- a/index.html
+++ b/index.html
@@ -10,5 +10,6 @@
 </head>
 <body>
     <h1>テスト用のファイルだよ。</h1>
+    <h1>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</h1> 
 </body>
 </html>>
\ No newline at end of file

表示されるのはステージされていないファイルのみ。
+の部分は新規で追加された部分
-の部分はもともとあったファイルから削除されたもの。

変更差分を確認(ステージ後)

# どっちでもいいです
$  git --staged
$  git --cached

コミット履歴を確認

$ git log
# 1コミット1行だけ表示(コミットメッセージくらいしかみれない)
$ git log --oneline
# 各コミットの変更差分を表示する
$ git log -p
# コミット数を指定して表示
$ git log -n <コミット数>

リポジトリとワークツリーからファイルを削除する。

$ git rm <ファイル名>
# ディレクトリを削除する場合(ファイル名とディレクト名を区別するため)
$ git rm -r <ディレクトリ名>
# リポジトリから削除したいが、ワークツリーには残したい場合
$ git rm -cached <ファイル名>

ファイルを移動(名前の変更もこれできる)

git mv <旧ファイル> <新ファイル>

リモートリポジトリを新規追加する

$ git remote add origin <リモートリポジトリのURL>

別にリモートリポジトリの名前はoriginでなくてもいいです。

Push(リモートリポジトリにコミットを反映する)

$ git push <リモート名> <ブランチ名>
#実例
$ git push origin master

上記のコマンドでは、originリポジトリのmasterブランチにpushしている

コマンドにエイリアスをつける

# 実例だけ。適宜変えてください。
$ git config --global alias.ci commit

上記のコマンドでは、グローバルに対してcommitをciを略するとしています。

ファイルへの変更を取り消す(ステージ前)

$ git checkout -- <ファイル名orディレクトリ名or.>

ファイルへの変更を取り消す(ステージ後)

git reset HEAD <ファイル名>

HEADのブランチの特定のファイルをリセットするという意味

直前のコミットをやり直す

git commit --amend

注意!!: リモートリポジトリにpushしたコミットはやり直さないでください。コンフリクトが発生して、地獄を見ます。

登録したリモートリポジトリを表示する

$ git remote
# 対応するURLを表示したかったら
$ git remote -v

リモートリポジトリから情報を取得してくる

$ git fetch <リモート名>
$ git pull <リモート名> <ブランチ名>

fetchとpullの違い
fetchはリモートリポジトリの内容をローカルリポジトリに保存するだけ
pullはリモートリポジトリの内容をローカルリポジトリとワークツリーに反映する

リモートリポジトリの詳細情報を表示する

$ git remote show <リモート名>

リモートの名前変更・削除

$ git remote rename <旧リモート名> <新リモート名>
$ git remote rm <リモート名>

新しいブランチを作成

$ git branch <ブランチ名>

ブランチの一覧を表示する

# ローカルのみ
$ git branch
# リモートリポジトリも表示する
$ git branch -a

ブランチを切り替える

$ git checkout <ブランチ名>
# ブランチの新規作成と同時に切り替える
$ git checkout -b <ブランチ名>

マージする

$ git merge <ブランチ名>
$ git merge <リモート名/ブランチ名>

ブランチの名前変更・削除する

$ git branch -m <ブランチ名>
$ git branch -d <ブランチ名>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

githubのローカル・リモートのブランチ名を変更する方法

githubのリモートブランチ名を変更する方法

ローカルブランチ名の変更は簡単にできたが、リモートブランチの変更が少し手間取ったのでメモ。


ローカルブランチ名の変更

ローカルブランチ名の変更方法。

$ git branch -m 旧ブランチ名 新ブランチ名

-mオプションを使う。(moveの略)

強制ではないので、既にブランチが存在する場合はエラーになる。

エラー
fatal: A branch named 新ブランチ名 already exists.

強制的に変更

-Mオプションを使うと強制的にブランチ名を作成できる。
既に存在している場合は上書きする。

$ git branch -M 旧ブランチ名 新ブランチ名

-M = -m+ -f
 ┗ -m = --move
 ┗ -f = --force


リモートブランチ名の変更

厳密にはリモートブランチ名を変更するコマンドはないため、ブランチ削除してから新しいブランチ名前でpushする。

  1. リモートブランチのコピー (pull)
  2. リモートブランチの削除 (push)
  3. リモートブランチの作成 (push)


1. リモートブランチのコピー

リモートブランチを削除する前に、現状をローカルにコピーする。

$ git pull リモートレポジトリ名 消すブランチ名

▼(例)リモートブランチft2をft1に変更

#pull用のローカルブランチ(ft)に移動
$ git checkout ft

#リモートブランチのft2の内容をコピー
$ git pull origin ft2

2. リモートブランチの削除 (push)

リモートブランチの削除には空のローカルブランチを送る。

$ git push リモートレポジトリ名 :消すリモートブランチ名
 ┗ ローカルブランチ名:リモートブランチ名のローカルを記載しない

#リモートブランチのft2に空のローカルブランチをpush
$ git push origin :ft2
 - [deleted]         ft2

deletedと表示されれば削除完了。

3. リモートブランチの作成 (push)

変更したい名前のリモートブランチを新規作成し、ローカルブランチの内容をプッシュする。

$ git push リモートレポジトリ名 ローカルブランチ名:リモートブランチ名

#ローカルブランチftの内容でリモートブランチft1を新規作成する
$ git push origin ft:ft1
Total 0 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'ft1' on GitHub by visiting:
remote:      https://github.com/~/git-test/pull/new/ft1
remote:
To github.com:~/git-test.git
 * [new branch]      ft -> ft1

new branchが表示されればOK。

リモートレポジトリを確認

git branch -aでローカルとリモートの全てのブランチを表示。

$ git branch -a
* ft
  master
  remotes/origin/ft1
  remotes/origin/master

無事、remotes/origin/ft1が作成されている。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

gitでエイリアス(ショートカットコマンド)を設定する方法

gitでエイリアス(ショートカットコマンド)を設定する方法

gitで頻繁に使うコマンドや長すぎるコマンドはエイリアス(ショートカットコマンド)をbashではなく、gitのconfigファイルで設定することができる。

目次

  1. エイリアス適用範囲
  2. 適用方法
    1. コマンド入力
    2. 設定ファイルを直接編集
    3. エイリアス設定早見表
  3. 設定時の注意点
  4. 外部コマンドのエイリアス設定


エイリアス適用範囲

用途に応じて適用範囲を下記3つから選べる

  1. システム全体
  2. ユーザー単位
  3. リポジトリ単位

エイリアス適用方法

エイリアスの適用方法は(1)コマンド入力、(2)設定ファイルを直接編集の2種類。

コマンド入力

$ git config [option] alias.エイリアス 通常コマンド
 ┗ 通常コマンドはgit以降

例えば、「git commit」を「git ci」(ユーザー単位)とする場合以下となる。

$ git config --global alias.ci commit


設定ファイルを直接編集

対象の設定ファイルに以下を記述する。

[alias]
        エイリアス = 通常コマンド

 ┗ 通常コマンドはgit以降

例えば、「git commit」を「git ci」(ユーザー単位)とする場合以下となる。

ユーザー単位の設定ファイルを開く
$ vi ~/.gitconfig 
.gitconfig
[alias]
        ci = commit


エイリアス設定早見表

No 適用範囲 設定ファイル コマンドオプション コマンド例
1 システム全体 /etc/gitconfig --system git config --system alias.ci commit
2 ユーザー単位 ~/.gitconfig --global git config --global alias.ci commit
3 リポジトリ単位 .git/config なし git config alias.ci commit


エイリアス設定時の注意点

・それぞれで同じエイリアスが使われている場合、優先度は、リポジトリ > ユーザー > PC全体の順になる。

・既存のコマンドは使用できない。
git commitのcommitを別の内容に置き換えはできない。


便利なエイリアス例

通常コマンド エイリアス 内容 コマンド(ユーザー単位)
commit ci コミット $ git config --global alias.ci commit
status st ステータス $ git config --global alias.st status
branch br ブランチ $ git config --global alias.br branch
checkout co チェックアウト $ git config --global alias.co checkout
log -1 HEAD last 最後のコミット $ git config --global alias.last 'log -1 HEAD'
log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit logg コミット履歴を美しく表示 $ git config --global alias.logg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"


外部コマンドのエイリアス設定

gitを除いた通常のコマンドもエイリアスとして設定可能。

※注意点
- 通常コマンドの冒頭に!をつける。
- gitconfigで設定するため、実行はgit エイリアス


▼設定事例

▼コマンド入力

$ git config --global alias.hello '!echo Hello World'



▼設定ファイルに直接記述

terminal
#vimエディタで.gitconfigを開く
$ vim ~/.gitconfig
.gitconfig
#helloというエイリアスを設定
[alias]
        hello = !echo "hello world"
terminal
#設定したエイリアスを実行
$ git hello
hello world



ご参考:git aliasについて(公式・英語)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git logを劇的に見やすくする方法。コミット履歴をグラフで表示

git logを劇的に見やすくする方法。コミット履歴をグラフで表示

gitでlogを表示するオプションはたくさんあるが、特に複数人開発で各作業者の作業状況を見るときにとても便利なコマンド。

git log --oneline --graph

以下のような形でコミットの流れを一覧で確認することができる。

image.png

* :コミットされたタイミング
| / \ :ブランチの流れ
|\ :マージ(marge pull request)

ログが画面に入りきらない場合、終端は「:」となっている。
・Enterを押せば過去のログをロード(表示)
終了したいときは、「q」をクリック

--graph

git log --graphを使うとコミットの流れをグラフで表示できる。

この状態では、Authorやdate、コミットメッセージが表示され冗長になる。

$ git log --graph
*   commit 4f919da1d5b3f845d0b7310ccb6dd58c0f6503fa (HEAD -> master)
|\  Merge: 584476934 8fbf5ff50
| | Author: Sadick <sadickjunior@gmail.com>
| | Date:   Fri Sep 11 21:44:31 2020 +0300
| |
| |     Merge pull request #21193 from atom/fs-admin-0.15.0
| |
| |     ⬆️ fs-admin@0.15.0
| |
| * commit 8fbf5ff503e002022f0d9df8cefdac19c4b83f5e
| | Author: runner <runner@Mac-1773.local>
| | Date:   Thu Aug 20 03:11:49 2020 +0000
| |
| |     :arrow_up: fs-admin@0.15.0
| |
* |   commit 584476934785cf5a8df83f428912559e5eacc764
|\ \  Merge: e4701771b af6f4e67f
| | | Author: Musa Ibrahim <small_musa@hotmail.com>
| | | Date:   Fri Sep 11 16:51:13 2020 +0100

--oneline

git logと合わせてよく使われるコマンドの一つ。
各コミットオブジェクトのログをその名の通りワンラインで表示してくれる。

--onelineあり
$ git log --oneline -1
4f919da1d (HEAD -> master) Merge pull request #21193 from atom/fs-admin-0.15.0

表示内容

以下3つの主要な情報のみを表示。
①コミットオブジェクトのハッシュ値(省略形) ②参照名 ③コメント

①コミットオブジェクトのハッシュ値(省略形)

4f919da1d

上8〜9桁を表示する。
省略なし:4f919da1d5b3f845d0b7310ccb6dd58c0f6503fa

表示桁数は重複がない桁でなされるため、コミットの数が大量に増えた場合は10桁以降も表示することもありうる。

②参照名

(HEAD -> master)
HEAD、ブランチ、タグ、リモートブランチの場所を表す。

③コメント

Merge pull request #21193 from atom/fs-admin-0.15.0
コミットメッセージが表示される。


onelineなし

--onelineを外せば、作業者(Author)や日付も確認できる。

--onelineなし
$ git log -1
commit 4f919da1d5b3f845d0b7310ccb6dd58c0f6503fa (HEAD -> master)
Merge: 584476934 8fbf5ff50
Author: Sadick <sadickjunior@gmail.com>
Date:   Fri Sep 11 21:44:31 2020 +0300

    Merge pull request #21193 from atom/fs-admin-0.15.0

    ⬆️ fs-admin@0.15.0


--onelineと--pretty=onelineの違い

--onelineと似たオプションに--pretty=onlineというのがある。

--prettyは表示フォーマットを指定するオプション。onlineを指定すると一行で書く。

--onelineとの違いは、コミットオブジェクトのハッシュ値が省略形にならないこと。

--oneline
$ git log --oneline -1
4f919da1d (HEAD -> master) Merge pull request #21193 from atom/fs-admin-0.15.0
--pretty=oneline
$ git log --pretty=oneline -1
4f919da1d5b3f845d0b7310ccb6dd58c0f6503fa (HEAD -> master) Merge pull request #21193 from atom/fs-admin-0.15.0

--abbrev-commit

ちなみに、ハッシュ値を省略するコマンドは--abbrev-commit。(abbrevはabbreviationの略で、省略という意味)

つまり、以下2つは同じ内容となる。
git log --oneline
git log --pretty=oneline --abbrev-commit


応用編

git log --graph --onelineをさらに見やすく設定する。

▼表事例
image.png

経過日数や、作業者(Author)情報を表示して、それぞれ任意の色をつける。

コマンド
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

--pretty=format:

git logの書式を設定するオプション。色の指定や、文字・記号の挿入ができる。

(1) %Cred%h%Creset
 ┗ %Cred :色をredにする
 ┗ %h : ハッシュを省略形で表示
 ┗ %Creset: 書式をリセット

%Cresetがないと次の書式指定がある箇所まで、書式が継続してしまう。

(2) %C(yellow)%d%Creset
 ┗  %C(color):カッコの中の色にする
 ┗  %d: 参照名を表示
 ┗  %Creset: 書式をリセット

(3) %s
 ┗ コミットメッセージ

(4) %Cgreen(%cr)
 ┗ %Cgreen: 緑色で表示
 ┗ ( ): カッコを表示
 ┗ %cr: コミットの相対日付を表示(n days ago)

(5) %C(bold blue)<%an>%Creset
 ┗ %C(bold blue): 太字・青色で表示
 ┗ < >: カッコを表示
 ┗ %an: 作業者名を表示 (author name)
 ┗ %Creset: 書式リセット



git logの書式設定オプション--pretty=format:の細かい情報はこちら


エイリアスの設定

長いコマンドを毎回入力するのは酷なので、エイリアス設定して超簡単に呼び出せるようにする。

以下コマンドでを実行すれば、git loggのみですぐに呼び出せるようになる。

$ git config --global alias.logg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"



エイリアス設定方法の詳細

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git log便利オプション --pretty=formatで表示書式を使いこなす

git logの表示書式を整える便利オプション--pretty=formatを使いこなす

git logのオプションの一つに--pretty=format:" "がある。

これを使うと欲しい情報を欲しい形で選択的に表示することができる。

ログをグラフで表示する--graphオプションと合わせて使用するとより見やすいグラフを表示することができる。

目次

  1. --pretty=format:のオプション
  2. よく使うオプション
  3. オプション一覧
    1. ツリーのハッシュとは?
    2. 親のハッシュとは?
    3. AuthorとCommiterの違い
  4. 色の指定(%C)
    1. %C(color)
    2. %Ccolor
    3. %C(オプション color)
    4. %Creset
  5. 文字や記号の挿入
  6. --pretty=format応用例


--pretty=format:のオプション

欲しい情報を表すオプション記号を指定することで、表示する情報を選択できる。

例えば、コミットのハッシュ値の短縮形を表す%hを使うと下記のようになる。

%h
$ git log  --pretty=format:"%h" -1
4f919da1d

末尾の「-1」はログ1つのみを表示するオプション。

コミットメッセージを表す%sの場合は下記となる。

%s
$ git log  --pretty=format:"%s" -1
Merge pull request #21193 from atom/fs-admin-0.15.0


--pretty=format:のよく使うオプション

--pretty=format:" "で使うオプションは複数あるが実際に使うのは限られている。

よく使うオプションのみ抜粋。

オプション 内容 実例
%h コミットのハッシュ(短縮形) 4f919da1d
%an Authorの名前 Sadick
%ae Authoのメアド sadickjunior @ gmail.com
%ad Authorの日付 Fri Sep 11 21:44:31 2020 +0300
%ar Authorの相対日付 3 days ago
%s コミットメッセージ Merge pull request #21193 from atom/fs-admin-0.15.0
%d 参照名(ref name) (HEAD -> master)

%aはauthor関連の情報なので、まとめると、%h, %a, %s, %dの4つに絞れる。

(%arはAuthor Relative)


--pretty=format:のオプション一覧

オプション 内容 実例
%H コミットのハッシュ 4f919da1d5b3f845d0b7310ccb6dd58c0f6503fa
%h コミットのハッシュ(短縮形) 4f919da1d
%T ツリーのハッシュ 4cda2817d9be96d5d80f0434ba99a85e42dd3b35
%t ツリーのハッシュ(短縮形) 4cda2817d
%P 親のハッシュ 584476934785cf5a8df83f428912559e5eacc764 8fbf5ff503e002022f0d9df8cefdac19c4b83f5e
%p ツリーのハッシュ(短縮形) 584476934 8fbf5ff50
%d 参照名(ref name) (HEAD -> master)
%an Authorの名前 Sadick
%ae Authoのメアド sadickjunior @gmail.com
%ad Authorの日付 Fri Sep 11 21:44:31 2020 +0300
%ar Authorの相対日付 3 days ago
%cn Committerの名前 GitHub
%ce Committerのメアド noreply @github.com
%cd Committerの日付 Fri Sep 11 21:44:31 2020 +0300
%cr Committerの相対日付 3 days ago
%s コミットメッセージ Merge pull request #21193 from atom/fs-admin-0.15.0

まだまだあります。

ツリーのハッシュとは?

tree hashはコミットの現在のディレクトリを示すハッシュ値。
git log --graphでブランチを切ると枝分かれしていくように、あの一本の線を表したのがツリーのハッシュ値。

HEAD(現在のコミット)やブランチは一つ一つの点を指すもの。
treeは派生した線なので、間のハッシュが削除や変更されてもtreeのハッシュは変わらない。

親のハッシュとは?

Parent hashは現在のコミットの大元となっているブランチのハッシュ値。

AuthorとCommiterの違い

Authorは作業そのものを行った人。Commiterはその作業を適用した人を指す。

githubを使用してプロジェクトを進めている場合、commiterはgithubになる。


色の指定(%C)

%Cを使うと色を指定することができる。色の指定方法は3種類。

  1. %C(color)
  2. %Ccolor
  3. %C(オプション color)
  4. %Creset


1. %C(color)

カッコの中に色を記述することで、指定したオプションの色を変更することができる。

--pretty=format:"%C(color)%オプション"

image.png

▼使用可能なカラー

色一覧
red
blue
yellow
black
magenta
cyan
white
auto
normal

autoはデフォルト設定のカラーになる。
(例: ハッシュ値ならyellow)


2. %Ccolor

%Cの後に直接色を記述する方法。使える色はred, blue, greenの3色に限られる。

--pretty=format:"%Ccolor"

C+色
Cred
Cblue
Cyellow


3. %C(オプション color)

書式は色設定と同時に、太字や下線などのオプションも設定できる。

image.png

オプション 概要
bold 太字
ul 下線
dim 減光
reverse 反転
blink 点滅

オプションは色とセットではなく、オプションのみでも使用可能。

$ git log --pretty=format:"%C(ul)%h"
$ git log pretty=format:"%C(reverse ul)%h"


4. %Creset

色付した書式の注意点として、%Cresetを設定しないと、続く対象が全て指定した色になってしまう。

%Cを使うことで色をクリアすることができる。

$ git log  --pretty=format:"%C(bold red)%h%Creset - %s - %C(cyan)%an%Creset - %ar"

image.png


文字や記号の挿入

ここまでで、色や太字などのオプションの設定を見てきた。
実際に出力するときには情報毎に区切ってより見やすくする必要がある。

やり方は簡単で、表示したい文字や記号を挿入するだけ。

▼文字HASH:とカッコを表示する

$ git log  --pretty=format:"HASH: %h (%ar)" -1
HASH: 4f919da1d (3 days ago)


--pretty=format応用例

これまでの内容を踏まえて、git logのグラフ表示を見やすく表示する。

git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

image.png

情報が色分けされていてとても見やすい。



<関連リンク>
--graphオプションについて
github 公式ページ
github 公式ページ(英語)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

まだgit log --decorateを使ってるの?

まだgit log --decorateオプションを使ってるの?

git logコマンドの --decorateオプションについて。

--decoreの有無で表示される内容が変化しなかったので調べてみた。

--decorateなし
commit 0b57f44b3371521f65eb7607310803c7e90dc023 (HEAD -> master, origin/master)
--decorateあり
commit 0b57f44b3371521f65eb7607310803c7e90dc023 (HEAD -> master, origin/master)

--decorateは不要

gitのバージョン2.12.2以降は git logコマンドに、git log --decorate=autoがデフォルトとなったので、なくても同じ結果が返ってくるため特に記述する必要がない。

--decorateを記述しているのは、過去の古い記事やコードを参照しているためと思われる。

▼バージョンによる違い

v1.8.3
commit 0b57f44b3371521f65eb7607310803c7e90dc023
v2.24.3
commit 0b57f44b3371521f65eb7607310803c7e90dc023 (HEAD -> master, origin/master)

例えば、git logをグラフ見やすくするときに、git log --graph --oneline --decorateを使っている場合があるが、実は--decorateをつける必要はない。


--decorateオプション

--decorateは参照名(ref name)を表示するオプション。
git logコマンドを実行した時に表示される、コミットのハッシュ値の後ろにカッコで表示される部分。

https://git-scm.com/docs/git-log

参照名(ref name)とは?

以下のようなgit logの場合、コミットのハッシュ値以下のカッコに囲まれた色付きの部分がこれに該当する。

image.png

参照名
 (HEAD -> master, origin2/master)

参照名からは、現在作業中のコミットオブジェクトか、そのコミットオブジェクトはブランチかどうか、対応するリモートブランチがあるかがわかる。

HEAD
現在作業中のコミットオブジェクトを指す。

HEAD -> master
現在作業中のコミットオブジェクトが、masterブランチであることを指す。

origin2/master
リモートレポジトリ名origin2のmasterブランチがこのコミットオブジェクトであることを指す。

--decorateの表示指定

--decorateが完全に無意味になったわけではなく、いくつかの表示方法の指定がある。使用する場合は意図的に--decorate=fullをつけることもある。

--decorate=XXX

表示指定 内容 実例
auto ターミナルの時のみshortで表示。それ以外は表示しない(noとする) (HEAD -> master, origin2/master) or 表示なし
short 接頭辞(refs/heads/、refs/tags/、refs/remotes/)なしで表示 (HEAD -> master, origin2/master)
full 接頭辞ありで表示 (HEAD -> refs/heads/master, refs/remotes/origin2/master)
no 参照名を表示しない なし

接頭辞について

shortとfullで接頭辞の表示・省略が切り替わる。
接頭辞をつけると、refs/heads/、refs/tags/、refs/remotes/などが表示される。

これらはブランチ名の省略されていない表記になる。

git branchでブランチ一覧を表示したときに見るのは省略形。

ブランチ名の例
$ git branch -a
* master
  slaves
  remotes/origin2/master
  remotes/origin2/slaves
  remotes/origin2/test

これに対して、実際の各ブランチを指すファイルは、ローカル・リモートレポジトリのブランチやタグ毎に別れたディレクトリに入っている。

ディレクトリとファイル一覧
$ find .git/refs
.git/refs
.git/refs/heads
.git/refs/heads/master
.git/refs/heads/slaves
.git/refs/tags
.git/refs/tags/v1.0
.git/refs/remotes
.git/refs/remotes/origin2
.git/refs/remotes/origin2/test
.git/refs/remotes/origin2/master
.git/refs/remotes/origin2/slaves

このファイルパスも細かく記述したのが--decorate=fullオプションとなる。

省略形で見ればわかるので、fullは基本不要かな。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Git】過去のコミットから特定のファイルを削除したい。GitHubからも

はじめに

GitHubにpushしてはいけないファイルをコミットしてしまっていた場合に、その履歴をまとめて修正したい場合、どうすればいいかを学んだ。
途中でエラーがでたところもあったので、その解決方法も書く。

手順

安全に行う為、ブランチを切る

git checkout -b delete-check

そのブランチ上で、試す

今回は例として.envファイルを削除する。

git filter-branch --tree-filter 'rm -f .env' HEAD 

filter-branch --tree-filterで各コミットに対し、その後に続く、rm -f .env' HEADのコマンドを実行する。

出力結果
WARNING: git-filter-branch has a glut of gotchas generating mangled history
     rewrites.  Hit Ctrl-C before proceeding to abort, then use an
     alternative filtering tool such as 'git filter-repo'
     (https://github.com/newren/git-filter-repo/) instead.  See the
     filter-branch manual page for more details; to squelch this warning,
     set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...

Rewrite 7575dc6065c2dbbeef43df034dbe859f5a078 (1/6) (0 secoRewrite 98d96539c8c44062b280efc10e588a99b41b (2/6) (0 secoRewrite 25c2d7bc0e4d3fe23553c7b7607306c300c2dc (3/6) (0 secoRewrite d47862db7be1ab51df7b5e09f351abbf7b (4/6) (0 secoRewrite 2d0e1d8d96a19d35bc3a4453bc653c0cdc3ec5 (5/6) (0 secoRewrite 3fee6b5c30b9ddf9432de818cc5d9d20b13e0 (6/6) (0 seconds passed, remaining 0 predicted)
Ref 'refs/heads/delete-check' was rewritten

こういった出力になり、上書きされていることがわかる。

masterブランチで実行する。

安全のために切ったdelete-check上で実行できることがわかったので、次にmasterブランチ上で同じコマンドを実行する。

git filter-branch --tree-filter 'rm -f .env' HEAD 

すると、

Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f

というエラーになり、

前のバックアップがあるから、上書きしたいんやったら -f つけて

と言われたので、

git filter-branch -f --tree-filter 'rm -f .env' HEAD 

-fをつけて実行すると成功。

GitHubにプッシュ

git push -f origin master

これでローカル、リモートどちらも上書きされる。

終わりに。

最後まで読んで頂きありがとうございます:bow_tone1:
転職の為、未経験の状態からReact,Railsを学習しております。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gitコマンド超省略版

Linux(Ubuntu)のターミナルからGitを操作する最低限のコマンドをまとめました。

クローン

git clone (URL)

コミット関係

基本これの繰り返し
※ cd で更新するディレクトリに予め移動

git add .
git commit -m 'commit comment'
git push origin master # masterブランチの更新

ブランチを切る

git branch -a # 一覧 
git checkout (ブランチ名) # 移動
git checkout -b feature # 作成+移動(featureは例)
git merge feature # featureをmasterにマージ(masterだけになる)

ここまで使えば個人レベルのgit管理はできそう

(おまけ)あんまり使ってない編

git branch -d feature # ローカルブランチ削除
git branch -d -r origin/feature # 追跡ブランチ削除
git push origin :feature # 空ブランチを指定してリモートブランチ削除

git reset --soft HEAD^ # 直前のコミット取り消し

resetは以下が参考になりそう
https://qiita.com/ChaaaBooo/items/459d5417ff4cf815abce

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Github DependabotでライブラリアップデートPRを自動作成した際の動作確認をなるべく楽にした話

そもそもDependabotとは

GithubDependabotという機能があるのはご存知でしょうか?
リポジトリ内で使用している依存関係(ライブラリ)で古いものがあれば更新をかけたPullRequestを自動発行してくれる機能です。
パブリックなリポジトリで以下のようなPRを見たことがある方も多いと思います。

スクリーンショット 2020-09-09 20.12.31.png

もともとは独立したサービスでしたが、Githubに買収されてネイティブ機能として取り込まれたので導入がしやすくなりました。
.github/dependabot.yml配下に設定ファイルを配置するだけでライブラリアップデートPR自動作成を有効に出来ます。

今回Dependabot自体の解説は省きますが私の携わるプロジェクトでは以下のような設定ファイルで月曜日の9時にチェックがかかるように運用を始めています。

version: 2
updates:
  - package-ecosystem: "gradle"
    directory: "/"
    target-branch: "develop"
    schedule:
      interval: "weekly"
      day: "monday"
      time: "09:00"
      timezone: "Asia/Tokyo"
    reviewers:
      - "ignis-ltd/with-android"

まずはGithub Dependabotについて詳しく知りたいという方は以下の公式ドキュメントや記事が参考になると思います

※現状「Dependabot」でググると買収される前の独立したサービスだった時代のマーケットプレイス版の記事がたくさん出てきますが、そちらはいずれ廃止されてネイティブ機能に統合される可能性が高いのでご注意下さい

Dependabotの運用課題

Dependabotは1ライブラリのアップデートにつき1つのPRを発行されます。
一部のライブラリアップデートが問題を起こす可能性もあるので問題を切り分けるためにも個別になっている事自体は正しい形だと思っているのですが、いくつもアップデートがある場合やや課題が残ります。

スクリーンショット 2020-09-09 20.12.13.png

サーバーサイドでも似たような課題は発生しうると思いますが、私の扱うプロジェクトではAndroidアプリなので上記のように5つのPRが一度に発行された場合5回ブランチをcheckoutしてビルドしてインストールして動作確認をする必要がありました。

もちろんCI上でテストを組んで自動化すればリスクを減らすことも出来ますが、やはりアプリの場合はUIの崩れ等が心配なのでマージ前に目視での動作確認は1度はしておきたいところです。
あるいはCIでブランチごとにデプロイまで行えばチェックアウトまではしなくても良いですが、それでも5回ダウンロードしてインストールして起動するだけでもちょっと大変ですよね。

解決策

そこで考えたアプローチとして、dependabotが発行したそれぞれのPRのブランチを一つのブランチへマージしてCIからビルドを行い、各PRにコメントとしてバイナリへのリンクを残すという手法を検討しました。
以下で実際のやり方をご紹介致します。

Dependabotが発行したブランチを統合する

まずアップデートがかかったGitブランチをすべて抽出して統合するRubyスクリプトを組んでみます。

  1. dependabot/の文字列から始まるブランチ一覧を取得する
  2. 現在のブランチ(develop)からアップデートcommitのパッチファイルを作成する
  3. 2.で取得したパッチファイルをすべて適用する

(Ruby力は底辺なのでそのあたりは見逃してください :pray:

Gemfile
source 'https://rubygems.org'

gem 'git'
merge_dependabot_branchs.rb
require "git"

dependabotBranchs = []
git_client = Git.open(Dir.pwd)
git_client.fetch
git_client.branches.each do |branch|
  if branch.name.start_with?('dependabot/')
    dependabotBranchs.append(branch)
  end
end

return if dependabotBranchs.size <= 0

dependabotBranchs.each do |dependabotBranch|
  system("git format-patch -1 #{dependabotBranch.gcommit} --unified=0")
end
system("git apply 0001-*.patch --unidiff-zero")

ちょっとした解説

ここで肝となるのがパッチファイルの作成と適用方法です。
git format-patchでパッチファイルを生成していますが、通常では前後3行の変更もDiffに含まれています
つまりアップデートがかかったライブラリの行が隣り合っているときなど、前後3行以内に変更がすでにある場合コンフリクトとして判断されてしまい自動での統合がされません。
Dependabotによるバージョンアップの変更だけを抽出すればコンフリクトは起こり得ないはずなので、近い行で変更があってもコンフリクトとみなさず統合してほしいものです。
そこで--unified=0パラメータを付与することで前後の行をDiffに含めないように調整しています。(参考

また、git applyでパッチファイルを適用する際にも小技を使っていて、通常では前後の行が含まれていない(--unified=0を指定した)パッチファイルでは適用が失敗してしまうので--unidiff-zeroパラメータを付与して前後の行を無視して適用されるようにしています。(参考

この辺の処理は当初使っていたruby-gitだと機能不足だったのでsystemコールに頼っています。

ここまででライブラリアップデートが統合されたブランチが出来上がっているはずなので、この状態でビルドすれば統合されたバイナリを生成できます。

Dependabotが発行したPRに統合したバイナリへのリンクを貼る

CI上でバイナリを生成してリンクURLも発行したと仮定して、もともとのDependabotが生成したPRにコメントを残すRubyスクリプトを組んでみます。
今度はGitではなくGithub APIを使って抽出します。

  1. 現在開かれているPullRequestでdependabot/の文字列から始まるブランチを抽出する
  2. 抽出したPullRequestに対してバイナリへのリンクと統合したPullRequest一覧をコメントとして貼る

(Ruby力底辺コード)

comment_dependabot_prs.ruby
require 'net/http'
require 'uri'
require 'json'

uri = URI.parse("https://api.github.com/repos/ignis-ltd/with_android/pulls")
request = Net::HTTP::Get.new(uri)
request["Accept"] = "application/vnd.github.v3+json"
request["Authorization"] = "token #{ENV['GITHUB_API_TOKEN']}"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

dependabotPullRequests = []
responseBodyJson = JSON.parse(response.body, symbolize_names: true)
responseBodyJson.each do |pull|
  if pull[:head][:ref].start_with?('dependabot/')
    dependabotPullRequests.append(pull)
  end
end

dependabotPullRequests.each do |pull|
  uri = URI.parse("https://api.github.com/repos/ignis-ltd/with_android/issues/#{pull[:number]}/comments")
  request = Net::HTTP::Post.new(uri)
  request.body = JSON.dump({
    "body" => "Deployed a binary that merged the following branches\n" + dependabotPullRequests.map { |pull| pull[:html_url] }.join(" ") + "\n\n#{ENV['INSTALL_PAGE_URL']}"
  })
  request["Accept"] = "application/vnd.github.v3+json"
  request["Authorization"] = "token #{ENV['GITHUB_API_TOKEN']}"

  req_options = {
    use_ssl: uri.scheme == "https",
  }

  response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
    http.request(request)
  end
end

ちょっとした解説

基本的にはGithub APIを使って愚直に実装しているだけです。

上記のRubyスクリプトの実行には以下の環境変数とが必要となります。Github API用のURLも適宜変更して下さい
Githubのトークン情報は直接含めず、CIのシークレット環境変数などを使って下さい。

  • GITHUB_API_TOKEN ... GithubへのコメントするためのTokenを指定して下さい
  • INSTALL_PAGE_URL ... 生成したバイナリへのリンクURLを指定して下さい
    • 今回はCIでのビルドやデプロイまでは言及しないので省略しますが、アプリのCIは個人的にはBitrise推しです。

ここまで組むことができればDependabotが発行したPullRequestに以下のようなコメントを残すことが出来ます。
どのブランチを統合したのかと統合されたバイナリをどのPullRequestからも参照することが出来るようになります。

スクリーンショット 2020-09-09 20.12.44.png

Dependabotの実行後にCIでスクリプトとビルドを定時実行させる

私のプロジェクトではDependabotの実行を月曜9:00に行っているため、このスクリプトを含んだCIの実行は月曜10:00に行うように調整しています。
以下はBitriseでの設定例です。このあたりはお好みで調整して下さい。

スクリーンショット 2020-09-10 2.43.58.png

補足というか注意点

最初のDependabotのブランチを統合するスクリプトはGitのブランチ情報を基準にしてますが、後のコメントする際のスクリプトはPullRequest基準で検索をかけるので、(基本的にはないと思いますが)PullRequestが発行されていないDependabotブランチが存在する場合や、ビルド中にブランチやPRに変更を加えた場合はコメントの内容とバイナリの実態にズレが生じます。

また、dependabot/という文字列でブランチ名を前方一致検索しているので、これに該当するブランチを手動で作った際に誤作動を起こすのでもう少し厳密な判定ロジックを設けるべきかもしれないです(横着感)

おわり

結構力技でしたが、ここまでやることで毎週の動作確認が1度で済ませられるのでコスト削減につながるかと思います。
小さなプログラムではそこまでライブラリが多くないと思うのでここまでする必要性も感じないかもしれませんが、10万行を超えてくる規模だと導入されているライブラリの数も膨大になり動作確認コストも馬鹿にできないので、このような対策を講じることでDependabotを最大限有効活用することが出来るようになりました。

また、今回DependabotをCI上で統合するお話ですが、スクリプトを書いて気合で統合してなんとかするという部分の話だけでCI側の話がほとんど出来ていないのでどこかでお話できたらと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git flow と github flow のまとめ

はじめに

Gitの運用方法といえばの2つのワークフローを理解するために他サイトを参考にまとめてみました。

git flow

git flowと言えばこの図をよくみます。

image.png

A successful Git branching model » nvie.com

master
常にリリース可能な状態

develop
開発中のブランチ

feature
機能を開発したりバグ修正などを行う
developから分岐したブランチになる
developにマージする

release
リリース用に準備を行う
developから分岐したブランチになる
developとmasterにマージする
機能開発したfeatureブランチをいきなりdevelopにマージするのではなく、releaseブランチを経由する

hotfix
緊急時の修正作業を行う
masterから分岐したブランチになる
developとmasterにマージする

メリット

  • Windowsアプリケーションなどのようにリリース作業に数日かかる開発に適している。
  • ブランチごとの役割がはっきりしているためブランチの運用ミスを減らせる。

デメリット

  • デプロイ作業が煩雑になる。

github flow

GitHubの開発で使用されており、git flowを簡略にしたワークフローです。

master
常にデプロイ可能な状態

feature
機能を開発したりバグ修正したり、緊急時の対応をしたりする。
developから分岐したブランチになる
developにマージする

git flowのようにブランチが目的ごとに分かれていません。
そのため、基本原則に従って、開発を進めます。

  • masterブランチは 常時デプロイ可能 である
  • 機能追加、バグフィックスなどは 説明的な名前のブランチ をmasterから作成する
    • 機能追加の例: add_user_notice (ユーザーの通知機能追加)
    • バグフィックスの例: fix_user_login_validation_error (ユーザーのログイン認証のVlidation修正)
  • 作成したブランチでローカル開発。小さい単位でこまめにコミットし、リモートにもこまめにPush
  • フィードバックや助言が欲しい時、ブランチをマージしてもよいと思ったときは、 Pull Request を作成する
    • フィードバックや助言が欲しい時に作成する Pull Request を WIP Pull Request という
    • WIP = Work In Progress
    • WIP Pull Request を行う場合は、Pull Request 名の頭に [WIP] をつけるのが慣習
  • レビューOKになったら、masterへマージ
  • masterへpushしたら、即デプロイをする

GitHub Flow 図解 - Qiita

メリット

  • Wedアプリケーションなどのように1日に数回デプロイを行う開発に適している。
  • git flowより理解しやすい。

デメリット

  • 機能開発や緊急時の修正などブランチが分かれていないため運用ミスが発生する可能性がある。

参考文献

A successful Git branching model » nvie.com

GitHub Flow 図解 - Qiita

GitFlow vs GithubFlow - Qiita

git flowとgithub flowとは?その違いは? - Qiita

【図解】git-flow、GitHub Flowを開発現場で使い始めるためにこれだけは覚えておこう:こっそり始めるGit/GitHub超入門(終) - @IT

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git-of-theseus で github の repository を可視化してみる方法

方法

pip3 install git-of-theseus
git clone git@github.com:boto/boto3.git
cd boto3
git checkout master
git-of-theseus-analyze ./
git-of-theseus-stack-plot cohorts.json
git-of-theseus-survival-plot survival.json
open stack_plot.png
open survival_plot.png 

とやると下記のような png ができる。

stack_plot.png

Appendix

https://github.com/erikbern/git-of-theseus

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む