【工欲善其事】利用 DeepSeek 实现复杂 Git 操作:从原项目剥离出子版本树并同步到新的代码库中

news2025/2/5 17:49:18

文章目录

  • 利用 DeepSeek 实现复杂 Git 操作
    • 1 背景介绍
    • 2 需求描述
    • 3 思路分析
    • 4 实现过程
      • 4.1 第一次需求确认
      • 4.2 第二次需求确认
      • 4.3 第三次需求确认
      • 4.4 V3 模型:中间结果的处理
      • 4.5 方案验证,首战告捷
    • 5 总结复盘

利用 DeepSeek 实现复杂 Git 操作


1 背景介绍

今天综合利用 DeepSeek V3R1 推理模型,成功解决了一个复杂的 Git 操作,谨以此文记录 DeepSeek 使用心得,以备后续复盘。这本是我一次操作上的疏漏,未能将 Fork 到本地的代码与原项目彻底脱钩,直到很晚才发现问题,已经很难快速用简单的 Git 命令恢复原样了。于是,我想到了 DeepSeek。

2 需求描述

现有一个从 GitHub 复刻(fork)到我本地的开源项目。从复刻到本地那天起,我又陆续在 main 分支提交了很多次(没有其他分支)。现在需要将我本人提交的所有节点从该副本完整迁移到另一个新仓库,并要求保留所有节点的历史提交记录(提交时间、注释信息等)。

图 0:迁移 Git 子版本树的需求描述示意图

【图 0:迁移 Git 子版本树的需求描述示意图】

3 思路分析

该需求涉及从原 Git 库彻底剥离需要的子版本树。Git 还没有能一步实现节点树 “脱钩” 的操作命令。但大方向是明确的,无非以下四步 ——

  1. 先找到脱钩位置(简单);
  2. 从脱钩点产生一个新的 Git 根节点(未知);
  3. 设法将脱钩点后续产生的提交版本依次追加到新的根节点上(未知);
  4. 最后删除原有版本树,重置远程推送分支 origin(简单);

以上四步逻辑关系清晰,正好可以用 DeepSeek 一试身手。

4 实现过程

4.1 第一次需求确认

因为涉及多次复杂 Git 操作,先用 V3 网页版直接提问(刻意未加任何提示词技巧):

我有一个本地 Git 代码仓库,是从 GitHub 一个开源项目上 fork 到本地的,但这样产生的提交不计入 GitHub 网站的个人贡献,因此我在提交了很多本地新增的版本后决定将其剥离出来。但我不知道应该怎么操作。帮帮我

以下是整理后的 DeepSeek V3 的回复,可以看到 V3 模型第一次理解有偏差:

要将本地 Git 仓库从 GitHubfork 中剥离出来,使其成为一个独立的仓库,并保留所有提交历史,可以按照以下步骤操作:

# 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 版本时需要严格遵守先后顺序。在我进一步的提示下,它才补全了这部分内容,并且给出了发生冲突时的解决方案,但比较官方:

如果在挑选提交时发生冲突:

  1. Git 会暂停挑选过程,并标记冲突文件。

  2. 手动解决冲突后,使用以下命令继续:

    git add <resolved-files>
    git cherry-pick --continue
    
  3. 如果你想跳过当前提交(例如冲突无法解决),可以使用:

    git cherry-pick --skip
    
  4. 如果你想取消整个挑选过程,可以使用:

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)内的所有提交内容

【图 1:切到孤立分支 master 后,移除暂存区(stage)内的所有提交内容】

之后就可以删除工作区内的冗余内容了(除了 .git 文件夹保留,其余均可删除):

# 查看当前待删文件(夹)
> git status -s
?? LICENSE
?? README.md
?? code/
?? notes/
> rm -Recurse -Force LICENSE,code,notes,README.md

图 2:清空工作区内的所有无关内容

【图 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 后出现一堆冲突文件

【图 3:批量执行 cherry-pick 后出现一堆冲突文件】

此时只需要用 git add * 命令直接将其标记为已解决,就能继续了:

图 4:手动处理冲突内容,并继续 git cherry-pick 操作

【图 4:手动处理冲突内容,并继续 git cherry-pick 操作】

接着,Git 会自动弹出本轮操作的提交注释页,询问是否需要修改注释内容。这里无需修改,直接关闭即可:

图:5:批量操作后的提交界面(无需修改,直接关闭即可)

【图:5:批量操作后的提交界面(无需修改,直接关闭即可)】

最后,再用 gitk --all 命令查看版本树,新的子版本树就诞生了:

图 6:利用 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 子版本树的完整迁移:

final repo snapshot

5 总结复盘

