Saturday, March 19, 2016

Git简介

Git和SNV最大的区别是Git多一个repository在local,这样如果check-in到prod的话可以现在local做好code review再push,还可以对自己的各个改动做备份(local SVN本地版本管理)。


工作流程


git pull
git checkout -b issue 1
git commit
git rebase -i HEAD~2
git pull (in mainline)
git rebase mainline (in issue1)
git merge issue1 (in mainline)
git push
git branch -d issue1

开始一个项目/bug时,都要习惯做git pull,否则可能会出现unexpected逻辑问题由于别人代码没有进入

Git commnds:

git fetch origin remoteBranch
git checkout remoteBranch
下载remote端的分支(非mainline)

git stach save
git stach pop
暂存改动,使得没有unstaged文件
恢复暂存的改动
git pull开始一个issue时,都要先做此步
git log查看本分支commit历史记录(从新到老排序)
branchgit branch显示所有分支
branchgit branch issue1创建issue1的分支,与mainline基点一致
branchgit checkout -b issue1创建且切换到issue1分支
git status查看在哪个分支,与origin/mainline(remote端)比ahead了几个commit,文件状态(增改删)。Commit后不显示文件状态
commitgit diff (test.java)
git diff abcd fghi
git diff -z --name-only abcd fghi
查看所有/单个文件与上次commit的不同,git add后不会显示diff。还可以比较两个版本所有代码的异同。最后可以只查看修改的文件名
commitgit checkout abcd Test.javarevert一个unstaged文件,abcd是commit id从git log可得
commitgit reset --hard abcdrevert所有文件(unstaged/staged),abcd是commit id从git log可得
commitgit add (test.java/*.java)commit前加入到index,任何添加修改都需要git add。之后gitstatus这些文件由红变绿(staged)
commitgit reset (test.java/*.java)git add的逆操作
commitgit reset --hard撤销git add的所有文件
commitgit clean -dfx删除新加且unstaged的所有文件
commitgit commit -m "add a log"
git commit --amend
执行前先做git status确保分支和修改文件正确。amend修改log最近提交的信息。
commitgit reset --soft HEAD~撤掉git commit,文件仍在git add后状态(staged)
commitgit reset HEAD~撤掉一个git commit(多个用HEAD~n),文件仍在git add前状态(unstaged)
commitpost-review --parent mainline -r 12345提交review,-r可以保证多次commit仍然是同一个code review。如果是mainline可以post-review -r
rebasegit rebase -i HEAD~3
shift zz to save
先在分支合并commit,3表示合并3个commit。如果在mainline执行这个操作,git将会把分支上各个commit合并到分支,可能需要resolve每个commit,非常没必要。
合并多个commit为一个,且汇总commit信息。把除第一行的pick改为s(squash)变成一个commit代码,下一页修改commit信息,shift+D删除全行。命令可加上issue1表示对此分支修改commit。若在主干,则执行
git rebase -i
pullgit checkout mainline切换到mainline更新最新代码
pullgit pull从remote端下载最新代码到mainline
rebasegit checkout issue1先切换到issue1,再执行rebase
rebasegit rebase mainline先切换到issue1,再执行rebase。如果出现error,就到有冲突的文件解决冲突
rebasegit add Test.javarebase后再add存在冲突的文件
rebasegit rebase --continuerebase状态下的git commit
rebasegit log此时会见到remote端的改动出现在log中
mergegit checkout mainline转换分支mainline或issue1
mergegit merge issue1先切换到mainline,把issue1分支并入到mainline
pushgit pushpush前要先build一下。push到remote端
pushgit branch -d issue1push后删除,不要重用
git cherry-pick abcd从某个commit引入到该分支,因id在各分支中唯一
git revert abcd撤销某个commit,会在commit msg加revert。cherry-pick的反操作,cherry-pick是引入新的commit,而revert是取消目前分支的某个commit。
git blame Test.java打印某一个文件的历史commit,可以快速找到引致错误文件的commit然后git revert
git stash save将未commit的临时改动存入stash,以方便revert而不丢失代码
git stash pop将stash的改动恢复到workspace

这个表格覆盖了一个code改动的流程,包括branch、commit、pull、rebase、merge、push六个大步骤。绿色是最常用命令,黄色是对应上行的逆操作。staging时候分支代码都一样,只有commit以后代码才会不同。

其他命令:

bisect:二分法(端点为good和bad)找到导致错误的commit,需要手动标记此版本好还是坏,git决定在哪个区间继续搜。


Rebase:

Git可以在local repository创建多个分支。mainline是server的分支。比较好的操作是创建一个分支用于修改自己的改动,再merge到mainline。
git checkout -b issue3
git commit -m ""
git checkout mainline
git merge issue3
git push
这个实践很好,如果这段过程中mainline没有push的话,也仍是一条直线。但如果有commit0时候,自己的分支有两个commit(由于code review中不断改动产生多次commit),merge过程就产生一个merge point(不是任何一个checkin point,issue3这个分支push了)。最大缺点是issue3的历史记录不在mainline上不好查看而且不能删除。












引入rebase既可以合并多次commit成一个还可以只出现主干。rebase就是在commit和merge之间加入一步,将最新的remote端代码更新到分支,也叫分支的base改到最新了,所以叫rebase。rebase时候,git会将mainline的改动按步骤一个commit by一个commit将merge到分支。resolve conflict过程会看到分支的最新代码没有出现是因为working on最初的commit,所以只要管好conflict即可,不用理其他代码。







gitignore:

.gitignore文件加入如下:可忽略这些文件永远不会checkin
*.pyc
.idea/

git-config

git config --global commit.template ~/a.txt 
git commit (not git commit -m "")
vim ~/.gitconfig to change name


TortoiseGit

利用bitBucket作为remote repository. 下载TortoiseGit作为client, TortoiseGit需要下载Git.exe

然后右击Git Clone(=SVN checkout) ,如果这个选项没出现就按着shift键才右击即可,然后输入bitbucket中的clone url,文件夹一定要为空。然后创建一个文件,就要commit并且push. commit表示代码写入local repository, push表示写入到remote server




ref: https://www.youtube.com/watch?v=YC6zraqIooM

每次push都输入git url


























No comments:

Post a Comment