C++ (week9):Git

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

sudoaptinstallgit

2.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.pub

3.粘贴公钥:
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-p10022


3.拉取仓库最近代码: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--rebase

rebase 后 (ABDC’):

A---B---D---C' (一条直线,C'是 C 的复制,hash 变了)

历史中看不出曾有一个分叉,好像 C’ 是看到 D 之后才做的。

全局设置 git pull --rebase 作为默认行为:
git config --global pull.rebase true


(2)merge

gitpull --no-rebase

merge 后 (ABCM 包含 D):

A---B---C---M\/ D---+

历史中清晰保留了分叉点、两条平行开发线,以及 M 将两者合并的动作。


4.git branch

1.查看分支

gitbranch
gitbranch-al
gitbranch-av

2.分支改名

gitbranch-m分支旧名 分支新名

例如:把本地的 master 改名为 main

gitbranch-mmaster main

3.切换分支

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--stat



7.本地项目推送到远程仓库

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 pop

git 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:master

10.子仓 (子模块 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-v

2.下载代码
下载enrigin/hal.git的远端enrigin_dev分支的代码

gitfetch enrigin enrigin_dev

3.本地合并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 仓库管理】