C++ (week9):Git
文章目录
- 一、概念
- 1.官网git手册
- 2.git介绍
- 3.git的工作原理
- 4.git 与 svn 的区别
- 5.git的工作区域
- 二、官网页面上进行的操作
- 1.新建仓库
- 2.邀请开发者
- 三、Linux上的git操作
- 0.安装git
- 1.基础配置:ssh-keygen、git config、git init
- (1)生成ssh key
- (2)身份设置:git config
- 2.克隆远程仓库到本地:git clone
- 3.拉取仓库最近代码:git pull
- (1)rebase
- (2)merge
- 4.git branch
- 5.Gerrit的 cherry-pick
- 6.查看本地状态
- (1)查看本地仓库状态:git status
- (2)看提交日志:git log
- (3)查看差异:git diff
- 7.本地项目推送到远程仓库
- (1)Github、Gitlab提交代码 (无代码审核)
- (2)Gerrit提交代码 (有代码审核,msg-hook)
- (3)git add:工作区内容→暂存区
- (4)将暂存区内容保存到本地仓库:git commit
- (5)将本地仓库中的commit推送到远程仓库:git push
- (6)查看仓库的状态:git status
- (7)查看git日志:git log
- (8)撤销工作树中未commit的修改:git restore
- (9)git reset:撤销commit提交、版本回退
- ①git reset --softHEAD~1:撤销commit
- ②git reset (--mixed) HEAD~1:撤销commit + 撤销add
- ③git reset --hard HEAD~1:撤销commit + 撤销add + 撤销工作区代码 (版本回退)
- 8.分支管理
- (1)合作开发的方式
- (2)分支管理
- (3)分支合并的原理、冲突管理
- (4)git rebase
- 9.解决git冲突问题
- (1)git stash 和 git stash pop
- (2)多用户操作不同的文件
- (3)手动修改冲突的文件
- (4)版本冲突
- (5)强行覆盖
- ①远程强行覆盖本地仓库
- ②本地强行覆盖远程仓库
- 10.子仓 (子模块 submodule)
- (1)初始化和更新子仓
- (2)同步子模块配置:sync
- (3)去初始化 (清除子模块内容):deinit
- 11.git指针:HEAD与origin
- (1)是什么
- (2)两者关系
- (3)总结
- 12.版本号标签
- 13.查看远端、下载代码、合并代码
- 四、Git操作 (复制的)
- 五、代码管理平台
一、概念
1.官网git手册
git官网手册:https://git-scm.com/docs
2.git介绍
3.git的工作原理
①工作区
②暂存区:.git/index
③版本库
生成版本号,用哈希值表示。它们以链表方式进行存储。
示例:
4.git 与 svn 的区别
git相当于在本地也有一个版本控制库,远程仓库也有一个版本控制库。
5.git的工作区域
工作区:你写代码的地方
临时存储区:git stash
暂存区:git add
本地仓库:git commit
远程仓库:git push
二、官网页面上进行的操作
1.新建仓库
2.邀请开发者
三、Linux上的git操作
0.安装git
1.Linux
sudoaptinstallgit2.Windows
git官网:https://git-scm.com/install/windows
1.基础配置:ssh-keygen、git config、git init
1.生成密钥:ssh-keygen
ssh-keygen-ted25519-C"你的邮箱@example.com"2.设置身份(一台电脑一次):
gitconfig--globaluser.name 姓名gitconfig--globaluser.email 邮箱3.项目初始化(每个项目目录一次)
它会在当前目录下生成一个隐藏的 .git 文件夹。只有当你本地写一个项目时才需要git init;如果你是要从网上git clone,那么作者当时已经git init过了,你就不要再本地git init了。
gitinit(1)生成ssh key
1.生成公钥:
#ssh-keygen -t rsa -C "你的邮箱"ssh-keygen-ted25519-C"你的邮箱"然后三次回车ras是传统加密算法,ed25519是最新的加密算法。推荐用ed25519来生成密钥。
2.复制公钥:.ssh目录下的id_rsa.pub里就是公钥信息
cat~/.ssh/id_rsa.pub3.粘贴公钥:
gitee,设置,安全设置,SSH公钥,粘贴进去
github:
生成SSH公钥后,如图:
回到终端验证是否绑定本地成功,输入指令
ssh-Tgit@github.com //然后输入yesyes然后就OK了
(2)身份设置:git config
在Gitee、GitHub上注册账号,配置 user name 和email。家目录下会生成.gitconfig文件。
gitconfig--globaluser.name"xxxEdwardxxx"gitconfig--globaluser.email"xxxxx@qq.com"2.克隆远程仓库到本地:git clone
1.获取仓库的地址
(1)gitee:
(2)github:
复制git连接,不能翻墙要用SSH连接,HTTPS会连不上
2.执行命令,将项目以文件夹形式 克隆到本地
gitclone 仓库地址3.测试能否连接到GitLab
ssh-Tgit@gitlab.riverbegin.com-p100223.拉取仓库最近代码:git pull
git pull = git fetch + git merge/rebase
初始:
C(本地)/ A---B\D(远程)当远程仓库出现分叉时,仅仅git pull会报错:
fatal: Need to specify how to reconcile divergent branches.需要手动指定是merge还是rebase:
(1)rebase
gitpull--rebaserebase 后 (ABDC’):
A---B---D---C' (一条直线,C'是 C 的复制,hash 变了)历史中看不出曾有一个分叉,好像 C’ 是看到 D 之后才做的。
全局设置 git pull --rebase 作为默认行为:
git config --global pull.rebase true
(2)merge
gitpull --no-rebasemerge 后 (ABCM 包含 D):
A---B---C---M\/ D---+历史中清晰保留了分叉点、两条平行开发线,以及 M 将两者合并的动作。
4.git branch
1.查看分支
gitbranchgitbranch-algitbranch-av2.分支改名
gitbranch-m分支旧名 分支新名例如:把本地的 master 改名为 main
gitbranch-mmaster main3.切换分支
gitcheckout<branch-name>4.创建分支
gitbranch<branch-name>5.删除分支
先切换到其他分支上,然后才能删除要删除的那个分支
gitbranch-d<branch-name>5.Gerrit的 cherry-pick
checkout是用远程覆盖本地。cherry-pick是远程与本地merge,可能会conflict。
6.查看本地状态
(1)查看本地仓库状态:git status
gitstatus(2)看提交日志:git log
gitloggitlog--oneline(3)查看差异:git diff
gitdiff#详细对比所有改动#未addgitdiff--stat#已add未commitgitdiff--cached--stat#相对远程:仅已提交的(不含未commit)gitdifforigin/enrigin_dev...HEAD--stat#相对远程:工作区现状(含未commit)gitdifforigin/enrigin_dev--stat7.本地项目推送到远程仓库
1.git add . 将改动保存到暂存区
2.git commit -m “你要记录的信息”
(1)Github、Gitlab提交代码 (无代码审核)
gitadd.gitcommit-m"提交信息"gitpush origin 分支名(2)Gerrit提交代码 (有代码审核,msg-hook)
gitadd.gitcommit.或gitcommit.--amendgitpush origin HEAD:refs/for/分支名gitpush origin HEAD:refs/for/mastergitpush origin @:refs/for/mastergitpush origin<commit-hash>:refs/for/mastergitpush origin HEAD~1:refs/for/master# 推送倒数第二个提交①origin:远程仓库名,origin是远程仓库的默认名称
②HEAD:这是 Git 的引用,表示当前分支的最新提交(即当前分支的 HEAD),HEAD也可缩写为@。或者使用特定的提交哈希(Commit Hash)。或者 想推送比 HEAD 早 n 个提交的版本,你可以用 HEAD~n
③refs/for/分支名:这是Gerrit 系统中特有的分支命名规则,不会直接将代码merge入仓库,而是要放进Gerrit进行代码审核
④master、enrigin_dev、develop:分支名
(3)git add:工作区内容→暂存区
git add 命令的作用就是将工作区中的修改 添加到暂存区
gitadd.暂存区与工作区的区别:
工作区(Working Directory):
工作区就是你当前在本地计算机上编辑的文件目录。你对文件的任何修改都会首先发生在工作区。
这些修改还没有被 Git 跟踪或准备提交。
暂存区(Staging Area):
暂存区是 Git 中一个临时的区域,用于存储已添加(git add)的修改,准备进行提交。
当你使用 git add 命令时,你是将文件的当前修改放入暂存区,而暂存区的内容就是下次 git commit 提交的内容。
工作区:你直接编辑文件的地方,所有修改都是本地的,Git 还没有记录这些变化。
暂存区:你通过 git add 命令将修改添加到的区域,Git 会记录你选择的修改,等待提交。
(4)将暂存区内容保存到本地仓库:git commit
git commit 将暂存区的修改保存到本地仓库,形成一个新的版本,作为项目历史的一部分。
gitcommit-m"提交描述信息"gitcommit.gitcommit.--amend(5)将本地仓库中的commit推送到远程仓库:git push
git push 命令用于将 本地仓库 中的 提交(commits) 推送到 远程仓库(例如 GitHub、GitLab 等)
gitpush<远程仓库名><分支名>gitpush origin master推送特定分支: 如果你在本地创建了新分支,并想推送到远程仓库,你可以使用:
gitpush origin new-branch(6)查看仓库的状态:git status
gitstatus(7)查看git日志:git log
(1)查看所有详细git提交日志
gitlog(2)只查看某一个文件的改动日志
gitlog 文件名(3)每次git提交仅显示一行日志
gitlog--oneline(8)撤销工作树中未commit的修改:git restore
恢复工作区的文件: 撤销 git add 但未 git commit的修改, 则输入命令:
gitrestore<要撤销修改的文件名>(9)git reset:撤销commit提交、版本回退
git restore 更侧重于 撤销修改(工作区或暂存区的变化),
git reset 更侧重于 撤销提交(更改提交历史)。
①git reset --softHEAD~1:撤销commit
使用场景:撤销最近的提交,保留文件更改:
撤销最近的提交,保留文件更改:新一笔提交又习惯性把git commit .加了–amend,用这个命令只回退一次commit,不修改本地
如果你希望撤销最近的提交,但希望保留文件的更改在工作区(即保留修改,不丢失),可以使用以下命令:
gitreset--softHEAD~1- –soft:只撤销 commit,不动工作区或暂存区(改动依然保留)
- HEAD~1:表示回退 1 个提交
这将撤销最近的 commit,但将所有更改保留在暂存区,以便你可以重新提交。
②git reset (–mixed) HEAD~1:撤销commit + 撤销add
撤销最近的提交,取消暂存但保留文件更改
如果你希望撤销最近的 commit,并将文件从暂存区中移除(即取消 git add),但仍然保留修改在工作区,可以使用:
gitreset HEAD~1这将撤销提交,并把文件的更改放回工作区(不再处于暂存状态)。
③git reset --hard HEAD~1:撤销commit + 撤销add + 撤销工作区代码 (版本回退)
1.版本回退:git reset
gitreset--hardHEAD^ //回退到上一个版本gitreset--hard版本号哈希值(一部分也行),版本可以前进和后退2.完全撤销最近的提交(包括文件更改):
如果你希望撤销最近的 commit,并且希望丢弃所有的更改(即恢复到提交前的状态),可以使用:
gitreset--hardHEAD~1注意事项:
使用 git reset --hard 会丢失工作区的更改,因此在执行之前,请确保你不再需要这些更改。
git reset 只会影响本地仓库的提交,撤销提交后仍然可以使用 git status 和 git diff 查看更改。
8.分支管理
(1)合作开发的方式
1.每一个成员都操作一个不同的文件,只使用master分支
(2)分支管理
gitmerge --no-ff-m"提交描述"develop //合并分支切换分支、合并分支
(3)分支合并的原理、冲突管理
1.如果本地与远程修改的不是同一个文件,则先pull,拉取远程更新本地的其他文件,再push。
2.如果本地与远程修改的是同一个文件,则会冲突。先将本地冲突文件拷贝到其他无关目录下,再pull合并远程。再对比本地冲突文件和远程有什么区别,人工合并代码后,再push。
(4)git rebase
9.解决git冲突问题
VSCode git/gerrit解冲突:https://blog.csdn.net/Edward1027/article/details/162942459
解决git冲突是一门很深的学问。后续慢慢补充。
上文中15也提到了 冲突时,用 备份 + 强行覆盖的方式,先pull再push,解决冲突。
如果本地有修改,则不能git pull。
(1)git stash 和 git stash pop
git stash 用于暂时保存当前更改,git stash pop 用于恢复并移除栈中的最新保存项。
gitstashgitstash popgit stash: git stash 用于将当前工作目录中的更改(包括暂存区和工作区)保存到一个新的栈中,并将工作目录恢复到最后一次提交的状态。这对于当你正在进行某个功能的开发,但需要暂时切换到其他任务时非常有用。执行 git stash 后,你的工作目录会清空,回到上次提交的状态,但你的修改被保存在栈中,稍后可以恢复。
git stash pop: git stash pop 用来恢复上次保存的更改(从栈顶恢复),并将它们应用到当前工作目录。恢复后,栈顶的存储会被删除(与 git stash apply 的区别在于,git stash pop 会删除栈中的内容)。
(2)多用户操作不同的文件
gitpull修改文件之前,先与远程仓库同步(pull),再推送(push)
(3)手动修改冲突的文件
gitpull--rebase<<<<<<<HEAD (你本地的修改)=======(远端的修改)>>>>>>>d65ebb9cba
这里有四个选项
- Accept Current Chagne 选择当前的修改
- Accept Incoming Change 选择合并的修改
- Accept Both Change 接受两者
- Compare Chagne比较查看
然后执行一下
gitadd.gitrebase--continue然后:q退出commit信息
然后git push就可以了
举例:
Gitlab解决冲突
(4)版本冲突
gitpull--forceorigin master:master操作同一个文件,容易与远程冲突
解决冲突:cp本地修改的文件到其他位置 备份,然后用远程仓库强制覆盖本地仓库,再把备份的修改文件mv回来
gitpull--forceorigin master:master(5)强行覆盖
①远程强行覆盖本地仓库
gitpull--forceorigin master:master②本地强行覆盖远程仓库
gitpush--forceorigin master:master10.子仓 (子模块 submodule)
(1)初始化和更新子仓
#1.初始化子模块配置
#2.(递归)克隆子模块代码到本地
gitsubmodule update--init--recursive(2)同步子模块配置:sync
sync 处理的是子模块配置的同步
gitsubmodulesync--recursive在修改 .gitmodules 文件后,确保子模块的 URL 和路径配置在 Git 配置中同步。
(3)去初始化 (清除子模块内容):deinit
deinit 处理的是子模块的清理和移除
gitsubmodule deinit-f.取消初始化子模块,即让 Git 认为该子模块不再被初始化和跟踪。
执行 deinit 后,子模块的内容会被从你的工作树中移除,但子模块的信息仍然保留在 .gitmodules 文件和 .gitmodules 的 git 配置中。
11.git指针:HEAD与origin
HEAD:当前已经commit的最新一笔HEAD指向当前所在分支顶端的那一条 commit,就是你本地当前最新一笔提交。
HEAD~:当前已经commit的上一笔commit。HEAD~=HEAD~1,就是 HEAD 指向那笔提交的直接上一个父提交(前一笔)。HEAD~2:往前数第 2 个提交。
(1)是什么
- HEAD:它是一个指向你当前工作目录所基于的提交的引用。通常情况下,HEAD指向的是当前分支的最新提交。当你在这个分支上做新的提交时,HEAD会自动更新到最新的提交上。HEAD可以看作是你现在工作的“位置”。
- origin:远程仓库的默认名
(2)两者关系
①同步状态:当comit hash (HEAD -> branch_name, origin/branch_name),这意味着你的本地分支(由HEAD指向)和远程仓库中的对应分支(origin/branch_name)处于相同的状态,或者说最后一次同步时是相同的。如果你在本地做了新的提交,而没有推送到origin,那么HEAD将领先于origin/branch_name。
②追踪分支:当你从远程仓库克隆了一个项目,Git会自动设置所谓的“追踪分支”。例如,本地的master分支可能配置为追踪origin/master。这意味着当你执行如git pull或git push命令时,Git知道应该与哪个远程分支进行同步。
③差异检查:你可以使用git diff来比较HEAD和origin/branch_name之间的差异,查看自上次同步以来你所做的更改。
(3)总结
总的来说,HEAD关注的是你在本地代码库中的当前位置,而origin则涉及到你如何与外部代码库(通常是远程仓库)进行同步和交互。它们各自的功能不同,但在日常的Git操作中经常一起使用来管理和同步代码版本。
12.版本号标签
gittag v1.0 //给当前分支的当前版本,打上v1.0的标签gittag v1.1 versionno //给某个版本号(哈希值)的分支打上v1.1的标签gittag //查看标签的情况gittag-dv1.0 //删除本地标签删除标签
13.查看远端、下载代码、合并代码
1.查看远端
新增一个enrigin/hal.git的远端
gitremoteaddenrigin ssh://git@gitlab.riverbegin.com:10022/enrigin/hal.git#查看是否添加成功gitremote-v2.下载代码
下载enrigin/hal.git的远端enrigin_dev分支的代码
gitfetch enrigin enrigin_dev3.本地合并enrigin/hal.git的enrigin_dev分支
gitmerge enrigin/enrigin_dev四、Git操作 (复制的)
git的使用
8、git reset --hard 端口号
10、git remote -v 查看是否添加远程名字,如果没显示,就说明还没传上去
11、git remote add origin https://gitee.com/fang_zhihao/git_fzh.git 添加上传远程地址
12、git fetch 更新仓库
13、git pull origin master 远程分支
14、git pull origin master --allow-unrelated-histories 如果你的仓库是非空的,那就在打一遍这个
15、git push origin master 将本地仓库推送到远程仓库
16、git branch -v 查看本地分支
17、git branch -r 查看远程分支
18、git branch -d 分支名 删除分支
19、git branch 分支名 创建分支
20、git checkout 分支名 查看哪个分支
30、git rm --cached (文件名) 撤回放入暂存区
34.(1) git log --pretty=oneline 查看日志
34.(2) git log 查看日志
34.(3) git log --oneline 查看日志
35.git reset --hard (文件名) 回退
五、代码管理平台
Git 平台(GitLab、GitHub、Gitee、Gerrit):都基于 Git 版本控制,支持分布式开发,适合协作开发和频繁的分支管理。
SVN:集中式版本控制系统,适合对代码版本控制要求不高的项目,不适合分布式开发和频繁的分支管理。
【GitLab 是一个基于 Git 的开源 DevOps 平台,提供了代码版本控制、CI/CD、代码审查、项目管理等功能】
【Gerrit 是一个专门用于代码审查的工具,支持 Git 仓库管理】
