layout: post title: Git进阶 category: Git tags: [Git] — 已备份到有道笔记 ##遇到问题 gitHub搭建博客时,更改jekyll配置文件_config.yml里面name,出了问题,导致jekyll serve启动失败。当初为了定位问题,我去gitHub上面直接修改相关配置后发现是OK的。这时候,本地的git和服务的git不一致。首次考虑到的当然是从远程上将修改正常的覆盖不正常的,用git pull时候,出现了问题,说有冲突不能合并。 ##解决问题
好吧,相关命令不熟悉,我就打开了已老早就安装在机子里面的Source Tree,想想还不会用这个工具,没办法,打开菜单里面的帮助说明,于是很简单就将我的sprying.github.io仓库加入管理,在管理面板的进行一系列尝试后,还是不会用这个工具,返回到命令行操作,发现commit中的内容是我想要的,而暂存中内容是不想要的,估计当时用完合并工具没点保存。现在pull还是提醒冲突,唉,没办法了,要补充下git命令知识了。 过程如下,先是搜索git历史回退、冲突解决,然后发现许多命令不知具体意思,于是了解一系列命令,reset、rebase、merge、patch、checkout、pull;这些文章结构清晰、有图、简单易操作,读完之后,发现自己建立起来的理解都是间接建立在别人理解上,还有许多关键地方没懂,还是不能解决我需要的问题。
好吧,只能走其它途径了,那就看以前收藏的git原理介绍问题。一篇是简明介绍,读完之后,发现又有收获,但发觉还是不明白地方。比如,git从远程取下数据后,怎么处理。另一篇是Pro git简体中文版教材。于是滴答滴答看起来了,+_+,这时已经浪费不少时间了,:-(。
这里,该说下git学习收获。由于这个是学习,为了图快,没进行实践演练。
##相关知识
###初始化、克隆库
Git文件状态
Git文件流转的三个工作区域:工作目录(working)、暂存区域(staged、index)、本地仓库(Head)。
四个状态:已提及状态(commited)、已暂存状态(staged)、已修改状态()、未追踪文件(unstage)
状态间切换命令
git checkout --<filename>
用暂存区的filename文件更新工作区的filename
git checkout <branch> --<filename>
用branch分支的文件替换暂存区和工作区的文件
git checkout [--] .
会将暂存区所有文件替换到工作区
git reset --<filename>
git reset --hard SHA
git add --<filename>
git add -u
将已追踪的文件更新保存到暂存
git rm <filename>
.gitignore忽略版本控制的文件
git信息查看
git status
查看要加入暂存的新增、修改文件,待提交(modified)的文件;合并冲突文件(unmerged)。
git log
查看历史;
git reflog
查看所有HEAD历史,只存于本地,包含上面的git log
可恢复reset的提交对象 git reset –hard HEAD@{1}
git diff
查看正在修改文件与暂存间的差异
git diff --cached/staged
查看暂存文件与Head的差异
git diff <source_branch> <target_branch>
git checkout HEAD
查看HEAD、暂存区、工作区的差异
git分支
git分支实际是文件指针,指向提交对象,创建一个分支就是一个引用,所以创建、切换的代价很小。
在当前分支创建切换到另一个分支,另一个分支内容与当前分支一致,都指向同一个提交对象。所以在项目里面,创建gh_page介绍项目网页分支时,要清空内容。
git checkout <branch>
检出branch分支,Head改变指向branch,更新暂存区和工作区
git checkout -b feature_x
分支创建和切换
git clone https://github.com/username/Demo.git,下载完成后,本地自动创建个master分支,默认远程名origin与origin/master分支。git里的分为本地分支(如master)和远程分支(如origin/master),本地分支的指针可修改,远程分支的指针无法直接修改。如要编辑origin/special分支,先要在本地创建special,简化后的命令为 git checkout -b specail origin/special
git branch -d feature_x
删除分支,如果分支没被合并,则不允许,用D可以强制
git merge <branch>
合并branch分支到当前分支,合并类型有快进(Fast forward)和三点合并。合并信息会有说明。
冲突时,先打开冲突文件,修改好后,再加到暂存中 可用工具git mergetool
看合并后的结果,发现可以继续在C5上修改,然后多次合并。
git rebase <target_branche>
分支的衍合 最终结果与marge一样。期间合并是打补丁过程,补丁有问题,则提示处理,处理好了,可参考 文章一、文章二(介绍冲突的类型,怎么处理rebase文件内冲突)。
git与远程的操作
git remote
当获取fetch时,过程如图
git merge origin/master
git pull 先git fetch后git marge(分支里面理解就是git marge origin/master)
patch
是种代码共享的方案
git标签
git这些基础知识,在用的过程中才能体现出价值,在看Pro git时,介绍了项目里使用分支用,git区别于其它vcs就是有关分支轻易实现。
本次Git进阶,所理解的可归结成一句话(理解可能有错),Git的文件存在三工作区,工作区(里面文件分为追踪与未追踪) 暂存区 HEAD区(HEAD是个指向当前分支的引用,由parent、child前后链接的提交对象构成数据库,Res中有各种分支引用,如master origin/master等,来指向具体的提交对象,而checkout的HEAD指向了一个分支引用)。
##问题答案 这个问题解决方案 git pull,此时内部机制应该是, 首先fetch,即下载链数据库、远程分支引用,这里都发生了变动; 再merge origin/master,由于两边改变了同一文件同一位置,会提醒冲突,要手动编辑后暂存与提交。
git add -u
git commit 编辑注释说明文件,默认说明已包括合并相关信息
git push 推送到远程,同时自动更新本地的origin/master指向
不过现在本地库被我在GUI界面里操作弄乱了,现在解决如下: git push -f
所谓冲突是怎样产生的?
我猜是由一些列算法计算的,从两分支共同提交对象的快照起,到合并时,若发现两分支各个快照相对前共同的快照,在相同文件相同位置都有变动,就提醒冲突。当然,你如果合并编辑,再次add 和 commit时,就会忽视算法提交成功。而在用eclipse的svn插件时,不同开发者同时修改同一文件,就会冲突不能提交,要进入合并编辑。
后续还要继续学习Pro Git ,其中还看过的命令没整合到这篇博文中来;闲暇时也可以翻翻http://rogerdudler.github.io/git-guide/index.zh.html
下一步进阶拓展点 参与一个开源项目 编写一个Demo,比如个税
究其本质深邃才能彻底解决问题,举一反三,可是过一阵子之后,好久没接触了,又要重新理解,这是个问题。