めんどくせーので個人用Gitメモ晒す

Gitメモ
基本的に-nか--dry-runで何をするか確認できる
色々ありすぎて理解しきれない→本買うよりここ http://git-scm.com/book/ja
zshあればbranchとか補完してくれて便利
よくまとまってる
http://transitive.info/article/git/
システムの人はこれ見た方が早い
http://keijinsonyaban.blogspot.jp/2011/05/git.html?m=1

gitのversionはできるだけ新しいものを使いたい（1.7.1だとorphenとかsingle-branchとか無い）

クローン
git clone ssh or http repo
ブランチ指定クローン
git clone -b branch git@...

ミラー
git clone --mirror repo

ブランチだけクローン（1.7.10以降？）
git clone --single-branch repo -b branch
fetchすると残り取ってくる

引数無しの時のpushモード変更
git config --global push.default simple ブランチ名が現在のブランチと同じときだけpush 1.8から？
simple（upstreamと同名のbranchだけpush）
nothing （必ず指定）
matching（masterとか含めて同名なら全てpush、1.7のデフォ）
upstream（trackingしているbranchにのみpush）
current（現在のcheckoutしているブランチと同名のリモートブランチだけpushする）
もある

checkout
git checkout hash or -b branch origin/branchname

直前のブランチに移動
git checkout -

一部stageを元に戻す(add -pの反対)
git checkout -p filename

add系

再帰的にadd
git add .

消えてるファイルを、削除をaddする
git add -u

上の両方を同時
git add -A

branch削除
git branch -d branch
リモート
git push origin :branch

branchの関係を表示
git show-branch -a

現在のbranchにpush
git push origin HEAD

push取り消し
git push origin HEAD^^^^:+master とか注意

今いるHEADじゃないところからpushする
git push origin master\^\^\^:master -f
git push origin HEAD\^:refs/heads/master
git push origin test:test

コンフリクト想定でpullする
git pull --rebase

rebaseでのコミットの書き換え（hash変わる）
git rebase -i HEAD~5
git add file
git commit --amend
git rebase --continue

コミットの分割（hash変わる）
git rebase -i HEAD~5
編集するcommitをeditにする
git checkout hash or ref -- fileで戻す
git commit --amend
checkoutで拾う、mergeとかして繰返し
git rebase --continue

圧縮コミット
git rebase -i HEAD~1
圧縮するコミットをsquash
コミットログ入れる
git rebase --continue

コミットの順番を入れ替える
git rebase -i HEAD~5
エディタで行を入れ替えて保存するとrebaseされる

直前のcommit
git commit --amend

現在のワーキングツリーの更新を直前のcommitにコメントそのままで追加
git commit -a --amend -C HEAD

add取り消し
git reset HEAD -- file

再帰的にadd
git add .

消えてるファイルを、削除をaddする
git add -u

上の両方を同時
git add -A

addしたいのはファイルの一部だけ
git add -p file

addやり直し
git rm --cached -- file

書き換えたpush -f 付きと同じ？
git push origin +master

無名ブランチでcommitしちゃった→reflogで戻す
git reflog確認
git reset --hard or --soft HEAD@{1}
hash確認
git checkout branch
git cherry-pick hash
git commit

なんかいろいろやり直したい
reflogで好きなとこ選んで
git reset --hard HEAD
git reset --hard HEAD@{ref}

gitに入ってないファイルを削除
git clean -n
git clean -f

hashの含まれるbranchをindexから探す
git branch --contains hash

hashの含まれるtagをindexから探す
git name-rev --name-only hash
git log -n1 hash | git name-rev --stdin とかも可能


indexに入ってるファイルをls
git ls-files
ls-treeもls-remoteもある

svn catみたいなもん
git show rev:filename

zipでくれ
archive --format=zip --prefix=archive/ HEAD -o archive.zip

変更のあったファイルだけtarで固める
git diff hash..tohash --name-only | tar czvf - -T - > chenged_files.tgz

stashで一回保存
git stash
確認
git stash list
git stash show
branch移すなりしてから適用
git pop
git apply削除しない

