Git学习(4)Git分布式优势与实战配置全解析

🔥keyipatience:个人主页

🎬作者简介:C/C++后端开发学习者

🌟专栏传送门:《c++》《linux》《c++高阶数据结构》《c++数据结构与算法》《前端学习》

《Git》

⭐️patience is key in life

Git 分布式版本控制系统

Git 是分布式 的,和 SVN 这种集中式不一样:每一台开发者电脑上,都保存一份完整的版本库(工作区、暂存区、所有历史提交记录全都有)。

集中式:只有中央服务器存完整仓库,本地只拿文件,断网基本没法提交、看历史。

分布式:本机就是完整仓库,断网也能正常 commit、查看历史、分支操作。

多人协作原理

每个人本地都有全套版本库:

  • 你在自己电脑修改文件、提交;同事在他电脑也修改同一份文件、提交;
  • 你们之间可以互相推送(push)、拉取(pull)对方的提交,同步修改;

优点:安全性高

每个人手里都有完整副本。 如果某一台电脑硬盘损坏、数据丢了,可以从其他任何人的仓库里复制一份完整版本库恢复,不怕单点故障

实际开发里的 "中央服务器

Git 本身分布式,不是必须要有中央服务器;但是实际工作几乎都会搭一个(比如 GitHub、Gitee、公司 GitLab)。大家都往这个公共仓库推代码、从这里拉代码,统一协作入口。

新建远程仓库

归属(下拉框)

选仓库属于谁:

  • 选自己账号:私人仓库
  • 如果你加入了 Gitee 组织,也可以选组织(团队共用)

仓库名称【必填】

只能英文、数字、横杠 -、下划线 _,不能中文、空格 ,就是仓库地址里的名字。 例:cpp-demo,仓库地址最后一段就是它。

仓库介绍(选填)

简单写这个项目是干嘛的,展示在仓库主页。

是否开源

  • 公开:所有人都能看、克隆你的代码;你可以设置别人能不能提 PR
  • 私有:只有你自己、你添加的成员可以访问,外网看不到

使用 Readme 文件初始化这个仓库

勾选:Gitee 自动帮你生成一个 README.md(项目说明文档) 勾选之后:远程仓库自带一个提交记录。后面本地上传代码的时候,就必须先 pull,不然 push 冲突。 不勾选:远程是空仓库,里面啥文件都没有,没有任何提交记录。本地代码直接 push 上去,不用 pull。

添加 .gitignore

.gitignore 的作用:告诉 git 哪些文件不要提交(编译产物、缓存、IDE 配置、日志等) 下拉选择对应模板:

许可证(开源仓库才需要关心,私有仓库随便选)

只有你选【公开】仓库时这个才有意义:

  • MIT:很宽松,别人可以拿你的代码改、商用,保留版权声明就行(最常用)
  • GPL:别人修改、基于你的项目发布,也必须开源
  • 私有仓库:许可证选不选无所谓,一般选【不添加许可证】

分支模型

