《Git权威指南》笔记1

2016-09-05 10:38:49来源:oschina作者:v1-alpha人点击


###Git初始化
####初始配 git config
设置用户名和邮箱:
git config --global user.name alpha
git config --global user.email xinlan1964@163.com
在git命令输出中开启颜色显示:
git config --global color.ui true
配置都会保存在INI格式的配置文件里,3个配置级别:
1)git config: 版本库级别.git/config
2)git config --global: 全局配置文件,用户级别 /home/用户/.gitconfig
3)git config --system: 系统级配置文件/etc/gitconfig
配置的命令格式就是:
git config
.
####创建版本库git init
在当前目录创建版本库:git init在当前目录生成版本库,git init path 在path下生成版本库。 这个版本库(仓库repository)就是.git目录。 而版本库所在的目录-->工作区。 git这种把版本库放在工作区根目录下的设计使得所有的版本控制操作都可以在本地完成,并且没有任何用于建立工作区和版本库的跟踪文件目录和原始文件的拷贝更安全。
把工作区的一个文件添加到版本库:`git add file` + `git commit -m 'comment'`
在工作区子目录上执行git命令时,git会在在子目录中依次向上递归查找.git目录,找到的.git目录就是对应的版本库。
####其他相关命令
git grep命令来搜索工作区的文件内容;
git rev-parse --git-dir/--show-toplevel/--show-prefix/--show-cdup:底层的一个命令;
git commit --amend --allow-empty --reset-author:重新修改最新的提交,允许空白提交,并改正作者和提交者的信息;
###Git暂存区
####查看提交日志 git log
git log : commit ID+author+date+comment
git log --stat: 可以看到每次提交的文件更变统计
git log --oneline: 精简输出方式显示日志
git log --graph --raw: 提交跟踪链
git log --decorate:显示的提交id旁显示提交关联的引用
git log -n:显示最近的n条日志
git log -p:显示日志的同时,显示改动
git log --fuller:同时显示作者和提交者
####查看文件状态 git status
git status: 查看文件状态
git status -s :精简格式输出状态。第一列的标记:版本库和暂存区的差异,第二列的标记:暂存区和工作区的差异。
git status命令在扫描工作区改动的时候,先依据.git/index文件中记录的用于跟踪工作区文件的时间戳、长度等信息判断工作区文件是否改变,如果工作区文件的时间戳改变了,说明文件的内容可能被改变了,需要打开文件读取文件内容,与更改前的原始文件相比较判断文件内容是否被改变。如果文件内容没有改变,则将该文件新的时间戳记录到.git/index文件中。
####对比文件 git diff
git diff : 比较工作区和暂存器,默认
git diff :比较工作区和branch
git diff --cached|--staged :比较暂存区和版本库
####理解Git暂存区 stage或index
.git/index就是暂存区,是一个包含文件索引的目录树,每个节点记录了文件名、文件的状态信息(时间戳和文件长度等)、文件索引(文件和对象库中对象实体间的对应)。文件内容没有存储在其中,而是保存在Git对象库.git/objects目录中。
####其他相关命令
git ls-tree -l HEAD:查看版本库中 HEAD 所指的目录树
git ls-files -s: 显示暂存区的目录树
git write-tree:把暂存区的目录树写入git对象库
git clean -fd:清除当前工作区中没有加入版本库的文件和目录
![工作区、暂存器、版本库](http://ww4.sinaimg.cn/mw690/686a355egw1f7ici5zklkj20ll0aut9v.jpg)
![Git版本库结构](http://ww3.sinaimg.cn/large/686a355egw1f7ici6lyv0j20hz0ezjsv.jpg)
###Git对象
Git对象都是保存在.git/objects目录下,每个对象都使用一个SHA1哈希值作为其ID。对象类型有:
1)tree:目录树,id+文件的状态信息(时间戳和文件长度等)+文件索引+文件名
2)commit: 提交,id+tree+parent+author+committer
3)blob:文件内容
4)tag:里程碑,tag名称+tag说明+对应的提交ID+tag创建时间+tag创建人
为什么不适用顺序的数字来表示提交:集中式版版本控制系统因为只有一个集中式的版本库,所以可以很容易地实现依次递增的全局唯一的提交号,想SVN就是如此。GIt作为分布式版本控制系统,开发可以非线性的,每个人都可以通过克隆版本库的方式在不同的本地版本库当中,在本地做的提交可以通过版本库之间的交互而互相分发,如果提交采用本地唯一的数字编号,在提交分发的时候会不可避免地造成冲突。这就要求提交的编号不能仅仅是本地局部有效,而是要“全球统一”。Git的提交通过SHA1哈希值(160bit,40个16进制数)作为提交ID可以做到“全球统一”。
如何访问Git库中的对象:
1)id,使用部分的SHA1哈希值。只写开头的几位哈希值;
2)分支名,使用master代表分支master中的最新提交,也可以用全称refs/heads/master或heads/master, 分支名@{n};表示分支名的前第n次改变时的提交;
3) 使用HEAD代表版本库中最近的一次提交;
4)提交对象^表示:父提交,^后带数字表示第几个父提交(合并提交时);
5)~数字可以表示往前推的第几父提交即祖先提交;
6)提交对象^{tree}:提交所对应的树对象;
7)提交对象:文件路径 :表示某次提交所对应的文件对象;
8):文件路径 :暂存区中的文件对象;
9)tag对象^{commit}:tag所指向的提交对象ID
####其他相关命令
git cat-file -t 哈希值: 查看哈希值表示的对象的类型
git cat-file -p 哈希值: 查看哈希值表示的对象的内容
git cat-file 类型 git对象 : 查看git对象的内容
git rev-parse git对象: 查看git对象对应的ID
###Git重置 git reset
git reset主要用于修改引用的游标指向。
git reset没有提供参数用于 指定 要重置的分支名。 重置命令实际上重置 HEAD所指向的引用的游标指向。
git reset体现 分支游标的变更。 一般主要用于重置暂存区
第一种用法:
git reset 提交对象 -- 某个文件: 包含路径。 提交对象下的某个文件 替换 暂存区中的文件,即替换暂存区目录树中的某个节点。 没有指定提交对象默认是HEAD。 工作区和HEAD不受影响。
第二种用法:
git reset --hard 提交对象:会做3个步骤:提交对象默认不写是HEAD
1)把 当前引用 重置到 提交对象 上;
2)替换暂存区,暂存区的目录树被重写,会被提交对象指向的目录树所替换;
3)替换工作区,工作区的文件也被替换后的暂存区中文件替换。
--soft: 只执行步骤1);
--mixed或不用参数:执行步骤1),2);####用reflog挽救错误的重置
.git/logs目录下的日志文件记录了分支的变更,这个日志开关由core.logallrefupdates控制。
git提供了一个git reflog命令,对这个文件进行操作:
git reflog show 分支名:显示分支日志文件内容###Git检出 git checkout
HEAD:可以理解为“头指针”,是当前工作区的“基础版本”,当执行提交时,HEAD指向的提交会做为新提交的父提交。
分离头指针:HEAD头指针指向一个具体的提交ID,而不是一个引用(分支)。
git checkout 修改HEAD本身的指向,覆盖工作区。默认使用暂存区覆盖。
第一种用法:
git checkout [-q] [commit] [--] 文件
commit是可选项,如果省略则相当于从暂存区进行检出。从commit的目录树替换暂存区和工作区的文件
第二种用法:
git checkout 分支
改变HEAD指针,把HEAD切换到分支。3个步骤:1)更新HEAD指向branch分支,2)用分支指向的目录树替换暂存区的目录树,3)用替换后的暂存区所指的文件替换工作区的文件。
第三种用法:
git checkout [-m] [[-b|--orphan] 新分支] [start_point]
创建和切换到新的分支,新的分支从start_point指定的提交开始创建。
###恢复进度 git stash
git stash list:查看保存的进度;
git stash:保存当前的工作进度。会分别对暂存区和工作区的状态进行保存;
git stash [-k|--keep-index]:在保存进度后不会将暂存区重置,默认会将暂存区和工作区强制重置。
git stash pop:[--index] [stash]:不使用任何参数,会恢复最新的保存的工作进度,并将恢复的工作进度从存储的工作进度列表中清除。如果提供stash参数,则从stash中恢复,恢复完毕后将从进度列表中删除stash。选项--index表示除恢复工作区外的文件,还尝试恢复暂存区。
git stash apply [--index][stash]:不删除恢复的进度的git stash pop;
git stash drop [stash]:删除一个存储的进度。默认删除最新的进度;
git stash clear:删除所有存储的进度;
git stash branch 分支名 stash:基于进度创建分支;git stash保存进度,实际上会将进度保存在引用refs/stash所指向的提交中。多次的进度保存,实际上相当于引用refs/stash一次又一次的变化,而resf/stash引用的变化由reflog(即.git/logs/refs/stash)所记录下来。
git stash使用2个提交,分别保存暂存区的进度和工作区的进度,最后合并这2个提交。
####其他相关命令
git --exec-path:查看git-cmd的命令安装目录,git命令很多都是用shell和perl开发,而一些运行效率要求高的命令则用c语言改写。执行git命令时,实际上是调用了对应的脚本文件实现相关功能。
git clean -nd: 查看工作区的哪些没有被跟踪的文件将被删除
git clean -fd: 强制删除多余的目录和文件
###Git基本操作
git describe:将最新提交显示为一个易记的名称。显示的时候会选取该提交最近的里程碑作为“基基础版本号”,后面附加标识距离“基础版本”的数字,以及该提交的SHA1哈希值缩写。 可以把git describe输出结果作为软件版本号。
git rm 文件:删除暂存区和工作区里的文件
git add -u:将工作区中(被版本库跟踪的)文件的变更(修改、删除)全部记录到暂存区中;
git add -A:将工作区中所有改动及新增文件天骄到暂存区;
git mv 文件名:移动文件。相当于对旧文件执行删除,对新文件执行添加=git rm + git add。2种方式的结果都会显示文件改名和改名前后2个文件的相似度。
git add -i:进入一个交互式界面,执行git操作命令
git add命令执行时,暂存区的目录树将被更新,同时工作区的修改(或新增)的文件内容会被写入对象库的一个新的对象中,而该对象ID被记录在暂存区的文件索引中。
git commit命令执行时,暂存区的目录树会写到版本库(对象库)中,当前引用分支游标会做相应的更新,即其最新指向的目录树就是提交时原暂存区的目录树。
git commit --amend -m "xxx": 修补式提交
git archive:文件归档,可以对任意提交对应的目录树建立归档,不用担心使用普通压缩工具会把.git目录,忽略的文件、临时文件都包含进来。
####文件忽略
git提供了忽略功能,当对工作区某个目录或某个文件设置了忽略后,再执行git status查看状态时,被忽略的文件即使存在也不会显示为未跟踪状态,甚至根本感觉不到这些文件的存在。
1)在.gitignore文件里加入不需要版本跟踪的文件名,可以是通配符;
2)可以使用git add -f 来强制 添加已被忽略的文件;
3) .gitignore可以放在任何目录中;
4)忽略之队未跟踪的文件有效,对于已加入版本库的文件无效;
5)文件.gitignore设置的文件忽略是共享式的(在所有的版本库中都生效)。针对具体版本库的“独享式”忽略可以在.git/info/exclude来设置文件忽略。 全局的独享式忽略可以通过配置core.excludesfile指定.gitignore文件
git忽略语法
1)忽略文件中的空行或以#开始的行会被忽略;
2)通配符,语法同linux;
3)如果文件名最前面是一个路径风格符,表示要狐狸的文件在此目录下,而非子目录的文件;
4)如果文件名最后一个是陆军分隔符,表示忽略的是整个目录,但同名文件不忽略,否则同名的文件和目录都忽略;
5)通过在文件名最前添加一个!,表示不忽略;
###改变历史
背景:在提交a,b,c,d,e,f中d是有问题的提交,f是当前的提交。要去掉提交d。
第一种方法:直接抛弃d,将e和f直接嫁接到c上;
第二种方法:把d和c合并,然后e和f嫁接到cd上;
先给提交进行标记
git tag f
git tag e HEAD^
git tag d HEAD^^
git tag c HEAD^^^
git tag b HEAD~4
git tag a HEAD~5
####拣选操作 git cherry-pick
git cherry-pick:从众多的提交中挑选出一个提交应用在当前的工作分支上,该命令需要提供一个提交ID作为参数,操作过程相当于将该提交导出为补丁文件,然后在当前HEAD上重放,形成无论内容还是提交说明都一致的提交。第一种方法:直接抛弃d,将e和f直接嫁接到c上:
git checkout c
git cherry-pick master^
git cherry-picker master
git checkout master
git reset --hard HEAD@{1}
第二种方法:把d和c合并,然后e和f嫁接到cd上:
git checkout d
git reset --soft HEAD^^
git commit -C c
git cherry-pick e
git cherry-pick f
git checkout master
git reset --hard HEAD@{1}
####变基操作 git rebase
git rebase是对提交执行变基操作,即可以实现将将指定范围的提交“嫁接”到另外一个提交上。
git rebase --onto
变基操作过程:
1)**执行git checkout切换到till**: 因为会切换到till,因此如果till指向的不是一个分支,则变基操作时在detached HEAD(分离头指针)状态下进行的,当变基结束后,还要对master分支执行重置以实现变基结果在分支中生效。
2)**将since..till所标识的提交范围写到一个临时文件中** :(since,till]范围的提交形成版本范围。
3)将当前分支强制重置git reset --hard 到newbase;
4)从保存在临时文件中的提交列表中,将提交逐一按顺序重新提交到重置后的分支上;
5)如果遇到提交已经在分支中包含,则跳过该提交;
6)如果在提交过程遇到冲突,则变基过程暂停。用户解决冲突后,执行git rebase --continue继续变基操作。或者执行git rebase --skip跳过此提交。或者执行git rebase --abort就此终止变基操作切换到变基之前的分支上。
第一种方法: 直接抛弃d,将e和f直接嫁接到c上:
git rebase --onto c e^ f
git checkout maset
git reset --hard HEAD@{1}
第二种方法:把d和c合并,然后e和f嫁接到cd上:
git checkout d
git reset --soft HEAD^^
git commit -C c
git tag newbase
git rebase --onto newbase e^ master
git tag -d newbase
####交互式变基
git rebase -i newbase: 会将since..till的提交罗列在一个文件中,然后自动打开一个编辑器来编辑这个文件。通过修改文件的内容设定变基操作,实现删除提交、将多个提交压缩为一个提交、更改提交的顺序,以及更改历史提交的提交说明等。
####丢弃历史
如果希望把tag A之前的历史提交全部清除,可以这样操作:基于tag A对应的提交构造一个根提交(即没有父提交的提交),然后载将mater分支的tag A之后的提交变基到新的根提交上,实现对历史提交的清除。
从tag A对应的提交构造出一个根提交至少有2种方法:
1)git commit-tree A^{tree}
2) git cat-file commit A^0|sed -e '/^parent/ d' >tmpfile ; git hash-object -t commit -w -- tmpfile
####反转提交 git revert
git revert重新做一次新的提交,相当于用错误的历史提交的反向提交,来修正错误的历史提交。

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台