Git是一个免费的开源分布式版本控制系统(Distributed Version Control System,简称 DVCS),旨在快速高效地处理从小型到大型项目的所有内容。
Git易用、体积小、具有闪电般快速的性能,具有诸如Subversion、CVS、Perforce和ClearCase之类的SCM工具,并且具有廉价的本地分支,方便的暂存区域和多个工作流等功能,极其适合管理大型项目。
版本控制(Version Control)是一种软件工程技术,在开发过程中用于管理对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本等。
实现功能:
简单来说,版本控制就是用于管理多人协同开发项目的技术。
没有进行版本控制或者版本控制本身缺乏正确的流程管理,在软件开发过程中将会引入很多问题,如软件代码的一致性、软件内容的冗余、软件过程的事物性、软件开发过程中的并发性、软件源代码的安全性,以及软件的整合等问题。
所有的版本控制都只能针对文本内容,像word这样的二进制内容,所谓版本,就是文件快照,不能比较差异,只能算带备份的网盘。
版本控制分类有:
本地版本控制
数据库记录文件的每次更新(对每个版本做一个快照,或是记录补丁文件),适合个人用。
代表产品有RCS。
集中式版本控制(Centralized Version Control )
开发者之间的合作方式是共用一个仓库(repository),无论这个仓库是在本地还是在远端,只要是所有成员都共同存取同一个仓库,那么这种方式就是集中式版本控制。
工作流程:
特点:
缺点:
操作必须在能够连网的环境下进行
所有的版本数据都存在服务器上,用户的本地只有自己以前所同步的版本,如果不连网,用户就看不到历史版本,也无法切换版本验证问题,或在不同分支工作。
中央服务器的单点故障的风险
如果中央服务器发生宕机,所有客户端将无法提交更新、还原等,也就无法协同工作。如果磁盘发生故障,信息尚无备份,还会有数据丢失的风险。
分布式版本控制(Distributed Version Control)
分布式版本控制系统没有“中央服务器”,每个开发者都可以建立一个完整的仓库。
分布式版本控制系统的核心不在于维持不同开发者间的同步,而在于让每个开发者拥有各自独立的变更集合,且开发者之间可分享自己的变更集合。
工作流程:
(需要连网)开始工作前,在客户端克隆出完整的远程仓库(临时中心服务器)
“拉”(pull)操作,意义是获取其他仓库的变更。
(不需要连网)然后工作,将更新提交到本地仓库
每个人都可以独立进行更新,所有更新都是在完整资料信息环境下进行的。
(需要连网)一次性地将本地仓库推送到远程仓库
“推”(push)操作,意义是将本地仓库中的变更送至其他仓库
特点:
缺点:
主流的版本控制系统(Version Control Server)有:
现在影响力最大且使用最广泛的是Git(分布式版本控制系统)与SVN(集中式版本控制系统)。
Git与SVN最主要区别:
SVN是集中式版本控制系统
版本库集中放在中央服务器。工作时,使用自己的电脑,所以首先要从中央服务器得到最新的版本,然后工作;完成工作后,需要把自己做完的活推送到中央服务器。集中式版本控制系统必须联网才能工作,对网络带宽要求较高。
Git是分布式版本控制系统
没有中央服务器,每个人的电脑就是一个完整的版本库,工作时不需要联网,因为版本都在自己电脑上。协同方法:比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,两人之间只需把各自的修改推送给对方,就可以互相看到对方的修改。
直接记录文件(称为文件快照),而非记录文件的差异内容
Git 和其它版本控制系统的主要差别在于存储数据的方式:
其它系统以文件变更列表的方式存储数据:每次提交只存储本次的修改内容
完整的工作文件 = 初始版本 + 每一次的修改内容。
Git以快照(Snapshot)流的方式存储数据:每次提交都是存储完整的工作文件(存储累计至本次提交的所有修改内容)
完整的工作文件 = 最新提交。
每次提交时,对当前文件制作一个快照并保存这个快照的索引。为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。Git 对待数据更像是一个快照流。
几乎所有操作都是本地执行
Git的大多数操作都只需要访问本地文件和资源,一般不需要来自网络上其它计算机的信息。如果你习惯所有操作都有网络延时的集中式版本控制系统,Git在这方面会让你感到速度神速。因为在本地磁盘上就有项目的完整历史,所以大部分操作看起来瞬间完成。
保证完整性
Git的所有数据在存储前都计算校验和,然后以校验和来引用。这意味着不可能在Git不知情时更改任何文件内容或目录内容。 这个功能建构在Git底层,是构成Git哲学不可或缺的部分。若在传送过程中丢失信息或损坏文件,Git就能发现。
Git使用计算校验和的机制叫做SHA-1散列(hash)。这是一个由40个十六进制字符(0-9和a-f)组成的字符串,基于Git中文件的内容或目录结构计算出来。SHA-1看起来是这样:
24b9da6552252987aa493b52f8696cd6d3b00373
实际上,Git数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名。
Git中的仓库数据都是以hash键值对的方式保存,相当于一个数据库。
- 当用户在工作区add操作后,变化(change)就变为Git对象数据库(blob、commit、tree对象)
- git命令(`git clone` 、`git checkout` 、`git reset`)将git数据库(版本库和暂存区)变为用户实际接触到的文件
4. Git一般只添加数据
Git的操作,几乎只是往Git数据库中增加数据,很难让Git执行任何不可逆操作,或者让它以任何方式清除数据。 同别的VCS一样,未提交更新时有可能丢失或弄乱修改的内容;但提交(commit)到Git中,就难以再丢失数据,特别是定期自动推送数据库到其它仓库的话。
官网:https://git-scm.com/
GitHub:https://github.com/git/git
Git是目前世界上最先进的分布式版本控制系统。Git是免费的、开源的,最初是为辅助Linux内核开发的,来替代BitKeeper。作者是Linux和Git之父李纳斯·托沃兹(Linus Benedic Torvalds)。
优点:
缺点:
在Git官网根据自己的操作平台下载安装程序,假设操作平台为Windows 10:
安装成功后在开始菜单中会有Git项,菜单下有3个子程序:
查看Git的当前环境详细配置 :
git config --list|-l
查看不同级别的配置文件:
git config --list --system
git config --list --global
git config --list --local
使用git config
命令设置Git的外观和行为(只需一次配置。之后,Git会自动遍历配置文件查找配置项)。对于同一配置项,优先级是system<global<local。
git config --system
:将配置写入系统
系统是指Git安装目录内的mingw64/etc/gitconfig文件,适用于所有用户和所有项目的配置。系统可以有多个用户。
git config --global
:将配置写入当前用户
当前用户是指$HOME/.gitconfig文件或C:/Users/$USER/.gitconfig文件,只适用于当前登录用户的配置。一个用户可以有多个项目。
$HOME目录指用户主目录,Windows平台是指C:/Documents and Settings/$USER,可自定义。
git config
:将配置写入当前项目,缺省参数默认是指--local
当前仓库是指当前项目的本地仓库(.git)内的config文件,只适用于特定项目的配置。一个项目只有一个本地仓库(.git)。
知道了配置文件的位置后,就可以使用文本编辑器实现配置命令(git config
)操作。
系统安装Git后,需要配置Git环境。
配置命令(git config
)的配置项有:
配置项 | 描述 |
---|---|
color.ui true | 默认终端开启着色(语法高亮) |
alias.ci commit | 设置别名。ci是commit的别名 |
user.name | 用户名 |
user.email | 邮箱 |
core.editor | 文本编辑器 |
merge.tool | 差异分析工具 |
core.paper “less -N” | 配置显示方式 |
color.diff true | diff颜色配置 |
core.filemode false | 忽略修改权限的文件 |
配置用户标识
Git是分布式版本控制系统,在初次使用前需要填写用户名和邮箱作为一个标识(作用是区分用户),因为每次Git提交都会使用该信息。它被永远的嵌入到了你的提交中:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
--global
选项,那么该命令只需要运行一次,之后无论在该系统上做任何事情,Git 都会从$HOME/.gitconfig文件中读取并使用这些信息。当想针对特定项目使用不同的用户名称与邮件地址时,可以在项目目录下运行没有 --global
选项的命令来配置配置文本编辑器
当需要输入信息时,Git会调用默认文本编辑器(默认Vim,安装时可选择)。 也可以使用以下命令配置文本编辑器,例如设置文本编辑器为Emacs:
$ git config --global core.editor emacs
本地仓库和远程仓库同步时,若使用SSH传输协议,则需要设置SSH密钥。
使用ssh-keygen -t rsa -C "用户E-mail"
命令,在本地创建SSH Key:
$ ssh-keygen -t rsa -C "ytkomon@hotmail.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/ytkom/.ssh/id_rsa):
Created directory '/c/Users/ytkom/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/ytkom/.ssh/id_rsa.
Your public key has been saved in /c/Users/ytkom/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:xxxxxx ytkomon@hotmail.com
The key's randomart image is:
换行符有:CR(CarriageReturn,回车)、LF(LineFeed,换行)、CRLF(回车换行)。
换行符 | 操作平台 |
---|---|
LF,即“\n” | Mac和Linux平台 |
CR,即’\r’ | 早期的Mac(现在已放弃) |
CRLF,即“\r\n” | Windows平台(包含Dos) |
不同操作平台默认使用的换行符不同,在文本处理时就会影响格式:
例如:触发错误提示“warning: LF will be replaced by CRLF”
例如:Unix/Mac文件在Windows打开,所有文字会变成一行
例如:Windows文件在Unix/Mac打开,在每行的结尾可能会多出一个^M符号
例如:Linux文件在windows上用记事本打开,会出现黑点
这些问题都可以通过一定方式进行格式转换。例如:在Linux下,命令unix2dos
是将Linux文件格式转换成Windows文件格式,命令dos2unix
是将Windows格式转换成Linux文件格式。
Git转换换行符的方法:参考关于git提示“warning: LF will be replaced by CRLF”终极解答。
方法一:适用于所有平台
运行git config --global core.autocrlf=true
或在.gitconfig
文件的“core”项中添加autocrlf=true
:提交时转换为LF,(若是Windows平台)检出时转换为CRLF。
方法二:只适合Mac和Linux平台
使用LF作为行结束符的Linux/Mac平台,不需要Git在检出文件时进行转换。
但不小心引入以CRLF为行结束符的文件时,希望Git能够自动修正,运行git config --global core.autocrlf input
命令,提交时转换为LF,检出时不转换。
方法三:只适用于Windows平台
运行git config --global core.autocrlf=false
命令,提交检出时均不转换。
Git的Windows客户端默认设置core.autocrlf=true
,只要保持工作区是纯CRLF文件,编辑器用CRLF换行,就不会出现警告;Linux最好不要设置,因为这个配置算是为Windows平台定制的。
Git CMD
Git CMD输入chcp 65001
命令(临时更改),即可更改为UTF-8编码,这保证了与文本编辑器的编码(通常为UTF-8)一致且在命令行模式下正确显示/使用中文。
Git Bash
参考:Git中文乱码问题解决方案。
若定制Git Bash的终端时选择了“Use WIndows’s default console window”,默认编码为936(CMD的默认编码)。
当文件路径中含有中文字符时,中文字符会被转换为unicode码,导致看不出来原来的文件名,执行下述命令,Git就不会对路径进行转换(不会对0×80以上的字符进行quote),从而显示出原来完整的中文路径:
$ git config --global core.quotepath false
让Git显示颜色,会让命令输出看起来更醒目:
git config --global color.ui true
忽略大小写
Git默认对文件名大小写不敏感,这样容易造成错误,因此重新配置为大小写敏感:
git config --global core.ignorecase false
设置Git GUI的界面编码
git config --global gui.encoding utf-8
设置commit提交时使用utf-8编码,可避免服务器上乱码,同时与Linux上的提交保持一致
git config --global i18n.commitencoding utf-8
在git log
时将utf-8编码转换成gbk编码,解决git log
乱码问题
git config --global i18n.logoutputencoding gbk
git log
显示中文(配合i18n.logoutputencoding = gbk),在/etc/profile末尾中添加:
export LESSCHARSET=utf-8
(当证书过期时)关闭证书验证
git config --global http.sslVerify false
使用git update-git-for-windows
命令升级(自动搜索当前版本,然后升级)或通过git clone
获取GitHub仓库上的最新开发版本:
$ git clone https://github.com/git/git # 安装至当前目录,当前目录应该是Git的安装路径
Git Bash,采用命令行的方式对版本进行管理,功能最为灵活强大,但是由于需要手动输入希望修改的文件名,所以相对繁琐。
Git的图形界面工具:简陋,只实现了Git所有功能的一个子集以降低操作难度。
参考:几款常用的Git图形化工具。
图形界面工具只是实现了命令行工具(Git Bash)的部分功能,但图形工具简单、便捷、不需要强记命令及用法。
官网:https://www.sourcetreeapp.com/
官方文档:Sourcetree Support
安装SourceTree
下载后,点击安装文件SourceTreeSetup-3.1.2.exe,弹出窗口要求注册Bitbucket Cloud账号:
网上的“不注册账号安装的教程”在版本3.1.2无效。
注册Bitbucket Cloud账号后,“下一步”由灰(不可点击)变亮(可点击),点击“下一步”
然后,按照提示安装即可。
添加本地仓库
将项目根目录拖拽到搜索框下面空白位置即可添加本地仓库(.git目录)。
使用方法:参考SourceTree+Git简单使用(Windows)。
将项目目录拖拽到本地仓库后,SourceTree的显示如下图:
配置外部差异比对/合并工具Beyond Compare
安装Beyond Compare(百度搜索中文破解版)
点击SourceTree的【工具】–【选项】–【比较】–“外部差异比对/合并”,下拉工具中选择Beyond Compare
自动显示安装路径(例如D:/Git/Beyond Compare 4/BComp.exe),使用默认参数
在C:/Users/用户名/.gitconfig文件中添加配置内容:
[difftool "sourcetree"]
cmd = 'D:/Git/Beyond Compare 4/BComp.exe' \"$LOCAL\" \"$REMOTE\"
[mergetool "sourcetree"]
cmd = 'D:/Git/Beyond Compare 4/BComp.exe' \"$LOCAL\" \"$REMOTE\" \"$BASE\" -o \"$MERGED\"
trustExitCode = true
[diff]
tool = sourcetree
[difftool]
prompt = true
[merge]
tool = sourcetree
[mergetool]
prompt = true
TortoiseGit,第三方的Git图形化客户端,可设置中文界面。
Git命令应该在项目目录内使用,否则因为找不到仓库(.git目录)而触发错误提示:
fatal: not a git repository (or any of the parent directories): .git
有多个分支时,为了避免错误操作,使用Git命令时必须清晰知道当前分支是哪一个。
参阅:Linux 命令大全
命令 | 功能 |
---|---|
cat 文件名 |
(concatenate)查看工作文件内容 |
cd dirName |
(change directory)切换路径至dirName |
clear |
(clear)清屏 |
cp 源文件名 新文件名 |
(copy)复制文件 |
echo ‘内容’ > 文件名 |
输出内容到文件中,每次输入都覆盖原来的文件 |
echo ‘内容’ >> 文件名 |
输出内容到文件中,每次输入都在末尾追加新内容 |
less 文件名 |
查看文件内容(逐步显示):回车键逐行;空格键逐屏;b键逐页 |
ls |
(list)查看当前目录内的所有文件 |
mkdir dirName |
(make directory)新建一个目录 |
mv 源文件名 新文件名 |
(move)移动文件或重命名 |
pwd |
(print working directory)查看当前所在的绝对路径 |
q |
(quit)退出 |
rm 文件名 |
(remove)删除一个文件。删除文件夹需要使用-rf 参数 |
rmdir |
(remove directory)删除文件夹。只能删除空文件夹,不常用 |
touch 文件名 |
在当前目录内新建一个文件 |
命令 | 功能 |
---|---|
git add 文件名 |
将工作文件的更改添加到暂存区 |
git checkout -- 文件名 |
检出:用暂存文件覆盖工作文件 |
git checkout -- 文件名 --hard |
检出:用版本文件覆盖工作文件和暂存文件 |
git commit -m “提交备注” |
将暂存区所有文件储存到本地仓库,备注是提交的提示信息 |
git config --list |
查看Git的当前配置 |
git diff 对象A 对象B |
查看对象之间的差异内容,对象可为:分支/版本/文件等 |
git diff --cached |
查看已暂存文件和上次提交之间的差异内容 |
git init |
初始化本地仓库(新建了一个隐藏目录.git) |
git log |
查看当前提交历史,版本重置(reset)后,是开始至重置版本 |
git reflog |
查看所有提交历史,版本重置后,是开始至重置时的版本 |
git reset --mixed 版本号 |
(默认方式)重置版本,重置了history,staged和working tree不变 |
git reset --soft 版本号 |
重置版本,重置了history和staged,working tree不变 |
git reset --hard 版本号 |
重置版本,重置了history、staged和working tree |
git revert 版本号 |
回滚版本,创建一个新提交并回滚指定版本的修改内容 |
git rm 文件名 |
删除版本文件,不删除工作文件,但状态变为未跟踪 |
git rm -f 文件名 |
强制删除版本文件,不删除工作文件,但状态变为未跟踪 |
git rm --cached 文件名 |
删除暂存文件,不删除工作文件,但状态变为未跟踪 |
git status |
查看文件状态 |
命令 | 功能 |
---|---|
git branch |
列出所有本地分支,使用星号(*)标示出当前本地分支 |
git branch -a |
列出所有分支(本地和远程分支) |
git branch -v |
列出每一个本地分支的最新提交(版本号、提交备注) |
git branch -d 分支名称 |
删除分支。如果分支没有被合并,则不允许删除,若使用-D 参数则强制删除分支 |
git branch -m 旧名 新名 |
重命名分支,若使用-M 参数则强制重命名 |
git branch 分支名称 |
创建分支 |
git checkout 分支名称 |
切换分支,切换时,若当前分支的修改未提交/隐藏,会中断切换 |
git checkout -b 分支名称 |
创建并切换到新分支 |
git merge 分支名称 |
将指定分支合并到当前分支,合并后,指定分支仍然存在 |
git rebase 分支名称 |
把指定分支更新到当前分支 |
git stash |
贮藏当前工作现场,存储当前改变后,返回到一个干净工作状态 |
git stash apply |
恢复但不删除储藏栈的工作现场 |
git stash drop |
删除工作现场 |
git stash list |
查看工作现场 |
git stash pop |
恢复并删除储藏栈的工作现场 |
切记:在切换分支前,一定要提交或隐藏当前分支的工作。
假设情景:分支A的工作忘记提交或冻结,然后从分支A切换到分支B,又在分支B编辑了分支A跟踪过的文件。最后, 从分支B切换回分支A。结果,工作文件被检出文件覆盖。工作文件将会恢复回切换前的状态,即被最后一次在分支A提交的版本覆盖,也就是说,后期的修改内容全部丢失。
$ git checkout master
error: Your local changes to the following files would be overwritten by checkout:
.gitignore
Please commit your changes or stash them before you switch branches.
error: The following untracked working tree files would be overwritten by checkout:
命令 | 功能 |
---|---|
git branch –-set-upstream-to=远程分支 本地分支 |
本地分支关联远程分支 |
git checkout -b 本地分支 远程库名/远程分支 |
取远程分支并创建新分支 |
git clone 远程仓库URL |
将远程仓库复制到本地仓库,URL可采用不同的传输协议 |
git init --bare 远程库名.git |
初始化一个远程仓库 |
git pull 远程仓库名 远程分支名:本地分支名 |
获取远程分支,合并到本地分支 |
git push -u 远程仓库名 本地分支名:远程分支名 |
推送分支,(-u 参数)建立upstream分支 |
git push 远程仓库名 本地分支名:远程分支名 |
推送分支,推送时一定要在本地仓库目录中 |
git push 远程仓库名 :远程分支名 |
删除远程分支 |
git push 远程仓库名 --delete 远程分支名 |
删除远程分支 |
git remote add 远程仓库别名 远程仓库URL.git |
本地仓库添加(关联)远程仓库 |
git remote rm 远程仓库名 |
本地仓库删除(取消关联)远程仓库 |
git remote show 远程仓库名 |
查看远程仓库信息 |
git remote -v |
(-v 参数)查看远程仓库详细信息 |
实际开发中,应该按照几个基本原则进行分支管理:
所以,团队合作的分支看起来就像这样:
git push origin branch-name
推送自己的修改.git pull
试图合并git push origin branch-name
推送就能成功官网:
个人博客:
感谢您的赞赏支持: