使用子树合并策略更新git项目的部分目录

背景

正在开发的一个项目中引用了第三方库的源码,由于历史原因,源码的引用并不是很规范(直接下载下来后作为自己项目的部分源码使用,还进行了一些修改),具体如下:

  1. 我有一个本地git项目project_local,其基本目录结构如下:
    project_local
    |-- CHANGELOG.md
    |-- CMakeLists.txt
    |-- README.md
    |-- jsoncpp
    |   |-- CMakeLists.txt
    |   |-- json
    |   `-- jsoncpp.cpp
    |-- thread_pool.h
    `-- vpf|-- CMakeLists.txt|-- FindVPF.cmake|-- PyNvCodec|-- PytorchNvCodec|-- VideoCapture.cpp|-- VideoCapture.h|-- VideoWriter.cpp`-- VideoWriter.h
    
    其中,vpf/PyNvCodec、vpf/PytorchNvCodec均为目录,下面还有子目录和各种文件,正是这两个目录来源于开源项目
  2. 线上github源码工程为project_online,其基本目录结构为:
    project_online
    |-- CMakeLists.txt
    |-- LICENSE
    |-- PyNvCodec
    |   |-- CMakeLists.txt
    |   |-- TC
    |   |-- inc
    |   |-- pybind11-2.1.1
    |   `-- src
    |-- PytorchNvCodec
    |   |-- CMakeLists.txt
    |   `-- src
    |-- README.md
    |-- SampleDecode.py
    |-- SampleDecodeMultiThread.py
    |-- SampleDecodeSw.py
    |-- SampleDemuxDecode.py
    |-- SampleEncode.py
    |-- SampleEncodeMultiThread.py
    |-- SamplePyTorch.py
    |-- SampleTensorRTResnet.py
    |-- SampleTorchResnet.py
    `-- Tests.py
    
  3. project_local项目中的vpf目录使用了project_online工程,即vpf/PyNvCodec、vpf/PytorchNvCodec两个目录均来源于project_online项目下的PyNvCodec和PytorchNvCodec
  4. 具体需要求是:project_online项目有更新了(新版本v1.1),我想把这些更新应用在vpf/PyNvCodec、vpf/PytorchNvCodec这两个目录上,其他文件和目录均保持不变

实现方法

推荐方法:推荐方法:使用子树合并策略 (Subtree Merge)

# 进入本地项目目录
cd /path/to/project_local# 1. 添加原始仓库为远程源
git remote add online https://github.com/original-owner/project_online.git
git fetch online# 2. 选择要合并的版本(标签或分支)
TARGET_VERSION="v1.1"  # 替换为实际版本# 3. 更新 PyNvCodec
git subtree pull --prefix=vpf/PyNvCodec online $TARGET_VERSION -m "Update PyNvCodec to $TARGET_VERSION"# 4. 更新 PytorchNvCodec
git subtree pull --prefix=vpf/PytorchNvCodec online $TARGET_VERSION -m "Update PytorchNvCodec to $TARGET_VERSION"# 5. 保留本地修改的文件(根据情况看是否执行)
git checkout HEAD -- vpf/PyNvCodec/local_settings.py
git checkout HEAD -- vpf/PytorchNvCodec/custom_config.h

这种方法确保:

  1. 精确更新指定目录
  2. 保留本地其他文件的修改
  3. 维护清晰的提交历史
  4. 支持后续持续更新
  5. 提供冲突解决机制

其他

关于git subtree pull 命令详解:

git subtree pull --prefix=vpf/PyNvCodec online $TARGET_VERSION -m "Update PyNvCodec to $TARGET_VERSION" 这个命令是 Git 子树策略的核心操作之一,下面我将详细解释其工作原理和每个参数的作用。

命令结构解析

命令部分说明
git subtree pull子树拉取操作
--prefix=vpf/PyNvCodec指定本地目标目录
online远程仓库别名
$TARGET_VERSION要拉取的远程版本(分支/标签)
-m "Update PyNvCodec to $TARGET_VERSION"合并提交信息

工作原理详解

1. 子树合并的本质

git subtree 是一种将外部仓库作为子目录集成到当前仓库的策略。与子模块不同,子树的内容直接属于主仓库,不需要额外的引用文件。

2. 命令执行流程

当执行 git subtree pull 时,Git 会执行以下操作:

  1. 创建临时分支:在后台创建一个临时分支,包含远程仓库指定版本的内容
  2. 提取子树历史:从临时分支中提取与指定目录相关的提交历史
  3. 重写路径:将远程路径重写为本地 --prefix 指定的路径
    • 远程:PyNvCodec/file.txt → 本地:vpf/PyNvCodec/file.txt
  4. 合并到当前分支:将重写后的提交合并到当前分支
  5. 创建合并提交:使用 -m 指定的消息创建合并提交
  6. 清理临时对象:删除临时分支和相关对象

3. 路径映射机制

原始远程结构:         本地映射后结构:
PyNvCodec/            vpf/PyNvCodec/
├── src/              ├── src/
├── inc/              ├── inc/
└── CMakeLists.txt    └── CMakeLists.txt

