絵があって簡単で面白い
↓↓↓↓↓↓↓↓↓↓↓↓
http://kinokoru.jp/archives/1017
アニメーションで面白い
↓↓↓↓↓↓↓↓↓↓↓↓
http://k.swd.cc/learnGitBranching-ja/
コミット取り消し
http://freak-da.hatenablog.com/entry/20111105/p1
- commitする バージョンを1つ進める
- stageする 特定の変更内容をindexに登録する(次回commit分に含める)
- index 次回commit分のファイル一覧
|.コマンド|.意味|
|git init|カレントディレクトリ以下をgit管理下に置く|
|git add |をstageする。に.(ピリオド)を指定すると変更分全て|
|git commit -m "" | 1行メッセージ付きでcommitする|
|git status | stage(to be commited)と変更分(not updated)の状態を確認する|
|git reset []| (git logで表示されるハッシュ文字列部分)まで戻る。指定が無ければindexを全てunstageする|
|git log [--format=oneline]|commitの履歴を見る。オプションでformatが幾つか指定出来る|
|git rm|ファイルを削除してgitに削除したことを伝える|
|git clean -fdxn ←確認 危険!必ず確認すること 実行→ git clean -fdx |管理対象外のファイルを削除する|
git config --global user.name "your name"
git config --global user.email [email protected]
git config --global color.ui auto
-
HEAD 現在作業しているワーキングツリーのコミットを指します。コミットが重なる度に先頭へ移動していきます。また git reset や git merge git rebase などのコマンドでも移動します。
-
ORIG_HEAD git reset や git merge など、通常のコミットとは違う極端な HEAD の移動が発生した時に、移動前の HEAD のコミットを指します。
-
MERGE_HEAD git merge を実行して、コンフリクトなどが発生してマージをしている最中にマージ元のブランチの先頭のコミットを指します。
-
CHERRY_PIKC_HEAD MERGE_HEAD とほぼ同じですが git cherry-pick を実行した場合のものです。
-
FETCH_HEAD git fetch した時、リモートから取得したコミットの先頭のコミットを指します。
http://tkengo.github.io/blog/2014/02/10/how-to-track-git-history/
コミットメッセージだけ修正してコミットし直したい:git reset --soft
変更内容を追加してコミットし直したい:git reset --mixed
コミット自体なかったことにしたい:git reset --hard
-
^ について ^ を指定することで、親のコミットを取得することができます。よく聞く話かとは思いますが git のコミットには必ず 1 つは親が存在します(一番最初のコミットを除いて)。親というのは要するに直前のコミットのこと。そしてマージが発生すると、そのマージコミットについては 2 つの親を持つことになります
-
~ について 親のコミットを取得できるのは ^ と同じなのですが ~ の方はマージコミットがあっても本流の方だけをたどっていきます。
中の挙動が詳しく書いてある
http://koseki.hatenablog.com/entry/2014/04/22/inside-git-1
- WhyやHowを書くこと。 WhereやWhatはいらん、diffを見ればわかる
- 言語は英語にする(最初の1文は必ず英語。そのあと補足で日本語は可)
- 1文の場合にはピリオドを付けない
- 主語は省き時制は現在の文章形式にする
- 文頭の英単語を大文字にする
- ファーストコミットは「Initial commit」 とする
- issueから発生したコミットは先頭に「[refs #"issue番号"]」を記述する。クローズの場合は[close #"issue番号"]
- 命令形とする http://stackoverflow.com/questions/3580013/should-i-use-past-or-present-tense-in-git-commit-messages/8059167#8059167
-
Gitlab
-
Gitosis
-
Gitolite
-
Gitorious インストールが難しいらしい
-
Gitblit インストール簡単だが、機能がまだそろっていないらしい
git config core.sharedRepository group
chmod -R g+ws hooks
chmod -R g+ws info
chmod -R g+ws objects
chmod -R g+ws refs
で--shareと同じ効果
issue-XXX/(大分類名)/ブランチ名で命名
issue-123/chat_timeline/extract-url_linkみたいな感じ
-
developブランチ 開発を行うためのブランチ。開発者は、主にこのブランチ上で作業を行う。次に紹介するfeatureブランチなど、他のブランチで行った作業は、ここにマージされる
-
featureブランチ 主要な機能を実装するためのブランチ。機能の実装やバグフィックスなど、タスクごとにfeatureブランチを作成し、作業を行う
-
releaseブランチ リリースの準備を行うためのブランチ。プロダクトをリリースする前に、このブランチを作成し、微調整を行う。releaseブランチを作成することで、リリース準備と次のバージョンに向けた開発のコードを分けることができる
-
masterブランチ リリースしたソースコードを管理するためのブランチ。リリース作業を行うと、releaseブランチはmasterブランチへマージされて、リリースタグが打たれる。開発者は、このブランチへのコミットは行わない
-
hotfixブランチ リリースされたソフトウェアに緊急の修正を行うためのブランチ。このブランチでの修正内容は、すぐにリリースされるので、hotfixブランチはリリースを管理するmasterブランチへマージされる
- masterで作業しない。ブランチを作って作業すること
- ブランチでは1機能もしくは1バグのみ作業すること
- メジャーバージョンは常に動くようにしておくこと
- チケットとリンクをとれるようにすること
- 基本すべて小文字
- "_"でなく"-"の方がよい(使っている人が多いかつかっこいい)
basename $(git remote show origin -n | grep "Fetch URL:" | sed 's/.*://;s/.git$//'
https://stackoverflow.com/questions/15715825/how-do-you-get-git-repos-name-in-some-git-repository
git log --graph --branches --pretty=format:"%d [%h] "%s""
git diff <branch name> --shortstat *.cc
git log --author="Taro Tanaka" --oneline --shortstat
git log --numstat --pretty="%H" | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%dn", plus, minus)}'
git log --since=2013-01-01 --until=2013-06-30 --oneline --numstat --no-merges --pretty=format:"" | cut -f1 | awk 'BEGIN {sum=0} {sum+=$1} END {print sum}'
git log -- <branch name> --oneline --numstat --no-merges --pretty = format: "" | cut -f1 | awk 'BEGIN {sum=0} {sum+=$1} END {print sum}'
git log --since=2015-09-01 --oneline --no-merges --numstat --pretty="" *.cc *.h | cut -f1 | awk 'BEGIN {sum=0} {sum+=$1} END {print sum}'
git log --since = 2013-01-01 --until = 2013-06-30 --oneline --numstat --no-merges --pretty = format: "" | cut -f2 | awk 'BEGIN {sum=0} {sum+=$1} END {print sum}'
git shortlog -se | awk -F't' '{print $2,$3}'
git log --since = 2013-01-01 --until = 2013-06-30 --oneline --no-merges | wc -l
git log --merges --format="%cn" | sort | uniq -c | sort -r | head
git log --name-only --pretty="format:" | grep -ve '^$' | sort | uniq -c | sort -r | head
git log --pretty="format:%cn:%s" | grep fu.k | cut -d":" -f1 | sort | uniq -c | sort -r
git submodule foreach --recursive 'git checkout master; git pull'
git submodule foreach --recursive git add -A .
git submodule foreach --recursive git commit -m 'submodule commit message'
git push --recurse-submodules=on-demand
孫もいるなら
git submodule foreach --recursive git push origin master
じゃないとだめっぽい
2017 Q3にリリースされる予定のgitで孫がいてもpushできるようになる見込み
git submodule deinit vendor/pelican-sober
git rm vendor/pelican-sober
rm -rf .git/modules/path/to/submodule
git commit -a
# Fetch the submodule commits into the main repository
git remote add submodule_origin git://url/to/submodule/origin
git fetch submodule_origin
# Start a fake merge (won't change any files, won't commit anything)
git merge --allow-unrelated-histories -s ours --no-commit submodule_origin/master
# ここでgit log しても表示されない
# Do the same as in the first solution
git rm --cached submodule_path # delete reference to submodule HEAD
git rm .gitmodules # if you have more than one submodules,
# 他のsubmoduleがある場合はviで対象部分のみ削除
# you need to edit this file instead of deleting!
rm -rf submodule_path/.git # make sure you have backup!!
git add submodule_path # will add files instead of commit reference
# Commit and cleanup
git commit -m "removed submodule"
# ここでgit log したら表示される
git remote rm submodule_origin
https://stackoverflow.com/questions/1759587/un-submodule-a-git-submodule
git diff 15dc8^!
https://stackoverflow.com/questions/436362/how-to-diff-a-commit-with-its-parent/449128#449128
git filter-branch -f --env-filter "GIT_AUTHOR_NAME='sea_mountain'; GIT_AUTHOR_EMAIL='[email protected]'; GIT_COMMITTER_NAME='sea_mountain'; GIT_COMMITTER_EMAIL='[email protected]';" HEAD
for i in $(git ls-files | xargs -i file {} | grep --line-buffered "ASCII\|UTF-8" | cut -d ":" -f 1); do echo $i; \
if diff /dev/null "$i" | tail -1 | \
grep '^\\ No newline' > /dev/null; then echo >> "$i"; \
fi; done
git ls-files | xargs -i file {} | grep --line-buffered "ASCII\|UTF-8" | cut -d ":" -f 1 | xargs -i nkf -Lu --overwrite {}
GIT_AUTHOR_NAME="" GIT_AUTHOR_EMAIL=""
を定義しておけばよい
stashしないファイルをgit addする
git stash -k
git reset
# ステージからもとに戻す
ssh-keygen -t rsa -C "[email protected]" -b 4096
cat ~/.ssh/id_rsa.pub
確認
ssh -T [email protected]
あとは、
https:// を [email protected]:に切り替える
これを使えばhttpsをsshに置き換えてくれる
git config --global "[email protected]:.pushinsteadof" "https://github.com/"
git remote set-url --push origin [email protected]:User/forked.git
pushurl = http://192.168.1.20/Test/hubot-rocketchat.git
http://sleepycoders.blogspot.jp/2012/05/different-git-push-pullfetch-urls.html
http://stackoverflow.com/questions/948354/default-behavior-of-git-push-without-a-branch-specified
git rebase -i xxx
pick->s
http://iwb.jp/git-commit-rebase-squash/
unset SSH_ASKPASS
- コミットしているなら git reflog
git rest --hard xxx
- ステージングしている git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")
git show xxx
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") xxx
- ステージングしていない 諦める
git filter-branch ~~f --msg-filter 'nkf -w' -~~ --all
階層構造になっていると工夫しないと認識されない
/*
/.*
/.*/*
/.*/*/*
という感じに階層分だけ最初に除外する。
ディレクトリがある場合は
/*
!/src/
/src/*
!/src/hello.c
というように上のディレクトリを一回対象外にして入れ直す
http://seesaawiki.jp/aki/d/.gitignore%20%A5%D5%A5%A1%A5%A4%A5%EB%A4%CE%BD%F1%A4%AD%CA%FD
git rm -r --cached .
git add .
git commit -m "Update .gitignore"
重いファイルをコミットした場合、ツリーから消さない限りリポジトリが重くなってしまう。
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch でかいファイル.tar.gz' --prune-empty --tag-name-filter cat -- --all
これでツリー上から完全削除される
http://www.walbrix.com/jp/blog/2013-10-github-large-files.html
"軽量化の仕方":http://techracho.bpsinc.jp/baba/2012_05_22/5594
これが一番良さそう
#my problem was that I had there a refs/remotes/origin/master line for a remote repository, delete it, otherwise git won't remove those files
check .git/packed-refs
#(optional)to check for the largest files
git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5
#(optional)to check what are those files
git rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98
#to remove a file from all revisions
git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_names' -- --all
#to remove git's backup
rm -rf .git/refs/original/
rm -rf .git/logs/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
# old
#to expire all the loose objects
#git reflog expire --all --expire='0 days'
#to check if there are any loose objects
#git fsck --full --unreachable
#repacking
#git repack -A -d
#to finally remove those objects
#git prune
リモートリポジトリにあげたら容量がもとに戻ってしまうので、リモートリポジトリを一旦削除して再度pushする必要がある。
http://stackoverflow.com/questions/2164581/remove-file-from-git-repository-history
git checkout ブランチ名 ファイル名
コミット時のユーザやメールアドレスを変更するとき
git commit --amend --author="sea_mountain [email protected]"
$ git rebase -i <コミット>
- エディタが開くので以下のように変更して保存
- (変更後)対象のコミットをeditに変更 $ git commit --amend -m "コミットメッセージ" --author="user.name <user.email>"
$ git log
$ git rebase --continue
git ls-files | sed -i 's/[ t]*$//'
以下のサイトにわかりやすく解説されている。
http://d.hatena.ne.jp/hokaccha/20120404/1333507076
公式文書は難解なので。。。
- git checkout -b ローカルのブランチ名 origin/リモートのブランチ名 でブランチを切ります。
- git rebase -iします。
- git push origin +ローカルのブランチ名:リモートのブランチ名 して強制的にコミットツリーを変更します。 他のリポジトリから変更を取得する際は、git fetchしてgit rebase origin/リモートのブランチ名 としましょう。
for FILE in `git ls-files`; do
TIME=`git log --pretty=format:%ci -n1 $FILE`
echo $TIME't'$FILE
STAMP=`date -d "$TIME" +"%y%m%d%H%M.%S"`
touch -t $STAMP $FILE
done
cd "$(git rev-parse --show-toplevel)"
git config --global user.name "your name"
git config --global user.email [email protected]
git commit --amend --reset-author
OR
.gitconfig
[user]
name = name
email = [email protected]
どうやらversion:1.8ではダメのよう
~/.gitconfig
[http "http://192.168.1.30"]
postBuffer = 524288000
proxy =
[http "http://192.168.1.40"]
postBuffer = 524288000
proxy =
[http "http://192.168.1.50"]
postBuffer = 524288000
proxy =
#[http]
# postBuffer = 524288000
# proxy = http://192.168.1.30:10080
#[https]
# postBuffer = 524288000
# proxy = http://192.168.1.30:10080
[url "https://"]
insteadOf = git://
idxファイル:インデックスを保持
pack ファイル:データ実体
This is where it all begins...
Commit committed
Version control is awful
COMMIT ALL THE FILES!
The same thing we do every night, Pinky - try to take over the world!
Lock S-foils in attack position
This commit is a lie
I'll explain when you're older!
Here be Dragons
Reinventing the wheel. Again.
This is not the commit message you are looking for
Batman! (this commit has no parents)
[email protected]形式でダウンロードできない場合
~/.gitconfig
[url "http://github.com/"]
insteadOf = [email protected]:
git clone http://xxx .
※古いバージョンだとできない?v1.8系は無理だった。
エラー文:
error:The following untracked workding tree files would be overwritten by merge:
解決法:
ようわからんけど、gitでリモートのブランチにローカルを強制一致させたい時
git fetch
git reset --hard FETCH_HEAD