用Git进行版本控制

上传人:艾力 文档编号:36578188 上传时间:2018-03-30 格式:PDF 页数:73 大小:677.33KB
返回 下载 相关 举报
用Git进行版本控制_第1页
第1页 / 共73页
用Git进行版本控制_第2页
第2页 / 共73页
用Git进行版本控制_第3页
第3页 / 共73页
用Git进行版本控制_第4页
第4页 / 共73页
用Git进行版本控制_第5页
第5页 / 共73页
点击查看更多>>
资源描述

《用Git进行版本控制》由会员分享,可在线阅读,更多相关《用Git进行版本控制(73页珍藏版)》请在金锄头文库上搜索。

1、 用 Git 进行版本控制李博杰 20120520 版本控制的史前时代用存储介质拷贝代码代码相互覆盖,不知道哪个版本是正确的搞错了无法恢复,需要定期手工备份diff echo n git catfile p HEAD | wc c; printf “000“; git catfile p HEAD) | sha1sumGit object hash (contd)文件内容blob对象git revparse HEAD:Makefile(echo n “blob “; echo n git catfile p HEAD:Makefile | wc c; printf “000“; git cat

2、file p HEAD:Makefile) | sha1sumtree对象git catfile p HEADtree不等于git catfile tree HEADtreegit revparse HEADtree(echo n “tree “; echo n git catfile tree HEADtree | wc c; printf “000“; git catfile tree HEADtree) | sha1sumGit object hash (contd)如果提交采用顺序编号,在分布式版本控制系统 中无法做到不同人的提交编号不同Git通过SHA1密码学意义上的无重复特性使得不

3、 同内容、不同时间、不同作者的提交“全球唯一”每个对象的ID与对象类型、长度、内容关联一个提交的ID与其父提交关联,使得修改历史会 产生连锁效应,谁也不能篡改历史Hash collision160位的SHA1 hash冲突的概率微乎其微,因而Git 并没有考虑hash冲突的问题Linus在Git邮件列表中回应此问题时说:在commit时,git如果发现待添加的新对象SHA1 值已经存在,则会认为这个对象已经存在,因而 引起冲突的新文件不会被保存。用户执行checkout时才会发现得到的文件与所期望的不同。Hash collision因此,即使恶意者提交了引起冲突的文件,也不 会改变历史。(构造

4、SHA1冲突是很难的!)如果真的在很偶然的情况下发生了冲突,则只要 修改待添加的文件(如加个空行)即可避开。如果提前获知一个patch,并构造冲突包抢先发 给Linus,则能让真正的patch被“虚假”提交进去例如 commit message 在显示时被认为是 0 结尾 的,因此可以用 hashobject 手工制作 commit 对象,在 0 后面藏一些好玩的东西访问对象的方法“ 基址”在不引起冲突的情况下,只要把 SHA1 hash 值 的前几位写出即可master = refs/heads/master = heads/masterHEAD“ 偏移”HEAD, HEAD, HEAD :

5、父提交HEAD2 :第二个父提交(有多个父提交时用)HEAD5 :祖先提交访问对象的方法内容树对象: HEADtree文件对象: HEAD:Makefile暂存区中的文件对象: :Makefile命令git show :查看提交或对象的详细信息git revparse :查询对象 IDgit catfile :查看对象内容和类型研究 Git 常用命令Git catfileGit revparseGit showGit lstreeGit lsfilesGit hashobjectGit revlist分支游标cat .git/refs/heads/masterEcho “Hello World

6、” READMEGit commit a m “Does master follow this new commit?”cat .git/refs/heads/masterrefs/heads/master就像一个游标,总是指向master (主分支)上“最新”的提交。refs/tags/tagxxx 指向 tag xxx (里程碑)refs/heads/branchxxx 指向 branch xxx (分支)git reset有了游标,我们就可以在git历史中任意穿梭了1. 将 HEAD 游标指向新的提交 ID2. 用游标所指向的提交替换暂存区3. 用暂存区替换工作区git resetgit

7、 reset soft (1)git reset hard (1,2,3) 危险!git reset (1,2)git reset mixed (1,2)git reset (contd)不指定commit,默认为HEADgit reset:丢弃已暂存的更改git reset hard丢弃工作区和已暂存的更改(危险)git reset filename:git add的反向操作git commit amend = git reset soft HEAD + git commit e F.git/COMMIT_EDITMSG 保存了上次的提交说明git reset hard HEAD:丢弃最近一

