自由开发者aosp源码修改部分如何提交保存上传服务器?-记录AI帮助我们实现过程

背景:

经常在做aosp开发时候经常面临一个问题,那就是从google或者清华源repo了aosp代码后,肯定会进行一些aosp代码的修改,但是因为大部分国内开发者都无法把这些修改commit进行push到google后台。所以导致自己的相关修改无法被有效的保存到服务器,一直commit在自己的本地,这样只是commit本地方式还是非常非常不方便,一旦更换电脑,或者说代码重新repo都无法很方便把自己前面commit进行合入。
在这里插入图片描述针对上面提到的痛点,那么有什么办法能够帮助解决么?下面介绍2种常见方案来解决该痛点。

方案1

核心原理:
把从清华源repo下来的aosp代码的所有git仓库,把他们统一迁移到自己的git服务器后台比如gitea等。这样在自己git服务器后台就拥有整套的aosp代码仓库,然后在出现repo自己服务器的aosp源码, 后续修改自己服务器repo的源码就可以很方便的进行push到服务器进行保存。
在这里插入图片描述

缺点:
这个相当于要把整套aosp的代码仓库都进行保存到自己git服务器后台,整个过程耗费时间,最重要是保存整套aosp代码的git仓库需要大量的硬盘空间,这个很多同学都是本地电脑搭建的git服务器后台,所以这个还是一个比较大的痛点。
针对上面这个方案占用空间大的痛点问题,那么是否有其他方案,可以实现不需要保存整套代码git库,只需要保存自己的修改,aosp代码依旧可以从清华源等地方下载,自己的所有修改commit只是push保存到git服务器后台。

方案2

核心原理:
aosp代码本身可以从google服务器,清华源等地方进行repo,不需要额外保存自己服务器,只需要保存自己针对aosp修改的commit到服务器后台既可以。这样既可以实现节省空间目的,也可以实现对aosp的所有修改进行了相关的保存目的。

在这里插入图片描述

那么具体方案2如何实现呢?这里我们设计的是使用一个shell脚本就可以,我们可以借助AI来帮忙实现一下这个shell脚本。

Shell脚本的实现

实现的shell脚本代码如下:

#!/bin/bash

# 修复版 AOSP Patch 生成脚本
# 修复问题:
# 1. 现在能正确遍历所有仓库(包括framework/native等)
# 2. 确保patch文件生成到正确的aosp_patches目录下

# 设置输出目录(使用绝对路径避免位置问题)
PATCH_BASE_DIR="$(realpath "${1:-aosp_patches}")"
mkdir -p "$PATCH_BASE_DIR"

# 初始化计数器和清单文件
total_repos=0
total_patches=0
MANIFEST_FILE="$PATCH_BASE_DIR/patch_manifest.csv"
echo "repo_path,commit_hash,commit_subject,patch_file" > "$MANIFEST_FILE"

echo "开始扫描所有AOSP仓库中的未push提交..."

# 修复1:使用正确的repo遍历命令
repo list | while read -r repo_line; do
    # 提取仓库路径
    repo_path=$(echo "$repo_line" | awk '{print $1}')
    
    # 进入仓库目录
    if [ ! -d "$repo_path" ]; then
        echo "警告: 仓库目录不存在: $repo_path"
        continue
    fi
    
    pushd "$repo_path" > /dev/null || continue
    
    # 检查是否有未push的commit
    unpushed_count=$(git log --branches --not --remotes --oneline 2>/dev/null | wc -l)
    
    if [ "$unpushed_count" -gt 0 ]; then
        # 修复2:确保创建正确的目标目录结构
        repo_patch_dir="$PATCH_BASE_DIR/$repo_path"
        mkdir -p "$repo_patch_dir"
        
        # 获取未push的commit列表
        commits=$(git log --branches --not --remotes --pretty=format:"%h" --no-color)
        
        # 为每个commit生成patch
        commit_count=0
        for commit in $commits; do
            # 获取commit信息并处理特殊字符
            commit_subject=$(git log -1 --pretty=format:"%s" "$commit" | 
                            tr -d "\n" | 
                            tr "/" "_" | 
                            tr " " "_" | 
                            sed 's/[^a-zA-Z0-9_]/./g' | 
                            cut -c -50)
            
            # 生成带描述的文件名
            patch_filename="${commit}_${commit_subject}.patch"
            patch_file="$repo_patch_dir/$patch_filename"
            
            # 生成标准patch文件
            git format-patch -1 --no-stat --no-numbered --stdout "$commit" > "$patch_file"
            
            # 添加元信息头
            sed -i "1i # Repository: $repo_path\n# Commit Hash: $commit\n# Original Subject: $(git log -1 --pretty=format:%s $commit)\n#" "$patch_file"
            
            # 记录到清单文件(使用绝对路径)
            echo "\"$repo_path\",\"$commit\",\"$commit_subject\",\"$(realpath --relative-to="$PATCH_BASE_DIR" "$patch_file")\"" >> "$MANIFEST_FILE"
            
            commit_count=$((commit_count + 1))
            echo "生成patch: $(realpath --relative-to="$PATCH_BASE_DIR" "$patch_file")"
        done
        
        echo "[✓] $repo_path: 生成 $commit_count 个patch"
        total_patches=$((total_patches + commit_count))
        total_repos=$((total_repos + 1))
        popd > /dev/null || exit 1
    else
        popd > /dev/null
    fi
