git是一款人数众多的分布式版本控制系统,可以保存代码的不同版本,当代码出现bug的时候也可以回溯到没有bug的版本,比较俩个版本之间的差别,从而找出bug源头,并且在多人协作的时候,我们也会修改到相同的文件,git也能帮我们完成修改的合并,可以节省不少时间,版本控制系统就应运而生,主要是应对有大项目,其他版本控制软件还有:CVS,Subversion,Mecurial, Bazaar等等。git是应用最广泛也是运用于中小项目最多的一个,版本控制的概念都是互通的。git入门最好入门,git主要是用命令行操作的。
仓库:指存储源文件,工程文件,资源文件和一些配置信息。可以是本地的仓库也可以是远程服务器的仓库,仓库之间可以相互同步。本地也可以同步到远程。
版本控制系统有以下特点:
1.记录历史版本信息(每一次修改的记录)
2.方便团队协作开发(合并代码便捷)
3.出现bug可以回滚到之前版本
常用的版本控制系统分类
集中式版本控制系统:SVN(小乌龟,国内常用的) , CVS(国外常用)
集中式版本控制弊端:
1.需要联网才能连上中央服务器进行回退版本或查看历史版本
2.所有上传和下载都是基于文件进行的,如果文件大会很慢
3.中央服务器坏了,代码都会被销毁
分布式版本控制系统:git
//git是基于本地进行创建仓库的,每一台电脑就是一台服务器,也是一个本地代码管理仓库 //git通过 git init命令创建本地仓库 本地仓库分为:工作区,暂存区 ,历史版本区 工作区是用于写代码的 暂存区用于临时存储代码 历史版本区通过暂存区提交过来,生成一个版本用于以后可以回滚(从本地仓库的历史版本区 通过命令回滚到工作区) 工作流程: 工作区=> git add . =>暂存区 =>git commit -m '描述'=>历史版本区=> 先拉取 git pull origin master=>本地解决代码冲突=>git push origin master=> 中央仓库 代码回滚: 从暂存区撤回到工作区=>git check 可以从暂存区回滚到工作区,也可以从历史版本区回滚到工作区 只要电脑上用就不需要联网 如果是团队协作开发必须有一个中央服务器(用于多人提交代码),在中央仓库拉取过后不联网都可以看 git的优点: 1.无需联网也能记录和查看历史版本信息 2.无需过多依赖本地仓库,每个人本地都有全部信息 3.git向中央服务器传输是文件流传输,而svn是文件传输,所以git比svn快N倍
公司里使用git操作:
//早上到公司 先拉取最新代码,在开始工作 //晚上下班或上传前 先拉取代码,如果有冲突先本地解决代码冲突 (因为直接上传会覆盖掉别人写的代码) 在把没有问题的代码上传 //如果项目过大,自己上传到自己的远程分支即可,合并分支代码由技术负责人合并
第一步:下载git
第二步:下载完git安装(建议c盘)
可以通过git --version 或右键查看git进行确认git是否安装
右键打开 git Base Here进行配置基本用户信息
黑窗口跟shift+右键打开Powershell窗口也可以
MAC系统需要安装homebrew,在通过homebrew安装git
MAC电脑操作git只能打开终端输入cd 然后把项目录拖入终端,然后进行git命令操作
工作流程
工作区=> git add . =>暂存区 =>git commit -m '描述'=>历史版本区=> 先拉取 git pull origin master=>本地解决代码冲突=>git push origin master=> 中央仓库
创建仓库完成版本控制
//提交文件前必须关闭文件,否则提交不上去 //1.创建仓库 git init //会生成一个隐藏的文件夹,‘.git’文件夹(这个文件夹千万不能删,因为暂存区和历史区还有一些其他信息都在这个文件夹里面, //删了就不是一个完整的git仓库),一个电脑可以创建多个仓库 //2.在本地编写完成代码后(在工作区),把一些文件提交到暂存区 //把某个文件提交到暂存区 git add xxx //把所有最新修改的文件都提交到暂存区 git add . 或 git add -A //3.查看当前所有文件状态 红色是都没有添加到暂存区=>绿色的都是在暂存区还没到历史版本区 git status //4.把暂存区内容提交到历史区 git commit -m '描述信息' //5.查看提交记录 git log //包含了回滚历史 git reflog //在工作区提交到暂存区,从暂存区提交到历史区:这些操作都是把内容复制过去一份传过去的, //本区依然存在这些信息(只有这样才能对比出那些文件在某个区) //6.回滚历史版本(回滚错误版本还可以使用git reflog进行查看回滚操作信息,在此回滚) //版本号 git reset --hard afdsfhiasdhoioawsfhnowedf1232 //7.远程仓库github和码云(源代码管理平台) //用户注册后,可以在自己的账户下创建仓库,用来管理项目的源代码(源代码是基于git传到仓库中的),熟知的框架库的源码都在这个 //github上面,可以随时下载下载研究和观看等 //readme.md文件是用来描述这个项目的内容或js库的使用说明 //8.设置远程仓库地址 //查看本地仓库是否和远程仓库连接(如果连接会显示远程仓库地址) git remote -v //建立本地仓库和远程仓库的链接(origin是随便起的名字可以改,一般采用这个) git remote add origin [git仓库连接地址] //9.往远程仓库提交代码 //提交之前先拉取 origin的名字对应的是远程地址,是我们之前设置本地和远程仓库连接定义的(如果定义的aaa,origin就是aaa) git pull origin master //把本地代码提交到远程仓库(需要输入远程仓库账户的用户名和密码,如果不想输入参考我博文中的设置SSH秘钥教程) git push origin master //拉取远程仓库的代码 git clone [远程地址][别名,默认仓库名]
项目开发流程
1.负责人或组长先创建中央仓库(增加协作者) 2.小组成员基于git clone命令把远程仓库及默认的内容克隆到本地 3.每个组员写完自己的程序后,基于‘git add/git commit’把自己修改的内容存放到历史区,然后通过‘git pull/git push’把本地信息 和远程仓库信息保持同步即可(可能涉及到冲突的处理)
1.配置用户名
git config -l 查看配置信息 git config --gobal -l 查看全局配置信息 git config --global user.name 全局配置用户名 git config --global user.email 全局配置邮箱地址 //必须设置,不设置会提示英文:翻译成中文就是你提示我你是谁、 //安装之后先配置在操作,修改的话重新配置即可
2.创建新仓库
//在项目主目录下进行创建新仓库 git init
3.从远程服务器克隆一个仓库
git clone [远程地址][别名,默认仓库名,可以不写] git clone做了三件事: 1.初始化一个git仓库‘git init’ 2.和对应的远程仓库保持关联 git remote add 3.把远程仓库默认内容拉取到本地‘git pull’
4.显示当前的工作目录下的提交文件状态
git status
5.将指定文件标记为将要被提交的文件
//可以单独提交文件名 .是代表提交所有 git add .
6.将标记过为将要提交文件取消标记(不提交)
//可以取消提交文件名 .是代表取消提交所有 git reset .
7.提交本地仓库并提供提交信息
git commit -m '提交信息' //查看刚刚提交的信息 git commit --amend
8.查看提交历史
git log
9.向远程仓库推送
//第一次推送 git push 远程地址 //第一次过后推送 git push
9.1 将本地仓库与远程仓库进行关联(第一次创建分支或者是分支首次提交时需要用到)
//第一次推送 git push -u 远程别名 分支名称 //第一次过后推送 git push -u origin master
10.从远程仓库拉取
// origin的名字对应的是远程地址,是我们之前设置本地和远程仓库连接定义的(如果定义的aaa,origin就是aaa) git pull origin master
11.清屏clear
clear 清屏
12.查看当前所有文件状态
红色(在工作区)绿色(在暂存区)看不见(证明所有修改信息都在历史版本区)
git status
13.从暂存区撤回文件(从暂存区删除)
//从暂存区删除某个文件 git rm --cached xxx //撤销文件在工作区的修改 git checkout -- 文件名 //撤销指定文件的 git add 操作,即这个文件在暂存区的修改 git reset 文件名 //撤销之前的所有 git add 操作,即在暂存区的修改 git reset
14.查看所有的历史记录(包括历史区回滚后)
git reflog
14.回滚到历史版本
通过git log会查询出历史版本号 //也可以通过git reflog 进行回滚历史操作版本进行回滚 //版本号 commit afdsfhiasdhoioawsfhnowedf1232 git reset --hard 版本号
15.查看远程仓库地址(用于查看本地仓库和远程仓库是否链接)
git remote -v
15.本地和远程仓库创建链接(origin是随便起的名字可以改,一般采用这个)
git remote add origin [git仓库连接地址]
16.删除本地和远程关联地址
git remote rm origin
17. 解决提交代码校验问题
如果在commit -m 报了这个错,那么说明git仓库开启了代码审查校验,就需要运行越过代码校验的代码,这个只需要在提交本地仓库时运行即可
pre-commit hook failed (add --no-verify to bypass)
越过代码校验代码
git commit -m "初始化" --no-verify
如果我们想去除校验代码,则采用以下两种方式中的其中一种即可
1. 进入项目的.git文件夹下面hooks文件夹,手动删除pre-commit文件 或者 2. 运行命令:rm -rf ./git/hooks/pre-commit 删除pre-commit文件
也有可能是我们代码中设置了eslint代码审查
分支操作
1. 查看分支
1.1查看本地分支
git branch
1.2查看远程分支
git branch -r
1.3查看所有分支
git branch -a
2.分支操作
2.1切换远程分支
git checkout [分支名]
2.2分支合并
合并前要先切回要合并进入的分支
以下表示要把user分支合并入master分支
//切换到master分支 git checkout master //把user分支并入到当前分支,也就是master分支 git merge user //成功提示 Merge made by recursive. README | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
2.3 pull下所有的分支(拉取所有分支)
git pull -a
2.4 git新建分支并且在切换分支开发
从当前分支创建一个新的开发分支,创建并切换到user 分支
git checkout -b user
2.5把新建的分支push到远端
git push origin user
2.6删除分支
// 删除远程分支 git push origin --delete 分支名称 // 删除本地分支 git branch -d 分支名称
2.7 强制拉取代码
新建了一个仓库之后,把本地仓库进行关联提交、拉取的时候,不允许拉取时可以加上
--allow-unrelated-histories
进行强制拉取
git pull origin master --allow-unrelated-histories
2.8 强制合并代码
当我们确保当前仓库没有问题时却合并不了代码可以加上
--allow-unrelated-histories
在当前分支强行合并其他分支
git merge origin master --allow-unrelated-histories
2.9 创建远程分支并建立本地到远端仓库的链接并提交代码
远程仓库上没有该分支,使用这个代码会在远程仓库创建一个远程分支
git push --set-upstream [远程仓库名] [需要在远程创建的分支名] git push --set-upstream origin login //login为创建分支的名字
3.0 git强制提交本地分支覆盖远程分支(谨慎使用)
远程仓库拥有该分支,并且该分支下也有代码 需要覆盖该远程分支的代码
git push [远程仓库名] [需要覆盖的远程分支名字] --force //user为创建分支的名字 git push origin user --force //user为创建分支的名字
git 迁移项目操作
在不改变原有项目分支和提交记录的情况下更换远程仓库地址
第一步:拉取原有仓库代码
git clone [远程地址][别名,默认仓库名,可以不写]
第二步:在项目文件夹.git文件父级通过命令行进入.git文件夹
cd .git
第三步:删除原有仓库地址进行替换新仓库地址
git remote set-url --push [远程仓库别名,大多数都是origin] [远程仓库地址] git remote set-url --push origin git@xxxxxxxxxxxxxxx.git
第四步:进行查看仓库远程地址是否为新地址
git remote -v
第五步:将log和仓库提交记录提交到当前仓库
git push --mirror
git 迁移项目操作(第二种方案)
会清空所有的提交记录
第一步:拉取原有仓库代码
git clone [远程地址][别名,默认仓库名,可以不写]
第二步:查看所有远程分支并拉取到本地
//查看所有分支 git branch -a //切换分支 git checkout [分支名]
第三步:查看当前仓库地址看用几个,然后进行删除
//查看仓库地址 git remote -v //删除 git remote rm [仓库远程别名]
第四步:添加仓库新地址
//添加新地址 git remote add [仓库别名] [git仓库连接地址] //查看仓库地址 git remote -v
第五步:将每个本地分支的代码分别提交到暂存区在提交远程仓库中
//提交当前分支代码 git add . //提交本地仓库 git commit -m '提交信息' //创建远程分支并提交代码 //可以直接 git push 因为终端会给出以下命令提示,根据终端提示的命令直接执行即可 git push --set-upstream [远程仓库名] [需要在远程创建的分支名] git push --set-upstream origin master //master为创建分支的名字
第六步:如果本地分支还有其他分支的情况下
//切换下个分支进行重复第五步,第六步 git checkout [分支名]
强制性操作
1. 强制推送
git push -u -f origin master
-f 是强制推送,因为远程仓库只有初始化的文件,所以强制推送上去就行了,不加-f 会报当前分支没有远程分支,强制推送可以覆盖master
合并代码操作
快速合并
快进合并在两个分支出现分叉的情况下是不允许执行的。当目标分支相对于当前分支的提交历史不是线性的,Git只能通过三路合并算法来决定如何对两个分支进行合并。三路合并算法需要使用一个专用commit来整合两边的提交历史。这个名词源于Git要想生成合并commit,需要用到三个commits:两个分支的顶端commit,以及它们的共同祖先commit。
其实就是主分支也出现了新提交。除了三路合并,也可以在dev开发分支上cherry-pick main分支的新提交,保持两边同步。
三路合并(正常合并)
三路合并(冲突合并)
合并其他命令
禁用快进合并,即使两个分支没有冲突,也会创建一个新的合并提交
git merge --no-ff 分支名
将其他分支的修改内容压缩成一个提交,并且不会自动提交合并结果
git merge --squash 分支名
取消合并
直接取消合并,恢复到合并代码冲突前的状态
git merge --abort
强制合并
强制合并会直接应用源分支的所有更改到目标分支,这可能导致数据丢失或不正确的结果。因此,在使用强制合并之前,建议先对工作区、索引和提交记录进行适当的备份,并确保了解操作的后果
当我们确保当前仓库没有问题时却合并不了代码可以加上 --allow-unrelated-histories 在当前分支强行合并其他分支
git merge origin master --allow-unrelated-histories
合并代码详解
代码合并、扁平化合并和变基合并是版本控制系统(如Git)中用于整合不同分支代码的策略,但它们之间存在一些关键区别。
代码合并(Merge)
代码合并是最常见的合并策略,它通常是将两个或多个分支的更改合并到一起。在Git中,git merge命令用于执行合并操作。这种策略会保留所有分支的提交历史,并创建一个新的合并提交(merge commit),该提交包含所有分支的更改。这种方法的优点是简单直观,可以保留完整的提交历史,但缺点是可能会引入不必要的合并提交,导致提交历史变得复杂和难以理解。
代码合并的操作
在Git中,代码合并是将一个分支的更改整合到另一个分支的过程。这通常发生在将功能开发分支的更改合并到主分支(如master或main)时。以下是使用Git实现代码合并的详细步骤:
- 切换到目标分支
首先,你需要切换到你要合并到的目标分支。这通常是主分支或其他长期分支。
git checkout main
这里,main是目标分支的名称。
- 拉取最新更改(可选)
在合并之前,通常建议拉取目标分支的最新更改,以确保你的本地分支与远程分支同步。
git pull origin main
- 执行合并操作
使用git merge命令来执行合并操作。你需要指定要合并的源分支。
git merge feature-branch
这里,feature-branch是包含你想要合并的更改的源分支的名称。
- 解决合并冲突(如果有)
如果源分支和目标分支有冲突,Git会停止合并并提示你解决冲突。你需要手动编辑冲突的文件,然后标记冲突已解决。
编辑冲突文件
git add <解决冲突的文件>
继续合并过程
git merge --continue
如果你决定不合并,可以使用以下命令取消合并
git merge --abort
一旦所有冲突都解决了,Git会创建一个新的合并提交,该提交包含了合并的所有更改。你可以为这个提交添加一个描述性的提交信息。
git commit
扁平化合并(Squash Merge)
扁平化合并是一种特殊的合并策略,它将多个提交合并成一个单独的提交。在Git中,可以通过git merge --squash命令来实现。这种策略的目的是简化提交历史,将多个小的提交合并成一个有意义的更改。扁平化合并后,你需要手动创建一个新的提交来完成合并。这种方法的优点是可以保持提交历史的清晰和简洁,但缺点是可能会丢失一些提交信息,如提交者、提交时间等。
在Git中,扁平化合并(Squash Merge)通常是指在合并一个特性分支(feature branch)到主分支(如
main
或master
)时,将所有该特性分支上的提交压缩成一个单独的提交。这样做可以保持主分支的提交历史更加整洁,因为所有的特性开发细节都被隐藏在一个单独的提交里。
要使用扁平化合并,你可以按照以下步骤操作:
- 确保你在主分支上:
首先,你需要切换到主分支,这是你想要合并特性分支到的目标分支。
git checkout main
- 拉取最新更改:
在合并之前,拉取主分支的最新更改,确保你的本地分支与远程分支同步。
git pull origin main
- 准备合并:
使用git merge
命令开始合并过程,但是加上--squash
选项来告诉Git你想要扁平化合并。
git merge --squash feature-branch
- 这里的
feature-branch
是你要合并的特性分支的名称。 - 创建新的合并提交:
扁平化合并后,所有feature-branch
上的提交都会被压缩成一个单独的提交。Git会暂停在这个状态,等待你创建一个新的提交信息来描述这个合并。
git commit
- 此时,你可以编写一个描述性的提交信息,来总结这个特性分支的所有更改。
- 推送更改:
最后,将扁平化合并后的更改推送到远程仓库。
git push origin main
- 这将会把扁平化合并后的提交推送到远程仓库的
main
分支。
需要注意的是,扁平化合并会丢失特性分支上的提交历史,因此如果你需要保留这些历史信息(例如,为了后续审计或回滚更改),你可能需要选择其他的合并策略,如普通的合并(
git merge
)或变基合并(git rebase
)。
变基合并(Rebase)
变基合并是一种将一个分支的更改应用到另一个分支上的策略。在Git中,git rebase命令用于执行变基操作。与合并不同,变基会改变提交历史,将当前分支的更改重新应用到目标分支的最新提交上。这意味着提交历史会被重写,使得更改看起来像是直接在目标分支上进行的。变基的优点是可以保持一个线性的提交历史,使得项目历史更加整洁和易于理解。然而,变基也存在一些缺点,如可能会引入冲突和需要额外的谨慎操作,因为它会改变提交历史。
- 确保你在目标分支上:
首先,你需要切换到目标分支,这是你想要将更改变基到的分支。
git checkout main
- 这里的
main
是目标分支的名称。 - 拉取最新更改:
在变基之前,最好拉取目标分支的最新更改,确保你的本地分支与远程分支同步。
git pull origin main
- 开始变基过程:
使用git rebase
命令将源分支的更改变基到目标分支上。你需要指定源分支作为参数。
git rebase feature-branch
- 这里的
feature-branch
是包含你想要变基更改的源分支的名称。 - 解决冲突:
如果源分支和目标分支有冲突,Git会停止变基过程并提示你解决冲突。你需要手动编辑冲突的文件,然后使用git add
命令标记冲突已解决。
# 编辑冲突文件 git add <解决冲突的文件> # 继续变基过程 git rebase --continue
- 如果你决定不继续变基,可以使用以下命令取消变基:
git rebase --abort
- 完成变基:
一旦所有冲突都解决了,Git会重新应用源分支的提交到目标分支上,并创建一个新的提交历史。