Gitee 新建页这个下拉:

  1. 标准模型(master /main 单主分支) 只有一条主分支,新版 Gitee 默认主分支名字是 main,老仓库叫 master。个人学习、课程作业、自己写项目,无脑选这个。
  2. GitFlow 分支模型 自动创建:main、develop、feature/、release/、hotfix/* 分支一套体系 适用:正规团队长期迭代项目,版本发布、bug 修复分开管理 不适合:个人小项目,太麻烦,分支太多用不上

其他小选项

  • 允许 Issue:开启后别人可以给你提问题、反馈 bug,私有仓库也可以关掉
  • 允许 Pull Request:别人可以提交代码修改请求,个人项目无所谓

组合方案两套

方案 1:你本地已经有仓库(推荐搭配)

网页填写配置:

  • 归属:自己账号

  • 仓库名:xxx

  • 是否开源:私有

  • 【不要勾选 Readme 初始化】

  • .gitignore:选 C++(按需)

  • 许可证:不添加

  • 分支模型:标准模型 创建之后,本地命令

    //给这个本地仓库绑定一个远程地址,远程的别名固定叫 origin
    git remote add origin https://gitee.com/xxx/xxx.git
    //把本地的提交记录,推送到远程 origin 对应的仓库的 master 分支
    git push -u origin main

    //手滑勾选了 Readme(远程有 README),上面 push 会报错,换成:

    git remote add origin https://gitee.com/你的名字/仓库名.git
    //专门用来解决:本地和远程各有第一条提交、历史互不关联的报错
    git pull origin main --allow-unrelated-histories//
    git push -u origin main

方案 2:本地是空的,打算新建一个全新仓库克隆下来再写代码(推荐搭配)

网页填写配置:

  • 归属:自己账号

  • 仓库名:xxx

  • 是否开源:私有

  • 勾选 Readme 初始化

  • .gitignore:选 C++

  • 许可证:不添加

  • 分支模型:标准模型 创建之后,本地只需要:

    git clone https://gitee.com/xxx/xxx.git

    //git clone干的事:

    1. 创建名为 xxx 的文件夹
    2. 进入文件夹,执行 git init,生成 .git,把这个文件夹变成本地 Git 仓库
    3. 执行 git remote add origin https://gitee.com/xxx/xxx.git,绑定远程地址
    4. 拉取远程仓库所有提交记录(git fetch)
    5. 检出默认分支(main/master),把所有文件放到本地文件夹

Gitee 克隆仓库的两种方式:HTTPS 和 SSH

1、HTTPS(简单)

复制代码
git clone https://gitee.com/hyb91/git_teaching.git
  • 优点:不用额外配置,复制链接直接克隆
  • 缺点:每次 push /pull 的时候,都要输入你的 Gitee 账号密码

2、SSH(配置完之后免密码,长期写代码推荐)

复制代码
git clone git@gitee.com:hyb91/git_teaching.git
  • 直接跑这条命令大概率报错:Permission denied (publickey),因为现在服务器不认你,没有密钥
  • 原理:SSH 靠一对密钥验证身份(公钥 + 私钥),不用输账号密码

SSH 完整配置步骤

1.生成密钥对

复制代码
ssh-keygen -t rsa -C "你的gitee绑定邮箱"

一路回车,不要设置密码。 生成两个文件,在 ~/.ssh/ 文件夹:

  • id_rsa:私钥!自己收好,绝对不能发给别人
  • id_rsa.pub:公钥,这个要复制内容放到 Gitee 上

2.把公钥上传到 Gitee Gitee 右上角头像 → 设置 → SSH 公钥 标题随便写,把 id_rsa.pub 里面全部文本粘贴进去,保存,验证账号密码。

3.配置完成后,再用 ssh 链接 clone。

详细剖析:

复制代码
git remote

列出所有远程仓库的别名 输出只有 origin,代表:这个本地仓库绑定了一个远程仓库,名字就叫 origin(就是我们之前说的默认远程别名)

其实当我们从远程仓库克隆后,实际上 Git 会自动把本地的 master 分支和远程的 master 分支对应起来,并且,远程仓库的默认名称是 origin

怎么理解:

origin 只是远程仓库的别名 ,就是一个简短代号,代替长长的仓库地址。 git clone 执行的时候,Git 自动执行了 git remote add origin 仓库地址( 给当前这个本地 Git 仓库,登记一个远程仓库,代号叫 origin)。 之后写 origin 就代表这个 Gitee 仓库,不用每次粘贴一长串链接。

用 git remote -v 就能看到 origin 绑定的真实地址。

复制代码
git remote -v

origin  git@gitee.com:hyb91/git_teaching.git (fetch)
origin  git@gitee.com:hyb91/git_teaching.git (push)
//- `(fetch)`:拉取地址,用来 `pull / fetch`(下载远程代码到本地)
//- `(push)`:推送地址,用来 `push`(把本地代码上传到远程)

本地 master 和远程 master 对应起来"(跟踪关系 / 上游关联)

克隆完成,本地会生成 master 分支,Git 自动设置: 本地 master 的上游(跟踪分支) = origin/master。相当于 Git 记住了你这个本地分支默认要推送到 origin 的 master 分支

这个绑定带来的效果: 你直接敲

复制代码
git push

等价于

复制代码
git push origin master:master

直接敲

复制代码
git pull

等价于

复制代码
git pull origin master:master

一句话:因为有这个跟踪绑定,命令可以简写,不用每次都写 origin master


对比另外一种路线 (git init + git remote add origin)

如果你是自己 git init 新建本地仓库、手动 remote add origin: 不会自动建立分支跟踪关系 所以第一次 push 必须加 -u:

复制代码
git push -u origin master

-u 的作用就是:手动建立这个跟踪绑定 ,绑定成功之后,后面也可以直接 git push。

向远程仓库推送

复制代码
# 1. ls 查看当前里面已有文件
ls
# 输出:README.en.md  README.md(clone下来自带的)

# 2. vim 新建并编辑 file.txt
vim file.txt
# 里面写入:hello git

# 3. cat file.txt 查看文件内容,确认写进去了
cat file.txt

# 4. git add .
git add .

# 5. git commit -m "create file.txt"
git commit -m "create file.txt"

commit 时的身份要求

提交时要注意,如果我们之前设置过全局的 name 和 e-mail,这两项配置需要和 gitee 上配置的用户名和邮箱一致,否则会出错。(Git和gitee配置要一样)

user.name/user.email(commit 作者信息) 是标记:这个代码是谁写的,commit 的时候就写进版本记录。 如果和 Gitee 账号里的邮箱不匹配:Gitee 识别不出是你提交的,头像不显示、贡献统计不算绿点,严格仓库会直接报错。

设置命令:

复制代码
# 全局(所有git仓库共用)
git config --global user.name "gitee用户名"
git config --global user.email "gitee绑定邮箱"

git push 语法

基础语法:

复制代码
git push <远程主机名> <本地分支名>:<远程分支名>

如果本地分支名字 和 远程分支名字一样,冒号和后面的远程分支可以省略:

复制代码
git push origin master
# 等价于
git push origin master:master

前面讲过的git push只有当前分支绑定了上游(跟踪关系) ,才能直接 git push

复制代码
# 1. 新建并切换到本地dev分支
git checkout -b dev

# 2. 修改文件、add、commit
git add .
git commit -m "开发功能"

# 3. 第一次推这个分支,带上 -u 建立跟踪
git push -u origin dev:dev

# 之后再在dev分支提交,直接简写
git push

git pull 拉取远程代码

场景:别人 / 你自己在 Gitee 网页上直接改了文件,远程仓库版本跑在你本地前面了,本地代码落后,需要把远程最新代码抓下来合并到本地

复制代码
git pull <远程主机名> <远程分支名>:<本地分支名>

底层本质: git pull = git fetch(下载远程更新记录) + git merge(自动合并到本地分支)

配置Git

忽略特殊文件

.gitignore :告诉 Git 哪些文件不要追踪、不要提交、不要上传到远程仓库。

怎么得到 .gitignore

两种方式:

  1. 新建仓库的时候(推荐) Gitee 创建仓库页面,勾选「添加 .gitignore」,选择对应语言模板(C/C++、Python、Java 等),平台自动帮你写好一大堆通用忽略规则。
  2. 仓库已经建好之后 自己在仓库根目录 手动新建名字为 .gitignore 的文件(注意开头有个点,是隐藏文件),自己写规则。

必须放在仓库根目录才全局生效;放在子文件夹只对这个文件夹生效。

规则写法示例

复制代码
# 井号 # 代表注释
*.ini    # *是通配符:所有以 .ini 结尾的文件
*.so     # 所有以 .so 结尾的文件(linux编译出来的动态库)

写完 .gitignore 之后,这个 .gitignore 本身也要提交到远程,让团队所有人共享这套忽略规则:

复制代码
vim .gitignore                  # 编辑写入忽略规则
git add .
git commit -m "add .gitignore"
git push origin master

验证是否生效

复制代码
touch a.so b.ini    # 新建两个被规则匹配的文件
git status

输出:working tree clean

含义:Git 完全看不见 a.so、b.ini,不会提示这是新文件,忽略成功。

3 个重要配套命令

1. 强制添加被 ignore 屏蔽的文件:git add -f

正常情况下,写在 gitignore 里的文件 git add 会直接无视。 如果你特殊情况非要提交它 ,加 -f(force 强制):

复制代码
git add -f a.so

不推荐经常用!一般是特殊需求才强制提交,违背 ignore 的初衷

2. 排查:看是哪一条规则把文件忽略了 git check-ignore -v

当你怀疑规则写错,想知道「为什么这个文件被忽略了」:

复制代码
git check-ignore -v a.so

输出示例:

复制代码
.gitignore:3:*.so	a.so

解读:是 .gitignore 文件第 3 行的 *.so 这条规则,把 a.so 忽略了,方便你定位修改。

例外规则:! 取反

复制代码
.*          # 忽略所有以 . 开头的隐藏文件(.xxx文件)
!.gitignore # !代表【不要忽略这个文件】,例外放行

如果只写 .*,.gitignore 本身也会被忽略,就提交不上去; 加 !.gitignore 代表:虽然上面说了忽略所有点开头文件,但是 .gitignore 除外,要追踪它。

重点补充

注意:. .gitignore 只对 untracked(从未提交 / 已经从版本库移除)的文件生效;对 tracked(曾经 commit 过)的文件无效

复制代码
git rm --cached 文件名

怎么用 git rm --cached和reset有什么不一样?

  1. 场景:文件从未 commit 过
    • 不小心 git add 了 → 用 git reset HEAD 文件名 撤回暂存
    • 此时文件回到 untracked,再写入 .gitignore 可以忽略
    • 误add了但是只要没有commit,2条命令效果相同
  2. 场景:文件已经 commit 过(tracked),以后不想再跟踪
    • 只做 git reset HEAD 文件 + 写进 .gitignore 不行!
    • reset 仅仅撤出暂存,文件仍然是 tracked,ignore 直接失效
    • 正确做法:git rm --cached 文件名 → 产生删除变更 → commit 提交这次变更
    • 提交后,文件变成 untracked,.gitignore 才会生效
  • git reset HEAD 文件:只操作暂存区,不改变 tracked 状态
  • git rm --cached 文件:在暂存区生成 "删除文件" 变更,commit 后解除跟踪

再分清楚:

跟踪类型 作用对象 用什么命令
文件跟踪 单个文件 git add
分支上游跟踪 整个分支 git push -u / git branch -u

Git 别名 alias(命令简写)

作用:给很长、高频敲的 git 命令起短别名,少打字。

复制代码
git config [--global] alias.别名名 原命令

eg:

复制代码
# git ci 代替 git commit
git config --global alias.ci commit
# git br 代替 git branch
git config --global alias.br branch
# git co 代替 git checkout
git config --global alias.co checkout

查看已经配好的所有别名

复制代码
git config --global --list

里面能看到你所有 alias.xxx

删除别名

复制代码
git config --global --unset alias.st

Git 标签 tag

tag 本质:给某一条 commit 起一个好记的别名,一般用来标记版本里程碑,比如 v1.0、v2.1,代替长长的 commit-id。 用处:commit id 一串哈希很难记,tag 名字清晰;以后回退、查看某个正式版本直接用 tag,不用复制哈希。

创建轻量标签(默认,最简单)

① 给【最新提交(HEAD)】打标签

复制代码
git tag v1.0

不加 commit id,默认打在当前最新这条 commit 上

② 给【历史某一条 commit】打标签

先查简短 commit id:

复制代码
git log --pretty=oneline --abbrev-commit

拿到哈希(比如 c6ce3f0),再打 tag:

复制代码
git tag v0.9 c6ce3f0

列出所有标签

复制代码
git tag

标签是按字母排序,不是按创建时间排序! 比如 v0.9、v1.0,列表里 v0.9 会在上面。

查看这个标签对应的提交详情

复制代码
git show v1.0

会展示对应的 commit 信息、作者、时间、文件改动 diff。

附注标签(带备注说明,推荐正式发布用)

复制代码
git tag -a v1.1 -m "版本v1.1:完成基础功能" [commit-id]
  • -a:annotated,附注标签(独立对象,带说明、打标签人信息)
  • -m "xxx":写标签备注
  • 末尾可选 commit-id,不写就是给最新 commit 打

对比:

  • 轻量标签(不加 - a):仅仅是 commit 的一个别名,没有额外备注信息,适合临时标记
  • 附注标签(-a):正式版本发布用,信息完整,推荐项目上线版本用

Git Tag 标签的推送与删除

删除【本地标签】

复制代码
git tag -d v0.9

只删本地,远程不受影响;标签还没 push 到远程时,直接这条就够了

推送标签到远程

复制代码
# 推送单个标签
git push origin v1.0

# 一次性推送所有本地标签
git push origin --tags

删除【已经推送到远程的标签】(两步!)

① 先删本地标签

复制代码
git tag -d v1.0

② 再推送删除指令到远程

复制代码
# 写法1:冒号语法,左边空代表删除
git push origin :refs/tags/v1.0

# 写法2:--delete,可读性更强,推荐你用这个
git push origin --delete v1.0

Git从本地到远程完整删除一个文件

复制代码
git rm test.txt       # 在 index(暂存区)写入【删除这条文件的改动】
git commit -m "删掉test.txt"  # 把这个"删除改动打包进一个commit提交里"
git push              # push 是推送 commit

Git删除分支完整指令

复制代码
# 1. 先切到别的分支,不能在要删的分支里面
git checkout main

# 2. 安全删除本地分支
git branch -d test-branch

# 3. 删除远程Gitee上的分支
git push origin --delete test-branch
//或者
git push origin :分支名


删除远程分支、远程 tag 的远程命令格式是一模一样的:`git push origin --delete xxx`
相关推荐
SH的全栈笔记4 小时前
敲下 git add 的那一刻,.git 里多了什么
git·后端
comyccccc4 小时前
STM32F407VET6核心板的部分电路绘制学习笔记
笔记·stm32·学习
叼烟扛炮4 小时前
Linux 学习笔记(三十六):并发进阶——读写锁 vs 自旋锁,到底怎么选?
linux·运维·服务器·笔记·学习
是隼人4 小时前
buuctf-pwn [极客大挑战 2019]Not Bad(orw+jmp)题解(学习过程持续更新)
学习·安全·pwn入门·ctf入门
lazy H5 小时前
【计算机网络】第 12 篇:IPv6 详解——地址格式、地址类型与双栈网络
网络·经验分享·后端·学习·计算机网络·408
(●—●)橘子……5 小时前
力扣 第525场周赛 练习理解
数据结构·python·学习·算法·leetcode
一只QAQ6 小时前
python语法学习
linux·python·学习
東隅已逝,桑榆非晚6 小时前
map和set的使用
数据结构·c++·笔记·学习
dadaobusi6 小时前
error:field ifru_addr has incomplete type sockaddr
学习