Git学习笔记
Git(本地)仓库实际就是项目文件夹下的.git目录。通常,人们都说添加文件到版本库分两步:先是保存到暂存区,随后的提交(commit)才算真正的保存到版本库。然而事实上,添加到git仓库的文件、目录都被当作对象用其SHA-1值作为文件名保存在.git/objects下,而暂存区(.git/index文件)只是保存了这些文件和文件夹的SHA-1值而已。提交的时候,会生成一个commit对象,新生成的commit对象包含了用暂存区的内容生成的一个tree对象的SHA-1值 、上一个commit对象的SHA-1值以及提交时的其他一些信息。一次一次的提交形成一个链式结构,称为分支(branch)。一开始只有一个默认的master分支(事实上,完成第一次提交后,master分支才真正创建出来),分支可以分叉,也可以合并,master分支或者别的分支其实只是一个指针,指向该分支的最近一次提交。HEAD也是一个指针,指向当前分支。所以,分支对于Git来说是非常轻量的,最主要的是commit对象。
基本的操作如图所示,当然,git的命令远远不止这些,这个图只是简单的表示了文件在不同存储区域的转化过程。其中,好像没有命令把文件从仓库提取到暂存区,其实并不是这样,checkout命令的另一种形式就可以填充暂存区,同时还有其他的命令也可以填充暂存区。况且,暂存区也是仓库的一部分,从仓库的这一部分取出来放到另一部分意义并不大,重要的是工作区里面的文件能够恢复成以前提交的版本。
使用git,理解分支的概念,熟悉分支的操作比较重要。哪怕是一个人使用git,但是如果要从不同的电脑上推送到远程仓库,也可能会不成功。因为git并不是简单的保存文件,而是将历次提交组织成了一条链。如果推送到服务器上的分支内容不能构成一条和本地分支一样的链,推送就不会成功。比如,已经在别的地方修改并推送过。这种情况下就需要将远程分支抓取(push)下来与本地分支合并后再推送。所以至少还要掌握简单的分支操作才能用好git。
以下是常用的git命令及用法:
一、仓库
1.git init [directory]
2.git clone
clone命令会抓取所有远程仓库的内容,包含远程仓库所有分支,自动生成一个叫origin的引用,同时自动生成本地master分支并跟踪远程master分支。可以用git remote show [origin]或git ls-remote [origin]来查看远程仓库包括远程分支的信息。
3.git remote add
添加远程仓库。这个命令实际上仅仅是为远程仓库添加了一个别名而已。
4.git fetch [remote-name]
从远程仓库抓取所有内容,包含远程仓库所有分支,但并不会自动合并任何分支到本地,不会改变工作目录和暂存区内容。
5.git pull [
抓取远程分支内容并合并到当前分支,如果当前分支已经设置有跟踪分支则可以省略
6.git push [
推送内容到远程仓库,省略远程仓库名称,则默认为origin(可配置)。
二、配置
1.git config [–system|–global|–local] user.name “
git config [–system | –global | –local] user.email “ |
配置分为几个级别,默认是本地配置,配置文件以“节.名称”的形式保存变量,user.name、user.email是访问远程仓库所需要的。
三、暂存区
1.git add
2.git rm [-f] [–cached]
3.git commit [–amend]//提交,–amend选项表示修订提交,亦即用这一次提交代替上一次提交,事实上修改了提交历史,如果已经推送到远程,则再次推送会出现问题。如果担心忘记提交,可以多次提交,使用–amend参数可以使多次提交也能保存提交历史很干净,当然,中间的版本是找不回来的,所以这个参数通常只是用来修改提交说明。
四、分支操作
1.git branch
2.git checkout
3.git merge [
merge命令用于将几个提交合并到当前分支HEAD指针上,由于合并时的情况非常复杂,所以这个命令的使用也非常复杂,一般用来合并分支,例如:git merge develope。因为一个分支只不过是一个指向commit对象的指针,所以语法上没毛病。但是,合并时可能会有冲突,git会把冲突标记在源文件里,所以这时冲突的文件就处于modify状态,解决冲突后,将文件add到暂存区,然后运行git merge –continue继续合并,当然,也可以用git merge –abort中止合并。最理想的合并称为快进式合并,也就是待合并分支超前当前分支若干个提交,这种合并只是修改一下指针,恢复一下暂存区而已,不会有冲突发生。同样地,远程分支也只是一个指针,当采用git fetch抓取数据后就需要用git merge origin/branch进行合并,这样分步操作与直接用pull相比的好处就是,如果有冲突的话,可以手工解决冲突后继续合并,而pull则会直接失败。
4.git rebase
变基操作相当于是“录像”然后“回放”,它查找当前分支与目标分支的共同祖先,然后依次记录之后历次提交的变化,然后再目标分支的基础上依次重现,最后当前分支与目标分支将没有分叉,就可以执行快进式合并了。变基相当于改变了提交历史,所以,不应该针对已经推送到远程仓库的分支进行变基,而应该是先变基再推送,因为这样的话,别人就可以很愉快执行快进式合并了。
五、恢复数据
1.git checkout
checkout(检出)可以指定任意提交的指针。用于恢复到指定的版本,包含工作区、暂存区、分支指针以及HEAD指针,也就是所有的一切都恢复到指定的提交时的状态。如果带文件路径参数,那么分支指针、HEAD指针将不变,只是提取文件出来。而git checkout –
2.git reset [
reset用于重置指针。mode主要有三种–soft、–mixed、–hard,–soft只是重置HEAD指针,–hard不但重置HEAD指针,还恢复暂存区和工作区,跟checkout功能差不多,但是checkout会检查是否存在修改的、暂存的文件,要安全得多。而–mixed则处于–soft和–hard的中间,重置HEAD指针和恢复暂存区,但是工作区不受影响,默认参数为–mixed。如果是带文件名的用法,则指针不动,但是会提取文件到暂存区,所以git reset HEAD