GIT 基本特点
1.直接快照,而非比较差异 2.近乎所有操作本地执行 3.时刻保持数据完整性
为什么要用GIT?
最明显特征是分布式:客户端并不只提取最新版本的文件快照,而是把原始的代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的提取操作,实际上都是一次对代码仓库的完整备份。
创建分支快捷轻便:创建分支其实只创建一个新的分支指针即可。
GIT基本原理:三种状态、四种对象(再次赘述下)
状态一:git repository 即 Git 目录( .git )
状态二:working copy Git 工作目录
状态三:staging area Git 暂存区域
四种对象:
用户环境设置:
git config [–global | --system ] (–system 参数修改/etc/gitconfig文件,针对所有用户适用配置;–global 参数修改~/.gitconfig文件,针对该用户适用配置)
初始化仓库:
git init (创建一个空的git仓库或初始化一个已存在仓库,会建立一个隐藏.git目录)
获取代码库:
git clone [url] (默认把远程仓库整个clone下来,但只会在本地创建master分支;如果远程还有其他分支,git branch -a查看所有分支;git支持ssh、git、http/s、本地协议,一般用ssh协议)
添加目录下修改、或新增加的文件到仓库暂存区:
git add -A | -u | -f | filename (-A表示添加所有文件;-u添加所有跟踪文件;-f 强制添加被忽略文件;filename添加指定文件)
删除文件:
git rm [filename] 删除受版本控制的文件或文件夹 (-rf是删除文件夹)
移动文件:
git mv [sourcefile] [destinationfile] 移动源文件为目标文件,相当于重命名。
忽略版本控制的文件用正则匹配添加在.gitignore:
eg: $ cat .gitignore
# frameworks/base # 此为注释,被git忽略
*.a # 忽略所有.a结尾的文件
!lib.a # 但lib.a除外
!build/ # 忽略build目录下的所有文件
doc/*.txt # 忽略doc目录下的所有.txt结尾文件,但不包含doc/notes/*.txt
/TODO # 仅忽略项目根目录下的TODO文件,但不包含subdir/TODO
提交存储在当前index即暂存区的文件:
git commit -m 'your description' (提交后会显示本次提交的完整 SHA-1 校验和, 以及在本次提交中,有多少文件修改过,多少行添改和删改过;-a参数会兼并git add动作)注:不填提交说明不能提交
查看仓库状态:
git status (查看仓库当前工作于哪个分支;查看文件状态:被修改,被删除,新增加等)注:每次提交前,都用git status查看下是不是都已暂存起来了,然后再提交。
git status会提示你目前工作目录下各修改过的文件的状态:
eg:当前干净目录:
新建文件并跟踪:git status提示“new file”处于“Changes to be committed”状态,说明是已暂存状态。
修改已有文件README:git status提示“modified”文件处于“Changes not staged for commit:”状态,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。要暂存这次更新,需要运行 git add
命令
git add 已修改文件:git status 提示已暂存状态,与刚才追加跟踪文件track一样:提示“Changes to be committed:”
git commit 两个文件:提示 “nothing to commit, working tree clean”
查看提交历史:
git log [ -5 | -p | - - author="fx" | - - since/- -until =“2017-06-06-24”| - - graph | - - pretty=format:%h:%s ] (最近5次提交;fx的提交;-p显示所有的commit的详细的修改内容及提交信息;指定日期之后或截止指定日期的提交;图 形方式显示提交;定义格式显示)
比较差异:
git diff :不带参数比较的是wc与staging的差异;
git diff - -cached 比较的是stading与仓库的差异;
git diff HEAD比较当前工作空间与本地仓库差异;
git diff newbranch比较当前工作空间与新分支差异;
git diff - -state统计差异文件个数;
git diff tag1 tag2 ;
git diff tag1:file1 tag2:file2 ;
git diff tag1 tag2 file
还原版本:
git reset - -hard HEAD 回复到HEAD状态;
git reset - -hard HEAD^ 彻底撤销最近一次提交;
git reset - -soft HEAD~3 将最近3次提交撤掉到stage状态;
git reset - - mixed 撤销add动作
撤销提交:
git revert master~3 或git revert SHA1
修改提交:
git commit - -amend (如果上次提交时遗漏了文件,可以在提交后将文件加入缓存然后用该命令提交即可,它会打开vi编辑器让你编辑commit message)注:只限于未push的提交
比较git reset、git revert、git checkout、git commit
•git reset:撤销最近的提交,此次之后的修改都会被退回到暂存区,ws不变(默认参数--mixed)
•git revert:撤销某次提交,此次操作之前的commit都会被保留
•git checkout - - file:将文件从stage的状态撤销,原有修改将找不到;
GIT如何创建分支并切换到新分支,如何在不同分支间转换,合并本地分支?
GIT如何把分支推送到共享服务器上,同世界分享?如何使用共享分支与他人协作,以及在分享之前进行衍合?解读如下......
test,master分支各有一次提交 共同祖先:C2
1、采用merge三方合并方式合并test分支的修改到master分支上:
$ git checkout master
$ git merge test
冲突解决:
任何包含未解决冲突的文件都会以未合并(unmerged)状态列出。git status --->显示unmerged状态
vi 冲突文件,合并部分用<<<,===,>>> 分隔符标记,手动解决冲突后,删掉这些标记;
在解决完所有文件的冲突后,执行git add ,使文件标记为冲突已解决;
运行git status查看文件状态为modified;
执行git commit 提交,完成这次合并提交。
2、采用rebase方式合并test分支的修改到master分支上,rebase方式官方叫衍合:分为两步完成
衍合基础:开发进程分叉到两个不同的分支,又各自进行了提交
说明:1、在test分支中,把C3里产生的差异保存到临时文件中;2、切换到master分支,将差异应用到master分支上;3、切换回test分支;
注:修改的是test分支,master分支没有变化。
step2:将test分支 rebase master 分支后:
$ git checkout master #切换回master分支;
$ git merge test #合并test分支到master分支,进行一次快进合并
在执行git rebase时,同时修改了同一文件的某一行或几行,可能会发生冲突。 冲突发生时,工作空间处于no branch的状态。
冲突解决:
用vi 编辑文件,找到<<<和>>>的冲突标记,解决冲突,然后删除掉冲突标记;
解决完冲突后,git add 文件,然后执行git rebase - - continue, 继续衍合其余的commit;
在执行git add 后,工作空间处于你所在的分支;如果此时还是no branch状态,说明冲突没有解决彻底;
解决冲突后,不要执行 git commit,否则会在执行git rebase --continue时,提示仍然有冲突,但实际上已经解决完冲突了;如果执行了git commit,那么在提示错误时,执行git rebase -- skip , 忽略此次冲突提示
3、采用cherry-pick的方式将test分支的修改合并到master分支上:git cherry-pick sha1
关于cherry-pick: cherry-pick 可应用于同一远程库不同分支的提交,也可用于不同远程库的分支,需在本地工作空间中添加远程库,fetch远程库的数据到本地库 。
$ git checkout master # 切换到master分支 ;
$ git cherry-pick C3-SHA1 # 合并test分支的C3提交到master分支 ;
$ git branch –d test # 合并完成后,可以删除test分支