最原始的版本控制是纯手工的版本控制:修改文件,保存文件副本。
保存的副本命名随意,版本难辨新旧,不能辨别每一版的修改内容。
diff与patch是用于源码版本控制中的两个最基本的概念
diff简介:diff用来比较两个文件或者目录之间的差异.
常用命令:
diff -u file1 file2
patch简介:patch是diff的反向操作。
通过diff.txt,把file1变成file2的内容:
patch file1 diff.txt
# 把diff.txt应用到file1文件上,命令结束后file1与file2中的内容是一样的
通过diff.txt,把file2变成原来的file1的内容:
patch -R file2 diff.txt
# -R代表的的意思是把diff.txt采用反向的方式,应用到file2,命令结束后file2和file1是一样的
RCS(Revision Control System)采用把diff的集合,采用RCS自己的格式保存到磁盘中(可以通过 diff -n file1 file2 产生RCS格式的diff内容),通过这些diff集合,重新回到文件修改的任何历史中的点。
CVS(Concurrent Versions System)诞生于1985年,有史以来第一个被大规模使用的版本控制工具。CVS 的出现让工程师以协同工作。
CVS存在的问题:不支持原子化提交,会导致客户端向服务器端提交了不完整的数据,还有网络传输效率低等。
SVN (Subversion)目的在是创建一个重好用的版本控制系统以取代CVS。优化了服务器上内容的存储, 实观了原子提交等。
SVN存在的问题:在局域网之外使用SVN,单是查看日志、提交数据等操作的延迟,就足以让基于广域网协同工作的团对抓狂了。
集中式版本控制存在的问题:
狭窄的提交通道:提交排队 ,不能同时修改。提交缺乏质量控制;缺乏代码门禁,在本地代码提交到服务器之问缺少检查防护。
数捃安全性差:单点故障、黑客攻击。
Git和其他版本控制系统的主要差别在于Git对待数据的方法。
其他系统以文件变更列表的方式存储信息,将保存的信息看作是一组基本文件和每个文件随时间逐步积累的差异。
Git则更像是对小型文件系统的一组快照,每次更新时,对全部文件制作一个快照1并保存这个快照的索引。
脆弱的中央库 | 强壮的分布库 |
---|---|
备份的重要性:集中式CVS存任单点故障,备份极其重要。 | 全是服务器:数据最安全;无带宽和性能瓶颈。 |
服务器压力:基本上所有的操作需要与服务器交互;操作受限于带宽 ,不能移动办公。 | 提交为本地操作:快;全离线操作;编码不会被冲突打断;能够移动办公。 |
安全性:单单点故障、黑客攻击等。 | 数据的完整性:Git数据、提交全部使用SHA1哈希,以保证完整性,甚至提交可以使用PGP签名。 |
不适合开源项目:强调集中管理,适合人数不多的项目。 | 工作模型:适合分布式开发,强调个体。 |
SVN不适合的领域:
跨地域的协同开发
对代码的高质量追求和代码门禁
Git不适合的领域:
不适合Word等二进制文档的版本控制,Git没有锁定/解锁模式,故不能排他式修改。
整体的读授权,不能将读授权精细到目录级别。解决方案:版本库按照目录拆分。
Git是一个版本控制工具,而且是一个开源的分布式版本控制工具。
Git的很多命令设计都是来源于 Bitkeeper,但是 Git 有更多属性:
极快的速度
简单的设计
对非线性开发模式的强力支持(允许成干上万个并行开发的分支)
完全分布式
有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)
Linux 系统:Ubuntu 10.10(maverick)或更新版本,Debian(squeeze)或更新版本:
sudo aptitude install git
sudo aptitude install git-doc git-svn git-email gitk
其中git软件包包含了大部分 Git命令,是必装的软件包。
软件包git-svn、git-email、 gitk本来也是Git软件包的一部分 ,但是因为有着不一样的软件包依赖(如更多perl模组,tk等),所以单独作为软件包发布。
Linux 系统:RHEL、Fedora、CentOS等版本:
§ yum install git
§ yum install git-svn git-email gitk
访问Git的官方网站:http://git-scm.com/。下载Git源码包。
展开源码包,并进入到相应的目录中。
tar -jxvf [Git源码包]
cd [解压后的Git源码包]
安装方法写在INSTALL文件当中,参照其中的指示完成安装。下面的命令将Git安装在/usr/local/bin中。
make prefix=/us/local all
sudo make prefix=/usr/local insta11
安装Git文档(可选)。
§ make prefix=/usr/local doc info
§ sudo make prefix=/usr/local install-doc install-html install-info
Linux的shell环境(bash)通过bash-completion软件包提供命令补齐功能,能够实现在录入命令参数时按一下或两下TAB键,实现参数的自动补齐或提示。例如输入git com后按下TAB键,会自动补齐为git commit。
将Git源码包中的命令补齐脚本复制到bash-completion对应的目录中:
cp contrib/completion/git-completion.bash /etc/bash_completion.d/
重新加载自动补齐脚本,使之在当前shell中生效:
. /etc/bash_completion
为了能够在终端开启时自动加载bash_ completion脚本 ,需要在本地配路文件 ~/.bash_profile /etc/bashrc文件中添加下面的内容:
if [ -f /etc/bash_completion ]; then
./etc/bash_completion
fi
Git提供的Windows安装包自带MinGW(Minimalist GNU for Windows,最简GNU工具集),在安装后MinGW提供了一个bash提供的shell环境(Git Bash)以及其他相关的工具软件,组成了一个最简系统(Minimal SYSTEM),这样在Git Bash中,Git的使用和在Linux下使用完全一致。
Step1:到https://git-scm.com/download/win下载Windows安装包
执行开始安装,设置自己想要的安装路径
Step2 :选择一些必要的组件
Step3:Git默认的编辑器,建议保持默认,也可已选择其他的,例如Notepad++。
Step4 :在安装过程中会询问是否修改环境变量。建议选择"Use Git Bash Only”,即只在 MinGW提供的shell环境中使用Git,不修改 PATH 环境变量,避免 Git 自带的工具与 Windows 下已有的产生冲突。
Step5:其它后续提示可以都采用缺省配置,进行安装过程。安装完成后,我们可以在 Windows 任意目录下,右键单击选中”Git Bash〞 启动Git Bash。
可以执行 git version
查看安装的 git 版本信息:
TortoiseGit是基于msysGit的图形界面工具。
Step1:访问网站https://tortoisegit.org/download/,下载安装包和对应的语言包。
Step2:安装过程中会询问要使用的SSH客户端,缺省使用内置的TortoisePLink(来自PuTTY项目)做为SSH客户端。TortoisePLink和TortoiseGit的整合性更好,可以直按通过对话框设置SSH私钥(PLTTV格式),而无需再到字符界面去配置SSH私钥和其他配置文件。
Step3:如果你的本地同时安装了命令行的Git版本,可以通过TortoiseGit的设置对话框选中Git提供的ssh客户端,这样在下载ssh协议的代码仓库的时候,通过命令行与TortoiseGit图形界面都可以使用同一套公钥和密钥。
Git有三种配置,分别文件的形式存放在三个不同的地方。可以在命令行中使用git config工具查看这此变量
系统配置(对所有用户都适用)
存放在git的安装目录下:%Git%/etc/gitconfig;若使用git config时用–system选项,读写的就是这个文件:
git config --system core.autocrlf
用户配置(只适用于该用户)
存放在用户目录下。(例如linux存放在:~/gitconfig;若使用git config时–global选项,读写的就是这个文件:
git config --global user.name
仓库配置(只对当前项目有效)
当前仓库的配置文件(也就是工作目录中的.git/config 文件):若使用git config时用–local选项,读写的就是这个文件
git config --local remote.origin.ur1
注:每一个级別的配置都会覆盖上层的相同配置,网如.git/config里的配置会麗盖%Git%/etc/gitconfig中的同名变量。
首次的Git设定
git config --global user.name "Chen Hao"
git config --global user.email 903121121@qq.com
这个配置信息会在Git仓库中提交的修改信息中体现,但和Git服务器认证使用的密码或者公钥密码无关
假如你正在Windows上写程序,又或者你正在和其他人合作,他们在Windows上编程,而你却在其他系统上,在这些情况下,你可能会遇到行尾结束符问题。这是因为Windows使用回车和换行两个字符来结束一行,而Mac和Linux只使用换行一个字符。 虽然这是小问题,但它会极大地扰乱跨平台协作。
Git可以在你提交时自动地把行结束符CRLF转换成LF,而在签出代码时把LF转换成CRLF。用core.autocrlf来打开此项功能,如果是在Windows系统上,把它设置成true,这样当签出代码时,LF会被转换成CRLF:
git config --global core.autocrlf true
Linux或Mac系统使用LF作为行结束符,因此你不想Git在签出文件时进行自动的转换;当—个以CRLF为行结束符的文件不小心被引入时你肯定想进行修正,把core.autocrlf没置成input来告诉Git在提交时把CRLF转换成LF,签出时不转换;
git config --global core.autocrlf input
这样会在Windows系统上的签出文件中保留CRLF,会在Mac和Linux系统上,包括仓库中保留LF。
如果你是Windows程序员,且正在开发仅运行在Windows上的项目,可以设置false取消此功能,把回车符记录在库中:
git config --global core.autocrlf false
• i18n.commitEncoding选项:用来让git commit log存储时,采用的编码,默认UTF-8
• i18n.logOutputEncoding选项:查看git log时,显示采用的编码,建议设置为UTF-8
#中文编码支持
git config --global gui.encoding utf-8
git config --global i18n. commitencoding utf-8
git config --global i18n. logoutputencoding utf-8
#显示路径中的中文:
git config --global core.quotepath false
http/https协议认证
设置口令缓存:
git config --global credential.helper store
添加HTTPS证书信任:
git config http.sslverify false
ssh协议认证
SSH协议是一种非常常用的Git仓库访问协议,使用公钥认证、无需输入密码,加密传输,操作便利有保证安全性
生成公钥:
在GitBash客户端命令行界面中输入下面的提示命令
ssh-keygen -t rsa -C [你的邮箱]
cat ~/.ssh/id_rsa.pub
查看已经生成的公钥,将其复制到相关网站的公钥管理库中
Git版本控制下的工程区域有三种:
版本库(Repository):在工作区中有一个隐藏目录.git,这个文件夹就是Gi的版本库,里面存放了Git用来管理该工程的所有版本数据,也可以叫本地仓库。
工作区(Working Directory):日常工作的代码文件或者文档所在的文件夹。
暂存区(stage):一般存放在工程根目录.git/index文件中,所以我们也可以把暂存区叫作素引(index)。
Git版本控制下的文件状态有三种:
已提交(committed):该文件已经被安全地保存在本地数据库中了。
己修改(modified):修改了某个文件,但还没有提交保存。
已暂存(staged):把已修改的文件放在下次提交时要保存的清单中。
工程准备
工程克隆——git clone
查看工作区
查看工作区的修改内容——git diff
查看工作区文件状态——git status
文件修改后提交推送
新增/删除/移动文件到暂存区——git add/ git rm/ git mv
提交更改的文件——git commit
推送远端仓库——git push
查看日志
查看当前分支上的提交日志——git log
分支管理
列出本地分支——git branch
新建分支——git branch / git checkout -b
删除分支——git branch -d
切换分支——git checkout
更新分支——git pull
合并分支——git merge
撤销操作
强制回退到历史节点—— git reset
回退本地所有修改而未提交的——git checkout
分支合并
合并目标分支内容到当前分支——git merge/git rebase
git init用于在本地目录下新建git项目仓库
git init [仓库名]
执行后,在当前[仓库名]目录下会自动生成一个名为.git的不可见的目录。
git clone用于克隆远端工程到本地磁盘
git clone [URL]
git lfs clone [URL]
#如果远端仓库支持二进制文件,则只有lfs才可以将二进制文件clone下来
在提交你修改的文件之前,需要git add把文件添加到暂存区
如果该文件是新建的,尚未被git跟踪的,需要先执行git add将该文件添加到暂存区,在执行提交。
git add [filename]
git add .
#将所有修改的文件放到暂存区
git rm将指定文件彻底从当前分支的缓存区删除,因此它从当前分支的下一个提交快照中被删除
如果一个文件被git rm后进行了提交,那么它将脱离git跟踪,这个文件在之后的节点中不再受git工程的管理。
git rm [filename]
执行git rm后,该文件会在缓存区消失。
你世可以直接从硬盘上删除文件,然后对该文件执行git commit,git会自动将删除的文件从索引中移除,效果一样。
git mv命令用于移动文件,也可以用于重命名文件
git mv [file] [dir]
#将文件移动到相应的目录下
git mv [file1] [file2]
#将file1重命名为file2
git diff用于比较项目中任意两个版本(分支)的差异,也可以用来比较当前的索引和上次提交间的差异
git diff [commit_id1] [commit_id2]
#比较两个节点之间的差距
git diff [branch1] [branch2]
#比较两个分支之间的差距
git diff --cached
#比较当前索引和上次提交的差距
git diff [] [] --name-status
#在diff后面加--name-status参数,只看文件列表
git status 命令用于显示工作目录和暂存区的状态
使用此命令能看到修改的git文件是否已被暂存,新增的文件是否纳入了git反本库的管理。
git status
git commit主要是将暂存区里的文件改动提交到本地的版本库
提交这个动作是本地动作,是往本地的版本库中记录改动,不影响远端服务器。
git commit [file] -m "[commit message]"
#提交file并附加提交信息
git commit -am "[commit message]"
#提交所有在暂存区改动的文件
git commit --amend
#通过文本模式修改上一次的提交信息,并新生成一个提交节点来代替所修改的节点
git log用于查看提交历史
默认不加其他参数的话,git log 会按提交时间由近到远列出所有的历史提交日志。每个日志基本包含提交节点、作者信息、提交时间、提交说明等。
git log
git log -[num]
#查看最近num次修改
git push将本地版本库的分支推送到远程服务器上对应的分支
在使用git commit命令将自己的修改从晢存区提交到本地版本库后,可以使用git push将本地版本库的分支推送到远程服务器上对应的分支。
成功推动远端仓库后,其他开发人员可以获取到你新提交的内容。
git push origin [branch_name]
#branch_ name决定了你的本地分支推送成功后,在远端服务器上的分支名
git push origin [branch_name]:[new_ branch_name]
#你的本地分支名可以与推送到远端的分支名不同
注:Windows对于大小写不敏感,注意推送到远端时会存在影响
git branch和git checkout -b都可以用于新建分支
两者都基于当前分支节点创建。
git branch新建分支后并不会切换到新的分支。
git checkout -b新建分支后会自动切换到新的分支。
git branch [branch_name]
git cheekout -b [branch_name]
git branch -d和git branch-D都可以用来删除本地分支,后者大写表示强制删除
有时候当事分 支上包含了未合并的改动,或者当事分支是当前所在分支,则-d无法删除,需要使用强制删除来达到目的。
git branch -d [branch_name]
git branch -D [brancn_name]
git branch -d -r [branch_name]
#用于删除服务器上的远程分支,branch_name为本地分支名。删除后还要推送到服务器上
git checkout用来切换/检出分支
git checkout branch_name
git checkout -f branch_name
# -f为强制删除
有时候,当前分支工作区存在修改而未提交的文件,与目的分支上的内容冲突,会导致checkout切换失败,即可加上-f
git pull从远端服务器上获取某个分支的更新,再与本地指定的分支进行合并
git pull origin [remote_branch]:[local_branch]
git pull origin [remote_branch]
#如果远程指定的分支与本地指定的分支相同,则可以直接执行该命令
git fetch从远端服务器中获取某个分支的更新到本地仓库
与git pull不同,git fetch在获取到更新后,并不会进行合并操作,这样能留给用户一个操作空间,确认内容符合预期后再合并节点
git fetch origin [remote_branch]:[local_branch]
git fetch origin [remote_branch]
#如果远程指定的分支与本地指定的分支相同,则可以直接执行该命令
git merge命令是用于从指定的分支(节点)合并到当前分支的操作
git会将指定的分支与当前分支进行比较,找出二者最近的一个共同节点base,之后将指定分支在base之后分离的节点合并到当前分支上。分支合并,实际上是分支间差异提交节点的合并。
git merge [branch_name_src] [branch_name_dst]
# 将源分支合并到目的分支
git merge [branch_name]
# 将分支合并到当前分支
git rebase用于合井目标分支内容到当前分支
git rebase这条命令用于分支合并,git merge也是用于分支合并。如果你要将其他分支的提交节点合并到当前分支,那么git rebase和git merge都可以达到目的
git rebase [branch_name]
git rebase和git merge背后的实现机制和对合并后节点造成的影响有很大差异,有各自的风险存在。
git merge不会破环源分支的节点,将源分支的最后一个节点合并到目的分支。git log会相对难看,不会保留源分支的commit。
git rebase基于最近的公共节点,将源分支所有的差异节点合并到目的分支,并在目的分支上产生新的commit_id,会保留所有的commit。会破坏掉源分支的节点。
git reset通常用于撤销当前工作区中的某些git add/commit操作,可将工作区内容回退到历史提交节点
git reset [commit_id]
git checkout .用于回退本地所有修改而未提交的文件内容。
git checkout .这是条有风险的命令,因为它会取消本地工作区的修改(相对于暂存区),用暂存区的所有文件直接覆盖本地文件,达到回退内容的目的。但它不给用户任何确认机会,所以谨慎使用。
git checkout .
git checkout -[filename]
#回退某个文件的未提交改动
git checkout [commit_id]
#工作区回退(检出)到某个提交版本
Step1:新建代码仓
在CSDN提供的代码仓服务上https://gitcode.net/projects/new#blank_project新建一个代码仓
Step2:添加公钥
新建的代码仓需要你添加本地的公钥用来拉去代码和修改后推送
将框中的密钥复制到对应的框中
Step3:拉取代码仓
点开个人仓复制相关链接
克隆远端仓库
Step4:修改工作区中的文件并push到远端仓库
Step1:通过git clone命令克隆原仓库到本地,切换到相关分支,并进入到目标目录
Step2:通过git pull命令加上目标仓库的地址和目标分支
Step3:分支合并过程中的冲突处理流程
快照(Snapshot)的定义是:关于指定数据集合的一个完全可用拷贝,该拷贝包括相应数据在某个时间点(拷贝开始的时间点)的映像。快照可以是其所表示的数据的一个副本,也可以是数据的一个复制品。 ↩︎