本文介绍: 介绍Git之前,还得先介绍版本控制系统(VCS), 和它的发展历史。

一、简介

介绍Git之前,还得先介绍下 版本控制系统(VCS), 和它的发展历史

纵观版本控制系统发展历史,广义上讲,版本控制工具的历史可以分为三代:

第一代

第一代版本控制系统被称为本地版本控制系统通过加锁并发执行转换成顺序执行。 一次只能有一个处理文件。具体流程如下:首先,应该文件放在一个服务器上,方便使用者上传下载文件;其次,任何人想对文件修改时,需要先把这个文件加锁通过checkout指令,使得其他人无法修改最后,当修改完成之后,需要释放锁,通过checkin指令,形成一个新的版本,存放到服务器端

第一代版本控制系统主要有 RCS、SCCS(1972年发布)和 DSEE(被认为是 Atria ClearCase 的前身)。目前,有些项目还在使用

悲观
每次获取数据时候,都会担心数据修改,所以每次获取数据时候都会进行加锁,确保在自己使用过程数据不会被别人修改使用完成后进行数解锁。由于数据进行加锁,期间对该数据进行读写的其他线程都会进行等待

第二代

第二代版本控制系统被称为集中式版本控制系统(Centralized Version Control Systems,CVCS),其对同步修改更加宽容,但有一个明显的限制用户必须在允许提交之前将当前修订合并他们工作中。

由上图可看到,在集中式版本控制系统中,如果服务器嗝屁了,那么所有的开发者就只能干瞪眼了!因为,SVN 对于项目管理依赖于服务器中的中心仓库的!我们更改必须要提交服务器中的中心仓库

第二代版本控制系统主要有 CVS、SourceSafe、Subversion、Team Foundation Server、SVK。

乐观
每次获取数据时候,都不会担心数据被修改,所以每次获取数据时候都不会进行加锁,但是在更新数据时候需要判断该数是否被别人修改过。如果数据被其他线程修改,则不进行数更新,如果数据没有被其他线程修改,则进行数更新。由于数据没有进行加锁,期间该数可以被其他线程进行读写操作
乐观锁一般会使用版本号机制或 CAS 算法实现

第三

第三代版本控制系统被称为分布式版本控制系统(Distributed Version Control Systems,DVCS),其允许合并提交分开。在每个使用者电脑上就有一个完整数据仓库没有网络依然可以使用

由上图可看到分布式式版本控制系统也可以有个服务器端的仓库用来同步开发者私有仓库!在分布式版本控制系统中,每个参与者的本地也会有一个完整仓库。及时服务器崩溃我们仍然可以使用 Git(仅在本地仓库管理我们的代码),在网络具备时,再和服务器进行同步即可

第三代版本控制系统主要有 Bazaar、Git、Mercurial、BitKeeper,、Monotone。目前,第三代版本控制系统已经大有一同江湖的趋势!

那么市面上常用的版本控制系统有哪些呢?

SVN 一个中式版本控制系统(Centralized VCS)

SVN(Subversion 的缩写)是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用分支管理系统。SVN 由 CollabNet 公司于 2000 年资助并发开发,目的是创建一个更好用的版本控制系统以取代 CVS。

2000 年 2 月,CollabNet 联系了 Open Source Development with CVS(Coriolis, 1999)的作者 Karl Fogel,问他是否愿意为这个项目工作。这时 Karl 已经在和他的朋友 Jim Blandy 讨论一个新的版本控制系统的设计。他不仅已经起好了名字 “Subversion”,而且有了 Subvesion 资料库基本设计

经过 14 个月的编码,在 2001 年 8 月 31 号,Subversion 可以“自我寄生”了。就是说,Subversion 开发人员停止使用 CVS 管理 Subversion 的源代码,开始使用 Subversion 代替。

2009 年 11 月,Subversion 被 Apache Incubator 项目接收。2010 年 1 月,正式成为 Apach软件基金会的一个顶级项目

以下是几款常用的 SVN 客户端图形化软件

BitKeeper