ログみたいcommit内容見たいdiffみたい
git log branch..tobranch or hash..tohash or ref..toref < -- file>
git show branch..tobranch or hash..tohash or ref..toref < -- file>
git diff branch..tobranch or hash..tohash or ref..toref < -- file>

reflog付き
git log -g

git cherry-pick hash 現在のブランチにcommit取り込み
git cherry -v master ブランチの上流に既に存在している変更を知る

git notes add hash or commitとかbranchとかに注釈を付ける
git notes remove hadh or commit 削除
git notes edit hadh or commit 削除

git diff ^hash..tohash showと同じじゃん、、

log
git shortlog リリース用のタイトルだけ取得

tag系
git tag -nlで確認
git checkout refs/tags/v2 チェックアウト
git checkout -b v2 refs/tags/v2 ブランチ+チェックアウト
git tag v2 hash タグ作る
git push --tags origin pushする
git push origin :v2 タグ消す

検索する
git grep <--cached> command

stringの含まれるcommitを探す
git log -S "string"
git log -G "regex" 正規表現
git log -G "regex" --patch 正規表現+patch形式

commitからbranchを探す
git branch -r --contains 0dc2f72
リモートも含めて検索が-r

とあるファイルと同じ変更を別ファイルにもしたい
git diff -- fromfile | patch tofile

gitでpatchを作る
git diff hash or branch..tobranch > branch.patch
適用
git apply branch.patch

設定確認global付けると全体設定
git config --global user.email "kota@insaneworks.co.jp"
git config --global user.name "Kota Shiratsuka"
git config <--global> -l
git config <--global> -eでエディタで編集
git config --remove-sectionとか削除
git config --global core.excludesfile ~/.gitignore_globalとかで項目毎に設定
.gitignore_globalで.DS_Storeとか*.swp入れとく
git config --global color.ui true色付けとく
git config core.filemode false パーミッション無視
git config --global core.autocrlf true or input or false 改行関係
git config M<--global> decorate true commitにHEADとかorigin/masterとかポインタ的な感じに表示してくれる

SQLiteをdiff表示（自分だけしか無理）
echo '*.db diff=strings' > .gitattributes
git config diff.sqlite3.textconv 'echo .dump|sqlite3'

CUIでnetwork
git log --graph <--oneline>

コミッター集計
git shortlog -ns

表示系
git config --global log.abbrevCommit true hashを可能な限り短く表示する
git config --global diff.noprefix ture diffにa/とかb/とかprefixいらない

Alias系
git config --global alias.network "log --graph --pretty=oneline" network風の表示
git config --global alias.tar "archive --format=tar --prefix=project-`date +%Y%m%d`/ HEAD | gzip > bar-`date +%Y%m%d`.tgz" tarで固める
git config --global alias.log1 "log --pretty=oneline  --decorate" 一行
git config --global alias.logshow "log --stat"log+stat見る
git config --global alias.ci "commit" svn互換
git config --global alias.co "checkout" svn互換
git config --global alias.zip "archive --format=zip HEAD -o" zipでくれ
git config --global alias.tar "archive --format=tar HEAD -o" tarでくれ
git config --global alias.tgz "archive --format=tgz HEAD -o" tgzでくれ
git config --global alias.wdiff "diff --word-diff"行単位じゃなくて単語単位でdiffくれ

SVN系
git svn clone -s https://svnserve/repo
-s付けるとtrunk/tag/branches認識
git svn rebase アップデート
git svn dcommit コミット

trackの全くない孤立した（空の）ブランチを作る（1.7.10以降？）当然履歴はぶった切れる
git --orphan branch
それ以前なら
git symbolic-ref HEAD refs/heads/gh-pages
rm .git/index
git clean -fdx

危ないけど強力すぎ（reflog or branch or stash or cp -aでなんかしら予防策取っておこう）
git reflog expire --expire=now --all

svnの参照ログを全部消す
git filter-branch --msg-filter ' sed -e "/^git-svn-id:/d" 


