【工欲善其事】利用 DeepSeek 实现复杂 Git 操作:从原项目剥离出子版本树并同步到新的代码库中
文章目录
- 利用 DeepSeek 实现复杂 Git 操作
- 1 背景介绍
- 2 需求描述
- 3 思路分析
- 4 实现过程
- 4.1 第一次需求确认
- 4.2 第二次需求确认
- 4.3 第三次需求确认
- 4.4 V3 模型:中间结果的处理
- 4.5 方案验证,首战告捷
- 5 总结复盘
利用 DeepSeek 实现复杂 Git 操作
1 背景介绍
今天综合利用 DeepSeek V3
和 R1
推理模型,成功解决了一个复杂的 Git
操作,谨以此文记录 DeepSeek
使用心得,以备后续复盘。这本是我一次操作上的疏漏,未能将 Fork 到本地的代码与原项目彻底脱钩,直到很晚才发现问题,已经很难快速用简单的 Git 命令恢复原样了。于是,我想到了 DeepSeek。
2 需求描述
现有一个从 GitHub
复刻(fork)到我本地的开源项目。从复刻到本地那天起,我又陆续在 main
分支提交了很多次(没有其他分支)。现在需要将我本人提交的所有节点从该副本完整迁移到另一个新仓库,并要求保留所有节点的历史提交记录(提交时间、注释信息等)。
【图 0:迁移 Git 子版本树的需求描述示意图】
3 思路分析
该需求涉及从原 Git
库彻底剥离需要的子版本树。Git
还没有能一步实现节点树 “脱钩” 的操作命令。但大方向是明确的,无非以下四步 ——
- 先找到脱钩位置(简单);
- 从脱钩点产生一个新的
Git
根节点(未知); - 设法将脱钩点后续产生的提交版本依次追加到新的根节点上(未知);
- 最后删除原有版本树,重置远程推送分支
origin
(简单);
以上四步逻辑关系清晰,正好可以用 DeepSeek
一试身手。
4 实现过程
4.1 第一次需求确认
因为涉及多次复杂 Git
操作,先用 V3
网页版直接提问(刻意未加任何提示词技巧):
我有一个本地 Git 代码仓库,是从 GitHub 一个开源项目上 fork 到本地的,但这样产生的提交不计入 GitHub 网站的个人贡献,因此我在提交了很多本地新增的版本后决定将其剥离出来。但我不知道应该怎么操作。帮帮我
以下是整理后的 DeepSeek V3
的回复,可以看到 V3
模型第一次理解有偏差:
要将本地
Git
仓库从GitHub
的fork
中剥离出来,使其成为一个独立的仓库,并保留所有提交历史,可以按照以下步骤操作:# 1. 备份当前仓库 # 2. 移除与上游仓库的关联: cd /path/to/your/repo git remote remove origin # 3. 创建新的 GitHub 仓库(不要初始化 README 或 .gitignore) # 4. 将本地仓库关联到新仓库: git remote add origin https://github.com/yourusername/new-repo-name.git # 5. 推送代码到新仓库: git push -u origin --all git push -u origin --tags # 6. 确保本地分支跟踪新的远程分支: git branch --set-upstream-to=origin/main main
要是按上述回复进行操作,其实只是把远程分支更新到了新仓库,完全没有实现想要的“脱钩”效果。
4.2 第二次需求确认
继续追问:
如果只想保留部分提交历史,比如只有我自己的提交历史,又该如何?
这次它听懂了,但给出的方案是借助第三方工具(由于不是理想回复,具体内容已精简):
# 1. 安装 `git filter-repo` pip install git-filter-repo # 2. 为避免直接操作原始仓库,建议先备份 git clone /path/to/your/repo new-repo cd new-repo # 3. 通过以下命令保留只有你提交的历史: git filter-repo --commit-callback ' if b"your-username" not in commit.committer_email:commit.skip() ' # 4. 清理远程信息 git remote remove origin # 5. 创建新的 GitHub 仓库 new-repo-name # 6. 关联新仓库并推送 git remote add origin https://github.com/your-username/new-repo-name.git git push -u origin --all git push -u origin --tags # 7. 效果验证(略)
由于需要安装第三方依赖,解决方案的可移植性较差。因此还需继续追问。
4.3 第三次需求确认
由于我想要的是 Git 原生命令,因此再次追问:
我不想安装第三方工具,Git 没有原生方法实现吗?
这次它终于听懂了,想到了孤立分支(--orphan
)和 cherry-pick
节点提取命令 ——
如果你不想安装第三方工具(如
git filter-repo
),Git 本身也提供了原生方法来实现部分提交历史的保留,但操作会稍微复杂一些。以下是使用 Git 原生命令实现的方法:# 1. 克隆你的本地仓库 git clone /path/to/your/repo new-repo cd new-repo # 2. 创建一个新的分支 git checkout --orphan new-branch # 3. 筛选并重新提交你的更改 # 从提交历史筛选想要的提交哈希值: git log --author="your-username" --oneline # 逐个挑选提交 git cherry-pick <commit-hash> # 如果需要挑选多个提交,可以将哈希值列出来: git cherry-pick <commit-hash-1> <commit-hash-2> <commit-hash-3> # 4. 清理旧分支 git branch -D main # 删除旧的主分支 git branch -m new-branch main # 将新分支重命名为主分支 # 5. 清理旧的远程分支 git remote remove origin # 6. 创建新的 GitHub 仓库 # 7. 关联新仓库并推送 git remote add origin https://github.com/your-username/new-repo-name.git git push -u origin main # 8. 验证
这里 DeepSeek
还漏掉了一个关键细节:cherry-pick
在遇到多个 commit
版本时需要严格遵守先后顺序。在我进一步的提示下,它才补全了这部分内容,并且给出了发生冲突时的解决方案,但比较官方:
如果在挑选提交时发生冲突:
Git 会暂停挑选过程,并标记冲突文件。
手动解决冲突后,使用以下命令继续:
git add <resolved-files> git cherry-pick --continue
如果你想跳过当前提交(例如冲突无法解决),可以使用:
git cherry-pick --skip
如果你想取消整个挑选过程,可以使用:
git cherry-pick --abort
4.4 V3 模型:中间结果的处理
由于 git log
命令得到的 commit
顺序是从新到旧,与 cherry-pick
相反,因此可以让 DeepSeek
帮我获取正确排序的哈希列表。这类简单任务 V3 完成得很好:
# 1. 逆序输出提交历史
git log --reverse
# 2. 筛选指定日期之后的提交
git log --since="2024-09-13 00:00:00"
# 3. 只保留哈希值
git log --pretty=format:"%H"
# 4. 组合命令
git log --since="2024-09-13 00:00:00" --reverse --pretty=format:"%H"
# 5. 解释参数
# --since="2024-09-13 00:00:00":筛选出指定日期之后的提交。
# --reverse:将提交历史从最旧到最新排列。
# --pretty=format:"%H":只输出提交的哈希值。
为了节省时间,我将最后的 PowerShell
命令作了进一步格式化处理,只保留 SHA1
哈希值的前八位,并用空格进行分隔:
(git log --since="2024-09-13 00:00:00" --reverse --pretty=format:"%H" | % { $_.Substring(0, 8) }) -join " "
4.5 方案验证,首战告捷
然后按照最后一次需求确认的结果,尝试用 --orphan
+ cherry-pick
来实现:
# 备份到新文件夹,再行处理
> git clone F:\Courses\Postman2\ newRepo
Cloning into 'newRepo'...
done.
> cd newRepo
# 获取待迁移节点列表(从早到晚排序)
> $tmp = (git log --since="2024-09-13 00:00:00" --reverse --pretty=format:"%H" | % { $_.Substring(0, 8) }) -join " "
# 从 main 分支切到孤立分支 master
> git checkout --orphan master
# 移除暂存区(stage)内的所有提交内容
> git rm --cached *
最后这步是为了清空当前工作区内的无关变更,以便执行 git cherry-pick
命令:
【图 1:切到孤立分支 master 后,移除暂存区(stage)内的所有提交内容】
之后就可以删除工作区内的冗余内容了(除了 .git
文件夹保留,其余均可删除):
# 查看当前待删文件(夹)
> git status -s
?? LICENSE
?? README.md
?? code/
?? notes/
> rm -Recurse -Force LICENSE,code,notes,README.md
【图 2:清空工作区内的所有无关内容】
然后就可以放心执行 git cherry-pick
了:
# 批量执行节点迁移
> $tmp
3b2de1fe e8f40cf3 1b02df31 00988a80 b0718962 a29d52c5 71ccc45b 1b0c9af2 24f0bdf5 d77cf64b c6be7f0b a0284fa4 bd0b88f3 3c548a07 e713024c 3b792f58 e29381e8 8cff3c5b 2ae4c28d 11887a88 254d26c7 125356db e6fead8b 2413c3b7 bfdf3bee
> git cherry-pick 3b2de1fe e8f40cf3 1b02df31 00988a80 b0718962 a29d52c5 71ccc45b 1b0c9af2 24f0bdf5 d77cf64b c6be7f0b a0284fa4 bd0b88f3 3c548a07 e713024c 3b792f58 e29381e8 8cff3c5b 2ae4c28d 11887a88 254d26c7 125356db e6fead8b 2413c3b7 bfdf3bee
# ...
error: could not apply 3b2de1f... Init my own repo. Added translation folder
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".
hint: Disable this message with "git config advice.mergeConflict false"
>
但是按默认的合并方式,会得到很多冲突报错,中断命令:
【图 3:批量执行 cherry-pick 后出现一堆冲突文件】
此时只需要用 git add *
命令直接将其标记为已解决,就能继续了:
【图 4:手动处理冲突内容,并继续 git cherry-pick 操作】
接着,Git
会自动弹出本轮操作的提交注释页,询问是否需要修改注释内容。这里无需修改,直接关闭即可:
【图:5:批量操作后的提交界面(无需修改,直接关闭即可)】
最后,再用 gitk --all
命令查看版本树,新的子版本树就诞生了:
【图 6:利用 gitk --all 查看当前所有版本树,新的子树(上方)已经生成完毕,且历史提交日期不变】
处理完最复杂的两步后,剩下的都是些简单的收尾工作:
# 删除本地旧分支 main
> git branch -D main
Deleted branch main (was bfdf3be).
# 删除远程跟踪分支 origin
> git remote remove origin
# 分支 master 重命名为 main
> git branch -m master main
# 新建目标仓库,重置远程跟踪分支
> git remote add origin git@github.com:SafeWinter/learn-postman2.git
# 推送到远程仓库
> git push -u origin main
这样就实现了 Git
子版本树的完整迁移:
5 总结复盘
上述操作过程看似一气呵成,其实中途有很多次微调没有记录,这里略作复盘:
DeepSeek
延续了 “遇强则强” 的大模型风格,要想得到满意的答复,提问者除了精准描述问题外,还需要对相关领域有扎实的基础;否则DeepSeek
只会跟着你的思路,无法立即看出问题的根源所在;- 一旦需求明确后,
DeepSeek
往往能很快提供准确回复,且该方案准确率极高(--orphan
+cherry-pick
组合);这种感觉就像是在和付费版ChatGPT 4x
对话,但又是完全免费使用,非常震撼; - 务必重视
R1
模型的推理过程,这是后续大幅提高准确率的关键。R1
模型会将当前会话的历史记录全部导入推理过程,十分智能; - 建议大家还是多用网页或手机版 DeepSeek,能在本地部署的都是完整模型的蒸馏版,虽然无需联网交流,但表现是大打折扣的;与其跟风“大炼钢铁”,不如多用 DeepSeek 解决一些实际问题;
- 本文介绍的版本树剥离方案还存在一个问题:各历史节点的提交时间和作者修改不一致——前者为当前操作时间,后者为历史记录时间 1。要让提交时间也回归到历史节点,只能从历史节点中提取提交时间,然后逐一提交。但这样的单独处理,只要存在对原内容的修改,当次
cherry-pick
操作就会中断,且必须手动处理内容冲突,DeepSeek
暂时无法给出包含手动处理版本冲突的自动化脚本,只能给出没有中断的情况下每次迁移的自动化脚本(如下所示)。要实现彻底自动化,还需要提问者自身对bash
脚本或PowerShell
脚本有相当程度的透彻理解。
# runcommit.ps1
param([Parameter(Mandatory=$true, Position=0)][string]$CommitHash
)# 获取作者日期和提交日期
$AUTHOR_DATE = git show -s --format=%aI $CommitHash
$COMMITTER_DATE = git show -s --format=%cI $CommitHash# 设置环境变量
$env:GIT_AUTHOR_DATE = $AUTHOR_DATE.Trim()
$env:GIT_COMMITTER_DATE = $COMMITTER_DATE.Trim()# 执行 cherry-pick
git cherry-pick --keep-redundant-commits --allow-empty $CommitHash
# 运行方法:.\runcommit.ps1 commit_SHA_value (Enter)
该问题在浏览器查看历史提交记录时才会出现,
GitHub
目前只能按实际提交时间排序,而Gitee
则可以选择排序方式。相比之下,国产的Git
托管平台在展示历史提交方面更有优势。 ↩︎
相关文章:

