直接上干货,git的核心3大知识点
'git是现代前端工程化必备的技能,熟读本篇文章,你可以轻松使用git,不懂的在下面留言,我会一一为你解答'
复制代码
1.git的三大区域
1.工作目录(你的index.html等等这些文件存放的文件夹)
2.暂存区 (你可以理解成停留在工作目录和版本中间的一个虚拟空间)
3.版本库(其实就是一个文件夹,在.git隐藏文件夹里的objects文件夹,里面存放了git对象和commit对象以及tree对象)
复制代码
2.git的三种对象类型
1.git对象(通过大量优化和算法压缩储存的文件,每个git对象直接保存了你所让git追踪的那个文件内容,它git中最基本的对象类型)
2.tree对象(每个tree对象只是一串索引,它指向了git对象,git对象才是真正存放文件内容的那个单位,一个tree对象可以指向多个git对象)
3.commit对象(每次使用 git commit -m命令提交生成的那个对象,里面包含了当前提交的暂存区里所有的树对象)
复制代码
3.git 一次完整的提交过程(深入底层命令,最详细的git提交过程)
1.文件未加入git追踪(没有把文件加入到git版本库中)
2.文件已经加入到git版本库中,但是没有给文件对应的git对象开启暂存区的状态
3.文件已经加入到git版本库中,并且给其文件对应的git对象开启了暂存区,给git对象开启暂存区后,使用write tree命令便会生成tree对象,这个tree对象的引用指向那个git对象,这里就很好理解为什么说git性能高,存放文件内容的都是git对象,但是拿去提交的都是树对象,这些树对象频繁的使用,但是他们仅仅是一串数字,指向了最终的基层文件git对象,最终的git对象一直躺在版本库的文件夹中没有动。
4.生成树对象后,提交到版本库,生成commit对象。这句话逼格听起来很高,实质就是将暂存区里所有的树对象打包,生成另外一串数字,塞到一个文件夹(版本库objects文件夹中),这串数字就是commit对象,它指向了这些树对象,这些树对象指向了他们对应的git对象,这样,一个commit对象就保存了你当前提交的所有文件的内容,并且存放在版本库中。
由上到下对应的关系 一个commit对象 => 所有被git追踪并开启暂存区的文件的tree对象 =>这些tree对象对应的git对象(git对象是最基本的对象,存放着文件的实质内容)
复制代码
上面这三大git知识点一定要吃透,然后开始看下面的运行逻辑
开启git第一件事git init -y
我们首先
echo '需要输入的内容' > test.txt , 为文件写入内容,会覆盖操作,没有这个文件则新建
git hash-object -w test.txt
将test.txt加入到git的版本库中,在版本库将生成对应的git对象,这个git对象保存了test.txt文件的全部内容,
但是此时还不保险,他只是对应了当前一个test.txt文件,我们必须保证项目其他文件的完整性,这只是第一步。
在加入到版本库后,我们通过 find .git/objects -type f命令查看版本库中的所有文件,他会返回下面这段代码
83baae61804e65cc73a7201a7252750c76066a30 test.txt
1f7a7a472abf3dd9643fd615f6da379c4acb3e3a demo.txt ....
,我们将为test.txt开启暂存区
我们找到对应的test.txt文件的那串字符,然后使用
git update-index --add --cacheinfo 100644 83baae61804e65cc73a7201a7252750c76066a30 test.txt
(上面这一步是让版本库中的test.txt的git对象,开启暂存区)
然后我们
git write-tree
此时生成树对象 ,这个树对象的内容,我们可以通过 git cat-file -p 命令查看
他会返回一串 *****bf3dd9643fd615f6da*****... test.txt 的git对象
这意味着,这个树对象,指向git对象。
此时我们可以提交了 使用git commit -m '这是我们的第一次提交'
这时候版本库中多了一个commit对象,我们可再次使用find .git/objects -type f命令查看,这时候发现多了两个文件,
一个是test.txt对应的tree对象,一个是刚提交的commit对象,有趣的是,这个commit对象,对应了之前最后一次提交的所有tree对象,这样我们只添加了一个test.txt文件,但是却重新保存了一个版本,这个版本就是commit对象的那串索引,
怎么样,到这里应该领会到了git的厉害之处了吧。,每次git保存的都是一个所有文件完整的版本。
提交后使用 git status 命令,查看当前git的状态 ,每当你有感觉不对的时候,应该使用git status命令,后面我会详细讲解
复制代码
git的高层命令 (实际开发的使用命令)
在git使用中,我们基本不会使用上面的底层命令,上面的底层命令只是为了让我们熟悉git的工作机制,让我们更好的使用git已经封装好的高层命令,出了问题能更好的解决。
1.git status 命令 ---git 最重要的命令
每次我们git init -y 后, 先输入git status 命令查看,如果有红色的字体显示,该文件没有加入到版本库,需要我们添加,如果是绿色的字体显示的文件,那么意味着我们需要提交了,如果没有文件显示,那么万事大吉,我们目前没有需要提交的对象,感觉不对劲,马上使用git status 命令查看当前git状态。
2.git add 文件的url | 文件夹url ---这条命令是将文件从工作目录中找到,然后添加到版本库中生成git对象,并给其开启对应的暂存区
3. git commit -m '此处是你这次提交需要写的注释' 提交命令,生成对应的树对象,并且生成commit对象,保存在版本库文件夹中,一个test.txt文件在版本中对应了三个文件,一个git对象用来保存文件内容,一个tree对象指向这个git对象,一个commit对象指向最新的提交版本的所有tree对象,也包括这个文件的tree对象。
本地的不考虑分支的提交工作已经做完 熟练操作这些命令很有必要,接下来将要学习git的分支操作
复制代码
git的分支操作(最重要的地方)
'这边先说本地的操作'
git的默认的主分支叫master 它的名字可以修改,但是我们不建议修改,这里方法不推荐
这条master分支我们一般认为他上面的代码,都是正式版本的,都是能跑的代码,只要不是确定能跑的代码,那么坚决不上主分支,在其他次分支测试稳定后再跳回到主分支合并那条稳定的次分支,这样做是为了保证主分支的稳定性。
下面,我们默认一开始是在master主分支上
git branch demo1 -- 这条命令可以让我们在当前所在的主分支上创建一个demo1的分支 ,这条新建的demo1分支,他的版本跟当前所在的master主分支的一样,他们通过git获取恢复的工作目录的文件内容都完全一致,相当于克隆了一份代码,拿到demo1这个分支上
使用git status命令查看,如果没有需要提交的对象(每次切换分支都要git status查看状态)
那么我们就使用 git checkout demo1 的命令跳到demo1的分支上,我们可以开始放心的修改我们的文件,一般开发都是一个人负责一个模块,你只要在你所在的这条demo1分支上修改文件,然后每个小阶段commit提交一下,就是安全的,等你的功能写完,跟项目的负责人通报,你的模块已经写完,需要合并,这时候项目负责人会告诉你,没问题,那么你再次使用 git checkout master 命令,切换到master的主分支上,此时切换过去的,肯定是最新的master主分支版本,然后使用git merge demo1命令,合并分支, 再次使用git status查看,此时如果有需要手动修改的冲突,那么手动处理一下,一般一个人负责一个模块是不会出现冲突的。
如果没有,那么万事大吉,一切完成!
'接下来是远程仓库的操作 ,请注意看好这里的每一句话'
依赖于 github
'项目经理创建远程仓库 '
项目经理为远程仓库配置别名
git remote add <shortname> <url>
添加一个新的远程 Git 仓库,同时指定一个你可以轻松引用的简写
git remote –v
显示远程仓库使用的 Git 别名与其对应的 URL
git remote show [remote-name]
查看某一个远程仓库的更多信息
git remote rename pb paul
重命名
git remote rm [remote-name]
如果因为一些原因想要移除一个远程仓库 你已经从服务器上搬走了或不再想使用某一个特定的镜像了,又或者某一个贡献者不再贡献了
项目经理推送本地项目到远程仓库
初始化一个本地仓库然后:
git push [remote-name] [branch-name]
将本地项目的master 分支推送到 origin (别名)服务器
'成员克隆远程仓库到本地'
git clone url (克隆时不需要 git init)
默认克隆时为远程仓库起的别名为origin
'成员推送提交到远程仓库'
git push [remote-name] [branch-name]
只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先将他们的工作拉取下来并将其合并进你的工作后才能推送
'项目经理更新成员提交的内容'
git fetch [remote-name]
这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看
必须注意 git fetch 命令会将数据拉取到你的本地仓库 - 它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。
'仅仅理解上面的,还是不能够在git随意遨游,下面我们来深入理解远程库'
远程跟踪分支是远程分支状态的引用。它们是你不能移动的本地分支。当你做任何网络通信操作时,它们会自动移动。
它们以 (remote)/(branch) 形式命名,例如,如果你想要看你最后一次与远程仓库 origin 通信时 master分支的状态,你可以查看 origin/master 分支
当克隆一个仓库时,它通常会自动地创建一个跟踪 origin/master 的 master 分支
假设你的网络里有一个在 git.ourcompany.com 的 Git 服务器。 如果你从这里克隆,Git 的 clone 命令会为你自动将其命名为 origin,拉取它的所有数据,创建一个指向它的 master 分支的指针,并且在本地将其命名为 origin/master。 Git 也会给你一个与 origin/master 分支在指向同一个地方的本地 master 分支,这样你就有工作的基础
他人推送提交到 git.ourcompany.com 并更新了它的 master 分支,那么你们的提交历史将向不同的方向前进。 只要你不与 origin 服务器连接,你的 origin/master 指针就不会移动
如果要同步你的工作,运行 git fetch origin 命令。 这个命令查找 “origin” 是哪一个服务器(在本例中,它是 git.ourcompany.com),从中抓取本地没有的数据,并且更新本地数据库,移动 origin/master指针指向新的、更新后的位置。
'推送其他分支'
当你想要公开分享一个分支时,需要将其推送到有写入权限的远程仓库上。 本地的分支并不会自动与远程仓库同步 - 你必须显式地推送想要分享的分支。 这样,你就可以把不愿意分享的内容放到私人分支上,而将需要和别人协作的内容推送到公开分支
如果希望和别人一起在名为 serverfix 的分支上工作,你可以像推送第一个分支那样推送它。
git push origin serverfix
这里有些工作被简化了。 Git 自动将 serverfix 分支名字展开为 refs/heads/serverfix:refs/heads/serverfix
你也可以运行 git push origin serverfix:serverfix,它会做同样的事 - 相当于它说,“推送本地的 serverfix 分支,将其作为远程仓库的 serverfix 分支”
git push origin serverfix:awesomebranch
如果并不想让远程仓库上的分支叫做 serverfix,可以运行以上命令将本地的 serverfix 分支推送到远程仓库上的 awesomebranch 分支。
git fetch origin
下一次其他协作者从服务器上抓取数据时,他们会在本地生成一个远程跟踪分支 origin/serverfix,指向服务器的 serverfix 分支的引用。要特别注意的一点是当抓取到新的远程跟踪分支时,本地不会自动生成一份可编辑的副本(拷贝)。 换一句话说,这种情况下,不会有一个新的 serverfix 分支 - 只有一个不可以修改的 origin/serverfix 指针。
git merge origin/serverfix (其他协作者)
可以运行 git merge origin/serverfix 将这些工作合并到当前所在的分支。
如果想要在自己的 serverfix 分支上工作,可以将其建立在远程跟踪分支之上:
git checkout -b serverfix origin/serverfix (其他协作者)
跟踪分支
从一个远程跟踪分支(origin/master)检出一个本地分支会自动创建一个叫做 “跟踪分支”(有时候也叫做 “上游分支” :master)。
只有主分支 或者 克隆时才会自动建跟踪分支.
跟踪分支是与远程分支有直接关系的本地分支。 如果在一个跟踪分支上输入 git pull,Git 能自动地识别去哪个服务器上抓取、合并到哪个分支。
如果你愿意的话可以设置其他的跟踪分支,或者不跟踪 master 分支。
git checkout -b [branch] [remotename]/[branch]
git checkout -b serverfix origin/serverfix
这是一个十分常用的操作所以 Git 提供了 --track 快捷方式
git checkout --track origin/serverfix
如果想要将本地分支与远程分支设置为不同名字
git checkout -b sf origin/serverfix
设置已有的本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的跟踪分支,你可以在任意时间使用 -u 选项运行 git branch 来显式地设置
git branch -u origin/serverfix (--set-upstream-to)
git branch -vv
查看设置的所有跟踪分支
git branch -vv
iss53 7e424c3 [origin/iss53: ahead 2] forgot the brackets
master 1ae2a45 [origin/master] deploying index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
testing 5ea463a trying something new
iss53 分支正在跟踪 origin/iss53 并且 “ahead” 是 2,意味着本地有两个提交还没有推送到服务器上。
master 分支正在跟踪 origin/master 分支并且是最新的。
serverfix 分支正在跟踪 teamone 服务器上的 server-fix-good 分支并且领先 3 落后 1,意味着服务器上有一次提交还没有合并入同时本地有三次提交还没有推送。
testing 分支并没有跟踪任何远程分支。
需要重点注意的一点是这些数字的值来自于你从每个服务器上最后一次抓取的数据。 这个命令并没有连接服务器,它只会告诉你关于本地缓存的服务器数据。 如果想要统计最新的领先与落后数字,需要在运行此命令前抓取所有的远程仓库。 可以像这样做:$ git fetch --all; git branch –vv
'删除远程分支'
git push origin --delete serverfix
复制代码
第二次在网上分享技术贴,非常喜欢掘金这个平台,后面我会再就深入页面层次的性能优化,ES6/7,typeScript,前端面试题,原生javaScript的性能优化等等...写出更多高质量的帖,为开源社区做出贡献!