1. Git简介
1.1. 什么是Git
Git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。也是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。
1.2. 什么是版本控制
版本控制最主要的功能就是追踪文件的变更。它将什么时候、什么人更改了文件的什么内容等信息忠实地了记录下来。每一次文件的改变,文件的版本号都将增加。除了记录版本变更外,版本控制的另一个重要功能是并行开发。软件开发往往是多人协同作业,版本控制可以有效地解决版本的同步以及不同开发者之间的开发通信问题,提高协同开发的效率。并行开发中最常见的不同版本软件的错误(Bug)修正问题也可以通过版本控制中分支与合并的方法有效地解决。
版本控制是软件配置管理的核心功能。所有置于配置库中的元素都应自动予以版本的标识,并保证版本命名的唯一性。版本在生成过程中,自动依照设定的使用模型自动分支、演进。除了系统自动记录的版本信息以外,为了配合软件开发流程的各个阶段。还需要定义、收集一些元数据来记录版本的辅助信息和规范开发流程,并为今后对软件过程的度量做好准备。当然如果选用的工具支持,这些辅助数据将能直接统计出过程数据,从而方便软件过程改进活动的进行。对于配置库中的各个基线控制项,应该根据其基线的位置和状态来设置相应的访问权限。一般来说,对于基线版本之前的各个版本都应处于被锁定的状态,如需要对它们进行变更,则应按照变更控制的流程来进行操作。
版本控制包括:检入检出控制、分支和合并、历史记录。
- 检入检出控制
软件开发人员对源文件的修改不能在软件配置管理库中进行,对源文件的修改依赖于基本的文件系统并在各自的工作空间下进行。为了方便软件开发,需要不同的软件开发人员组织各自的工作空间。一般说来,不同的工作空间由不同的目录表示,而对工作空间的访问,由文件系统提供的文件访问权限加以控制。
访问控制需要管理各个人员存取或修改一个特定软件配置对象的权限。开发人员能够从库中取出对应项目的配置项进行修改,并检入到软件配置库中,对版本进行“升级”;配置管理人员可以确定多余配置项并删除。
同步控制的实质是版本的检入检出控制。检入就是把软件配置项从用户的工作环境存入到软件配置库的过程,检出就是把软件配置项从软件配置库中取出的过程。检人是检出的逆过程。同步控制可用来确保由不同的人并发执行的修改不会产生混乱。 - 分支和合并
版本分支(以一个已有分支的特定版本为起点,但是独立发展的版本序列)的人工方法就是从主版本——称为主干上拷贝一份,并做上标记。在实行了版本控制后,版本的分支也是一份拷贝,这时的拷贝过程和标记动作由版本控制系统完成。版本合并(来自不同分支的两个版本合并为其中一个分支的新版本)有两种途径,一是将版本A的内容附加到版本B中;另一种是合并版本A和版本B的内容,形成新的版本C。 - 历史记录
版本的历史记录有助于对软件配置项进行审核,有助于追踪问题的来源。历史记录包括版本号、版本修改时间、版本修改者、版本修改描述等最基本的内容,还可以有其他一些辅助性内容,比如版本的文件大小和读写属性。
1.3. 常见的版本控制工具
- GIT
- SVN (CollabNet Subversion):Google
- VSS (Visual Source Safe):微软
- CVS (Concurrent Versions System):开源
1.4. Git的起源
很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了。
Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那Linux的代码是如何管理的呢?,
事实是,在2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码!
你也许会想,为什么Linus不把Linux代码放到版本控制系统里呢?不是有CVS、SVN这些免费的版本控制系统吗?因为Linus坚定地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。
不过,到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。
安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议,被BitMover公司发现了,于是BitMover公司怒了,要收回Linux社区的免费使用权。
Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!
Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。
1.5. 集中式版本控制与分布式版本控制
集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。
集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟。
那分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。
在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
2. Git的使用
2.1. Git的安装
2.1.1. 下载
官网下载:
https://git-scm.com/downloads
或在国内镜像网站下载:
https://registry.npmmirror.com/binary.html?path=git-for-windows/
2.1.2. 安装
根据安装程序提示完成安装。
安装完成后在文件夹中点击鼠标右键
出现图上选项即表示安装成功。
2.1.3. 配置
点击Git Bash Here选项,弹出命令框,在命令行输入
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
$ git config --global --get user.name #查看user.name
$ git config --global --get user.email #查看user.email
$ git config --global -l #列表参数
2.2. 创建数据库
版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
#在/d/GitBash下创建文件夹learngit文件夹
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash
$ mkdir learngit
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash
$ cd learngit/
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit
$ pwd
/d/GitBash/learngit
#通过 git init 命令把这个目录变成Git可以管理的仓库
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit
$ git init
Initialized empty Git repository in D:/GitBash/learngit/.git/ #.git目录是Git来跟踪管理版本库的
2.3. 添加文件到版本库
现在我们编写一个 readme.txt 文件,内容如下:
Git is a version control system.
Git is free software.
把一个文件放到Git仓库只需要两步:
(1)用命令 git add 告诉Git,把文件添加到仓库
(2)用命令 git commit 告诉Git,把文件提交到仓库
- git commit 命令, -m 后面输入的是本次提交的说明,可以输入任意内容,当然最好
是有意义的,这样就能从历史记录里方便地找到改动记录。
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ vim readme.txt
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ cat readme.txt
Git is a version control system.
Git is free software.
#git add把文件添加到仓库
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git add readme.txt
warning: in the working copy of 'readme.txt', LF will be replaced by CRLF the next time Git touches it
#git commit把文件提交到仓库
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git commit -m "wrote a readme file"
[master (root-commit) 9a1ae89] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
#git log查看日志
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git log
commit 9a1ae89cfd737cccb74ee8642ea79fe194288981 (HEAD -> master)
Author: yuyang <2755469212@qq.com>
Date: Tue Jul 11 10:24:41 2023 +0800
wrote a readme file
commit 可以一次提交很多文件,所以可以多次 add 不同的文件
#创建file1.txt file2.txt file3.txt
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ touch file1.txt file2.txt file3.txt
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ ll
total 1
-rw-r--r-- 1 Administrator 197121 0 Jul 11 13:53 file1.txt
-rw-r--r-- 1 Administrator 197121 0 Jul 11 13:54 file2.txt
-rw-r--r-- 1 Administrator 197121 0 Jul 11 13:54 file3.txt
-rw-r--r-- 1 Administrator 197121 92 Jul 11 10:52 readme.txt
#把文件添加到仓库
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git add file1.txt file2.txt file3.txt
#查看git状态
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: file1.txt
new file: file2.txt
new file: file3.txt
#把文件提交到仓库
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git commit -m "add 3 files"
[master 87cc81e] add 3 files
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file1.txt
create mode 100644 file2.txt
create mode 100644 file3.txt
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git status
On branch master
nothing to commit, working tree clean
2.4. 更新版本
修改readme.txt文件,改成如下内容:
Git is a distributed version control system.
Git is free software.
#修改readme.txt文件
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ vim readme.txt
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ cat readme.txt
Git is a distributed version control system.
Git is free software.
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ 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.txt
no changes added to commit (use "git add" and/or "git commit -a")
#通过git diff来查看修改前后readme.txt的不同
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git diff readme.txt
warning: in the working copy of 'readme.txt', LF will be replaced by CRLF the next time Git touches it
diff --git a/readme.txt b/readme.txt
index 46d49bf..9247db6 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
Git is free software.
##把文件添加到仓库
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git add readme.txt
warning: in the working copy of 'readme.txt', LF will be replaced by CRLF the next time Git touches it
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: readme.txt
##把文件提交到仓库
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git commit -m "add distributed"
[master c53adb7] add distributed
1 file changed, 1 insertion(+), 1 deletion(-)
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git status
On branch master
nothing to commit, working tree clean
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git log
commit c53adb7fc9b1c119b6471c31545b28cffcfa8211 (HEAD -> master)
Author: yuyang <2755469212@qq.com>
Date: Tue Jul 11 10:33:33 2023 +0800
add distributed
commit 9a1ae89cfd737cccb74ee8642ea79fe194288981
Author: yuyang <2755469212@qq.com>
Date: Tue Jul 11 10:24:41 2023 +0800
wrote a readme file
更新第三个版本
修改readme.txt文件如下:
Git is a distributed version control system.
Git is free software distributed under the GPL.
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ vim readme.txt
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git add readme.txt
warning: in the working copy of 'readme.txt', LF will be replaced by CRLF the next time Git touches it
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git commit -m "append GPL"
[master 1851f87] append GPL
1 file changed, 1 insertion(+), 1 deletion(-)
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git log
commit 1851f871a9c2172ad51174c6124ff605237b158b (HEAD -> master)
Author: yuyang <2755469212@qq.com>
Date: Tue Jul 11 10:52:56 2023 +0800
append GPL
commit c53adb7fc9b1c119b6471c31545b28cffcfa8211
Author: yuyang <2755469212@qq.com>
Date: Tue Jul 11 10:33:33 2023 +0800
add distributed
commit 9a1ae89cfd737cccb74ee8642ea79fe194288981
Author: yuyang <2755469212@qq.com>
Date: Tue Jul 11 10:24:41 2023 +0800
wrote a readme file
git log 命令可以添加-pretty=oneline来实现简易查看
Administrator@MS-NFZEFOSAMOUJ MINGW64 /d/GitBash/learngit (master)
$ git log --pretty=oneline
1851f871a9c2172ad51174c6124ff605237b158b (HEAD -> master) append GPL
c53adb7fc9b1c119b6471c31545b28cffcfa8211 add distributed
9a1ae89cfd737cccb74ee8642ea79fe194288981 wrote a readme file
2.5. 版本回退
每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为 commit 。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个 commit 恢复,然后继续工作,而不是把几个月的工作成果全部丢失。
当前有4个版本被提交到Git仓库:
版本1:wrote a readme file
Git is a version control system.
Git is free software.
版本2:add three file
file1, file2, file3
版本3:add distributed
Git is a distributed version control system.
Git is free software.
版本4:append GPL
Git is a distributed version control system.
Git is free software distributed under the GPL.
准备把 readme.txt 回退到上一个版本,也就是 add
distributed 的那个版本。
首先,Git必须知道当前版本是哪个版本,在Git中,用 HEAD 表示当前版本,也就是最新的提交,上一个版本就是 HEAD^ ,上上一个版本就是HEAD^^ ,当然往上100个版本写100个 ^ 比较容易数不过来,所以写成HEAD~100 。
现在,我们要把当前版本 append GPL 回退到上一个版本 add distributed ,就可以使用 git reset 命令:
$ git reset --hard HEAD^
HEAD is now at c53adb7 add distributed
#看看readme.txt的内容是不是版本add distributed
$ cat readme.txt
Git is a distributed version control system.
Git is free software.
再从当前版本add distributed回到版本append GPL
$ git reset --hard 1851f87 #1851f87是版本append GPL 的前几位id
HEAD is now at 1851f87 append GPL
3. Git常见命令
3.1. git --version
查看git版本
git --version
3.2. git config
设置提交代码的用户名和电子邮件地址。
git config –global user.name “[name]”
git config –global user.email “[email address]”
3.3. git init
初始化/创建一个新的代码库
git init [repository name]
3.4. git clone
通过指定的URL复制一个代码库
git clone [url]
3.5. git add
将一个文件添加至stage(暂存区)
git add [file]
将多个文件添加至stage(暂存区)
git add a.txt b.txt ...
将所有文件添加至stage(暂存区)
//忽略以.开头的隐藏文件
git add *
//将隐藏文件也添加到暂存区
git add .
3.6. git commit
在版本历史记录中永久记录文件
git commit -m “[文件标注信息]”
提交git add命令添加的所有文件,并提交git add命令之后更改的所有文件
git commit -a
3.7. git diff
显示尚未添加到stage的文件的变更
git diff
显示添加到stage的文件与当前最新版本之间的差异
git diff –staged
显示两个分支之间的差异
git diff [分支1] [分支2]
3.8. git reset
既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用 HEAD`时,表示最新的
版本。
– --soft :仅仅移动本地库 HEAD 指针
– --mixed: 移动本地库 HEAD 指针,重置暂存区
– --hard:移动HEAD指针,重置暂存区,工作区,省略git checkout – file
从stage中撤出指定的文件,但可以保留文件的内容
git reset [file]
撤销指定提交之后的所有提交,并在本地保留变更
git reset [commit]
丢弃所有的历史记录,并回滚到指定的提交
git reset –hard [commit]
git reset --hard HEAD^ #
#等价于
git reset --mixed HEAD^
git checkout -- readme.txt
3,9, git status
显示所有需要提交的文件
git status
3.10. git rm
删除工作目录中的文件,并将删除动作添加到stage
git rm [file]
3.11. git log
显示当前分支的版本历史记录
git log
显示某个文件的版本历史记录,包括文件的重命名
git log –follow[file]
简易显示版本历史记录
git log --oneline
3.12. git show
显示指定提交的元数据以及内容变更
git show [commit]
3.13. git tag
给指定的提交添加标签
git tag [commitID]
3.14. git branch
显示当前代码库中所有的本地分支
git branch
创建一个分支
git branch [branch name]
删除指定的分支
git branch -d [branch name]
3.15. git checkout
切换分支
git checkout [branch name]
创建一个分支,并切换到新分支上
git checkout -b [branch name]
把版本课的文件重置到工作区(撤销工作区的修改)
git checkout --[file]
3.16. git merge
将指定分支的历史记录合并到当前分支
git merge [branch name]
3.17. git remote
查看远程库的信息
git remote
显示更详细的信息
git remote -v
将本地的代码库连接到远程仓库
git remote add [远程仓库名] [远程仓库链接]
3.18. git push
将主分支上提交的变更发送到远程仓库
git push [远程仓库名] master
将指定分支上的提交发送到远程仓库
git push [远程仓库名] [branch]
将所有分支发送到远程仓库
git push –all [远程仓库名]
删除远程仓库上的一个分支
git push [远程仓库名] :[branch name]
3.19. git pull
获取远程仓库上的变更,并合并到你的工作目录
git pull [Repository Link]
3.20. 查看提交的每一次命令
git reflog
4. Git工作原理
Git分为:工作区、暂存区、版本库、远程仓库
- Workspace:工作区,就是平时存放项目代码的地方
- Index / Stage:暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息的一个虚拟空间
- Repository/master:仓库区(版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
- Remote:远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换(github,gitee等)
前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用 git add 把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用 git commit 提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个 master 分支,所以,现在, git
commit 就是往 master 分支上提交更改。