メアドとか一括変更
git filter-branch --commit-filter '
        if [ "$GIT_AUTHOR_NAME" = "kota" ];
        then
                GIT_AUTHOR_NAME="Kota Shiratsuka";
                GIT_AUTHOR_EMAIL="kota@example.com";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

とあるディレクトリだけbranchに切り出す
git filter-branch --subdirectory-filter dir/
git push -u origin master:branch
pullとかfetchすると死ぬので
git pull origin branchする事

''で囲ったコマンドを実行しながらrebaseみたいな事する。hashが全部変わるので凶悪
git filter-branch --tree-filter 'rm -f passwords.txt' HEAD

消えたリモートブランチをローカルからも削除
git remote prune origin

リモートブランチ削除
git push origin :branchname

Submodule
git submodule add repo dir
まとめて更新
git submodule foreach --recursive 'git pull origin master'

検証とか
git bisect
http://qiita.com/usamik26/items/cce867b3b139ea5568a6

再パックや不要なオブジェクトをGCして容量圧縮
reflogなどは全て失われるので注意
git gc
さらに小さくするには--aggressive（デルタ再計算を行う）
http://git-scm.com/book/ja/Gitの内側-メインテナンスとデータリカバリ
git gc --prune

徹底的に消す
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch password.txt" --prune-empty -- --all
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --aggressive --prune=now

gcしたしreflogもないしもうダメだ
git fsck --full
git checkout hash
これでダメならバックアップから戻すか、諦める

バックアップから復旧する場合、
git pull file://git/repo
で他のリポジトリをpullできるのでrebaseなりして適切な状態まで持っていこう

Gitの参照先を見つける
git show-ref

tig使え
gitv
zshでの注意点
HEAD@{1}とかは""で囲うとかしないとblob解釈されて使えないので注意


git format-patch "HEAD^”
[kota@deathnote ~/Git/centos-packer]$ git send-email 0001-v20130101.patch
0001-v20130101.patch
Who should the emails be sent to (if any)? kota@insaneworks.co.jp
Message-ID to be used as In-Reply-To for the first email (if any)? no
Are you sure you want to use <no> [y/N]? y
(mbox) Adding cc: Kota Shiratsuka <kota@insaneworks.co.jp> from line 'From: Kota Shiratsuka <kota@insaneworks.co.jp>'

From: Kota Shiratsuka <kota@insaneworks.co.jp>
To: kota@insaneworks.co.jp
Subject: [PATCH] v20130101
Date: Mon, 13 Jan 2014 02:14:35 +0900
Message-Id: <1389546875-2909-1-git-send-email-kota@insaneworks.co.jp>
X-Mailer: git-send-email 1.8.5.2
In-Reply-To: <no>
References: <no>

    The Cc list above has been expanded by additional
    addresses found in the patch commit message. By default
    send-email prompts before sending whenever this occurs.
    This behavior is controlled by the sendemail.confirm
    configuration setting.

    For additional information, run 'git send-email --help'.
    To retain the current behavior, but squelch this message,
    run 'git config --global sendemail.confirm auto'.

Send this email? ([y]es|[n]o|[q]uit|[a]ll): y
OK. Log says:
Sendmail: /usr/sbin/sendmail -i kota@insaneworks.co.jp
From: Kota Shiratsuka <kota@insaneworks.co.jp>
To: kota@insaneworks.co.jp
Subject: [PATCH] v20130101
Date: Mon, 13 Jan 2014 02:14:35 +0900
Message-Id: <1389546875-2909-1-git-send-email-kota@insaneworks.co.jp>
X-Mailer: git-send-email 1.8.5.2
In-Reply-To: <no>
References: <no>

Result: OK

署名する

.bashrcに
pgrep -q gpg-agent || `eval $(gpg-agent --daemon)`
とか書いとく

git commit -S -a
とか
signed-offするなら -Ss

git worktree
git worktree add workdir
git worktree add workdir branch
git worktree list
git worktree remove 

rm -rf して
git worktree prune