git - distributed version control

Git常用操作命令收集:

Administration:
git init

Starting …
git clone –progress -v git://github.com/jquery/jquery.git jquery
git fetch -a
git fetch –tags

Configuration: .gitconfig
git config –global user.name “xx”
git config –global user.email “xx@xx.com
git config –global alias.co checkout
git config –global alias.b branch
git config –global alias.br branch -r
git config –global alias.ci commit
git config –global alias.st status
git config –global alias.unstage ‘reset HEAD –’
git config –global alias.last ‘log -1 HEAD’
git config –global core.autocrlf false
git config –global alias.logs ‘log –color –graph –decorate=short –all –date-order’
git config –global core.ignorecase false
git config –global mergetool.fugitive.cmd ‘gvim -f -c “Gdiff” “$MERGED”‘
git config –global merge.tool fugitive

单个project的git配置位于.git/config
可以用如下命令搞定:
git config user.name “xx”
git config user.email “xx@xx.com

Configuration: .gitignore
.gitignore
target
bin
.db .[oa]
*~
!lib.a
/TODO

Git Insight:
Log:
git log –graph –decorate –branches
git log –graph –decorate –all
git log -[n]
git log –pretty=format:”%h - %an, %ar : %s”

Remote
查看远程仓库:$ git remote -v
添加远程仓库:$ git remote add [name] [url]
删除远程仓库:$ git remote rm [name]

拉取远程仓库:$ git pull [remoteName] [localBranchName]
推送远程仓库:$ git push [remoteName] [localBranchName]
查看远程branch: git branch -r
把远程分支check到本地: git checkout -b alpha origin/alpha
check出远程的一个tag: git checkout -b alpha1.1.1 1.1.1.20110501_alpha

Branch:
查看本地分支:$ git branch
查看远程分支:$ git branch -r
创建本地分支:$ git branch [name] –> 切换分支:$ git checkout [name]
创建新分支并立即切换到新分支:$ git checkout –track -b [name]
删除分支:$ git branch -d/-D [name]

Merge:
git merge –no-commit –no-ff [name] 执行merge,但是不做本地修改
git merge [name]

Push:
本地分支push到远程 $ git push origin [name]
本地版本push到远程 $ git push origin [name],
$ git push origin refs/tags/tagname

删除远程版本: $ git push origin :refs/tags/[name]
$ git push origin :[name]
删除远程分支: $ git push origin :heads/[name]
$ git push origin :[name]

Tag:
查看版本:$ git tag
创建版本:$ git tag [name]
创建annoted tag:git tag -a v1.2 -m “This is tag v1.2”
删除版本:$ git tag -d [name]

Cherry-pick:
The advantage is commit log will be linear and clean

git clean -xdf

git mergetool
–>manually edit, save

Best Work flow practiSe:
clone the remote repo
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature
git checkout master
git merge –squash my_new_feature
git branch -D my_new_feature
In fact, our workflow is a little different, as we tend to do squash merges instead of raw merges. This allows us to turn our entire feature branch into a single commit on master. Then we delete our feature branch. This allows us to logically structure our commits on master, even if they’re a little messy on our branches.

git-bisect - Find by binary search the change that introduced a bug

git rebase []

: git checkout , then …
git log ..HEAD > temp
git reset –hard
git reset –hard , with –onto

“git reset” means “git reset –mixed”

git rebase master
git rebase master topic = git checkout topic, git rebase master
git rebase –onto master E topic

git gc –auto一般不做事,除非have around 7,000 loose objects or more than 50 packfiles
git gc –aggressive –prune 可以清理,
git count-objects -v 查看有多少object
git fsck –strict 检查git

git blame 查看谁在那个commit改了什么内容
git blame -L 23,44
git blame -L 23,+10

HOW TO USE SUBMODULE

添加submodule
git submodule add git://github.com/chneukirchen/rack.git rack
git commit -m ‘first commit with submodule rack’
获取submodule
git submodule init 如果找不到iconv2,需要手动复制过去
git submodule update
更新submodule:
进入子目录进行更新
在git中更新submodule:
进入submodule, git merge origin/master
git submodule update

git clone …
git submodule update –init –recursive

清理垃圾:
git gc –prune=now
git gc –prune= defaults to prune objects older than two weeks ago.

让git区分大小写
git config –global core.ignorecase false
强制修改文件大小写
git mv -f name.java Name.java

HOW TO EDIT LAST COMMIT:

