記事:
commit1=origin/master commit2=HEAD output=archive.zip git archive $commit2 $(git diff --name-only $commit1 $commit2 --diff-filter=ACMR) -o $output
記事:
grep "\[remote" .git/config [remote "origin"] [remote "dev"] [remote "stg"] [remote "prod"] ...
git ls-remote <remote name>
git grep xxx # 大文字、小文字を無視 git grep -i xxx # 正規表現(拡張) git grep -E "i\-[a-z0-9]+"
find . -name '*example*' | xargs -i bash -c 'git mv {} $(echo {} | sed s/example//)'
git switch -c new-branch
git restore .
git clone --depth 1 --branch <master> --single-branch <repo url>
--- .git/config.orig +++ .git/config [remote "origin"] ... - fetch = +refs/heads/master:refs/remotes/origin/master + fetch = +refs/heads/*:refs/remotes/origin/*
x.y.zで区切られたタグをバージョンの降順に表示したい。
git config --global alias.tag-sr '!git tag | sort -r -t . -n -k 1,1 -k 2,2 -k 3,3'
git log -p -S <'deleted code line'> <file path>
git log --diff-filter=D --summary
git checkout <commit>^ -- <file path>
リポジトリの履歴からファイルを削除するには、BFG Repo-Cleaner または git filter-branch コマンドを使用できます。
wget https://repo1.maven.org/maven2/com/madgag/bfg/1.13.0/bfg-1.13.0.jar alias bfg='java -jar bfg-1.13.0.jar'
git clone --mirror git://example.com/some-big-repo.git
# デフォルトでは最新のコミットは残す。--no-blob-protectionをつけると最新のコミットも対象にする # 10MB以上のファイルを削除 bfg --strip-blobs-bigger-than 10M --no-blob-protection ./some-big-repo/ # ワイルドカードで拡張子を指定して削除 bfg --delete-files "*.rpm" --no-blob-protection ./some-big-repo/ # du -sh で確認しても、まだ容量は減っていない # 以下のようなディレクトリにレポートが出来る。 ./some-big-repo.bfg-report/YYYY-mm-DD/HH-MM-SS/ # 提案されたコマンドを実行すると、du -sh でもサイズ縮小を確認できる。 cd ./some-big-repo/ git reflog expire --expire=now --all && git gc --prune=now --aggressive # repoから削除したファイルは stage(A 扱い)で残っている git status # 実際に削除する git reset HEAD find . -name '*.rpm' -delete # gitにコミットしたくないファイルを .gitignoreに追加 echo '*.rpm' >> .gitignore git add .gitignore git commit -m 'ignore rpm files' # 問題なければremoteへpush。複数の人が使っているrepoの場合、再度cloneして貰う。 git push
wget https://confluence.atlassian.com/bitbucket/files/321848291/321979854/1/1360604134990/git_find_big.sh chmod +x git_find_big.sh cd ./some-big-repo/ ../git_find_big.sh > ../result.txt vim ../result.txt -- # repoから削除したいファイルだけ記載 -- # 空白で連結した変数を用意 git_ignore_files=$(grep -P '^\d+' ../result.txt | cut -d ' ' -f 7 | tr '\n' ' ')
cd ./some-big-repo/ # 1MB以上のファイルを探す find . -type f -size +1M | grep -v .git/ > ../result.txt # *.rpmのファイルを探す。 find . -type f -name "*.rpm" | grep -v .git/ > ../result.txt # gitの履歴から消すファイルを別ディレクトリへバックアップしておきたい場合 rsync -a --files-from=../result.txt ./ ../backup/ # 空白で連結した変数を用意 git_ignore_files=$(cat ../result.txt | tr '\n' ' ')
cd ./some-big-repo/ git filter-branch -f --index-filter "git rm -r --cached --ignore-unmatch ${git_ignore_files}" -- --all # du -sh . すると大夫サイズが減っている
git cloneはremoteと同じリポジトリを全てチェックアウトするため、巨大なリポジトリだと遅い。
git init example/ cd example/ git config core.sparsecheckout true git remote add origin git@github.com:example/example.git mkdir -p .git/info/ echo "test/" > .git/info/sparse-checkout git pull origin master
項目 | サイズ | 秒数 |
repo全体 | 120MB | 27 |
一部分 | 60MB | 17 |
[fetch] prune = true
または
git config --global alias.delete-merged-branches '!git branch --merged | grep -vE "^\*|^\s*master|^\s*develop|^\s*release" | xargs git branch -d'
git branch --sort=-committerdate | head -n 10
git tag --sort=-committerdate | head -n 10
時々自動で実行されるが、手動で実行したい時。
git gc --auto
# --date=relative Date: 9 days ago # --date=local Date: Wed Sep 12 17:05:44 2018 # --date=default Date: Wed Sep 12 17:05:44 2018 +0900 # --date=iso Date: 2018-09-12 17:05:44 +0900 # --date=rfc Date: Wed, 12 Sep 2018 17:05:44 +0900 # --date=short Date: 2018-09-12 # --date=raw Date: 1536739544 +0900
git add .
作業ブランチで開発中に、先に進んだmasterからの差分に変えたい時。
git co working_branch # origin masterが先に進んだ場合、そこまでbaseを進める git pull --rebase origin master # コンフリクトした場合、ファイルを修正してadd git add path/to/file git rebase --continue git push origin working_branch
例:
git co -b work # 作業コミット # commit1にまとめたい場合、commit2〜3のpickをfixupに変えて保存。コメントの変更は反映されない。 git rebase -i origin/master -- pick 98c99fe commit1 fixup c4599fe commit2 fixup ecd0587 commit3 --
sudo yum install git git-svn SVN_REPO=example SVN_REPO_PATH=file:///var/www/svn/$SVN_REPO/ mkdir $SVN_REPO cd $SVN_REPO/ git svn init -s --prefix=svn/ $SVN_REPO_PATH time git svn fetch
local branchが必要なのか分からなくなった場合。
# 確認 git remote prune origin --dry-run # 削除 git remote prune origin # fetchした時に消して欲しい場合 git fetch --prune --dry-run git fetch --prune
# 確認 git branch --merged # 削除 git branch -d <branch name> # mergeしてないとエラーが出る。強制削除は -D # まとめて消す(y/n確認) # 確認不用であれば -p を削除 git branch --merged | grep -vP '^\*|(master|develop)$' | xargs -p -I % git branch -d %
git log -p <file or directory>
git show <commit hash. HEAD, HEAD^2 >
git clone https://github.com/puppetlabs/puppetlabs-ntp.git ... Cloning into 'ntp'... fatal: unable to access 'https://github.com/puppetlabs/puppetlabs-ntp.git/': SSL connect error # debug export GIT_CURL_VERBOSE=1 git clone https://github.com/puppetlabs/puppetlabs-ntp.git ... * NSS error -12286 [#j8f0b91f]
sudo yum update nss # 問題が出ないバージョン rpm -q nss nss-3.28.4-4.el6_9.x86_64
reset --hardをやりすぎた時に戻す。 削除したbranchを戻す。 ただし、コミットしてないファイルは戻ってこない。
# 直近4つまでの作業ログを見る git reflog -n 4 # 戻したい所まで戻す git reset --hard <HEAD@{N} or commit id>
# 直近4つまでの作業ログを見る git reflog -n 4 # <HEAD@{N}>を元に <branch name> を作る git branch <branch name> <HEAD@{N} or commit id>
.gitignore に入れたパターンは「git status」等で差分として表示されなくなる 親フォルダにまとめて記載しておけば、子フォルダにも適用される。
# vimの作業ファイル *.swp [#vc3fcd3c] # subversionのディレクトリ .svn/ # macOSの不要ファイル .DS_Store # windowsの不要ファイル Thumbs.db # ansibleのリトライファイル *.retry [#cd80a5a4]
* a1234567 - user01 - Merge branch 'develop' into release/1.10 (x hours ago) [#z5cdc466] |\ | * b1234567 - user02 - Merge branch 'release/1.10' into develop (x days ago) | |\ | * \ c1234567 - user03 - Merge branch 'release/1.10' into develop (x days ago) | |\ \ | * \ \ d1234567 - user04 - Merge tag 'v1.10.0' into develop (x days ago) | |\ \ \ | * \ \ \ e1234567 - user04 - Merge branch 'release/1.10' into develop (x days ago) | |\ \ \ \ | * \ \ \ \ f1234567 - user03 - Merge branch 'release/1.10' into develop (x days ago) ...
# git log --graph で誤り前のコミットidを探す。この例では「aa123456」とする git reset aa123456 --hard # treeを見て間違ったマージより先に取り込みたいコミットがあれば、cherry-pickやmergeで取り込む git cherry-pick <commid it> git merge <commid it> # force pushで強制的に修正 git push -f origin release/1.10
git fetch git co origin/release/1.10 git pull -p
作業ブランチでrebase後、pushしたい時など。
[alias] push-f = push --force-with-lease
git reset --hard origin/<branch name>
git commit --amend --author="user <user@example.com>"
Linuxで開発しているリポジトリをWindowsでcloneして編集しようとすると、パーミッションの違いが検出されて邪魔な時がある。
git config core.filemode false # 確認 git config -l | grep core.filemode
diff -uw file-a file b
git diff -w
うっかりAWSキー等がgithubに流出している事故が多い。
(実際に流出するとAWSからメールが来て、AWSアカウントが制限状態になる。該当キーを削除するまで続く)
# インストール git clone https://github.com/awslabs/git-secrets.git cd git-secrets/ sudo make install # 全体設定に追加 git secrets --register-aws --global git secrets --install ~/.git-templates/git-secrets git config --global init.templatedir '~/.git-templates/git-secrets' # 既存プロジェクトに追加 git secrets --install /path/to/repository # 既存ディレクトリをチェック git secrets --scan -r /path/to/repository
# 確認 find /path/to/repository/.git/hooks/ -type f ! -name "*.sample" # 削除 find /path/to/repository/.git/hooks/ -type f ! -name "*.sample" -delete
git merge --no-ff topic
git fetch origin git reset --hard origin/master
メジャーなフローがあるので必要に応じて選んだり、カスタマイズすると良さそう
sudo yum erase ius-release sudo rm /etc/yum.repos.d/ius*.repo*
# 古いgitは削除 sudo yum erase git # EPELリポジトリも必要 yum install \ https://repo.ius.io/ius-release-el7.rpm \ https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm sudo yum install git2u # バージョン確認 git --version git version 2.4.3
sudo yum install --enablerepo=rpmforge-extras git git --version git version 1.7.12.4
git config -l --global
cat ~/.gitconfig
git clone https://github.com/example/example.git cd example/ git submodule add https://github.com/example2/example2.git path/to/example2-test
git clone https://github.com/example/example.git cd example/ # 初回はinitしないとsubmoduleディレクトリが空のまま git submodule init # 更新 git submodule foreach git pull origin master # または git submodule update --remote
git submodule deinit path/to/submodule git rm path/to/submodule # git v1.8.5未満だと、.gitmodulesから消すコマンドが必要 git config -f .gitmodules --remove-section path/to/submodule
brew install git echo 'export PATH=/usr/local/Cellar/git/2.7.0/bin:$PATH' >> ~/.bash_profile source ~/.bash_profile
sudo port install git +svn +doc +bash_completion +gitweb
./setup\ git\ PATH\ for\ non-terminal\ programs.sh
そのままだと管理されないので".gitkeep"ファイルを入れる
mkdir dummy touch dummy/.gitkeep git add dummy
git fetch --prune origin
# タグをリモートと同期 git fetch --tags # タグの作成 git tag release/1.00 git tag release/1.01 # タグ一覧 (-n でアノテーションタグも表示) git tag -n release/1.00 release/1.01 # ローカルタグ削除 git tag -d release/1.01 # リモートにpush。このままpushしてもリモートのタグは消えない git push origin release/1.01 # または、以下(意図しないタグまでpushされる可能性がある) git push --tags # リモートのタグ削除 git push --delete origin release/1.01
git tag -a release/1.02 hogehoge git tag -n release/1.02 hogehoge
git tag release/1.00 release/1.01 release/1.02 # リネームしたいcommit hashを確認 git rev-parse release/1.01 e2f61a85745f777a720227594fa3442dfbd15647 # git tag new-tag old-tag git tag release/1.01.new release/1.01 # 新しいタグのcommit hashが同じか確認 git rev-parse release/1.01.new e2f61a85745f777a720227594fa3442dfbd15647 # delete local old tag git tag -d release/1.01 git tag release/1.00 release/1.01.new release/1.02 git push origin --tags # delete remote old tag git push --delete origin release/1.01
git fetch origin --prune 'refs/tags/*:refs/tags/*' # このコマンドでは消えなかった: git version 2.16.4 git fetch origin --prune --tags
git checkout master git cherry-pick 99daed2
error: a cherry-pick or revert is already in progress
git cherry-pick --abort
git cherry-pick master..next
git remote -v git remote set-url origin <新しいリポジトリのURL>
if [[ -f /etc/bash_completion ]]; then # RHEL/CentOS 6, Ubuntu 12.04 LTS . /etc/bash_completion elif [[ -f /etc/profile.d/bash_completion.sh ]]; then # RHEL/CentOS 7 [ -n "$BASH_COMPLETION" ] || BASH_COMPLETION=/etc/bash_completion [ -n "$BASH_COMPLETION_DIR" ] || BASH_COMPLETION_DIR=/etc/bash_completion.d [ -n "$BASH_COMPLETION_COMPAT_DIR" ] || BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d elif [[ -f /usr/local/etc/bash_completion ]]; then # macOS: brew . /usr/local/etc/bash_completion [ -n "$BASH_COMPLETION" ] || BASH_COMPLETION=/usr/local/etc/bash_completion [ -n "$BASH_COMPLETION_DIR" ] || BASH_COMPLETION_DIR=/usr/local/etc/bash_completion.d [ -n "$BASH_COMPLETION_COMPAT_DIR" ] || BASH_COMPLETION_COMPAT_DIR=/usr/local/etc/bash_completion.d fi
RS="\[\033[0m\]" HC="\[\033[1m\]" UL="\[\033[4m\]" INV="\[\033[7m\]" FBLK="\[\033[30m\]" FRED="\[\033[31m\]" FGRN="\[\033[32m\]" FYEL="\[\033[33m\]" FBLE="\[\033[34m\]" FMAG="\[\033[35m\]" FCYN="\[\033[36m\]" FWHT="\[\033[37m\]" BBLK="\[\033[40m\]" BRED="\[\033[41m\]" BWHT="\[\033[47m\]" GIT_PS1_SHOWDIRTYSTATE=1 GIT_PS1_SHOWUPSTREAM=1 GIT_PS1_SHOWUNTRACKEDFILES= GIT_PS1_SHOWSTASHSTATE=1 if [[ ! -f ~/.git-prompt.sh ]]; then wget -q https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh -O ~/.git-prompt.sh fi if [[ -f ~/.git-prompt.sh ]]; then . ~/.git-prompt.sh # CentOS default # export PS1='[\u@\h \W]\$ ' export PS1="[$FMAG\u$FWHT@$FCYN\h$FWHT: \W\$(__git_ps1)]\$ " fi
git for windowsではデフォルトで、改行コードの自動変換される。
vi ~/.gitconfig ---- [core] autoCRLF = false ----
# ワーキングディレクトリはそのままで、コミットだけ取り消す git reset --soft HEAD^ # コミットを取り消し、ワーキングディレクトリも戻す git reset --hard HEAD^
git diff -w
git config --global color.ui auto
git diff HEAD^ .
git diff --word-diff
git diff master branch1 path/foo.txt
git diff master:path/foo.txt branch1:path/bar.txt
git branch -m <old branch> <new branch> # または、現在のブランチ名を変更 git branch -m <new branch>
git branch -a
git checkout -b hoge-prototype git branch * hoge-prototype [#z7f0a526] master # リモートに同名ブランチとしてpush git push origin hoge-prototype
git push -u origin HEAD
# カレントをmasterに変更 git checkout master # ローカルブランチを削除 # 強制削除: -D git branch -d hoge-prototype # 同名のリモートブランチを削除 git push --delete origin hoge-prototype # または':' git push origin :hoge-prototype
# 作業中ブランチに切替 git co mybranch git fetch origin git merge --no-ff origin/master
git diff --no-prefix HEAD~ > hoge.patch patch --dry-run -p0 < hoge.patch patch -p0 < hoge.patch
git rebase origin/master --autostash # または設定に入れる git config --global rebase.autostash true
git pull error: Your local changes to the following files would be overwritten by merge: example/hoge.txt # 変更を待避(git stash saveと同じ) git stash # 最新に更新 git pull # 保存したワークツリーを戻す。オプションを省略した場合、直近(stash@{0})がデフォルト # apply: 変更点を適用後、stashは保存したまま。間違った操作をした場合、stashが残るのでこちらの方が安全 # pop: 変更点を適用後、stashは削除される git stash apply git push # stashした一覧 git stash list git stash pop
git checkout master error: The following untracked working tree files would be overwritten by checkout:
git stash -u
git blame -L 5 file.txt d23bebd3 (username 2013-01-02 10:54:57 +0900 5) 05 change # 5-6行目を誰が変更したかを見る。オフセット指定もできる。-L 5,+1 git blame -L 5,6 file.txt d23bebd3 (username 2013-01-02 10:54:57 +0900 5) 05 change 469dbe58 (username 2013-01-02 11:04:25 +0900 6) 06 change
git blame d23bebd3^ file.txt
公開鍵(~/.ssh/id_rsa.pub)/秘密鍵(~/.ssh/id_rsa)が無いと起きる
ssh-keygen -t rsa
mkdir /tmp/foo git archive master | tar -x -C /tmp/foo
よくoriginやmasterといった名前が出てくるが、これは".git/config" に記載があるため。
直接編集しても結果は同じ
cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = git://github.com/heroku/ruby-sample.git
git remote add origin git://github.com/heroku/ruby-sample.git