集中式与分布式的差别:
集中式的服务器挂了所有人都挂了,因为完整仓库只存在服务器上,分布式如果github挂了你可以重新建一个服务器,然后把任何一个人的仓库clone过去
一句话总结:分布式版本控制的每个节点都是完整仓库
.git
的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。
把文件添加到版本库
首先这里再明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。
不幸的是,Microsoft的Word格式是二进制格式,因此,版本控制系统是没法跟踪Word文件的改动的,前面我们举的例子只是为了演示,如果要真正使用版本控制系统,就要以纯文本方式编写文件。
因为文本是有编码的,比如中文有常用的GBK编码,日文有Shift_JIS编码,如果没有历史遗留问题,强烈建议使用标准的UTF-8编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持。
以下内容复制了廖雪峰的博客:
git status
命令可以让我们时刻掌握仓库当前的状态,上面的命令告诉我们,readme.txt被修改过了,但还没有准备提交的修改。
虽然Git告诉我们readme.txt被修改了,但如果能看看具体修改了什么内容,自然是很好的。比如你休假两周从国外回来,第一天上班时,已经记不清上次怎么修改的readme.txt,所以,需要用git diff
这个命令看看:
1 2 3 4 5 6 7 8 9 10 |
$ git diff readme.txt diff --git a/readme.txt b/readme.txt index <span class="number">46</span>d49bf.<span class="number">.9247</span>db6 <span class="number">100644</span> --- a/readme.txt +++ b/readme.txt <span class="decorator">@@ -1,2 +1,2 @@</span> -Git <span class="keyword">is</span> a version control system. +Git <span class="keyword">is</span> a distributed version control system. Git <span class="keyword">is</span> free software. |
git diff
顾名思义就是查看difference,显示的格式正是Unix通用的diff格式,可以从上面的命令输出看到,我们在第一行添加了一个“distributed”单词。
git diff是工作区和暂存区的比较
1 |
git diff --cached #是暂存区(stage)和分支(master)的比较 |
多次对同一个文件 git add <filename>, 之后的添加会覆盖之前的。(不过git diff 可以查看之前的修改)
问题:我同事经常直接 git reset –hard 后面不跟任何版本号,这个是什么意思?
查看当前HEAD指针指向的版本号,这个查看当前版本号把人坑完了,git reset –hard会回退到你最近提交的版本上,如果你修改了工作区的内容只add了没有commit 那么使用了这个命令之后会回退到你最近一次commit的那个版本,你在工作区的修改就会丢失掉。
暂存区就没有任何内容了
这句话不妥,暂存区不是没有任何内容了,而是暂存区的内容都已经同步到了最近的一次提交,但内容还是存在的。
1 2 |
git diff --cached |
上述命令可以对比暂存区和最近一次提交的不同
在完成一次提交之后执行 git diff –cached 返回的结果是空的,那么说明 a(已提交仓库)和 b (暂存区)是完全一样的,所以暂存区并不为空
Git是跟踪更新的,没有变化时,说是空的也是可以的
把一个文件改其中一行,再重命名,提交,git会识别出修改+重命名这个操作,而不是删文件+新文件这个操作。
- git diff:是查看working tree与index file的差别的。 git diff –cached:是查看index file与commit的差别的。 git diff HEAD:是查看working tree和commit的差别的。(你一定没有忘记,HEAD代表的是最近的一次commit的信息)
撤销修改:
对于文件 myfile.txt
① 修改后 未add(添加到暂存区) 需要撤销修改时:
git checkout — myfile.txt 或 手动删除工作区修改 工作区 : clean 暂存区: clean ② 修改后 add了(未commit) 再次修改文件 要撤销第二次修改时: git checkout — myfile.txt (将暂存区恢复到工作区) 暂存区有第一次的修改需要commit ③ 修改后 add了(未commit),需要撤销修改时: git reset HEAD myfile.txt (将暂存区修改删除) 此时工作区的修改还未撤销 git checkout — myfile.txt (撤销工作区修改) ④ 修改后 add并commit了,需要撤销修改时: git reset –hard HEAD^ (版本回退)**个人感觉是这样的: git checkout –file 就是相当于把当前缓冲区的文件覆盖到工作区 git reset 就是把版本库的文件覆盖到缓冲区
我实在是看不下去了,一会儿暂存区一会儿版本库的,请先分清概念,经过我的实验,提交代码的更改一共分2个阶段。
1).从工作目录,提交到stage。 2).从stage提交到master。
从工作目录提交到stage,需要用add或者rm命令,只提交到stage,而没有提交到master,是不会自动同步到master的。
从stage提交到master用commit命令。
退回也是要分两步,一个是从master退回到stage,然后再从stage退回到工作目录。
对于还没有提交到stage的,可以从stage用checkout命令退回,这一步会取stage中的文件状态,覆盖掉工作目录中文件的状态,跟master完全没关系。
对于已经到达stage的,想把state中的文件状态用master中的覆盖掉,就用reset命令,这样就把stage中修改用master的状态覆盖掉了,完全跟工作目录没关系
Git鼓励大量使用分支:因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master
分支上工作效果是一样的,但过程更安全。
因为git的分支必须指向一个commit,没有任何commit就没有任何分支,提交第一个commit后git自动创建master分支
git diff 比较的是工作区与暂存区的不同
如果两者相同则不出现任何提示
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,
以及指向master的一个指针叫HEAD。
个人认为:当工作区与暂存区及分支都相对干净(commit后,又没对工作区做任何修改)时,暂存区里面存在着与分支里相同的内容,
所以此时git diff filename 不出现任何提示。
我觉得嘛,暂存区就像购物车,没到付款的时候你都不确定购物车里的东西全部都是要的。。。每拿一件商品就付一次款。。。那才麻烦大了
版本回退(回退后前进): 使工作区回到之前某次commit的内容
跟踪修改:每次修改,如果不add到暂存区,那就不会加入到commit中。
撤销修改:总之,就是让这个文件回到最近一次git commit或git add时的状态。
对于文件 myfile.txt
① 修改后 未add(添加到暂存区) 需要撤销修改时:
git checkout — myfile.txt 或 手动删除工作区修改 工作区 : clean 暂存区: clean
② 修改后 add了(未commit) 再次修改文件 要撤销第二次修改时: git checkout — myfile.txt (将暂存区恢复到工作区) 暂存区有第一次的修改需要commit
③ 修改后 add了(未commit),需要撤销修改时: git reset HEAD myfile.txt (将暂存区修改删除) 此时工作区的修改还未撤销 git checkout — myfile.txt (撤销工作区修改)
④ 修改后 add并commit了,需要撤销修改时: git reset –hard HEAD^ (版本回退)**
个人感觉是这样的: git checkout –file 就是相当于把当前缓冲区的文件覆盖到工作区 git reset 就是把版本库的文件覆盖到缓冲区
删除文件:命令git checkout — readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销(重要命令)
git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
PS:命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。
问题:在开始安装了git后是设置了用户名和地址。
$ git config –global user.name “Your Name”
$ git config –global user.email “[email protected]”
这里创建ssh key时又需要用到了邮箱地址。
问题是,这两个的邮箱地址需要一致的吗。
不需要。config设置的只是代码提交者的信息。
分支策略:
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
分支作用:
master 分支是主分支,要时刻与远程同步,一般我们发布最新版本就用master分支
develop 分支是开发分支,团队中所有人都在这个分支上开发,所以也需要与远程同步
bug 分支一般只在本地使用来修复bug,一般不需推送远程仓库中
feature 分支是否需要推送到远程,要看是不是有几个人合作开发新功能,如果你是一个开发,那就留在本地吧
release 分支一般是系统管理,推送或抓取的分支一般与开发人员无关
other 分支大家按需求分配