8、次提交及此后的 更改(危险)最后一道防线: git reflog上张slides中带hard的都被标为“危险”,因为工 作区没有备份,一旦覆盖永久丢失;那么版本库 中被reset丢弃的提交还能找回来吗?.git/logs/HEAD, .git/logs/refs/heads/master游标的更改是有历史记录的,因此这些被“丢弃” 的提交事实上记录在册不过不能高枕无忧,默认 90 天过期,过期后的 更改记录会被清理掉git reflog:查看游标历史最后一道防线: git reflog (contd)访问对象的方法又多了一种:HEADn : HEAD 游标的第 n 次变化mastern : m

9、aster 分支游标的第 n 次变化HEAD0 就是刚刚进行的操作git reset HEAD1 就能把刚刚被 reset 的提交 找回来啦利用git reset对分支游标和工作区的强大控制能 力,我们可以在历史中自由穿梭,甚至改变历史破坏 git 的防线不小心commit了一个大文件,无论如何reset hard 版本库也不会变小只要被引用,对象就会一直保留直接删除对应的 object ,版本库的一致性被破坏git fsck noreflog : dangling 的对象就是没有 被引用的对象,随时可能被清理掉git reflog expire expire=now allgit fsckg

10、it pruneGit checkoutgit reset虽然强大,但针对的都是HEAD,而HEAD 指向的是refs/heads/master,这就意味着只能修改 当前分支。那么HEAD本身该如何修改呢?git checkout 将某个特定的提交检出:更新 HEAD 指向,用此提交更新暂存区和工作区危险,暂存区和工作区的未提交改动会被覆盖git checkout 不更新 HEAD ,只覆盖 指定路径的文件git checkout (contd)You are in detached HEAD state?分离头指针,就是HEAD头指针指向了一个具体 的提交,如果再次执行checkout,就会

11、覆盖掉这 个HEAD,从而丢失这一串提交。事实上可以通过 reflog 这个神器找回来推荐的方式是创建新的分支:git checkout b new_branch_name 省略 commit ,则默认为 HEADGit stash如果有一些未提交的改动,现在希望参考一下原 来的版本,怎么办?git stash可以保存当前进度,把工作区和暂存区尚 未提交的改动照个快照保存起来,然后reset hardgit stash list查看保存的进度列表(栈)又一种访问对象的方法: stashngit stash pop把栈顶的进度“出栈”git stash apply应用栈顶的进度,但不出栈git

12、stash 原理stash之后,发现多了个refs/stash,内有提交ID一个提交如何同时表示工作区和暂存区?顺藤摸瓜,发现一个commit,它有两个parentgit catfile 不要这么快就忘了哦 这是一个合并提交,内容为工作区进度 ( Work In Progress, WIP )一个 parent 是原来的 HEAD另一个 parent 是暂存区进度(它的 parent 是原 来的 HEAD )git checkout (contd)git checkout 用暂存区覆盖工作区git checkout 切换到已有分支:更新 HEAD 指向 refs/heads/branch ,用

13、分支的最新提交覆盖暂 存区和工作区git checkout b 从 创建新分支,覆盖暂存区和工作区git checkout之前忘记git stash,欲哭无泪git 中的时光穿梭机如果说git log是版本库历史的一张平面图,那么git图形工具就是一张全息图,能更直观地展示各 提交间的相互关系。gitk (原生)qgit ( QT )gitg ( GTK+ )在命令行下,git log graph也可以显示提交关系查看指定范围的历史git log中不仅可以指定一个提交,还可以指定提交 范围。git log oneline A:A的所有历史提交(一棵树)git log oneline D F:两

14、棵树的并集git log oneline G D:是取反,即不包括树Ggit log oneline G.D:与上面相同git log oneline D.G:与上面不同查看指定范围的历史 (contd)git log oneline B.C:两个版本能够共同访问到的除 外= B C not $(git mergebase all B C)git log oneline B:不包括自身的历史提交git log oneline B!:只包括自身,不包括历史提交使用git revlist可列出匹配的提交ID定制 git log 的输出git log 3:显示最近的3条日志git log p:显示日

15、志时同时显示GNU diff样式改动如: git log p 1 headgit log stat:显示日志时同时显示diffstat改动摘要git log pretty=raw:显示commit的原始数据git log pretty=fuller:同时显示Author和Committergit show:显示单个提交git diffgit diff B A:比较两个commit或taggit diff A:比较工作区和Agit diff cached A:比较暂存区和Agit diff:比较工作区和暂存区git diff cached:比较暂存区和HEADgit diff HEAD:比较工作区和HEAD git blame查看这个文件的每行最早是在什么版本、由谁引 入的,以便定位引起bug的版本和开发者git blame 只查看某几行:(6,10中间不能有空格)git blame L 6,10 READMEgit blame

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号