编程导航Git话题讨论

Git

68 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡
综合
交流
文章
问答

Git WorkTree 是什么?凭什么能让 AI 编程效率翻倍?

你是小阿巴,正在用 AI 帮你开发一个《美吉外卖》项目。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/cYXGRPqkZAmTAa9j.jpg) 好家伙,任务有点多啊! - 首页商家列表:展示附近的外卖商家 - 搜索功能:搜索想吃的菜品或商家 - 个人中心页面:查看订单历史、修改收货地址 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/5rxRrWnEL7ZIq38S.jpg) 你灵机一动:不如让 3 个 AI 同时帮我写代码,效率岂不是直接翻 3 倍?! 说干就干,你在同一个项目文件夹下打开了 3 个 AI 对话窗口,分配不同的任务,让 AI 们同时开工,美滋滋~ ![](https://pic.code-nav.cn/post_picture/1601072287388278786/je24kNsVr5feFxzA.jpg) 结果你发现,AI 们在执行过程中修改了同一个文件,相互覆盖,导致代码全乱套了! 这个问题可难不倒你,你心想:俺只要手动把项目文件夹复制 3 份,每份交给一个 AI 单独干活不就好了? ![](https://pic.code-nav.cn/post_picture/1601072287388278786/ww9SmRXELJkfOobP.jpg) 这次,3 个 AI 都顺利完成了任务,但是你却傻眼了:我怎么把 3 份代码合并到一起啊?!难道要人工一行行比对、手动复制粘贴?那不得累死…… ![](https://pic.code-nav.cn/post_picture/1601072287388278786/rAxW1uEZMHX4IBRr.jpg) 你赶紧向号称「AI 编程之狗」的鱼皮求救。 鱼皮听完,淡定地说:用 Git WorkTree 啊。 你一脸懵:鸡特?卧客吹?这都是啥玩意儿? ### Git 是啥? 鱼皮:Git 是目前最流行的代码版本管理工具,几乎所有程序员都在用。 简单来说,**Git 就是代码的时光机**。 当你用 Git 管理项目时,每次保存代码都会形成一个 **版本**,就像游戏里的存档点。如果写错了代码,随时可以回到之前的版本,再也不怕 AI 把项目搞崩了。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/ytsOZ1U6TndJ5BM8.jpg) 而且多人协作开发时,每个人可以拉一个自己的 **分支**,就像从主干上长出的树枝,各写各的互不影响,写完再合并回主干。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/yZR1xheSnGVFvSNj.jpg) 接下来我要教你的 WorkTree,就是 Git 的一个隐藏技能。 ### 什么是 Git WorkTree? 鱼皮:正常情况下,一个项目的 Git 仓库只有一个工作目录,也就是说你同一时间只能在一个分支上干活。想切换分支,就得先保存手头的代码,从当前分支爬下来,然后再爬到另一个分支上开始干活,来回折腾。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/rcNlZuuP5hovL9qP.jpg) 但用了 WorkTree,你可以让一个仓库同时拥有多个工作目录,每个目录对应不同的分支,你可以开启分身术,同时在不同的分支上干活,互不干扰。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/wmLDFjcbzNxIfg5s.jpg) 你挠了挠头:等等,那不是也会多出好几个文件夹吗?和我刚才手动复制有啥区别? 鱼皮:区别大了!你手动复制的是整个仓库,每份都有完整的 `.git` 目录和历史记录,不仅占用空间;而且写完代码后,还得跨多个文件夹对比代码、手动合并,费时又容易出错。 而 WorkTree 创建的文件夹,只是 **链接** 到同一个 `.git` 目录。就像同一棵树上长出的不同枝干,虽然各自开枝散叶,但根系是共享的,本体只有一棵树。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/oh6m4mByoD3o7cV9.jpg) 你恍然大悟:所以我在任意一个工作树里提交代码,其他工作树也能看到这次提交? 鱼皮:没错,因为它们本质上是同一个 Git 仓库。 ### 怎么用 Git WorkTree? 你两眼放光:听起来有点儿夯啊,快教我怎么用! 鱼皮:很简单,就几条命令。 比如你的项目在 `meiji-takeout` 文件夹,想同时搞首页商家列表、搜索功能和个人中心这 3 个功能,可以创建 3 个工作树,分别对应 3 个功能分支: ```bash # 创建 3 个工作树,对应 3 个功能分支 git worktree add -b feat/shop-list ../feat-homepage git worktree add -b feat/search ../feat-search git worktree add -b feat/user-profile ../feat-profile ``` ![](https://pic.code-nav.cn/post_picture/1601072287388278786/ixU3eVd0kXIO1bhH.jpg) 执行完之后,你的项目文件夹结构就变成了: ``` /projects/ ├── meiji-takeout/ ← 主仓库(main 分支) ├── feat-homepage/ ← 工作树1(首页商家列表) ├── feat-search/ ← 工作树2(搜索功能) └── feat-profile/ ← 工作树3(个人中心) ``` ![](https://pic.code-nav.cn/post_picture/1601072287388278786/vwpWvaZgT84CrPeo.jpg) 每个文件夹都是一个完整的工作目录,可以独立写代码、提交、推送。 你激动了:那我在每个文件夹里分别开一个 AI 编程助手,让 3 个 AI 各干各的,岂不是美滋滋? 鱼皮:没错,这就是 WorkTree 在 AI 时代最香的用法。**每个 AI 一个工作树,并行开发,互不打扰**。 ![三个 AI 同时干活](https://pic.code-nav.cn/post_picture/1601072287388278786/yIcPGrd5oRCOk1S8.jpg) 像 Cursor 这样的 AI 编程工具,已经内置了 WorkTree 的支持。你可以直接在 Cursor 里开启 [Parallel Agents](https://cursor.com/docs/configuration/worktrees)(并行代理)模式,它会自动帮你创建和管理工作树,让多个 AI 同时干活,完成后一键将代码合并到主分支。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/txEJ7vyvmLh0rvYZ.jpg) ### 开发完怎么合并? 你:3 个功能都开发完成了,最后代码怎么合并到一起呢? 鱼皮:流程很简单,输入几行命令就好了,当然你也可以让 AI 帮你完成。 1)每个工作树里的代码完成后,先用 `git add .` 命令把改动的文件添加到 Git 的暂存区,然后用 `git commit` 命令提交保存。 ```bash git add . git commit -m "完成首页商家列表" ``` ![](https://pic.code-nav.cn/post_picture/1601072287388278786/9J8CckzzDZiAQgvP.jpg) 2)接着切回主分支,用 `git merge` 命令把各个功能分支的代码依次合并进来就行了。 ```bash cd ../meiji-takeout git merge feat/shop-list git merge feat/search git merge feat/user-profile ``` ![](https://pic.code-nav.cn/post_picture/1601072287388278786/yISKZfY5m18e3WNq.jpg) 3)合并完之后,记得用 `git worktree remove` 把用完的工作树删掉,保持项目整洁。 ```bash git worktree remove ../feat-homepage git worktree remove ../feat-search git worktree remove ../feat-profile ``` 4)最后,如果你的代码托管在 GitHub 开源平台上,执行 `git push` 命令同步到远程就完事了。 你突然想到:等等,那如果两个 AI 恰好改了同一个文件,会怎么样? 鱼皮:那在合并的时候会产生 **冲突**,Git 会提示你哪些地方有冲突,需要你手动决定保留谁的代码、删掉谁的代码。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/Mnaui3wJuPAaNnib.jpg) 你皱起眉头:那不是很麻烦?我又看不太懂 AI 写的代码…… 鱼皮:所以分配任务时,要尽量让不同的 AI 改不同的文件。比如刚才的首页商家列表和搜索功能,都会用到 “商家列表” 这个组件,就不适合拆给两个 AI 分别做,最好交给一个 AI 一把梭。而个人中心是独立的模块,可以放心交给另一个 AI。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/TNCrZIQNy7MT0Jfr.jpg) 总之,WorkTree 给了你让多个 AI 并行写代码的能力,但任务怎么拆,还得你自己规划好。 ### 结尾 你兴奋地搓搓手:所以有了 WorkTree,AI 们各自在独立的文件夹里干活,不会打架;合并代码时也不用手动复制粘贴了,一举两得啊! 以后我指挥多个 AI 同时干活,效率直接起飞! 鱼皮:不错,多了解一些编程技术和工具能让你的 AI 开发效率翻倍。如果你想系统学习 AI 编程,可以看看我免费开源的 [《AI 编程零基础教程》](https://ai.codefather.cn/vibe),从入门到实战一条龙讲解。点个收藏关注不迷路~ > 开源指路:https://github.com/liyupi/ai-guide ![](https://pic.code-nav.cn/post_picture/1601072287388278786/C8qnztDn1dP8tICq.jpg)

想问一下参加工作的uu们,各位公司关于代码托管平台是如何搭建和管理的,是自己公司有自己的服务器,还是购买的云服务器私有化部署,或者是直接使用了有些平台的saas平台进行托管。如果是自己公司服务器上搭建的,包含平时运维,用到的技术栈是哪些呢,gitlab+Jenkins,还是有其他可选的技术?方便大家提供一些搭建思路吗,万分感谢

搭建Gitlab私服(社区版)

<font style="color:black;background-color:#FFFFFF;">注意:要使用CentOS7版本安装,CentOS6版本不行。</font> ### 1.官网地址 首页:https://about.gitlab.com/ 安装说明:https://about.gitlab.com/installation/ ### 2.提前下载所需rpm(文末有安装包) yum安装gitlab-ee(或ce)时,需要联网下载几百M的安装文件,非常耗时,所以应提前把所需RPM包下载并安装好。 下载地址是: https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/7/gitlab-ce-10.8.2-ce.0.el7.x86_64.rpm 下载好后上传到Linux系统,习惯上还是放在/opt目录下 ### 3.安装 ```shell sudo rpm -ivh /opt/gitlab-ce-10.8.2-ce.0.el7.x86_64.rpm sudo yum install -y curl policycoreutils-python openssh-server cronie # sudo yum install lokkit sudo lokkit -s http -s ssh sudo yum install postfix #yum install keyutils-libs-devel libcom_err-devel libselinux-devel libverto-devel -y #rpm -ivh mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm sudo systemctl enable postfix.service sudo chkconfig postfix on curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash sudo EXTERNAL_URL="http://gitlab.example.com" yum -y install gitlab-ce ``` ### 4.访问 + 初始化配置 gitlab-ctl reconfigure + 启动Gitlab服务 gitlab-ctl start + 停止Gitlab服务 gitlab-ctl stop 访问Linux服务器IP地址即可,如果想访问EXTERNAL_URL指定的域名还需要配置域名服务器或本地hosts文件。 初次登录时需要为gitlab的root用户设置密码。 ![gitlab.png](https://pic.code-nav.cn/post_picture/1643218270658023426/sa0pnLJhofzwBEiy.png) ### 所需要的文件 [gitlab-ce-10.8.2-ce.0.el7.x86_64.rpm](https://www.yuque.com/attachments/yuque/0/2024/rpm/34310486/1707470675275-02a3eea6-9e82-452d-b57c-26e877c5c382.rpm)

Git 推送失败问题解决指南

当执行 `git push -u origin master` 时遇到类似以下错误: ```git error: failed to push some refs to 'http://xxxx.cn/vip/xxx.git' To http://xxxx.cn/vip/xxx.git ! refs/heads/master:refs/heads/master [rejected] (fetch first) Done hint: Updates were rejected because the remote contains work that you do not hint: have locally. This is usually caused by another repository pushing to hint: the same ref. If you want to integrate the remote changes, use hint: 'git pull' before pushing again. ``` 或简化版错误: ```git [rejected] master -> master (fetch first) error: failed to push some refs ``` 这是 Git 常见的版本冲突问题,原因是远程仓库存在本地没有的更新,为防止覆盖远程变更而拒绝推送。 ## 推荐解决方案 最简洁高效的处理方式是执行以下命令: ```bash # 拉取远程master分支并以rebase方式整合本地更改 git pull --rebase origin master # 完成整合后再次推送(-u参数会建立本地与远程分支的关联) git push -u origin master ``` 这种方式会: 1. 将远程最新更改下载到本地 2. 以线性方式重新应用你的本地提交 3. 建立本地与远程分支的关联关系 ## 备选解决方案(适用于复杂冲突) 如果遇到复杂的代码冲突,可使用标准合并流程: ```bash # 拉取远程更新并合并到本地 git pull origin master # 若出现冲突,编辑冲突文件后标记为已解决 git add <冲突的文件路径> # 提交合并结果 git commit -m "合并远程更新并解决冲突" # 推送本地更改 git push origin master ``` ## 注意事项 - `git pull --rebase` 会改写提交历史,保持提交记录更整洁 - 多人协作时,推送前先拉取是良好习惯 - 解决冲突时需仔细检查代码,确保逻辑正确 - 首次推送分支时,`-u` 参数只需使用一次,后续可直接用 `git push` 以上方法可解决绝大多数推送失败问题,推荐优先使用 `git pull --rebase` 方式,它能更优雅地处理分支同步问题。

【Git】文件操作 - 误删除

# 情况一:文件已经commit,不小心在资源管理器中删除了该文件 ~~~bash git restore 文件名 ~~~ <img src="https://pic.code-nav.cn/post_picture/1796822714790887426/153MBdEzGNysm0bb.webp" alt="image-20231124205815891" width="100%" /> --- # 情况二:(reset)不仅在资源管理器中删除了,还将删除操作提交了 解决办法:reset(重置),即恢复到上一个版本 ~~~bash git reset [option] [commitId] ~~~ option 参数的选项有以下几种 1. `git reset --mixed` :此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本, 只保留源码,回退commit和add信息 2. `git reset --soft`:回退到某个版本, 只回退了commit的信息 。如果还要提交,直接commit即可 3. `git reset --hard`:彻底回退到某个版本,本地的源码也会变为上一个版本的内容,慎用! git reset --hard 39829c0 <img src="https://pic.code-nav.cn/post_picture/1796822714790887426/tvgpShOhnZHuaJbb.png" alt="image-20231124210501089" width="100%" /> 回车之后可以发现文件已经恢复了,此时再查看日志,它将我们的提交过程丢失了: <img src="https://pic.code-nav.cn/post_picture/1796822714790887426/ZSVbMiYcT01CwpIL.png" alt="image-20231124210540925" width="100%" /> ---- # 情况三:(revert)如果又想要恢复文件,又不想让提交过程丢失 git revert 版本号,这个版本号是恢复到哪个提交**之前** - revert 与 reset 的作用一样,都是恢复版本,但是他们两者的实现方式不同。 - 简单来说 reset 是直接恢复到上一个提交,工作区的代码自然也恢复到上一次提交的代码;而 revert 是新增一个提交,但是这个提交是使用上一次的代码。 - 因此,他两恢复后的代码是一致的,区别是一个新增提交(revert),一个是回退提交(reset) - 正因为 revert 永远是在新增提交,因此本地仓库版本永远不可能落后于远程仓库,可以直接推送到远程仓库,故而解决了 reset 之后需要加 -f 参数的问题,提高了安全性。 ![image-20231124210845915](https://pic.code-nav.cn/post_picture/1796822714790887426/prT82T3M5bYrEPcQ.webp) 如果需要远程仓库也回退,可以使用“`git push -f -u origin master`”强制推送到远程仓库。 --- # `--amend` git reset 还提供了恢复到上一次提交的快捷方式: ~~~bash git reset --soft HEAD~1 # 只回退了 commit add的操作还在 ~~~ 其实平日开发中最多的误操作是这样:刚刚提交完,突然发现了问题,比如提交信息没写好,或者代码更改有遗漏,这时需要撤回到上次提交,修改代码,然后重新提交。 这个流程大致是这样的: ~~~bash # 1. 回退到上次提交 $ git reset HEAD^ # 2. 修改代码... ... # 3. 加入暂存 $ git add . # 4. 重新提交 $ git commit -m 'fix: ***' ~~~ 针对这个流程,git 还提供了一个更便捷的方法: ```bash git commit --amend ``` 这个命令会直接修改当前的提交信息。如果代码有更改,先执行 git add,然后再执行这个命令,比上述的流程更快捷更方便。

【Shell】利用 Windows PowerShell 统计 Git 项目提交次数

> 本文为 AI 生成内容 在软件开发和项目管理中,了解团队成员或自己在Git项目中的活跃程度是评估项目进展和个人贡献的重要指标。 今天,我们就来探讨如何使用 Windows PowerShell 编写脚本来统计Git项目的提交次数,这对于跟踪项目进度、分析开发效率以及评估个人绩效都有着重要的意义。 ## 效果 <img src="https://pic.code-nav.cn/post_picture/1631847729158258689/9YlWavQSoPAEQJSV.png" alt="PixPin_2025-02-08_15-00-51.png" width="360px" /> ## 脚本 ``` # 确保输出编码为 UTF-8 $OutputEncoding = [System.Text.Encoding]::UTF8 # 定义包含多个 Git 仓库的目录 $repos = @( "C:\99\code\test", "C:\99\code\test2" ) # 提示用户输入 Git 账号名 $gitUsername = Read-Host "Please enter your Git username" # 提示用户输入年份 $inputYear = Read-Host "Please enter the year" # 初始化每个月的提交次数 $monthlyCounts = @{} for ($month = 1; $month -le 12; $month++) { $monthlyCounts[$month] = 0 } # 遍历每个仓库 foreach ($repo in $repos) { if (Test-Path "$repo\.git") { Push-Location $repo # 遍历每个月 for ($month = 1; $month -le 12; $month++) { # 计算每个月的起始和结束日期 $startDate = "$inputYear-$month-01 00:00:00" $endDate = "$inputYear-$month-$([datetime]::DaysInMonth($inputYear, $month)) 23:59:59" # 查询指定用户在本月的提交次数 $userCount = git log --after="$startDate" --before="$endDate" --pretty='%aN' | Where-Object { $_ -eq $gitUsername } | Measure-Object -Line | Select-Object -ExpandProperty Lines # 累加到每个月的提交次数 $monthlyCounts[$month] += $userCount } Pop-Location } } # 输出每个月的提交次数 $monthlyCounts.GetEnumerator() | Sort-Object Key | ForEach-Object { $month = $_.Key.ToString("00") # 确保月份为两位数 $count = $_.Value Write-Output "$month $count" } # 计算总提交次数 $totalCount = ($monthlyCounts.Values | Measure-Object -Sum).Sum # 输出总提交次数 Write-Output "-----" Write-Output "total $gitUsername $totalCount" ``` ## 脚本使用方法 ### 1. 创建脚本文件 将上述代码复制到一个文本编辑器中,例如Windows自带的记事本或者更专业的代码编辑器(如Visual Studio Code)。 然后将文件保存为`git.ps1`,注意文件扩展名必须是`.ps1`,这是PowerShell脚本文件的标准扩展名。 ### 2. 运行脚本前的权限设置(可选) 由于Windows默认情况下可能会限制运行PowerShell脚本的权限,你需要先确保当前的执行策略允许运行本地脚本。可以按照以下步骤进行操作: - 以管理员身份打开PowerShell。 - 输入以下命令查看当前的执行策略: ```powershell Get-ExecutionPolicy ``` - 如果当前策略不允许运行脚本,你可以将执行策略临时修改为`RemoteSigned`,这样可以运行本地创建的脚本,命令如下: ```powershell Set-ExecutionPolicy RemoteSigned ``` 在运行完脚本后,你可以将执行策略改回原来的设置,以保证系统安全。 ### 3. 运行脚本 - 打开PowerShell,并导航到保存`git.ps1`脚本的目录。例如,如果脚本保存在`D:\Scripts`目录下,可以使用以下命令进入该目录: ```powershell Set-Location D:\Scripts ``` - 运行脚本,在PowerShell中输入: ```powershell ./git.ps1 ``` - 按照脚本的提示,依次输入你的Git用户名和需要统计的年份,脚本将自动计算并输出每个月的提交次数以及全年的总提交次数。 ## 总结与应用 通过这个Windows PowerShell脚本,我们可以高效地统计Git项目的提交次数。无论是团队管理者想要了解团队成员的工作进度,还是开发者自己想要回顾自己在一年中的代码贡献,这个脚本都能提供有价值的数据支持。在实际应用中,你可以将这个脚本集成到项目的自动化脚本中,定期生成提交次数报告,以便更好地进行项目管理和分析。 希望这篇博客对你理解和使用Windows PowerShell统计Git项目提交次数有所帮助。如果你有任何问题或建议,欢迎在评论区留言交流。 > 我还有一个 node 版的,会打开一个 html 可视化看,但我的所有node项目是放在一个 node 私人仓库里面的,分享不了

在idea的git工具中,历史commit包含敏感信息(还没有提交到remote),请问怎么解决敏感信息commit

<img src="https://pic.code-nav.cn/post_picture/1675435243533766658/hko07tYVNcJb6Sj3.webp" alt="image.png" width="100%" />

用户体量增长背景下,管理系统如何由项目化系统过渡到产品化系统,从而有效的对版本进行更好的管理和控制

### 问题描述 当项目化软件转向产品化软件,作为开发技术人员如何对版本进行更好的控制 ### 背景信息和具体疑问 在若依(前后端不分离版本)框架且用户体量在不断提升(体量在1000+),但用户的个性化定制需求大不相同,针对这种情况如何对版本进行更好的控制,提升开发人员的开发效率,避免'重复造轮子'? ### 已有理解 利用git版本分支进行控制,但大的用户体量却已然满足不了当下这种体量增长的趋势,因此想请教一下鱼皮哥,谢谢!

docker搭建gitlab-runner

## 使用docker容器技术部署gitlab runner 要使用`docker-compose`文件部署GitLab Runner,你可以按照以下步骤操作: ```shell sudo mkdir -p /opt/store/gitlab-runner ``` 1. **创建`docker-compose.yml`文件**: 创建一个名为`docker-compose.yml`的文件,并添加以下内容: ```yaml version: '3.8' services: gitlab-runner: image: registry.cn-hangzhou.aliyuncs.com/misaka-open/gitlab-runner:alpine3.18 container_name: "gitlab-runner" restart: always volumes: - '/opt/store/gitlab-runner:/etc/gitlab-runner' - '/var/run/docker.sock:/var/run/docker.sock' # 这个挂载是将宿主机上的docker socket挂载到了容器内,这样容器内执行的docker命令会被宿主机docker daemon最终执行 ``` 在这个文件中,我们定义了一个名为`gitlab-runner`的服务,使用的是`gitlab/gitlab-runner:latest`镜像,并设置了卷挂载,以便GitLab Runner可以访问宿主机的Docker socket,从而能够执行Docker命令。 2. **启动服务**: 完成`docker-compose.yml`文件的编写后,使用以下命令来启动服务: ```shell docker-compose up -d ``` <img src="https://pic.code-nav.cn/post_picture/1768277211082678273/V3hFz1bHxPq7Z5U0.webp" alt="image-20241220210654105.png" width="100%" /> 这个命令将会启动GitLab Runner服务,并且以后台模式运行。你可以使用`docker ps`命令来验证服务是否已经成功启动。 3. **注册GitLab Runner**: 启动GitLab Runner容器后,你需要注册Runner。进入容器内部,执行注册命令: ```shell docker exec -it gitlab-runner gitlab-ci-multi-runner register ``` 按照提示输入GitLab实例的URL、注册token、Runner描述、标签等信息。对于执行器(executor),选择`docker`。 ```shell Enter the GitLab instance URL (for example, https://gitlab.com/): http://www.codefather.cn/ Enter the registration token: GR1348941yeBTxcSbQyCRywtspD-b Enter a description for the runner: [f20fce6332f4]: yupao-backend-runner Enter tags for the runner (comma-separated): build Enter optional maintenance note for the runner: Enter an executor: parallels, docker+machine, kubernetes, docker, docker-windows, docker-autoscaler, instance, custom, shell, ssh, virtualbox: docker Enter the default Docker image (for example, ruby:2.7): registry.cn-hangzhou.aliyuncs.com/acs/maven #这是配置了国内的中央仓库地址下载依赖比较快 ``` <img src="https://pic.code-nav.cn/post_picture/1768277211082678273/5YOqHKammChKiINO.webp" alt="image-20241220211421165.png" width="100%" /> <img src="https://pic.code-nav.cn/post_picture/1768277211082678273/AFnfu6IjubjACBc4.webp" alt="image-20241220211738334.png" width="100%" /> 以上步骤可以帮助你使用`docker-compose`文件部署GitLab Runner。确保你已经安装了Docker和Docker Compose,并且你的系统满足GitLab Runner的运行要求。

Git 基本使用

# Git 安装 官网:[Git (git-scm.com)](https://git-scm.com/) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/ahsyStKnqQbb2CHT.webp) 具体版本根据自己计算机 32 或者 64 位为准 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/dlF0Z7wmuYdaruhz.webp) --- # Git 常用命令 ## 常用 GIt 命令 | **命令** | **作用** | **示例** | | --- | --- | --- | | `git config --global user.name "用户名"` | 设置全局的用户名,用于标识你在 Git 中的身份 | git config --global user.name "张三" | | `git config --global user.email "邮箱"` | 设置全局的电子邮件地址,用于标识你的身份。 | `git config --global user.email "zhangsan@example.com"` | | `git init` | 初始化一个新的 Git 仓库。 | 在一个新文件夹中运行 `git init` 来创建一个本地仓库。 | | `git status` | 显示工作目录的状态,包括哪些文件被修改但尚未提交。 | 在仓库中运行 `git status` 查看有哪些文件需要提交。 | | `git add 文件名` | 将文件添加到暂存区,准备提交 | `git add README.md` 把 README.md 文件添加到暂存区。 | | `git commit -m "日志信息" 文件名` | 将暂存区的更改提交到仓库,并附带一条提交消息。 | `git commit -m "添加了 README 文件"` 提交暂存区的更改,并加上说明。 | | `git reflog` | 显示历史记录,包括每一个提交的哈希值和操作。 | 运行 `git reflog` 查看所有的历史操作。 | | `git reset --hard 版本号` | 将仓库重置到指定的版本。 | `git reset --hard 98c7f4e` 将仓库重置到哈希值为 98c7f4e 的提交。 | ## 设置用户签名 ``` git config --global user.name 用户名 git config --global user.email 邮箱 ``` **注意点:** **签名的作用是区分不同操作者身份。用户的签名信息在每一个版本的提交信息中能够看 到,以此确认本次提交是谁做的。Git首次安装必须设置一下用户签名,否则无法提交代码。 ** **如何查看自己签名是否设置成功?** 打开 git Bash,查看当前用户——我这里是 ASUS ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/B7XrAlUIzEsU5dde.png) 在计算机 C 盘找到这个位置 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/6HfMYTAu5ectjwe2.webp) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/vw2ESladFSW18tps.png) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/7nCWUJ5Lxe5d0KsX.webp) 我刚刚设置的就有了 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/hG0j73wyj8nltaxv.png) --- ## 初始化本地库 ``` git init ``` 创建一个空的文件夹 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/YbWbatdBdAJynAyK.png) 右键打开 Git,输入指令 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/SjG2n9bDMpkIoYgr.webp) 没看见可能是隐藏了 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/UnMAfKZmOH7OuyGP.webp) --- ## 查看本地库状态 ``` git status ``` 默认分支系统自动会设置为 master ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/On4WASH1qjUNqi8y.webp)![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/f50DJqerkmTID22Z.webp) 随便新建个文件,并随便添加写东西,模拟写好的代码 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/vvtbZV2lrqI0ClNw.png) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/M6Sk1lPjd6GQFeTu.webp) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/NjJ6xHlxm7iReScy.png) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/HTMdndZzgDhYqkrF.webp) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/RY048i7FJJvdoBcw.webp) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/F1MswzJK9zW2fmcn.webp) 这里显示了有未追踪的文件,需要 git add 把它从工作区添加至暂存区 --- ## 添加至暂存区 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/JgNzMsWW7rJ9NlWF.webp) ``` git add 文件名 ``` LF 转换成 CRLF 是安装 Git 时默认的,这里知道即可 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/YDBODcvHVh6DUDpX.png) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/NsdS1Nvm3v9Umn7M.webp) 继续查看本地库状态,文件现在放在了在暂存中的文件 提示的 git rm --cache + 文件 可以删掉在暂存区的文件 但文件始终都在工作区保存着的,只是删掉了暂存区里的文件而已 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/E13tfpnPLXY1K62i.png) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/TSHgE0nHM5YWcgAb.webp) --- ## 提交本地库 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/LdS6VCchUaDUfbpn.webp) 文件添加到暂存区,那么下一步就可以提交到本地库了,从而做到版本控制 ``` git commit -m "日志信息" 文件名 ``` ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/yEyuRVqcdlbCZgTM.webp) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/YGrtDqlEZRS7fL07.webp) 再次查看本地库,会发现 no commit yet 没有了,因为刚才已经 commit 提交一次了 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/IMoVU3La01oP3AyB.png) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/jNIdJN8QWjx9rIQH.webp) 这是可以查看版本信息 `git log`: 用于查看仓库的历史提交记录。 `git reflog`: 用于查看引用(如分支、标签和 HEAD)的变动历史,常用于恢复丢失的提交。 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/P1nkk5853jiyN6rK.webp) --- ## 修改命令 情景模拟,如果此时对 helloworld.txt 文件内容进行修改,再进行查询本地库状态 这是因为修改过代码但是又没有 add 添加导致的 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/ETQNPzBzkeQ1wsqP.png) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/pM3WB8fQ3EMdHIR0.webp)![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/IgIBlFIm80MyXfrr.webp) 此时再次执行 add 命令即可 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/xk6mNF4xEifSzEjU.webp) 再次版本提交 commit 提交至本地库,就有了第二个版本 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/C8yVvYK8AdlcjAqu.webp) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/R3V99sSWp7zGOGFJ.webp) 当前“指针”也是指向第二个版本 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/jUCVb0wQqzfEocqI.png) --- ## 历史版本切换 ``` git reset --hard 版本号 ``` `git log`: 用于查看仓库的历史提交记录。 `git reflog`: 用于查看引用(如分支、标签和 HEAD)的变动历史,常用于恢复丢失的提交。 可以理解成 log 为详细版,reflog 为精简版 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/a3oAtGRCArDoabNX.webp) **这里的版本号就是 git log 和 git reflog 是生成的一长串字符** **只是说,reflog 只显示前 7 位,log 显示的是全部** ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/S2vk5XPF5e6c3BnT.webp) 情景模拟,下面这是第二个版本的,我要切换成第一个版本回去看看 执行 reset 命令,reflog 查询的“指针”就会移动到原先的第一个 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/oQO8XMdAhs0VG0QU.png)![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/In5pO32zS1jNKR3w.webp) 查看文件,已经回到了最开始写的样子(没有了第二次添加的 Java 字样) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/jQMMwnP9poCLupeU.png) --- # Git 分支操作 公司里服务器运行模式 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/44ePBxOKFw8ZtDPj.webp) ## 分支概述 举个例子: 想象你正在写一本书,这本书有一个主稿本(这相当于你的主分支,通常叫做 `main` 或 `master`)。每次你想添加新章节或修改现有内容时,你可以直接在主稿本上做这些更改。但是,如果直接在主稿本上修改,一旦出现错误或者需要撤销某些更改,可能会非常麻烦。 为了避免这种情况,在版本控制系统中,当你要开始一个新的功能或修复一个 bug 时,你可以从主分支创建一个“副本”,这个副本就称为“分支”。 在这个副本上,**你可以自由地进行更改而不会影响到主分支上的代码。** 一个简单的步骤说明: ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/vj8EkEgCORiD4VHV.png) 1. 从主分支创建分支 - 假设主分支是 `main`,你可以创建一个名为 `feature-1` 的分支来开发新功能。 - 这个 `feature-1` 分支就像是 `main` 分支的一个快照,你在 `feature-1` 上所做的任何更改都不会立即影响到 `main` 分支。 2. 在分支上工作 - 在 `feature-1` 分支上编写代码、测试并调试,直到新功能完成且稳定。 3. 合并分支到主分支 - 当你对 `feature-1` 分支满意后,你可以将其合并回 `main` 分支。这意味着将 `feature-1` 分支中的所有更改应用到 `main` 分支上。 4. 删除分支(可选) - 如果不再需要 `feature-1` 分支,你可以将其删除以保持仓库的整洁。 --- ## 常用分支命令 | **命令** | **作用** | **示例** | **说明** | | --- | --- | --- | --- | | `git branch 分支名` | 创建一个新的分支。 | 如果你想创建一个名为 `feature-login` 的新分支,你可以输入 `git branch feature-login`。 | 这个命令会创建一个新分支,但它不会自动切换到这个新分支。你需要使用 `git checkout` 命令来切换到新创建的分支。 | | #### `git branch -v` | 列出所有本地分支及其最近的一次提交的信息。 | 输入 `git branch -v` 将列出所有分支及每个分支的最新提交。 | 当前所在的分支会被标记出来,通常会用星号 (`*`) 或者颜色突出显示。 | | #### `git checkout 分支名` | 切换到指定的分支。 | 如果你想切换到 `feature-login` 分支,你可以输入 `git checkout feature-login`。 | 这个命令会将你的工作目录切换到指定的分支,并更新文件到该分支的最新状态。 | | #### `git merge 分支名` | 把指定的分支合并到当前分支。 | 如果你想将 `feature-login` 分支合并到当前分支 `main`,你应该先确保你已经切换到了 `main` 分支,然后输入 `git merge feature-login`。 | 这个命令会尝试将 `feature-login` 分支的所有更改合并到当前分支。如果在这个过程中有任何冲突,Git 会提示你解决这些冲突。 | --- ## 查看创建切换分支 列出所有本地分支及其最近的一次提交的信息。 ``` git branch -v ``` ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/tuo3QL1oGlHAUxJN.png) 假设你想要添加一个新功能,并将其合并到主分支中 **创建并切换到新分支**: ``` git checkout -b feature-login ``` - `**git checkout**`: 这个命令通常用于切换分支。 - `**-b**`: 这是一个选项,告诉 Git 在切换分支之前先创建一个新的分支。 - `**feature-login**`: 这是你想要创建的新分支的名字。 这条命令结合了 `git branch` 和 `git checkout`,创建并立即切换到新分支。 当然也可以分步骤来 ``` git branch feature-login ``` ``` git checkout feature-login ``` 现在就选择到了新创建的 feature-login 分支中,并对该分支的文件进行操作 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/Xjha4XoRptpcvSLz.webp) **开始在新分支上工作**: 编辑文件,添加新功能(假设)。 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/UXGgRul531UNLjgQ.png) 使用 `git add .` 添加文件到暂存区。 使用 `git commit -m "Add login feature"` 提交更改。 这样就完成了查看、创建、切换分支操作 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/oqh3ReIs9rr5vCpA.webp) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/wP6YVUnNj8jzMKIi.png) --- ## 合并分支(正常合并) ``` git merge 分支名 ``` 如果你想将 `feature-login` 分支合并到当前分支 `main`,你应该先确保你已经切换到了 `main` 分支,然后输入 `git merge feature-login`。 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/oYA2ttSYUB2IzMYl.webp) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/5FM70ZY7kh498jLd.png)![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/H0jR6U4xRZsfbFpo.webp) ``` cat 文件名 ``` 查看当前文件内容,和之前副分支(feature-login)上的对比 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/lP0QJvfSF0djyPJB.webp) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/nhzWahNG22TEBSfy.webp) **这就是一个正常的合并,并没有产生代码的冲突** **因为这是 master 分支没有任何修改,只是在 feature-login 分支上修改并合并的** **不会产生冲突合并** --- ## 合并分支(冲突合并) ### 产生冲突的原因 1. **两个分支上的不同修改** - 假设你有两个分支:`main` 和 `feature-login`。 - 在 `main` 分支上,你可能修改了一个文件中的某一行。 - 在 `feature-login` 分支上,你可能也修改了同一个文件中的同一行,但修改的内容不同。 2. **Git 无法自动合并** - 当你尝试将 `feature-login` 分支合并到 `main` 分支时,**Git 发现两个分支对同一个文件的同一行有不同的修改**。 - Git 无法自动确定应该保留哪个版本的修改,因为这两种修改可能是互斥的。 - 因此,Git 会停止合并过程,并标记出冲突的地方。 --- ### 如何解决冲突 1. **识别冲突** - Git 会在命令行中告诉你哪些文件发生了冲突,并且在这些文件中插入特殊的冲突标记。 - 冲突标记通常包括三个部分:`<<<<<<< HEAD`、`=======` 和 `>>>>>>> other-branch-name`。 - `<<<<<<< HEAD` 标记冲突开始,表示当前分支(通常是你要合并到的目标分支)的版本。 - `=======` 标记冲突中间,用于分隔两个版本。 - `>>>>>>> other-branch-name` 标记冲突结束,表示另一个分支的版本。 2. **手动编辑文件** - 打开发生冲突的文件,找到冲突标记。 - 检查 `HEAD` 版本和另一个分支的版本,决定保留哪一部分或如何合并这两部分。 - 删除冲突标记,并保存文件。 3. **标记冲突解决** - 使用 `git add <file>` 命令标记你已经解决了冲突。 - 对于每个解决冲突的文件,都需要执行这个命令。 4. **完成合并** - 一旦所有冲突都被解决并标记,你可以继续完成合并过程。 - 使用 `git commit` 命令创建一个新的提交,这个提交包含了合并的结果。 --- ### 示例演示 假设你有两个分支:`main` 和 `feature-login`。在 `feature-login` 分支上,你修改了第一行文件中内容,而在 `main` 分支上,你也修改了相同的位置,但内容不同。 在 master 分支倒数第二行添加内容,同时添加暂存区,并提交到本地库 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/T1w3810VFR1qbqKq.png)![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/L5wF3l5g3NSlEzqn.webp) 切换到 feature-login 分支,也进行修改,最后一行添加 feature-login test 同时添加暂存区,并提交到本地库 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/CGj3Op0u2a0HUhqy.png) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/SSgFr1IY2bpAAEsJ.png) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/53FgzD8JzH9SlVdZ.webp) 回到 master 分支,尝试合并,产生冲突合并 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/71V3uy1x2i7hVVTa.webp) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/DRilkEYpLboX2O1w.webp) 同时分支状态也发生变化,git status 获取状态,手动合并代码 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/1Z9geU6V0w2vvmjq.png) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/K5jvupSwrCLf1qId.webp) 打开文件会发现 Git 已经标注好冲突的位置,产生合并冲突,Git 不知道要合并哪个分支的版本 需要自己手动解决 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/2JsrX1qPr9kY83ie.webp) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/irSkWndD0WBRFV2h.webp) 因为是两个分支版本的最后两行出问题的 如果我 master test 和 feature-login test 都想要的话,直接进行修改即可 像下面这样子直接修改 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/luNtROFd5KRadTwe.png) 意思是说我合并后的最后两行想要合并成这样子,Git 给出冲突标注也要删除 **记住,这里也要添加到暂存区,但 commit 提交的时候就不用带文件名了,不然 Git 就会报错** 修改后也是要添加并提交的 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/MuoGZCsqskp4XtiM.webp) 进行添加带文件名没有什么问题 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/cYRauS7dMFcmImLl.png) 但是在 commit 提交带文件名就会报错 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/sSfSgBIHLb5XJLw2.webp) ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/1ZJqjBJNljHfO1og.webp) 不带文件名 commit 提交即可,右边括号也不显示 merging 合并中了 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/wilDsvXg4hskx887.webp) 查看文件,合并分支成功,手动解决冲突合并 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/lxh6OxzUTBMxoiBn.webp) **注意,此时切换到 feature-login 分支,文件还是只有一行的状态** 毕竟是把 feature-login 的分支合并到 master 分支去的,那 feature-login 分支也就没必要也一起合并 ![image.png](https://pic.code-nav.cn/post_picture/1667553683887370242/a89zoKD8itn6tP34.webp)

下载 APP