C++ (week9):Git 文章目录一、概念1.官网git手册2.git介绍3.git的工作原理4.git 与 svn 的区别5.git的工作区域二、官网页面上进行的操作1.新建仓库2.邀请开发者三、Linux上的git操作0.安装git1.基础配置ssh-keygen、git config、git init(1)生成ssh key(2)身份设置git config2.克隆远程仓库到本地git clone3.拉取仓库最近代码git pull(1)rebase(2)merge4.git branch5.Gerrit的 cherry-pick6.查看本地状态(1)查看本地仓库状态git status(2)看提交日志git log(3)查看差异git diff7.本地项目推送到远程仓库(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 rebase9.解决git冲突问题(1)git stash 和 git stash pop(2)多用户操作不同的文件(3)手动修改冲突的文件(4)版本冲突(5)强行覆盖①远程强行覆盖本地仓库②本地强行覆盖远程仓库10.子仓 (子模块 submodule)(1)初始化和更新子仓(2)同步子模块配置sync(3)去初始化 (清除子模块内容)deinit11.git指针HEAD与origin(1)是什么(2)两者关系(3)总结12.版本号标签13.查看远端、下载代码、合并代码四、Git操作 (复制的)五、代码管理平台一、概念1.官网git手册git官网手册https://git-scm.com/docs2.git介绍3.git的工作原理①工作区②暂存区.git/index③版本库生成版本号用哈希值表示。它们以链表方式进行存储。示例4.git 与 svn 的区别git相当于在本地也有一个版本控制库远程仓库也有一个版本控制库。5.git的工作区域工作区你写代码的地方临时存储区git stash暂存区git add本地仓库git commit远程仓库git push二、官网页面上进行的操作1.新建仓库2.邀请开发者三、Linux上的git操作0.安装git1.Linuxsudoaptinstallgit2.Windowsgit官网https://git-scm.com/install/windows1.基础配置ssh-keygen、git config、git init1.生成密钥ssh-keygenssh-keygen-ted25519-C你的邮箱example.com2.设置身份(一台电脑一次)gitconfig--globaluser.name 姓名gitconfig--globaluser.email 邮箱3.项目初始化(每个项目目录一次)它会在当前目录下生成一个隐藏的 .git 文件夹。只有当你本地写一个项目时才需要git init如果你是要从网上git clone那么作者当时已经git init过了你就不要再本地git init了。gitinit(1)生成ssh key1.生成公钥#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-Tgitgithub.com //然后输入yesyes然后就OK了(2)身份设置git config在Gitee、GitHub上注册账号配置 user name 和email。家目录下会生成.gitconfig文件。gitconfig--globaluser.namexxxEdwardxxxgitconfig--globaluser.emailxxxxxqq.com2.克隆远程仓库到本地git clone1.获取仓库的地址(1)gitee(2)github复制git连接不能翻墙要用SSH连接HTTPS会连不上2.执行命令将项目以文件夹形式 克隆到本地gitclone 仓库地址3.测试能否连接到GitLabssh-Tgitgitlab.riverbegin.com-p100223.拉取仓库最近代码git pullgit pull git fetch git merge/rebase初始C(本地)/ A---B\D(远程)当远程仓库出现分叉时仅仅git pull会报错fatal: Need to specify how to reconcile divergent branches.需要手动指定是merge还是rebase(1)rebasegitpull--rebaserebase 后 (ABDC’)A---B---D---C (一条直线C是 C 的复制hash 变了)历史中看不出曾有一个分叉好像 C’ 是看到 D 之后才做的。全局设置 git pull --rebase 作为默认行为git config --global pull.rebase true(2)mergegitpull --no-rebasemerge 后 (ABCM 包含 D)A---B---C---M\/ D---历史中清晰保留了分叉点、两条平行开发线以及 M 将两者合并的动作。4.git branch1.查看分支gitbranchgitbranch-algitbranch-av2.分支改名gitbranch-m分支旧名 分支新名例如把本地的 master 改名为 maingitbranch-mmaster main3.切换分支gitcheckoutbranch-name4.创建分支gitbranchbranch-name5.删除分支先切换到其他分支上然后才能删除要删除的那个分支gitbranch-dbranch-name5.Gerrit的 cherry-pickcheckout是用远程覆盖本地。cherry-pick是远程与本地merge可能会conflict。6.查看本地状态(1)查看本地仓库状态git statusgitstatus(2)看提交日志git loggitloggitlog--oneline(3)查看差异git diffgitdiff#详细对比所有改动#未addgitdiff--stat#已add未commitgitdiff--cached--stat#相对远程仅已提交的不含未commitgitdifforigin/enrigin_dev...HEAD--stat#相对远程工作区现状含未commitgitdifforigin/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 origincommit-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 commitgit commit 将暂存区的修改保存到本地仓库形成一个新的版本作为项目历史的一部分。gitcommit-m提交描述信息gitcommit.gitcommit.--amend(5)将本地仓库中的commit推送到远程仓库git pushgit push 命令用于将 本地仓库 中的 提交commits 推送到 远程仓库例如 GitHub、GitLab 等gitpush远程仓库名分支名gitpush origin master推送特定分支 如果你在本地创建了新分支并想推送到远程仓库你可以使用gitpush origin new-branch(6)查看仓库的状态git statusgitstatus(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 resetgitreset--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 rebase9.解决git冲突问题VSCode git/gerrit解冲突https://blog.csdn.net/Edward1027/article/details/162942459解决git冲突是一门很深的学问。后续慢慢补充。上文中15也提到了 冲突时用 备份 强行覆盖的方式先pull再push解决冲突。如果本地有修改则不能git pull。(1)git stash 和 git stash popgit 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--rebaseHEAD 你本地的修改远端的修改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)同步子模块配置syncsync 处理的是子模块配置的同步gitsubmodulesync--recursive在修改 .gitmodules 文件后确保子模块的 URL 和路径配置在 Git 配置中同步。(3)去初始化 (清除子模块内容)deinitdeinit 处理的是子模块的清理和移除gitsubmodule deinit-f.取消初始化子模块即让 Git 认为该子模块不再被初始化和跟踪。执行 deinit 后子模块的内容会被从你的工作树中移除但子模块的信息仍然保留在 .gitmodules 文件和 .gitmodules 的 git 配置中。11.git指针HEAD与originHEAD当前已经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://gitgitlab.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 --prettyoneline 查看日志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 仓库管理】