上述操作过程看似一气呵成,其实中途有很多次微调没有记录,这里略作复盘:

  1. DeepSeek 延续了 “遇强则强” 的大模型风格,要想得到满意的答复,提问者除了精准描述问题外,还需要对相关领域有扎实的基础;否则 DeepSeek 只会跟着你的思路,无法立即看出问题的根源所在;
  2. 一旦需求明确后,DeepSeek 往往能很快提供准确回复,且该方案准确率极高(--orphan + cherry-pick 组合);这种感觉就像是在和付费版 ChatGPT 4x 对话,但又是完全免费使用,非常震撼;
  3. 务必重视 R1 模型的推理过程,这是后续大幅提高准确率的关键。R1 模型会将当前会话的历史记录全部导入推理过程,十分智能;
  4. 建议大家还是多用网页或手机版 DeepSeek,能在本地部署的都是完整模型的蒸馏版,虽然无需联网交流,但表现是大打折扣的;与其跟风“大炼钢铁”,不如多用 DeepSeek 解决一些实际问题;
  5. 本文介绍的版本树剥离方案还存在一个问题:各历史节点的提交时间和作者修改不一致——前者为当前操作时间,后者为历史记录时间 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)

  1. 该问题在浏览器查看历史提交记录时才会出现,GitHub 目前只能按实际提交时间排序,而 Gitee 则可以选择排序方式。相比之下,国产的 Git 托管平台在展示历史提交方面更有优势。 ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2293418.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】线程池实现

目录 一、线程池简介线程池的核心组件实现步骤 二、C11实现线程池源码 三、线程池源码解析1. 成员变量2. 构造函数2.1 线程初始化2.2 工作线程逻辑 3. 任务提交(enqueue方法)3.1 方法签名3.2 任务封装3.3 任务入队 4. 析构函数4.1 停机控制 5. 关键技术点解析5.1 完美转发实现5…

数据结构实战之线性表(三)

目录 1.顺序表释放 2.顺序表增加空间 3.合并顺序表 4.线性表之链表实现 1.项目结构以及初始代码 2.初始化链表(不带头结点) 3.链表尾部插入数据并显示 4.链表头部插入数据 5.初始化链表&#xff08;带头结点&#xff09; 6.带头结点的链表头部插入数据并显示 7.带头结…

【python】python基于机器学习与数据分析的手机特性关联与分类预测(源码+数据集)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;专__注&#x1f448;&#xff1a;专注主流机器人、人工智能等相关领域的开发、测试技术。 python基于机器学习与数据分析的手机特性关联与分类…

ZOJ 1007 Numerical Summation of a Series

原题目链接 生成该系列值的表格 对于x 的 2001 个值&#xff0c;x 0.000、0.001、0.002、…、2.000。表中的所有条目的绝对误差必须小于 0.5e-12&#xff08;精度为 12 位&#xff09;。此问题基于 Hamming (1962) 的一个问题&#xff0c;当时的大型机按今天的微型计算机标准来…

全面解析文件上传下载删除漏洞:风险与应对

在数字化转型的时代&#xff0c;文件上传、下载与删除功能已经成为各类应用程序的标准配置&#xff0c;从日常办公使用的协同平台&#xff0c;到云端存储服务&#xff0c;再到社交网络应用&#xff0c;这些功能在给用户带来便捷体验、显著提升工作效率的同时&#xff0c;也隐藏…

【C语言深入探索】结构体详解(二):使用场景

目录 一、复杂数据的表示 二、数据的封装 三、多态的模拟 四、回调函数的实现 五、多线程编程 六、通信协议的实现和文件操作 6.1. 使用结构体实现简单通信协议 6.2. 使用结构体进行文件操作 七、图形界面编程 结构体在C语言中具有广泛的应用场景&#xff0c;以下是一…

【大模型】AI 辅助编程操作实战使用详解

目录 一、前言 二、AI 编程介绍 2.1 AI 编程是什么 2.1.1 为什么需要AI辅助编程 2.2 AI 编程主要特点 2.3 AI编程底层核心技术 2.4 AI 编程核心应用场景 三、AI 代码辅助编程解决方案 3.1 AI 大模型平台 3.1.1 AI大模型平台代码生成优缺点 3.2 AI 编码插件 3.3 AI 编…

RK3566-移植5.10内核Ubuntu22.04

说明 记录了本人使用泰山派&#xff08;RK3566&#xff09;作为平台并且成功移植5.10.160版本kernel和ubuntu22.04&#xff0c;并且成功配置&连接网络的完整过程。 本文章所用ubuntu下载地址&#xff1a;ubuntu-cdimage-ubuntu-base-releases-22.04-release安装包下载_开源…

从零开始实现一个双向循环链表:C语言实战

