git的使用原则是可复用,不重复,需放进git远程仓库的文件:源代码、第三方文件。
不需放进git远程仓库的文件:自动生成的文件(如obj,exe等),因为自动生成的文件在修改源代码后会改变其内容,如果push前目标分支有更新,你需要先pull再rebase,那么因为自动生成的文件会造成你需要手动合并修改,这是徒劳的,极易造成混乱,为了避免这种状况,自动生成的文件不能被放进远程仓库。
git的工作方法(workflow)
1.并行分叉式——集中式工作流
2.并行分支式——功能分支工作流
3.串行排队式——Gerrit
4.pull request——Githup(对远程仓库的合并修改都由仓库owner和管理员控制)
基本配置
git config --global user.name "thomson"
git config --global user.email "thomson@gmail.com"
@tips 基础配置,自报家门user.name和user.email , 用--global说明电脑上所有的git仓库都将用它标记
git config --global color.ui true //配置git显示不同颜色,更醒目
git config --global alias.st status //命令缩写,st代表status,可以用git st代替git status
git config --global alias.co checkout //命令缩写
git config --global alias.cm commit //命令缩写
git config --global alias.br branch //命令缩写
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" //配置得五颜六色
@tips 如果想删除这些快捷命令,可以在.git/config里把 [alias] 下的对应内容删掉
初始化仓库
mkdir <dirname> //在当前路径下创建一个新目录
cd <dirname> //cd进新建的目录
pwd //显示当前的工作路径
git init //把当前目录变成git可以管理的仓库,相当于在当前目录下新建一个空的git仓库,在当前目录下会新建一个.git目录,默认隐藏(可以使用ls -ah查看),这是跟踪管理版本库的,不可手动修改
添加、提交、查看文件修改记录
git add <filename1> <filename2> <filename3> //正常添加后不会有提示(没消息就是好消息,哈哈)
git commit -m "describe commit info" //提交本地修改,字符串是提交说明
git status //实时查看仓库当前的状态
git diff <filename> //查看文件的修改记录
查看提交记录和回退版本
git log //查看当前分支的提交记录
git log --pretty=oneline //每次提交记录用一行显示,在记录很多时不会全部显示,在:输入数字N即可显示当前位置顺序后的N条提交信息
git reset --hard HEAD^ //把当前分支文件版本回退到前一版本,HEAD代表前一版本,HEAD100代表第前100个版本,这里HEAD指的是当前分支
git reset --hard version_id //version_id代表提交版本号,可以回退到具体某个版本 @tips reset参数有--hard --soft --mixed,hard会删除包括缓存的所有修改,soft会保存所有修改(用到再查)
git reflog //记录你操作的每一次命令,在回退到旧版本后想重新回到新版本时可以用来找到新版本的version_id
git reverse //如果已经push,想远程仓库回退回之前的版本,用此命令
工作区(文件存放目录)、暂存区(stage)、版本库(repository)
工作区有一个隐藏目录.git,这个不算工作区,而是git的版本库,版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有git自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
@tips 暂存区就像购物车,没到付款的时候你都不确定购物车里的东西全部都是要的,每拿一件商品就付一次款,那才麻烦大了(非常形象的比喻,233333)
@tips git add是把修改后的文件添加到暂存区,git commit是把暂存区的所有内容提交到当前分支,如果最新修改没有被add进暂存区,提交时不会提交最新修改,而是被add进暂存区的修改
git diff -- <filename> //在工作区修改文件后没有执行git add命令,直接执行git commit的话git不会把当前工作区的最新修改提交到版本库,使用此命令可以查看当前工作区的文件和版本库中同一文件的异同
撤销修改
git checkout -- <filename> //把文件在工作区的修改全部撤销,这里分两种情况:”一种是此文件自修改后还没有被add,现在撤销修改就回到和版本库一模一样的状态;一种是文件已经被add,add后又做了修改,撤销修改就回到添加到暂存区后的状态。“此操作就是让文件回到最近一次git commit或git add时的状态。
git reser HEAD <filename> //当修改过的文件被add进暂存区,但是想回退时,可以用命令,与git checkout -- filename一起用就可以彻底消除修改
删除文件
rm <filename> //在文件系统中删除文件
git rm <filename> //在git版本库中删除文件
git checkout -- <filename> //如果在文件系统文件找不回来,使用此命令从版本库中提取文件最新版本到工作区,但是会丢失最近一次提交后修改的内容
远程仓库、推送版本
@tips 因为本地git仓库和githup远程仓库之间的传输时通过ssh加密的,所以需要生成本地ssh key上传到githup,githup允许添加多个key,在所用电脑生成ssh key上传即可,这样在所用电脑均可推送
ssh-keygen -t rsa -C "email@example.com" //一般不设置密码,如果为了保密也可以设置密码,生成完毕可以在主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub,前者是私钥,后者是公钥,私钥需保密,公钥可以公开
git remote add origin git@github.com:thomson/testRepo.git //关联远程仓库
git branch --set-upstream dev_v2.2 origin/dev_v2.2 //本地分支关联远程分支
git push -u origin master //-u是第一次push时加上的,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令,在以后就可以使用git push origin master推送最新修改了。在githup新建仓库后第一次push用此命令会报错,如下:
因为在githup仓库有文件在本地没有,所以要先rebase,执行git pull --rebase origin master,把远程仓库文件拉去到本地,然后再push 即可
git rebase //当你push时目标分支有更新,你需要先pull下目标分支的更新,然后切换到开发分支,执行rebase命令合并更新,合并更新可能会提示冲突,这时需要手动合并,如果没有提示冲突则会快速合并,合并完成之后便可push。@tips rebase命令实际上执行的过程是把你在本地做的修改放在最新更新的后面,就像你是在最新更新过的文件做修改一样,这一过程就可能会产生冲突需要手动解决。(另一种说法就是,在rebase时,git先把你在本地做的修改全保存在一个地方,然后删除你的修改记录,把最新的更新拉过来当本地仓库,然后再把刚保存的文件合并到工作区的文件上,你再commit,push时就可能会产生冲突)
git push -f //强制推送,用你本地的文件替代git仓库中的内容,慎用,操作之后仓库中的数据会不见
git push origin <local branch name>:<origin branch name> //push的完成命令
git pull //从远程拉去文件,相当于先git fetch再git merge
- git fetch origin develop
- git checkout develop
- git merge origin/develop
git pull origin <origin branch name> //拉取远程分支代码与本地当前分支merge
git clone git@github.com:thomson/Test2.git //从远程仓库克隆一个到本地仓库,克隆可以通过https协议,但是每次都要输入口令,比较麻烦,git默认是用ssh
@tips track的作用:把本地某个分支与远程某个仓库分支对应起来
@tips 往githup上push项目时提示无权限,可能是因为ssh没设置好,http://segmentfault.com/q/1010000003061640
分支管理
@tips 分支就如科幻电影里的平行宇宙,创建自己的本地分支然后修改文件commit,完毕之后再一次性push到远程仓库的分支。
而后对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变,当我们在dev分支完成了工作,就可以把dev合并到master上,
git branch //查看分支,加上-a可以查看全部分支
git branch <name> //创建分支
git checkout <name> //切换分支
git checkout -b <name> //创建新分支dev并切换到dev分支,相当于git branch dev和git checkout dev两条命令的合成
git merge <name> //在当前分支上合并dev分支,合并之后没push不会修改远程仓库的数据,如果没有修改冲突,可以进行快速合并,如果有则需手动修改再提交
git branch -d <name> //删除本地dev分支
git branch -r -d origin/<origin branch name> //删除本地的远程分支
git branch push :<origin branch name> //删除远程分支
@tips 实际团队开发分支管理图
解决冲突
@tips 当在一个分支B1上修改了文件A并且提交,切换到分支B2时又修改了文件A也提交,那么此时切换到分支B1再合并分支B2时会出现冲突,无法快速合并,需要手动修改文件A的内容,然后再add和commit
git log --graph --pretty=oneline --abbrev-commit //可以以字符图形显示查看文件合并的过程
git merge --no-ff -m "describtion" dev //禁用快速合并并在合并后生成一个新的commit,-m和"cescribtion"是生成新commit用的,这个需要手动修改文件
忽略特殊文件
@tips 把你不想被VCS管理的文件的文件名或某后缀名的文件或某文件夹下的文件路径加入到.ignore文件中,把.ignore文件提交到VCS,这样git就可以忽略这些文件了,略如.ignore文件如下:
Windows:
Thumbs.db
ehthumbs.db
Desktop.ini
Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build
My configurations:
db.ini
deploy_key_rsa
//.gitignore不起作用
@tips 有时候push代码时,对某些文件做了修改但是不想把这些文件提交上去,在.gitignore也定义了规则忽略,但是push还是把文件提交上去了,这是因为git系统已经追踪到了文件的修改,此时要想忽略文件的修改就需要修改缓存,把相应的文件取消追踪,如此.gitignore文件中的相应规则就可以生效了。
git update-index --assume-unchanged <file.name>
本地分支关联远程分支
git branch --set-upstream-to dev_v2.0 origin/dev_v2.0
合并分支完毕之后消除merge状态只需提交本地修改即可。
window下git提交和检出时换行符[LF]被自动转换成[CRLF]造成的问题
@tips 当文件内容变动会造成使用问题时(比如根据文件内容生成MD5),就需要手动设置,但这治标不治本。如果是多人同时参与项目开发,那么每个人都需要这样配置,比较省事情的做法是提取文件内容时,对文件内的[CRLF]->[LF]进行手动转换,常见的有
Pattern CRLF = Pattern.compile("(\r\n)");
Matcher m = CRLF.matcher(middleLicense);
if(m.find()){
middleLicense = m.replaceAll("\n");
}
AutoCRLF
git config --global core.autocrlf true //提交时转换为LF,检出时转换为CRLF
git config --global core.autocrlf input //提交时转换为LF,检出时不转换
git config --global core.autocrlf false //提交检出均不转换
SafeCRLF
git config --global core.safecrlf true //拒绝提交包含混合换行符的文件
git config --global core.safecrlf false //允许提交包含混合换行符的文件
git config --global core.safecrlf warn //提交包含混合换行符的文件时给出警告
附上git官网 http://git-scm.com/