BitKeeper 是一套 BitMover 公司开发的分布式版本控制软件,它曾是一款专有软件。BitKeeper 是最初的分布式源代码控制系统。BitKeeper 的许多概念取自 TeamWare(Larry McVoy 在 Sun 公司开发产品)。

BitMover 公司 CEO Larry McVoy 与 Linus 曾是好友, Larry 说服 Linus 在内核开发使用 BitKeeper。而 BitKeeper 在免费使用许可证加入很多限制条件,惹恼了内核开发者,最终促使 Linus 开发出了毁灭 BitMove r的 Git。

2016 年 5 月 11 日,BitKeeper 宣布以 Apache 2.0 许可证开源

Git 一个分布式版本控制系统(Distributed VCS)

在 Linux 开源的初期,Linux 开源项目的代码是 linus 本人通过 linux 命令 diff 和 patch 两条命令手动完成。随着 Linux 代码越来越壮大,靠 Linus 一个人手动合并已经不现实。2002 年,Linus 选择了一个商业版本控制系统 BitKeeper 作为 Linux 内核代码管理工具(BitKeeper 的开发商 BitMover 授权 linux 社区免费使用)。但是,免费使用是有很多的限制的,因此 linux 社区大佬开始破解 BitKeeper。其中,samba 的作者 andre破解成功了。但是被 BitMover 公司发现,收回免费使用权。

迫不得已,Linus 选择自己开发一个分布式版本控制工具以替代 BitKeeper。linus 闭关一个月,写出了 Git。在一个月后,Git 成功接管了 Linux 社区的版本控制工作,并且开始开源。维基百科中,有如下历史记录

  • 2005 年 4 月 3 日,开始开发 Git。

  • 2005 年 4 月 6 日,项目发布

  • 2005 年 4 月 7 日,Git 就可以作为自身的版本控制工具了。

  • 2005 年 4 月 18 日,发生第一个分支合并

  • 2005 年 4 月 29 日,Git 的性能就已经达到了 Linus 的预期。

  • 2005 年 6 月 16 日,Linux 核心 2.6.12 发布,那时 Git 已经在维护 Linux 核心源代码了。

  • 在 2005 年 7 月 26 日,Linus 功成身退,将 Git 的维护交给另外一个 Git 的主要贡献者 Junio C Hamano

在 Linus Torvalds 开发出 Git 分布式版本控制系统 11 年后的 2016 年,BitKeeper 宣布在 Apache 2.0 许可证开源

二、Git常用命令

git commit提交规范

typecommit 的类型
feat: 新特性
fix: 修改问题
refactor代码重构
docs: 文档修改
style代码格式修改, 注意不是 css 修改
test测试用例修改
chore: 其他修改, 比如构建流程依赖管理.
scopecommit 影响范围比如routecomponentutilsbuild
subject: commit 的概述建议符合 50/72 formatting
body: commit 具体修改内容, 可以分为多行, 建议符合 50/72 formatting
footer: 一些备注, 通常是 BREAKING CHANGE 或修复的 bug 的链接.

三、Git异常场景处理

场景1:git 文件名大小写的坑

当你创建了一个 Components.jsx 的文件,后来给它改了个名,components.jsx,  会发现一个神奇的现象:git 对这个改动没有跟踪记录

git 默认情况下是不区分大小写的,需要单独设置

git config core.ignorecase false

场景2:刚刚提交的代码发现写错了怎么办?

刚提交了一个代码发现有几个字写错了:

怎么修复

当场再写一个修复这几个错别字的 commit?可以是可以,不过还有一个更加优雅和简单解决方法:commit -—amend

“amend” 是「修正」的意思。在提交时,如果加上 –amend 参数,Git 不会在当前 commit 上增加 commit,而是会把当前 commit 里的内容和暂存区(stageing area)里的内容合并起来后创建一个新的 commit,用这个新的 commit 把当前 commit 替换掉。所以 commit –amend 做的事就是它的字面意思:对最新一条 commit 进行修正

具体地,对于上面这个错误,你就可以把文件中的错别字修改好之后,输入

git add 笑声.txt

git commit --amend -m 'XXX'