文章目录 1链表的再次介绍2为什么选择双向循环链表&#xff1f;3代码实现&#xff1a;从初始化到销毁1. 定义链表节点2. 初始化链表3. 插入和删除节点4. 链表的其他操作5. 打印链表和判断链表是否为空6. 销毁链表 4测试代码5链表种类介绍6链表与顺序表的区别7存储金字塔L0: 寄存…

51单片机 06 定时器

51 单片机的定时器属于单片机的内部资源&#xff0c;其电路的连接和运转均在单片机内部完成。 作用&#xff1a;1、用于计时&#xff1b;2、替代长时间的Delay&#xff0c;提高CPU 运行效率和处理速度。 定时器个数&#xff1a;3个&#xff08;T0、T1、T2&#xff09;&#xf…

【C++】P1957 口算练习题

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述输入格式&#xff1a;输出格式&#xff1a; &#x1f4af;我的做法代码实现&#xff1a; &#x1f4af;老师的做法代码实现&#xff1a; &#x1f4af;对比分析&am…

Workbench 中的热源仿真

探索使用自定义工具对移动热源进行建模及其在不同行业中的应用。 了解热源动力学 对移动热源进行建模为各种工业过程和应用提供了有价值的见解。激光加热和材料加工使用许多激光束来加热、焊接或切割材料。尽管在某些情况下&#xff0c;热源 &#xff08;q&#xff09; 不是通…

CCF-GESP 等级考试 2023年12月认证C++八级真题解析

2023年12月真题 一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 正确答案&#xff1a;C 考察知识点&#xff1a;数学问题 解析&#xff1a;本题可抽象为分类计数问题&#xff0c;应使用加法原理&#xff0c;而不是乘法原理。答案为 ACB 的方案数 2 加上 ADB 的…

vscode搭建git

vscode搭建git 一、安装git二、vscode上搭建git(1) 先创建本地仓库再上传到远程仓库&#xff0c;远程仓库名是根据本地仓库名一致(2) 先创建远程仓库&#xff0c;再将本地仓库上传到指定远程仓库 一、安装git 网络教程很多&#xff0c;在此就不赘述了 参考&#xff1a;git安装…

解决Mac安装软件的“已损坏,无法打开。 您应该将它移到废纸篓”问题

mac安装软件时&#xff0c;如果出现这个问题&#xff0c;其实很简单 首先打开终端&#xff0c;输入下面的命令 sudo xattr -r -d com.apple.quarantine 输入完成后&#xff0c;先不要回车&#xff0c;点击访达--应用程序--找到你无法打开的app图标&#xff0c;拖到终端窗口中…

ChatGPT-4o和ChatGPT-4o mini的差异点

在人工智能领域&#xff0c;OpenAI再次引领创新潮流&#xff0c;近日正式发布了其最新模型——ChatGPT-4o及其经济实惠的小型版本ChatGPT-4o Mini。这两款模型虽同属于ChatGPT系列&#xff0c;但在性能、应用场景及成本上展现出显著的差异。本文将通过图文并茂的方式&#xff0…

读书笔记--分布式架构的异步化和缓存技术原理及应用场景

本篇是在上一篇的基础上&#xff0c;主要对分布式应用架构下的异步化机制和缓存技术进行学习&#xff0c;主要记录和思考如下&#xff0c;供大家学习参考。大家知道原来传统的单一WAR应用中&#xff0c;由于所有数据都在同一个数据库中&#xff0c;因此事务问题一般借助数据库事…

BUU10 [极客大挑战 2019]LoveSQL1

万能用户名&#xff08;密码随便&#xff09; 登录进去以后发现是这个东西&#xff0c;然而并没有什么卵用 然后就开始爆破数据库名字--表名--列名 注意&#xff1a;这道题需要将所有的表名都爆出来&#xff0c;需要在payload里头写 group_concat()&#xff0c;否则页面只会显…

tomcat核心组件及原理概述

目录 1. tomcat概述 1.1 概念 1.2 官网地址 2. 基本使用 2.1下载 3. 整体架构 3.1 核心组件 3.2 从web.xml配置和模块对应角度 3.3 如何处理请求 4. 配置JVM参数 5. 附录 1. tomcat概述 1.1 概念 什么是tomcat Tomcat是一个开源、免费、轻量级的Web服务器。 Tomca…

冰蝎v4.0.5 来啦

webshell始终是渗透测试的热门&#xff0c;上次护网写冰蝎检测规则&#xff0c;加密流量&#xff0c;有点压力&#xff0c;今天终于有空来复现一下&#xff0c;我知道玩知乎的大佬很多&#xff0c;轻一点喷&#xff0c;学习新知识不丢人&#xff5e; ailx10 1949 次咨询 4.9 …