git
- git
- Githubとssh接続する
- .gitignoreについて
- ブランチ作成元のブランチ名を取得する
- ブランチ作成元のコミットIDを取得する
- マージ時に発生する差分の取得
- cloneやpullせずに git diffを取得する
- リモートブランチからローカルブランチを作成する
- サーバにローカルブランチをpushする
- ステージング解除
- 変更の取り消し
- cherry-pick
- 追跡していないファイルの削除
- 作成元ブランチの変更を取り込む
- git rebaseを使って複数コミットをsquashする
- ログをCSVに変換する
- git stash
- 差分があり、ステージングしていないファイル一覧
- サーバにないが、ローカルにあるリモートブランチを削除する
- git submodule
- git log
- git merge
- コンフリクトの対応
- 直前のコミットの取り消し
- 他のブランチ/コミットのファイルを取得する(git show)
- ファイルごとの最終更新日の取得
- リモートリポジトリと紐づける
- 行単位でコミットする
- 設定
- コンソールにブランチ名を表示する
- 接続先URLを確認する
- gitコマンドを実行するディレクトリを指定する
- tagをつける
- 特定ブランチの特定ファイルを取得する
- コミットログのタイムゾーン設定
- git log since時にタイムゾーンを意識する
- パスワードを保存する
- git bashのファイルパス <-> Linuxファイルパス変換
- 各ファイルの直近のコミット日とコミットコメントを取得する
- ローカルにclone可能なリポジトリを作成する
- Github Templateの変更をマージする
- git bashで日本語ファイルパスとUTF-8ファイルを扱う
Githubとssh接続する
# 接続確認
ssh -T git@github.com
# sshがつながらない場合は、.ssh/configに下記を記載
Host github github.com
HostName github.com
IdentityFile ~/.ssh/github_rsa
User git
参考
.gitignoreについて
https://qiita.com/inabe49/items/16ee3d9d1ce68daa9fff
.gitignoreに書かずに、ローカル管理する
.git/info/exclude
配下に配置する。
ブランチ作成元のブランチ名を取得する
git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -1 | awk -F'[]~^[]' '{print $2}'
※作成元でsquashしていると取得できない?git show-branch
で確認する。
ブランチ作成元のコミットIDを取得する
git show-branch --sha1-name | tail -n 1 | grep -v "$(git rev-parse --abbrev-ref HEAD)" | awk -F'[]~^[]' '{print $2}'
※作成元でsquashしていると取得できない?git show-branch
で確認する。
参考
マージ時に発生する差分の取得
source_branch=
target_branch=
git diff --name-status ${target_branch}...${source_branch}
参考
cloneやpullせずに git diffを取得する
リモートブランチだけを取得する。
diff_path=/tmp/`uuidgen`
git_dir=/tmp/`uuidgen`
mkdir $git_dir
pushd $git_dir > /dev/null
# 対象リポジトリのURL
git_url=
git init
git remote add origin $git_url
git fetch origin
# 比較対象のブランチ
source_branch=
target_branch=
# オプションは任意
git diff --name-status origin/$target_branch...origin/$source_branch > $diff_path
popd > /dev/null
rm -rf $git_dir
cat $diff_path
# ファイルの後始末
rm $diff_path
リモートブランチからローカルブランチを作成する
git branch ${new_branch} origin/${base_branch}
# ブランチは作成されるが、ブランチの移動(checkout)は発生しない。
サーバにローカルブランチをpushする
git push --set-upstream origin ${branch_name}
ステージング解除
新規
git rm --cached -r ${対象ファイル}
変更
git reset HEAD ${対象ファイル}
変更の取り消し
git checkout <対象パス>
cherry-pick
別ブランチの特定のコミットだけを取り込む。
ファイル変更が発生しているコミットでないと指定できない。
# 対象のコミットを探す
git log --name-status
# 対象のコミットIDを指定する。複数指定できる。
git cherry-pick ${commit_id_01} ${commit_id_02}
追跡していないファイルの削除
git clean <オプション>
git cleanのオプション
オプション | 意味 |
---|---|
-n | 対象のファイルを確認する(削除はされない) |
-d | ディレクトリを含める |
-f | 削除を実行する |
作成元ブランチの変更を取り込む
git rebase ${branch}
git rebaseを使って複数コミットをsquashする
- file1,file2作成
- file3作成
- file1削除
3つまとめて、file1をなかったことにしたい。
commit 4623fd071700a748b645afb84f9bb226eb65559f (HEAD -> main)
Author: SampleUser0001 <ittimfn+github@gmail.com>
Date: Thu Jul 13 00:45:18 2023 +0900
rm file1
D file1
commit b4ebab3559c365c024df48521ecda95ed22f073f
Author: SampleUser0001 <ittimfn+github@gmail.com>
Date: Thu Jul 13 00:44:48 2023 +0900
second
A file3
commit fb08e045a624168dde9efd71e744e26b1ec35583
Author: SampleUser0001 <ittimfn+github@gmail.com>
Date: Thu Jul 13 00:44:29 2023 +0900
first
A file1
A file2
git log --oneline
4623fd0 (HEAD -> main) rm file1
b4ebab3 second
fb08e04 first
git rebase -i fb08e04
pick b4ebab3 second
pick 4623fd0 rm file1
# Rebase fb08e04..4623fd0 onto fb08e04 (2 commands)
#
# Commands:
# (省略)
# pickをsquashにするとまとめられる。すべてをsquashにはできない。
ログをCSVに変換する
git --no-pager log \
--pretty=format:"\"%ae\",\"%s\"" \
--date=short --no-merges --all --date-order > ../commits.csv
フォーマット
git stash
stash
git stash
一覧
git stash list
適用
git stash apply stash@{0}
差分があり、ステージングしていないファイル一覧
git diff --name-only
サーバにないが、ローカルにあるリモートブランチを削除する
git fetch -p
git submodule
他のリポジトリをライブラリとして取り込むことができる。
登録
git submodule add ${リポジトリURL}
読み込む
git cloneしただけだと、読み込まれない。
git submodule init
更新する
git submodule update
git log
更新したファイル一覧を表示する
git log --name-only
git log --stat
ファイル単位で更新履歴を出力する
git log -p ${対象ファイル or 対象ディレクトリ}
ファイル単位で更新履歴を出力する:参考
git merge
fast-forward
git merge --ff
コマンド。--ff
オプションはなくてOK。
- マージ時点でブランチ作成後に作成されたコミットがある場合、並び替えが発生する。
- マージ先ブランチの後ろに、マージ元ブランチのコミットが追加される。
- 他のブランチなどからマージされたコミットがある場合は、その後ろにつく。
- 時系列的に間似合った場合でも、後ろにつく。
- コミットIDはマージ前後で同じ。
- non-fast-forwardと異なり、マージポイントが作成されない。
- マージした痕跡が見つからなくなる。
non-fast-forward
git merge --no-ff ${source_branch}
コマンド。- マージポイントが作成される。
- マージ時点でブランチ作成後に作成されたコミットがある場合、時系列で並ぶ。
- feature/a, feature/bブランチがあり、下記順にコミット+マージした場合、
- feature/a : A1
- feature/b : B1
- feature/b -> develop(squash)
- feature/a : A2
- feature/a -> develop(non-fast-forward)
- develop
- A1, B1, A2の順に並ぶ。
- feature/a, feature/bブランチがあり、下記順にコミット+マージした場合、
コミットしないマージ
git merge ${ブランチ名} --no-commit
コンフリクトの確認
# dry-runはない。実際にマージしてみる。
git merge --no-commit ${source_branch}
# もとに戻す
git merge --abort
# ???
git status
cloud9環境の場合は、対象のファイルを開くと見た目をいい感じにして表示してくれる。
マージの取り消し
git merge --abort
rebase と mergeの違い
- 前提 : mergeはオプション指定なし。(fast-forwardする。)
- rebase
- 現在のブランチの後ろにコミットが付与される。
- merge
- コミットされた順番通りに並び替えが発生する。
コンフリクトの対応
基本(手動)
git status
# Unmerged paths: のファイルがマージできなかったファイル
<<< HEAD
自分側
===
相手側
>>> ブランチ名
git add ${filepath}
git commit ${filepath}
一括採用
# 相手のブランチを採用する
git checkout --theirs ${filepath}
# 自分のブランチを採用する
git checkout --ours ${filepath}
直前のコミットの取り消し
直前のコミットの逆で上書き(revert)
git revert HEAD
履歴を削除
git reset --hard HEAD^
他のブランチ/コミットのファイルを取得する(git show)
git show ${branch}:${path} > ${export_path}
ファイルごとの最終更新日の取得
git ls-files . | xargs -I@ bash -c 'echo "$(git log -1 --format="%cd" --date=format:'%Y/%m/%d_%H:%M:%S' -- @)" @'
参考
リモートリポジトリと紐づける
Github
git remote add origin git@github.com:SampleUser0001/${プロジェクト名}.git
git branch -M main
git push -u origin main
行単位でコミットする
実際には行単位ではなく、差分単位だが……
# 実行すると、差分をステージングするか順番に聞かれる。
git add -p
設定
改行コード
git config --global core.autocrlf ${value}
値 | checkout | commit |
---|---|---|
true | LF -> CRLF | CRLF -> LF |
input | 何もしない | CRLF -> LF |
false | 何もしない | 何もしない |
コンソールにブランチ名を表示する
export PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(__git_ps1 " (%s)" 2>/dev/null) $ '
接続先URLを確認する
git remote -v
gitコマンドを実行するディレクトリを指定する
git -C ${path} ${git_command}
tagをつける
git tag -a ${tag} -m ${message}
特定ブランチの特定ファイルを取得する
git cat-file -p ${branch}:${filepath}
コミットログのタイムゾーン設定
ローカルのタイムゾーンを設定する。
git config --global log.date local
git log since時にタイムゾーンを意識する
git log --since="2023-10-05T00:00:00+09:00"
パスワードを保存する
git bashのファイルパス <-> Linuxファイルパス変換
Windows -> Linux
linux_path=$(echo ${win_path} | sed 's@^\([a-zA-Z]\):@/\L\1@' | sed 's@\\@/@g'
Linux -> Windows
win_path=$(echo ${linux_path} | sed 's@^/\([a-zA-z]\)@\U\1:@' | sed 's@/@\\@g'
参考
各ファイルの直近のコミット日とコミットコメントを取得する
git ls-files | while read file; do
echo -e "$file\t$(git log -1 --format=$'%ai\t%s' -- "$file")"
done
別解
git ls-tree -r main --name-only | while read file; do
# 各ファイルに対する最後のコミットの情報を取得
commit_info=$(git log -1 --format="%ai|%s" -- "$file")
# コミット日時とメッセージを分割
commit_date=$(echo $commit_info | cut -d'|' -f1)
commit_message=$(echo $commit_info | cut -d'|' -f2)
# コミット日時を システムのタイムゾーンに変換
commit_date_converted=$(date -d "$commit_date" '+%Y-%m-%d %H:%M:%S %z')
# ファイルパス、変換後のコミット日時、コミットメッセージを出力
echo "$file\t$commit_date_converted\t\"$commit_message\""
done
ローカルにclone可能なリポジトリを作成する
git init --bare --share=true ${repository_name}
# git clone ${dir_path}でcloneできる。
Github Templateの変更をマージする
# TemplateのリポジトリURLを紐付ける
github_template_repository=git@github.com:${user}/${template}
git remote add template ${github_template_repository}
# Templateのブランチをfetchする
git fetch
# fetchしたブランチをマージする。(おそらくコンフリクトが発生する。)
git merge template/main --allow-unrelated-histories
# 手動マージで良いが、テンプレート側の修正を優先する場合は下記。
git checkout --theirs .
# コミット
git commit
git bashで日本語ファイルパスとUTF-8ファイルを扱う
文字化け対応。
おそらくこれで良いのたが、完全な確証がない。
- git bashの左上アイコンから、文字コードをSJISに変更する
- 下記を実行。
chcp.com 65001
- git bash再起動