done

echo "=============================================="
echo "扫描完成!"
echo "共在 $total_repos 个仓库中发现 $total_patches 个未push的commit"
echo "Patch文件已保存到: $PATCH_BASE_DIR"
echo "目录结构:"
tree -L 3 "$PATCH_BASE_DIR" | head -15
echo "=============================================="

# 生成修复版应用脚本
APPLY_SCRIPT="$PATCH_BASE_DIR/apply_patches.sh"
cat > "$APPLY_SCRIPT" << 'EOF'
#!/bin/bash

# AOSP Patch 应用脚本(修复版)
# 确保正确解析相对路径

PATCH_BASE_DIR="$(cd "$(dirname "$0")" && pwd)"
MANIFEST="$PATCH_BASE_DIR/patch_manifest.csv"
SUCCESS_LOG="$PATCH_BASE_DIR/success.log"
FAIL_LOG="$PATCH_BASE_DIR/fail.log"

# 初始化日志
echo "Patch应用报告 - $(date)" > "$SUCCESS_LOG"
echo "失败记录 - $(date)" > "$FAIL_LOG"
success_count=0
fail_count=0

# 读取CSV格式的清单文件
tail -n +2 "$MANIFEST" | while IFS=, read -r repo_path commit_hash commit_subject patch_file; do
    # 清理CSV字段中的引号
    repo_path=${repo_path//\"/}
    patch_file=${patch_file//\"/}
    
    # 获取完整patch路径
    full_patch_path="$PATCH_BASE_DIR/$patch_file"
    
    echo -n "正在应用 $commit_hash ($commit_subject) 到 $repo_path ... "
    
    # 进入仓库目录
    if pushd "$repo_path" >/dev/null 2>&1; then
        # 应用patch
        if git am --whitespace=nowarn "$full_patch_path" >/dev/null 2>&1; then
            echo "成功" | tee -a "$SUCCESS_LOG"
            success_count=$((success_count + 1))
        else
            echo "失败" | tee -a "$FAIL_LOG"
            git am --abort >/dev/null 2>&1
            fail_count=$((fail_count + 1))
        fi
        popd >/dev/null
    else
        echo "仓库不存在: $repo_path" | tee -a "$FAIL_LOG"
        fail_count=$((fail_count + 1))
    fi
done

echo "=============================================="
echo "应用结果统计:"
echo "成功: $success_count"
echo "失败: $fail_count"
echo "----------------------------------------------"
echo "成功记录: $SUCCESS_LOG"
echo "失败记录: $FAIL_LOG"
echo "=============================================="

if [ "$fail_count" -gt 0 ]; then
    echo "警告: 有 $fail_count 个patch应用失败!"
    exit 1
fi
EOF

chmod +x "$APPLY_SCRIPT"
echo "已生成修复版应用脚本: $APPLY_SCRIPT"

上面代码保存到generate_patches.sh文件,generate_patches.sh放到aosp的根目录。
使用示例:
生成patch:

./generate_patches.sh /path/to/save_patches

生成的patch文件结构:

/path/to/save_patches/
├── frameworks/
│   └── base/
│       ├── abcd123_Fix_memory_leak.patch
│       └── efgh456_Add_new_feature.patch
├── patch_manifest.csv
└── apply_patches.sh

应用patch:

/path/to/save_patches/apply_patches.sh

这个改进版本能更清晰地标识每个patch的用途,同时在应用时能提供更详细的信息,方便问题排查。

实战结果

下面是我在aosp14上的一个实战体验:

test@test:~/disk2/aosp14$ rm aosp_patches/ -rf;./generate_asop_patches.sh
开始扫描所有AOSP仓库中的未push提交...
生成patch: frameworks/base/768227252484_modify_recent_show_mutilwindow_split_task_thumbnai.patch
生成patch: frameworks/base/c0b465576254_add_for_left.right.bar.patch
生成patch: frameworks/base/2408081e2df7_Revert_.modify_dumpsys_activity_containers_show_st.patch
生成patch: frameworks/base/60a6bd792ddd_modify_dumpsys_activity_containers_show_style.patch
生成patch: frameworks/base/2e980f7dadfc_add_ratio_for_cmd_start_splitscreen.patch
生成patch: frameworks/base/244c2ac15f46_start_splitscreen_by_use_intent_not_taskId.patch
生成patch: frameworks/base/be2cf046814e_add_a_cmd_startTask_for_splitscreen.patch
[] frameworks/base: 生成 7 个patch
==============================================
扫描完成!
共在 0 个仓库中发现 0 个未push的commit
Patch文件已保存到: /home/test/disk2/aosp14/aosp_patches
目录结构:
/home/test/disk2/aosp14/aosp_patches
├── frameworks
│   └── base
│       ├── 2408081e2df7_Revert_.modify_dumpsys_activity_containers_show_st.patch
│       ├── 244c2ac15f46_start_splitscreen_by_use_intent_not_taskId.patch
│       ├── 2e980f7dadfc_add_ratio_for_cmd_start_splitscreen.patch
│       ├── 60a6bd792ddd_modify_dumpsys_activity_containers_show_style.patch
│       ├── 768227252484_modify_recent_show_mutilwindow_split_task_thumbnai.patch
│       ├── be2cf046814e_add_a_cmd_startTask_for_splitscreen.patch
│       └── c0b465576254_add_for_left.right.bar.patch
└── patch_manifest.csv

2 directories, 8 files
==============================================
已生成修复版应用脚本: /home/test/disk2/aosp14/aosp_patches/apply_patches.sh


上面可以看出已经针对framework/base目录识别到了有7个本地commit,看看对应的生成patch目录情况:

test@test:~/disk2/aosp14$ tree aosp_patches/
aosp_patches/
├── apply_patches.sh
├── frameworks
│   └── base
│       ├── 2408081e2df7_Revert_.modify_dumpsys_activity_containers_show_st.patch
│       ├── 244c2ac15f46_start_splitscreen_by_use_intent_not_taskId.patch
│       ├── 2e980f7dadfc_add_ratio_for_cmd_start_splitscreen.patch
│       ├── 60a6bd792ddd_modify_dumpsys_activity_containers_show_style.patch
│       ├── 768227252484_modify_recent_show_mutilwindow_split_task_thumbnai.patch
│       ├── be2cf046814e_add_a_cmd_startTask_for_splitscreen.patch
│       └── c0b465576254_add_for_left.right.bar.patch
└── patch_manifest.csv

2 directories, 9 files

可以看到确实有针对一个个commit生成patch,后期到了新的aosp代码,只需要拷贝这个目录到根目录然后进行apply_patches.sh既可以。

但是也发现有bug,主要是针对这些未提交commit仓库并没有识别全面,比如framework/native等目录是没有识别正确,让AI进行修改其实一直也无法修改正确,这块其实还是AI生成的代码并没有去分析我们实际framework/native的情况,或者这种情况AI其实也没有很好的方法规则来识别过滤出没有push的commit,所以还是需要程序员们看懂修改去修改修复。

使用AI帮助编写一些提效的脚本工具一些感悟:

上面的AI生成的脚本确实整体上帮我们完成了%70左右工作,但其实还是会有一些bug,比如识别没有push的commit其实需要考虑的实际的aosp仓库状态情况,所以实际使用起来才会发现有相关的bug。但是大家注意一旦有了bug后,发现只是把bug告诉AI去修改,发现AI基本上很难修改好,毕竟AI其实还是属于大模型生成的,目前没有实际分析你场景具体问题原因,帮你准确修改好相关bug,所以这块大家也不要期待AI完全可以写出一个适合你实战的代码。

虽然AI无法完美满足你的实战需求代码,但是AI确实可以给你生成一个基本上可以用的成品代码,这个已经最少帮你节省了%70以上时间了,万事开头难,AI都帮助你开好了头,也帮你实现了一个基本可用的代码,你只需要在这个基础上改善完善他的功能,修复一些bug既可以,所以AI完全替代程序员这个事情是不太存在的,但是AI可以大大提升我们每个程序员的开发效率,让AI做出一些基本可用的模块类工作,节省我们大量的时间成本,我们程序员注意力集中在更高难度的一些AI无法实现需求和bug上。

总结AI对于我们程序员影响:
不用过多的去焦虑AI是否会完全取代我们程序员,因为很多现实场景需求还是很复杂的,完全取代程序员不太可能,但是AI确实不在编程方面帮助我们提升很大的效率,我们可以多使用AI来帮助做一些模块类的工作,自己经历投入到更加复杂,有门槛,有技术含量,AI无法完成的一些工作。
同时AI生成的那些代码,大家也要进行熟悉,不能过渡依赖AI,因为产生bug,或者需求变更的,都需要程序员自己去开发解决,过渡依赖可能浪费大量时间去提问,却得不到好的结果。

在这里插入图片描述

更多framework实战干货,请关注下面的“千里马学框架”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值