Suppose you just made a commit, and you’re working on some more changes, when you realize you made a mistake in the previous commit. Here’s how you can go back and fix it, without losing any of the new work you’ve done since you commited:

1.Save your work so far.
2.Stash your changes away for now: git stash
3.Now your working copy is clean at the state of your last commit.
4.Make the fixes. (If you just want to change the log, skip this step.)
5.Commit the changes in “amend” mode: git commit –all –amend
6.Your editor will come up asking for a log message (by default, the old log message). Save and quit the editor when you’re happy with it.
7.The new changes are added on to the old commit. See for yourself with git log and git diff HEAD^
8.Re-apply your stashed changes: git stash apply
9.Continue happily with your life.

HOW TO EDIT HISTORY COMMIT: we rewrite the history

1.Save and stash your work so far.
2.copy the commit you want to edit onto your clipboard.
3.Start the interactive rebase process, git rebase –interactive ID^, with the ^ to refer to the parent of that commit
3.Your editor will come up with several lines like pick d3adb33 Commit message, one line for each commit since the older one.
4.Change the word “pick” to “edit” in front of the commit you want to change.
5.Save and quit.
6.Edit your project files to make the correction, then run git commit –all –amend.
7.After you’ve committed the fixed version, do git rebase –continue.
8.Git will do its magic, recreating all the commits since then.
You might need to resolve some conflicts, if the change you made affected later commits. Follow Git’s instructions to resolve those.
9.Once the rebase is done, re-apply the stash and continue happily with your life.

echo ‘.zip -delta’ > .gitattributes
echo ‘
.tar -delta’ > .gitattributes
echo ‘.bz2 -delta’ > .gitattributes
echo ‘
.tar -delta’ > .gitattributes
echo ‘.a -delta’ > .gitattributes
echo ‘
.so -delta’ > .gitattributes
echo ‘.gz -delta’ > .gitattributes
echo ‘
.bmp -delta’ > .gitattributes
echo ‘.jpg -delta’ > .gitattributes
echo ‘
.png -delta’ > .gitattributes
echo ‘*.zip -delta’ > .gitattributes

web浏览git代码:
git instaweb
只能浏览代码

gitweb

git reset –soft HEAD^^
回到前两个commit,然后修改,commit可以悔2步棋

搭建git://服务器:
(0)准备git
/home/yu/t/code.git是一个真正的bare git
(1)apt-get install git-daemon-run
(2)修改/etc/sv/git-daemon/run
注意base-path名字后面不能加/,否则出错,git-daemon很蠢
加入–syslog就可以查看详细log,便于debug
加入–export-all可以不用给每个git都加入whitelist
git-daemon –verbose –syslog –reuseaddr –export-all –base-path=/home/yu/t /home/yu/t/code.git
(3)运行
sv down git-daemon
sv up git-daemon
(4)测试
git clone git://IP/code

查看2个commit之间的ancestor关系:
git merge-base –is-ancestor
查看n个commit的所有merge-base(best common ancestor):可能不止一个(criss-cross merges)
git merge-base -a –octopus
merge-base(best common ancestor):可能不止一个(criss-cross merges like this:

---1---o---A
    \ /
     X
    / \
---2---o---o---B

Performance

测试速度
time git status
查看调用了多少次lstat
strace git status 2>&1 1>/dev/null | grep lstat | wc -l
清除disk cash
sudo sh -c “sync; echo 3 > /proc/sys/vm/drop_caches”
sudo sh -c “sync; echo 0 > /proc/sys/vm/drop_caches”

track HTTP requests:
GIT_CURL_VERBOSE=1. GIT_TRACE_PACKET=1

查看所有包含refs/for的refs:
git for-each-ref refs/for

删除所有refs/for的refs:
for n in $(git for-each-ref –format=’%(refname)’ refs/for);
do
git update-ref -d $n;
done

patch

(1)create: git format-patch 3553e4ca0cf2cd..cbd9946fd591f8 –cover-letter –output-directory out
(2)apply : git apply xx.patch
(3)revert: patch -p1 -R < xxx/1.diff

(1)create: git diff xx yy > 1.diff
(2)apply : patch -p1 < 1.diff
(3)revert: git apply -R xxx/1.diff

重写commit的email
git commit –amend –reset-author

cherry-pick range:
git cherry-pick A..B
but it’s not the best, git rebase -i has better sequencing control

清理git历史
bfg repo cleaner
git filter-branch