【工欲善其事】利用 DeepSeek 实现复杂 Git 操作:从原项目剥离出子版本树并同步到新的代码库中
文章目录 利用 DeepSeek 实现复杂 Git 操作1 背景介绍2 需求描述3 思路分析4 实现过程4.1 第一次需求确认4.2 第二次需求确认4.3 第三次需求确认4.4 V3 模型:中间结果的处理4.5 方案验证,首战告捷 5 总结复盘 利用 DeepSeek 实现复杂 Git 操作 1 背景介绍…...

网络编程套接字(中)
文章目录 🍏简单的TCP网络程序服务端创建套接字服务端绑定服务端监听服务端获取连接服务端处理请求客户端创建套接字客户端连接服务器客户端发起请求服务器测试单执行流服务器的弊端 🍐多进程版的TCP网络程序捕捉SIGCHLD信号让孙子进程提供服务 …...
前端学习-事件委托(三十)
目录 前言 课前思考 for循环注册事件 语法 事件委托 1.事件委托的好处是什么? 2.事件委托是委托给了谁,父元素还是子元素 3.如何找到真正触发的元素 示例代码 总结 前言 才子佳人,自是白衣卿相 课前思考 1.如果同时给多个元素注册事件&…...

线程池以及在QT中的接口使用
文章目录 前言线程池架构组成**一、任务队列(Task Queue)****二、工作线程组(Worker Threads)****三、管理者线程(Manager Thread)** 系统协作流程图解 一、QRunnable二、QThreadPool三、线程池的应用场景W…...