Git 会自动处理路径转换,确保远程文件放入正确的本地目录。

关键特性与优势

1. 历史保留

  • 保留完整的提交历史(包括作者、日期等信息)
  • 可以通过 git log vpf/PyNvCodec 查看子树历史
  • 保持原始提交哈希不变(通过重写实现)

2. 双向同步

  • 拉取更新git subtree pull
  • 推送修改git subtree push --prefix=... online branch
  • 允许将本地修改推送回原始仓库

3. 冲突处理

当子树目录有本地修改时:

  1. Git 会自动尝试合并
  2. 如果自动合并失败,会暂停并提示解决冲突
  3. 解决冲突后使用 git commit 完成合并

4. 与普通合并的区别

特性git subtree pull普通 git merge
影响范围仅指定目录整个仓库
历史处理重写路径后保留原始历史保留原始路径
冲突概率更低(仅限子树目录)更高(整个仓库)
工作目录不需要干净状态需要干净状态

使用示例场景

初始添加子树

# 首次添加子树(创建初始提交)
git subtree add --prefix=vpf/PyNvCodec online v1.0.0 -m "添加PyNvCodec v1.0.0"

更新子树

# 更新到新版本
git subtree pull --prefix=vpf/PyNvCodec online v1.2.0 -m "更新PyNvCodec到v1.2.0"

处理冲突

# 如果发生冲突
git mergetool -t vscode  # 使用VS Code解决冲突
git commit -m "解决PyNvCodec合并冲突"

查看子树历史

git log --graph --oneline --decorate -- vpf/PyNvCodec

高级选项

1. 压缩历史 (--squash)

git subtree pull --prefix=... --squash -m "更新"
  • 优点:创建一个合并提交,不引入外部历史,保持仓库整洁
  • 缺点:丢失详细提交历史,无法追溯子树内部变更

2. 指定合并策略

git subtree pull --prefix=... -X theirs  # 优先使用远程版本
git subtree pull --prefix=... -X ours    # 优先使用本地版本

3. 拆分子树历史

# 查看子树历史
git subtree split --prefix=vpf/PyNvCodec --rejoin

常见问题解决方案

  1. 目录不存在错误

    mkdir -p vpf/PyNvCodec  # 确保目标目录存在
    touch vpf/PyNvCodec/.gitkeep  # 添加占位文件
    git add vpf/PyNvCodec/.gitkeep
    git commit -m "创建PyNvCodec目录"
    
  2. 权限拒绝错误

    # 确保没有未提交的修改
    git status# 暂存当前修改
    git stash# 执行子树拉取
    git subtree pull ...# 恢复暂存修改
    git stash pop
    
  3. 大型仓库优化

    # 浅层克隆历史
    git subtree pull --prefix=... --squash# 限制历史深度
    git config subtree.online.shallow true
    

与替代方案的比较

方案优点缺点
子树策略无需外部依赖,完整历史学习曲线较陡峭
子模块明确分离,易于更新需要额外命令,协作复杂
手动复制简单直观丢失历史,难以更新
仓库合并保留完整历史污染主仓库历史

git subtree pull 是管理项目内嵌外部代码库的专业解决方案,特别适合需要保留历史同时精确控制更新范围的情况。

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

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

相关文章

pikachu通关教程-CSRF

CSRF(get) 用bp进行抓包 选择action value值的修改 点击test in browser copy然后放在bp代理的浏览器上,会出现一个提交按钮,这时候点击之后信息就被修改了。 CSRF(post) 请求的方式不同,其他都是一样 CSRF Token 存在cookie 首先要先下载一…

AI驱动游戏开发:Unity与ML-Agents结合

AI驱动游戏开发:Unity与ML-Agents结合 系统化学习人工智能网站(收藏):https://www.captainbed.cn/flu 文章目录 AI驱动游戏开发:Unity与ML-Agents结合摘要引言技术架构与开发流程1. Unity与ML-Agents协同机制2. 开发…

如何给windos11 扩大C盘容量

动不动C盘就慢了,苹果逼着用户换手机,三天两头更新系统,微软也是毫不手软。c盘 从10个G就够用,到100G 也不够,看来通货膨胀是部分行业的。 在 Windows 11 中扩大 C 盘容量,主要取决于磁盘分区布局和可用空…

Kafka入门-消费者

消费者 Kafka消费方式:采用pull(拉)的方式,消费者从broker中主动拉去数据。使用pull的好处就是消费者可以根据自身需求,进行拉取数据,但是坏处就是如果Kafka没有数据,那么消费者可能会陷入循环…

SpringBoot自动化部署实战技术文章大纲

技术背景与目标 介绍SpringBoot在现代开发中的重要性自动化部署的价值:提升效率、减少人为错误、实现CI/CD适用场景:中小型Web应用、微服务架构 自动化部署核心方案 基于Docker的容器化部署 SpringBoot应用打包为Docker镜像使用Docker Compose编排多容…

TDengine 集群运行监控

简介 为了确保集群稳定运行,TDengine 集成了多种监控指标收集机制,并通过 taosKeeper 进行汇总。taosKeeper 负责接收这些数据,并将其写入一个独立的 TDengine 实例中,该实例可以与被监控的 TDengine 集群保持独立。TDengine 中的…

