Git(一)
一、Git和Svn的对比
Git
是分布式版本控制系统,而SVN
是集中式版本控制系统,那么两者有什么区别呢?
先说集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。
集中式版本控制系统最大的毛病就是必须联网才能工作。
分布式版本控制系统没有"中央服务器",每个人的电脑都是一个完整的版本库,这样就不用联网才能工作,既然每个人的电脑上都有一个完整的版本库,那么多人是如何协作的呢?双方只需要将自己的修改push
给对方即可。和集中式版本控制系统相比,分布式版本控制系统的安全性更高,因为每个人的电脑都有自己的版本库,一个人的电脑坏了,从其他人复制过来即可。而集中式版本控制系统的中央服务器若是挂了,则所有人都不可以工作了。
而在实际使用分布式版本控制系统的时候,通常也需要一台"中央服务器"的电脑,这个服务器的作用仅仅是用来方便"交换"大家的修改。
当然,Git
的优势不单是不必联网这么简单,Git
强大的分支管理将SVN
远远甩开。不过,现在依旧还是很多公司在使用SVN
,但是技术的不断更新是不可避免的。
二、Git的使用
1.创建版本库
什么是版本库呢?版本库又名仓库(repository),可以理解成一个目录,这个目录里面的所有文件都可以被Git
管理起来,每个文件的修改、删除,Git
都能追踪,以便任何时刻都可以追踪历史,或者在将来的某个时刻可以"还原"。
创建一个空目录:$ mkdir learn
进入该目录:$ cd learn
初始化版本库:$ git init
创建并编辑文件:$ vim readme.md
git is the best version control soft
添加到暂存区:$ git add readme.md
提交到本地库:$ git add -m "first commit" readme.md
第一次提commit
可能会报fatal: unable to auto-detect email address
,需要执行以下命令添加全局属性:
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
2.工作区和暂存区
当前我们能看到的目录learn
就是工作区。
工作去有一个隐藏目录.git
,这个就是Git
的版本库,Git
的版本库存了很多的东西,其中最重要的就是称为stage
(或者叫index
)的暂存区,还有Git
为我们自动创建的第一个分支master
,以及指向master
的一个指针叫HEAD
。
git add
命令实际上就是把要提交的所有修改放到暂存区(Stage
),然后,执行git commit
就可以一次性把暂存区的所有修改提交到分支。
3.版本回退
提交成功后,我们使用git status
命令查看工作区的状态:
$ git status
On branch master
nothing to commit, working tree clean
修改readme.md
后,再次使用git status
查看状态:此时会提示我们有未提交的文件readme.md
,Git
有着丰富的提示功能来引导我们去执行下一步。
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: readme.md
使用git diff
可以查看和已提交的文件的差异:这里提示我们有添加新的一行i want to use git rather than svn
。
$ git diff readme.md
warning: LF will be replaced by CRLF in readme.md.
The file will have its original line endings in your working directory
diff --git a/readme.md b/readme.md
index 62b4535..61ff15d 100644
--- a/readme.md
+++ b/readme.md
@@ -1 +1,2 @@
git is the best version control soft
+i want to use git rather than svn
commit
后该文件,我们可以使用git log
查看每次修改的基本信息:
$ git log
commit 91a1989071919b0d52e1b77c6f8f397f01d6a2ca (HEAD -> master)
Author: hucheng <hucheng@gmail.com>
Date: Sat Nov 2 14:48:13 2019 +0800
second commit
commit d7ee8048dc525a2dfa3be193a1f5485b8206d2c4
Author: hucheng <hucheng@gmail.com>
Date: Sat Nov 2 12:15:09 2019 +0800
first commit
使用git log --pretty=oneline
可以获取更简洁的信息:
$ git log --pretty=oneline
91a1989071919b0d52e1b77c6f8f397f01d6a2ca (HEAD -> master) second commit
d7ee8048dc525a2dfa3be193a1f5485b8206d2c4 first commit
我们可以看到91a...
是版本号(commitId
) ,这个数字是经过sha1算出来的,每提交一个版本会生成一个commitId
,Git
会将所有的commitId
依次自动串成一条时间线。当前的版本为91a...
,我们可以使用git reset --hard commit_id
跳转到指定的版本:
$ git reset --hard d7ee8048dc525a2dfa3be193a1f5485b8206d2c4
HEAD is now at d7ee804 first commit
如果要重返未来,我们可以使用git reflog
查看未来的历史版本的commitId
:
$ git reflog
d7ee804 (HEAD -> master) HEAD@{0}: reset: moving to d7ee8048dc525a2dfa3be193a1f5485b8206d2c4
91a1989 HEAD@{1}: commit: second commit
d7ee804 (HEAD -> master) HEAD@{2}: commit (initial): first commit
4.撤销修改
命令git checkout -- readme.txt
意思就是,把readme.txt
文件在工作区的修改全部撤销,这里有两种情况:
①readme.txt
自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
②readme.txt
已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,使用git checkout -- file
这种方式只能撤回到添加到暂存区之前。如果添加到暂存区后,只能使用git reset
版本回退,如果已经push
到远程仓库,那么不能撤回了,只能修改后再push
。
5.删除文件
添加一个新的文件test.txt
,并提交到工作区。使用rm test.txt
删除后,使用git status
发现出问题了。使用git restore test.txt
命令可以撤销删除。
若是要删除文件,使用git rm text.txt
,然后git commit -m "msg"
这样才能正确的删除。
6.远程仓库
公司中常常会自己搭建Gitlab
作为远程的代码托管中心,个人用户使用GitHub
就足够了。注册GitHub
后,因为本地仓库和GitHub
仓库的传输是经过SSH
加密的,我们需要生成rsa公钥和私钥并将公钥给GitHub
。
Window下Git Bash
输入命令:ssh-keygen -t rsa -C "youremail@example.com"
,会在用户目录下的.ssh
文件夹下生成公钥和私钥,点GitHub
头像->Setting
->SSH AND GPG keys
->New SSH KEY
,将公钥id_rsa.pub
添加到其中。
添加远程库:点GitHub
头像->Your repositories
->New
输入信息后点击create repository
即创建了GitHub
远程仓库,在创建了GitHub
仓库后,它提示我们无本地库和有本地库的做法。
这里我们这里已经存在本地库了,我们使用git remote add origin https://github.com/hucheng1997/learn.git
将本地库和远程库关联起来,,然后使用git push -u origin master
第一次推送master
的所有内容,以后我们只需要使用git push origin master
推送修改即可。注:第一次push
可能需要登陆GitHub
账号。
分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在,也就是有没有联网都可以正常工作,而SVN在没有联网的时候是拒绝干活的!当有网络的时候,再把本地提交推送一下就完成了同步。
克隆远程库:执行git clonehttps://github.com/hucheng1997/learn.git
即克隆了远程库。实际上,Git支持多种协议,默认的git://
使用ssh,但也可以使用https
等其他协议。
使用https
除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh
协议而只能用https
。