c语言操作符(详细讲解)
目录 前言 一、算术操作符 一元操作符: 二元操作符: 二、赋值操作符 代码例子: 三、比较操作符 相等与不相等比较操作符: 大于和小于比较操作符: 大于等于和小于等于比较操作符: 四、逻辑操作符 逻辑与&…...

【自然语言处理(NLP)】深度学习架构:Transformer 原理及代码实现
文章目录 介绍Transformer核心组件架构图编码器(Encoder)解码器(Decoder) 优点应用代码实现导包基于位置的前馈网络残差连接后进行层规范化编码器 Block编码器解码器 Block解码器训练预测 个人主页:道友老李 欢迎加入社…...
JavaScript 入门教程
JavaScript 入门教程 JavaScript 入门教程引言学习 JavaScript 的好处常见的 JavaScript 框架和库 安装开发环境下载并安装 Node.js 和 npm安装常用开发工具(如 VS Code)配置本地开发环境 基础语法入门数据类型变量与常量运算符算术运算符比较运算符 条件…...

浅析CDN安全策略防范
CDN(内容分发网络)信息安全策略是保障内容分发网络在提供高效服务的同时,确保数据传输安全、防止恶意攻击和保护用户隐私的重要手段。以下从多个方面详细介绍CDN的信息安全策略: 1. 数据加密 数据加密是CDN信息安全策略的核心之…...
代码随想录刷题day22|(字符串篇)344.反转字符串、541.反转字符串 II
目录 一、题目思路 二、相关题目 三、总结与知识点 3.1 字符数组转换成字符串 一、题目思路 344反转字符串比较容易,双指针即可在空间复杂度为O(1)的基础上解决; 541反转字符串II :其中for循环中 i 每次的取值,不是 i&#…...