Git 会把你带到提交信息编辑界面。可以看到,提交信息默认是当前提交的提交信息。你可以修改或者保留它,然后保存退出然后,你的最新 commit 就被更新了。

场景3:想直接丢弃刚写的提交?

有的时候,刚写完的 commit 写得实在太烂,连自己的都看不下去,与其修改它还不如丢掉重写。这种情况,就可以用 reset 来丢弃最新的提交。

git reset --hard HEAD^

// --hard 标志告诉 git 要完全重置工作目录暂存区,去匹配最后一次提交。在这个过程中,所有未提交的改动和新添加的东西都会被删除。
// HEAD 是一个指向最后一次提交的指针

// 如果你只是想回滚到之前的一个特定提交

git reset --hard commit_id

// --soft 参数:仅仅在本地库移动 HEAD 指针。
// --mixed 参数:在本地库移动 HEAD 指针重置暂存区。
// --hard 参数:在本地库移动 HEAD 指针重置暂存区、重置工作区。

场景4:需求代码一顿敲,自信push结果发现推错了分支?

方法1:reset
# 取消最新的提交,然后保留现场原状
git reset HEAD~ --soft
git stash

# 切换正确的分支
git checkout feature2
git stash pop
git add .    # 或添加特定文件
git commit -m "commit message"
方法2:cherry-pick(摘樱桃)
git log //在dev分支找到要合并的commit记录
git checkout feature2
# 把主分支上的最新提交摘过来
git cherry-pick commitId //需合并到feature2的commitId

# 再删掉主分支上的最新提交
git checkout dev
git reset HEAD~ --hard

场景5:一个需求分支代码commit了太多次,合并到master前想简化提交记录

新建分支就改了一行代码,推送前看了下提交记录,

发现修改了n次,想要精简提交记录,可以使用

git rebase -i <branchName> 
// -i 是希望调整commit message
// branchName目的分支

pick完当前分支相对目标分值的commit 之后,会提示代码冲突解决需要

git rebase --continue  // 继续变基操作

git push -f //强推

场景6:代码已经 push 上去了才发现写错?

(1)出错的内容在你自己的 branch

需要修改的commit 未 push 到远端,可以直接对需要修改的commit进行操作,然后push;

若修改的commit 已经 push 到远端,由于你在本地对已有的 commit 做了修改,这时你再 push 就会失败,因为中央仓库包含本地没有的 commits。但这个和前面讲过的情况不同,这次的冲突不是因为同事 push 了新的提交,而是因为你刻意修改了一些内容,这个冲突是你预料到的,你本来就希望用本地的内容覆盖掉中央仓库的内容。那么这时就不要乖乖听话,按照提示去先 pull 一下再 push 了,而是要选择「强行」push:

git push origin branch1 -f

-f 是 —force 的缩写,意为「忽略冲突,强制 push」。

(2)出错的内容已经合并到 master
同事的工作都在 master 上,你永远不知道你的一次强制 push 会不会洗掉同事刚发上去的新提交。所以除非你是人员数量和行为都完全可控的超小团队,可以和同事做到无死角的完美沟通,不然一定别在 master 上强制 push。

在这种时候,你只能退一步,选用另一种策略:增加一个新的提交,把之前提交的内容抹掉

有两种回退方案可供选择 git revert 和 git reset

git revert commit_id
// git revert是用一次新的commit来回滚之前的commit,此次提交之前的commit都会被保留;
// git revert --abort:冲突发生后,当前的操作会回到指令执行之前的样子,回到原始的状态,相当于什么事没有发生
// git revert --quit:冲突发生后,从反做操作行为退出,该指令会保留文件冲突
// git revert --skip:冲突发生后,跳过此次反做操作
// git revert --continue:冲突发生后,解决冲突并add后,执行该命令,会继续之前的操作流程

git reset [--soft | --mixed | --hard] [HEAD]
// git reset是回到某次提交,提交及之前的commit都会被保留,但是此commit id之后的修改都会被删除;

注意:在回滚这一操作上看,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现;但是git reset是直接把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit还会被引入

原文地址:https://blog.csdn.net/qq_35081500/article/details/109509764

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_30722.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注