C# 委托UI控件更新例子,何时需要使用委托

1. 例子1 private void UdpRxCallBackFunc(UdpDataStruct info) {// 1. 前置检查防止无效调用if (textBoxOutput2.IsDisposed || !textBoxOutput2.IsHandleCreated)return;// 2. 使用正确的委托类型Invoke(new Action(() >{// 3. 双重检查确保安全if (textBoxOutput2.IsDis…

[10-2]MPU6050简介 江协科技学习笔记(22个知识点)

1 2 3 欧拉角是描述三维空间中刚体或坐标系之间相对旋转的一种方法。它们由三个角度组成,通常表示为: • 偏航角(Yaw):绕垂直轴(通常是z轴)的旋转,表示偏航方向的变化。 • 俯仰角&a…

虚拟环境共享系统包

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 虚拟环境共享系统包 python basic_pipelines/detection.py如果报错显示如下: Traceback (most recent call last):File "/home/ai/hailort/hailo-rpi5-exam…

Java求职者面试题解析:基础概念、计算机基础与源码原理

Java求职者面试题解析:基础概念、计算机基础与源码原理 第一轮:基础概念问题 1. 什么是Java的跨平台特性? Java的跨平台特性是指Java程序可以在任何支持Java虚拟机(JVM)的设备上运行,而无需重新编译。这…

网页前端开发(基础进阶4--axios)

Ajax Ajax(异步的JavaScript和XML) 。 XML是可扩展标记语言,本质上是一种数据格式,可以用来存储复杂的数据结构。 可以通过Ajax给服务器发送请求,并获取服务器响应的数据。 Ajax采用异步交互:可以在不重新加载整个页面的情况下&am…

设计模式-迪米特法则

迪米特法则 迪米特法则 (Law of Demeter, LoD),也被称为“最少知识原则 (Principle of Least Knowledge)”,是面向对象设计中的一个重要原则。 核心思想:一个对象应该对其他对象有尽可能少的了解。 更具体地说,它规定了一个对象…

结构性-代理模式

动态代理主要是为了处理重复创建模板代码的场景。 使用示例 public interface MyInterface {String doSomething(); }public class MyInterfaceImpl implements MyInterface{Overridepublic String doSomething() {return "接口方法dosomething";} }public class M…

Unity大型项目资源框架

🎯 Unity大型项目资源管理:低端机检测后自动切换资源框架(大厂风格) 🧩 框架目标 ✅ 启动时检测机型性能,判定设备等级 ✅ 同一资源有高配/中配/低配不同压缩格式 ✅ 根据设备等级,加载对应资源包(AB) ✅ 支持动态切换(可用来切换特效/贴图分辨率/模型LOD) ✅ 保证…

MATLAB仿真:偏振光在光纤通信中的应用研究_可复现,有问题请联系博主

MATLAB仿真:偏振光在光纤通信中的应用研究 1. 研究概述 本文通过MATLAB仿真研究偏振光在光纤通信中的关键技术,包括偏振态生成、传输特性和检测方法,重点分析偏振模色散(PMD)的影响机制,并设计偏振控制优化方案。 %% 主程序框架 clc; clear; close all; addpath(Polar…

CTA-861-G-2017中文pdf版

CTA-861-G标准(2016年11月发布)规范未压缩高速数字接口的DTV配置,涵盖视频格式、色彩编码、辅助信息传输等,适用于DVI、HDMI等接口,还涉及EDID数据结构及HDR元数据等内容。

C++核心编程_继承方式

继承的语法&#xff1a;class 子类 : 继承方式 父类 继承降属性权限&#xff0c;不可升属性权限 继承方式一共有三种&#xff1a; 公共继承 保护继承 私有继承 #include <iostream> #include <string> using namespace std;class Base1 { public:int m_A; p…

Dockerfile常用指令介绍

Dockerfile常用指令介绍 Dockerfile是一个文本文件&#xff0c;用于定义Docker镜像的构建过程。下面介绍一些最常用的Dockerfile指令及其用法&#xff1a; 基础指令 FROM - 指定基础镜像 FROM python:3.9-slim这是Dockerfile的第一个指令&#xff0c;用于指定构建镜像的基础镜…

Spring中@Primary注解的作用与使用

在 Spring 框架中&#xff0c;Primary 注解用于解决依赖注入时的歧义性&#xff08;Ambiguity&#xff09;问题。当 Spring 容器中存在多个相同类型的 Bean 时&#xff0c;通过 Primary 标记其中一个 Bean 作为默认的首选注入对象。 核心作用&#xff1a; 解决多个同类型 Bean …

本地优先的状态管理与工具选型策略

本地优先&#xff1a;合理把控状态共享边界 在 React 应用开发过程中&#xff0c;开发者容易陷入一个认知误区——过度追求状态的全局化。许多新手开发者在项目初期就急于引入 Redux、Zustand 或 Jotai 等状态管理工具&#xff0c;将一些本应属于组件内部的琐碎状态&#xff0…