python学opencv|读取图像(五十三)原理探索:使用cv.matchTemplate()函数实现最佳图像匹配
【1】引言 前序学习进程中,已经探索了使用cv.matchTemplate()函数实现最佳图像匹配的技巧,并且成功对两个目标进行了匹配。 相关文章链接为:python学opencv|读取图像(五十二)使用cv.matchTemplate()函数实现最佳图像…...

win10部署本地deepseek-r1,chatbox,deepseek联网(谷歌网页插件Page Assist)
win10部署本地deepseek-r1,chatbox,deepseek联网(谷歌网页插件Page Assist) 前言一、本地部署DeepSeek-r1step1 安装ollamastep2 下载deepseek-r1step2.1 找到模型deepseek-r1step2.2 cmd里粘贴 后按回车,进行下载 ste…...

冯·诺依曼体系结构
目录 冯诺依曼体系结构推导 内存提高冯诺依曼体系结构效率的方法 你使用QQ和朋友聊天时,整个数据流是怎么流动的(不考虑网络情况) 与冯诺依曼体系结构相关的一些知识 冯诺依曼体系结构推导 计算机的存在就是为了解决问题,而解…...

本地部署 DeepSeek-R1 模型
文章目录 霸屏的AIDeepSeek是什么?安装DeepSeek安装图形化界面总结 霸屏的AI 最近在刷视频的时候,总是突然突然出现一个名叫 DeepSeek 的玩意,像这样: 这样: 这不经激起我的一顿好奇心,这 DeepSeek 到底是个…...
Mybatis——sql映射文件中的增删查改
映射文件内的增删查改 准备工作 准备一张数据表,用于进行数据库的相关操作。新建maven工程, 导入mysql-connector-java和mybatis依赖。新建一个实体类,类的字段要和数据表的数据对应编写接口编写mybatis主配置文件 public class User {priva…...

【开源免费】基于Vue和SpringBoot的流浪宠物管理系统(附论文)
本文项目编号 T 182 ,文末自助获取源码 \color{red}{T182,文末自助获取源码} T182,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...

nth_element函数——C++快速选择函数
目录 1. 函数原型 2. 功能描述 3. 算法原理 4. 时间复杂度 5. 空间复杂度 6. 使用示例 8. 注意事项 9. 自定义比较函数 11. 总结 nth_element 是 C 标准库中提供的一个算法,位于 <algorithm> 头文件中,用于部分排序序列。它的主要功能是将…...

DNS缓存详解(DNS Cache Detailed Explanation)
DNS缓存详解 清空DNS缓存可以让网页访问更快捷。本文将从什么是DNS缓存、为什么清空DNS缓存、如何清空DNS缓存、清空DNS缓存存在的问题四个方面详细阐述DNS缓存清空的相关知识。 一、什么是DNS缓存 1、DNS缓存的定义: DNS缓存是域名系统服务在遇到DNS查询时自动…...

课设:【ID0022】火车票售票管理系统(前端)
技术栈:Java,JavaSwing,MySQL 数据库表数量:12个 1.功能描述 管理员功能 管理员是系统的高级用户,拥有对整个系统的全面管理权限。管理员的功能模块包括以下六个方面: 对用户管理增删查改 对售票员…...
Ruby 类和对象
Ruby 类和对象 引言 在软件开发中,类和对象是面向对象编程(OOP)的核心概念。Ruby 作为一种动态、解释型编程语言,也以简洁的方式支持面向对象编程。本文将深入探讨 Ruby 中的类和对象,包括它们的定义、创建、使用以及一些高级特性。 类与对象的定义 类 在 Ruby 中,类…...
Java基础知识总结(三十八)--读取数据
使用Reader体系,读取一个文本文件中的数据。返回 -1 ,标志读到结尾。 import java.io.*; class { public static void main(String[] args) throws IOException { /* 创建可以读取文本文件的流对象,让创建好的流对象和指定的文件相关联。…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...