☰
开源鸿蒙Flutter工程代码托管与可复现验证实战
2026/10/16 3:52:54 网站建设 项目流程

今天这篇是“开源鸿蒙跨平台开发”系列的第二篇。昨天我们刚把开发环境跑通,今天的问题马上摆在眼前:工程只躺在本机,换台机器、换个协作者就完全抓瞎。所以第二天的任务特别明确——把本地这个 Flutter 跨平台 Demo 上传到代码托管平台,并且做一次干净环境下的可复现验证。

不要小看这一步。上传不是一个git push就完事的事,里面夹着远程仓库初始化方式、认证令牌、分支命名、换行符、构建产物误提交这一堆细枝末节。任何一个地方没处理好,都会让你卡在“本地能跑、一推就挂”的尴尬状态。我这次也是踩了好几个坑才把整个过程跑通,这篇就把踩坑和验证过程原原本本记录下来,给正在折腾开源鸿蒙跨平台开发的兄弟们做一个参考。

1. 为什么第二天要先搞定代码托管:从“本地能跑”到“哪里都能跑”

1.1 跨平台工程为什么要第一时间上仓库

做开源鸿蒙(OpenHarmony)跨平台开发,和普通纯原生开发有个明显区别:工程目录里不只有一套代码。以我正在用的 Flutter 跨平台方案为例,一个工程里同时存在android、ios、ohos等平台目录,再加上公共的lib、test、资源目录,文件数量轻松上千。这种多平台工程,一旦没有版本管理,最经典的场景就是:你今天改了一个平台配置,明天忘了;三天后想回退,发现回不去;想和同事实时同步,只能靠压缩包飞来飞去。

我个人的判断是:跨平台项目的“可追溯性”比原生项目更重要。因为多平台目录之间经常有隐式关联,比如公共依赖版本变了,某个平台目录没有同步更新,构建就会炸。如果你没有一份被所有人认可的仓库记录,出了问题你连“上次能跑是哪一次提交”都定位不到。

还有一个团队协作上的现实原因。我这次是个人在搞,但代码托管之后,后续拉一个协作者进来,大家各自用 IDE 打开同一个仓库,改完推分支、提合并请求,配合效率会完全不一样。就算你是单打独斗,把一个公开仓库挂出来,别人看到你的工程结构、提交历史,也能快速帮你定位问题。

1.2 选择代码托管服务的几个考量点

这次选的是一家国内公开代码托管平台(为了不把这篇记录写成软文,下文统一叫它“某托管平台”)。为什么没选其它家?我在实际使用中比较看重这几点:

一是访问速度。开源鸿蒙生态里经常要拉各种三方依赖和构建缓存,仓库本身如果再慢,体验会很糟糕。国内节点明显更稳。

二是免费私有仓库和协作者数量。我一开始用公开仓库,但后来发现某些工程配置里会偶发出现本机用户名、路径之类的信息,还是私有仓库更省心。某托管平台对个人用户免费私有仓库的限制比较宽松,小团队够用。

三是认证方式。它同时支持账号密码(实际推荐用访问令牌)、SSH 公钥,而且可以用令牌细粒度控制仓库权限。这个对我来说很关键,因为我不太想每台机器都放相同的 SSH 私钥,令牌可以单独失效,安全上更好管理。

四是附带基础设施。平台自带 WebIDE、代码扫描、CI 流水线能力,后面想跑自动构建验证,直接在仓库里配置就行,省得再搭一套。虽然我这次还没深入用,但至少短期不需要额外找工具。

1.3 这次要上传的工程长什么样

我先明确一下这次上传的工程背景。前两天搭好的项目是一个非常基础的 Flutter 跨平台 Demo,没有接复杂原生模块,只带了一个计数器页面和对应的单元测试。因为目标是验证“代码能推到仓库、别人拉下来也能跑”,所以工程越简单越容易排查问题。

工程核心目录结构大致是:

project_root/ ├── android/ # Android 平台工程 ├── ios/ # iOS 平台工程 ├── ohos/ # OpenHarmony 平台工程 ├── lib/ # Flutter 业务代码 ├── test/ # 单元测试 ├── pubspec.yaml # 依赖声明 ├── pubspec.lock # 依赖锁定文件 ├── .metadata # Flutter 工程元数据 └── README.md # 说明文档

这里最需要注意的是ohos目录,它是这套跨平台方案跑在 OpenHarmony 设备上的关键,属于平台源码,必须提交。而.dart_tool、build、oh_modules这类本地生成目录,则绝对不应该进仓库。

选择这样一个简单的工程做验证有个好处:真实可复现,踩坑时能快速判断是“工程配置问题”还是“代码本身问题”。如果你现在要上传的是一个复杂商用项目,也建议先拿精简 Demo 跑通整条流程,再逐步把代码搬进去。

2. 上传前最后一遍自查:扫掉“隐形雷”

很多人第一次 push 失败,并不是因为命令敲错,而是工程里带着一堆“隐形雷”。我把 push 之前最好自查一遍的几项列一下。

2.1 .gitignore 到底该忽略哪些东西

Flutter 工程用模板创建时一般会自带一份.gitignore,但那是给 Android/iOS 场景准备的,放到 OpenHarmony 跨平台工程里并不完整。我这次就吃过亏:模板默认文件漏掉了 OpenHarmony 构建产物目录,导致第一次准备提交时,git 状态里多出来几百个编译缓存文件。

针对开源鸿蒙 Flutter 工程,我的忽略模板如下:

# dart 工具缓存 .dart_tool/ # 构建产物 build/ ohos/.ohos/ ohos/oh_modules/ ohos/.hvigor/ # 第三方依赖缓存 node_modules/ # IDE 本地配置 .idea/ .iml .vscode/ *.log # 本地环境配置 .env

重点解释几个容易纠结的目录:

ohos/.ohos/是 OpenHarmony 平台侧的本地生成目录,里面都是构建中间产物,必须忽略。ohos/oh_modules/是三方依赖加载目录,类似 Android 的 Gradle 缓存,同样不该提交。但ohos/目录本身不能整个忽略,它的源码、配置文件、资源文件是要入库的,否则别人拉下来之后,OpenHarmony 平台工程就是空壳。

build/是整个 Flutter 工程的构建输出,每次都重新生成,无论如何都不该提交。

pubspec.lock应该提交,这一点我放到后面第 5 节详细说,这里先记住结论:锁文件不是垃圾,它是可复现构建的定海神针。

2.2 全局用户信息与仓库级覆盖

git 提交需要用户信息,如果本机从来没配置过,commit 时会报错或者生成一串不明所以的名字。我这次在干净环境克隆验证时,第一次提交就差点踩到“未配置 user.name”的报错。

配置方法很直接:

git config --global user.name "你的名字或代号" git config --global user.email "你的邮箱"

如果你同时对多个仓库有不同身份需求,可以在仓库目录下用不带--global的命令覆盖:

git config user.name "某个仓库专用身份" git config user.email "对应邮箱"

这里有一个习惯建议:提交信息最好能带上明确的意图,比如feat: 初始化开源鸿蒙跨平台工程、fix: 修复 OpenHarmony 构建参数错误。我试过一段时间随缘提交,几天之后看历史,完全想不起来当时的改动逻辑。带前缀和简述的提交信息,后面排查问题时效率会高很多。

2.3 换行符与文件权限:跨平台的两只“幽灵”

Windows 和 Linux/macOS 的换行符不一致,是跨平台项目最容易踩的坑。Windows 默认用 CRLF,Linux/macOS 用 LF。如果 git 没有统一规则,经常会出现“明明只改了一行,diff 里却显示整个文件都变了”的诡异现象。

我不建议把决定权完全交给 git 的自动转换。稳妥是先明确项目的换行符规则。我的做法是:在项目根目录放一份.gitattributes,把默认换行符固定成 LF,这样无论推之前用的是 Windows 还是 macOS,clone 到任何平台都能保持一致。

# 默认统一使用 LF * text=auto eol=lf # 二进制文件不做换行处理 *.png binary *.jpg binary *.ico binary

然后在本机设置里关闭自动转换:

git config --global core.autocrlf false

这样做的好处是避免 git 自作主张去改文本文件的换行符,让 diff 和协作更干净。坏处是你需要确保 IDE 保存文件时也默认使用 LF,否则会产生无意义的换行差异。VSCode 这类编辑器里设置一下即可,几乎零成本。

另外,文件权限方面,跨平台项目偶尔会遇到:在 Windows 上某个 shell 脚本没有可执行权限,推上去之后,在 Linux 机器上拉下来发现脚本不能直接执行。如果仓库里确实需要放脚本,建议在提交前设置好权限位,并在提交后用下面命令确认:

git ls-files -s

看到模式位是100755的就是有可执行权限,100644则没有。这里不是所有文件都需要执行权限,一般只针对.sh等脚本文件。

2.4 本地提交与分支命名

正式 push 之前,先在本地完成一次干净提交。我的习惯是:

git init git branch -M main git add . git status --short git commit -m "feat: 初始化开源鸿蒙跨平台工程"

这里提前执行git branch -M main是有原因的:现在新仓库默认分支基本都是main,如果你的本地分支还叫master,推到远程时大概率会被拒绝或者创建一个同名旧分支,后续每次命令都要带origin master,很别扭。干脆一开始就统一叫main。

git status --short一定要看,而且要逐行扫一遍。它能非常直观地告诉你哪些文件被跟踪、哪些文件被忽略了。如果你看到漏掉的文件(比如ohos目录里的关键配置没出现在列表里),说明.gitignore写过头了,赶紧回去改。

提交完成之后再检查一遍提交历史:

git log --oneline

看到一条干净的“初始化”提交,就可以进入下一步了。

3. 完整上传实操:从空仓库到首次 push

3.1 在托管平台创建空仓库(关键选项别选错)

在网页端创建仓库时,最关键的一点是:不要勾选自动生成 README、.gitignore、license 文件。

平台的设计是贴心的,它会在你创建仓库时询问是否要顺带生成这些文件,方便那些完全不想动手的用户。但这对我们这种“本地已经有完整工程”的情况反而是个坑。一旦远程仓库里有 README,本地仓库也有 README,两个仓库的历史互不相干,首次 push 时 git 会以“远程存在本地不存在的提交”为由拒绝推送,提示fetch first。虽然可以用 rebase 解决,但完全没有必要多这一步。

另外两点建议:仓库名用全小写,多个单词用短横线连接。这是我一直沿用的习惯,因为某些平台在 URL 路径上对大小写敏感,全小写能避免“克隆时明明看着一样,却 404”的诡异问题。可见性方面,如果你不确定工程里会不会残留敏感信息,先选私有仓库,后续确认没有泄露再切公开也不迟。

3.2 添加远程仓库地址(HTTP 与 SSH 两种姿势)

创建完空仓库后,平台会给你两个地址:HTTPS 地址和 SSH 地址。

HTTPS 地址格式类似:

https://某托管平台域名/你的用户名/工程名.git

SSH 地址格式类似:

git@某托管平台域名:你的用户名/工程名.git

如何选择?我个人推荐优先 SSH。HTTPS 虽然配置简单,但每次 push 要么反复输入账号密码,要么依赖凭据管理器缓存令牌,偶尔还会遇到凭证过期导致认证失败的问题。SSH 只要把公钥放进平台,之后就再也不用管认证了。

不过 SSH 需要提前生成密钥并添加公钥。生成命令:

ssh-keygen -t ed25519 -C "你的备注信息"

一路回车会生成默认位置的密钥对。然后把~/.ssh/id_ed25519.pub的内容复制到平台个人设置里的 SSH 公钥列表里即可。

添加远程仓库的命令:

git remote add origin 你选定的地址 git remote -v

git remote -v会显示当前远程地址,确认无误再继续。如果之后想换地址,用git remote set-url origin 新地址修改就行。

3.3 首次 push 的完整命令与输出

在完成本地提交、远程地址指向正确之后,首次 push 的命令是:

git push -u origin main

-u表示把本地main分支和远程main分支建立关联。之后在这个分支上再执行git push,git 就知道该推到哪个远程分支了。

我第一次 push 时,因为远程仓库是空的,过程还算顺利,命令执行后会有类似下面的输出:

枚举对象中: 352, 完成. 对象计数中: 100% (352/352), 完成. 使用 8 个线程进行压缩 压缩对象中: 100% (340/340), 完成. 写入对象中: 100% (352/352), 6.37 MiB | 0 bytes/s, 完成. 总共 352(差异 0),复用 352(差异 0),包复用 0 To 某托管平台域名:用户名/工程名.git * [new branch] main -> main 分支 'main' 设置为跟踪来自 'origin' 的远程分支 'main'。

看到* [new branch]和分支 'main' 设置为跟踪就说明首推成功了。如果输出里出现! [rejected]、Authentication failed、error: failed to push some refs,请直接跳到下一节,对应的坑我都有记录。

首推成功之后,再多做两个确认动作:

git remote -v git log --oneline --graph --all

前者确认远程地址正确,后者确认本地和远程的提交历史没有分叉。如果一切正常,工程就已经在仓库里安家了。

3.4 认证模式选择:账号密码 / 访问令牌 / SSH 公钥

很多人第一次在平台网页里设置认证时,会习惯性输入账号密码去 push,结果发现一推一个报错。这是我见过最高频的坑之一,原因得从平台的安全策略说起。

现在的托管平台普遍不再允许直接用账号密码走 git HTTP 协议,而是要求使用“访问令牌(Access Token)”。令牌本质就是一段可配置权限范围的字符串,在 git 提示输入密码时,把令牌粘贴进去即可。

创建令牌时,权限范围我通常只勾选repo(仓库读写)相关权限。如果只是个人使用,不需要把admin、delete这类高风险权限全开。令牌的优点是随时可以单独失效:某台机器泄露了,直接在平台撤销令牌,完全不影响账号密码。

SSH 公钥则适合长期稳定的开发机。公钥绑定的是机器,一旦某台电脑丢失,只要在平台删除对应公钥,那台电脑就再无访问权,同样不需要改密码。

我这次的实际策略是:主力开发机用 SSH,临时验证机用 HTTP + 一次性令牌。两套方式并行不冲突,也不会因为认证方式不同导致仓库状态不一致。

4. 踩坑实录:高发问题与排查思路

这一节是全文的重点。我按实际踩坑的高发顺序,把问题和完整的排查过程记录在这里。

4.1 坑一:远程仓库自带的 README 挡了首推

现象是 push 时报错,提示! [rejected] main -> main (fetch first),然后是一句failed to push some refs。

我当时愣了一下,明明本地代码没问题,为什么不让推?用git pull --rebase origin main拉下来一看,远程有个 README.md 文件,而且整个远程历史里只有那一次“Initial commit”。

原因其实很简单:创建仓库时,平台默认勾选了“初始化仓库时自动生成 README 文件”。本地历史从零开始,远程历史也从零开始,但两边各自有一个“根提交”,git 没办法直接合并两个没有共同祖先的历史。

解决办法有两种:

一是创建仓库时完全不勾选自动生成文件,这是治本方法。二是已经生成时,在本地做一次 rebase 强行缝合:

git pull --rebase origin main git push -u origin main

--rebase会把本地提交“叠加”到远程提交之上,形成一个线性历史。注意如果本地已经做了很多提交,rebase 过程中遇到冲突会比较痛苦,所以最好的策略还是第一条:从源头避免。

4.2 坑二:认证失败与令牌权限不足

第二次遇到的坑是在干净验证机上(临时用 HTTP 方式拉取仓库)认证失败。执行 push 时提示:

remote: HTTP Basic: Access denied Authentication failed

第一反应是密码输错了,检查环境变量里也没有代理干扰,后来冷静下来想了下:这个提示几乎可以确定是认证方式问题,不是网络问题。

排查思路是这样:如果是 SSH 方式,认证主要依赖密钥文件和平台公钥的匹配,报错通常是Permission denied (publickey);如果是 HTTP 方式,认证依赖“账号 + 令牌”或者“令牌作为密码”。我这次在干净机器上用的 HTTP 方式,输入账号密码后提示 Access denied,原因就是平台禁止密码直接作为 git 密码使用。

解决步骤:

  1. 打开平台个人设置,找到“访问令牌”页面。
  2. 点击生成令牌,勾选repo范围。
  3. 复制令牌字符串。
  4. 在 git 提示输入密码时,粘贴令牌而不是账号密码。

另外常见的情况是令牌生成时只勾了只读权限,push 时同样会被拒绝。所以检查令牌权限时一定要确认包含写权限。为了减少这类问题,我把常用的开发机和临时验证机都慢慢切换到了 SSH 公钥方式,长期稳定,心理负担小很多。

4.3 坑三:master 与 main 分支不一致

在本地已经养成git init后直接提交习惯的人,很容易遇到分支名不一致。

我这次在另一台机器上验证时,本地分支默认成了master,而远程仓库默认是main。push 时 git 提示分支被拒绝,因为远程不存在同名分支。如果强行用git push origin master,会看到远程多出一个master分支,自己想要的 main 分支却没有同步,后续操作还要区分名字,非常不习惯。

最干脆的做法:

git branch -M main git push -u origin main

branch -M是强制重命名当前分支,即使分支已经叫master也会直接改成main,不存在误操作提示。建议所有新项目在git init后立刻加这条命令,形成肌肉记忆。

4.4 坑四:构建产物被塞进仓库后 push 巨慢

这是最让人焦虑的一个坑。第一次 push 的时候,我图省事直接git add .,结果 git status 里出现了一千多个文件,其中大半是构建缓存。push 阶段能看到进度条卡在某个百分比半天不动,明显不对劲。

当时先中断了 push,然后执行:

git rm -r --cached ohos/oh_modules git rm -r --cached ohos/.ohos git rm -r --cached build git rm -r --cached .dart_tool

--cached参数表示从 git 索引中移除,但不会删除本地文件。这是处理已经误提交文件的标准方式:保留本地内容,只让 git 不再跟踪。

随后补上第 2 节说的.gitignore规则,再重新提交:

git add . git commit -m "chore: 移除构建产物并完善 gitignore" git push

如果你已经在多次提交里都包含了大量构建产物,仓库体积已经膨胀到几十 MB 甚至更多,还想要彻底清理历史,那就得用历史重写工具。个人项目里,如果这个仓库还没有别人在用,可以使用git filter-repo这类工具,把历史中所有指向构建目录的提交都过滤掉,然后再强制推送到远程。

但要注意,历史重写会改变所有提交的哈希值。如果仓库里已经有协作者分支,重写历史之后所有人的本地分支都会失效,协调成本极高。正好借这个教训说一句:.gitignore建仓第一天就要配好,不要在 push 时才想着补。

4.5 坑五:clone 后构建失败(锁文件、SDK 路径和大小写)

前四个坑都出现在推送阶段,第五个坑是推送成功之后、在干净环境验证时冒出来的。

clone 下来之后,我运行依赖安装命令,结果发现本地短暂生成了一个新的pubspec.lock文件,而且 diff 巨大。翻看提交历史,发现仓库里根本没有把锁文件提交上去。这意味着别人 clone 后,依赖解析会基于“当前最新版本区间”重新拉取,极容易出现“我本地能跑、你本地不能跑”的版本漂移问题。

解决办法:把锁文件纳入版本管理。这是 Flutter/Dart 项目的标准习惯。pubspec.lock记录了所有传递依赖的精确版本号,提交它之后,别人 clone 下来执行依赖安装时,只要环境一致,就能得到完全相同的依赖树。开源鸿蒙跨平台工程里还有oh-package.json5这类 OpenHarmony 侧依赖声明,同样遵循这个原则:声明文件要提交,锁文件如果可以也应该提交,目的是锁版本。

第二个构建失败原因是 SDK 路径问题。Flutter 工程里会有一些本地配置存放 SDK 路径,这类文件不应该提交,因为每台机器的路径不同。但你要是把整个配置文件都放进.gitignore,别人 clone 下来又不知道去哪找配置模板。

正确处理是:提交一份示例配置文件(比如local.properties.example),真正的本地文件(local.properties)留在.gitignore里。别人 clone 后参考示例文件复制一份本地配置即可。我在 README 里专门写了一段“如何配置本地 SDK 路径”的说明,这样可复现验证流程才算闭环。

第三个构建失败原因是文件名大小写。Windows 文件系统默认大小写不敏感,但 Linux/macOS 敏感。某个资源文件的真实命名是BlueToothService.kt,代码里引用的是bluetoothservice.kt,Windows 下能顺利编译,clone 到 Linux 构建机上就报“找不到文件”。查了半天才意识到是大小写问题。git 本身对大小写跟踪也不敏感,需要用git mv把文件改名成正确大小写,或者在仓库里刻意保持所有文件路径完全一致的小写规范。对跨平台工程来说,我建议从第一天就统一文件命名规则,避免埋下这类隐患。

5. 可复现验证全记录:换一台机器也能构建

push 成功只是第一步,真正的目标是让别人(或者明天的你)在一个全新环境里,把仓库 clone 下来之后能一键跑起来。这一节就是我这次做的可复现验证完整过程。

5.1 模拟干净环境:浅克隆与完整克隆

我在另一台机器上(或者说,在当前机器的另一个独立目录里)模拟了一次“新电脑”的操作。为什么不直接在原有工程目录里验证?因为原目录下还有本地生成的各种缓存,它们会掩盖问题,让“clone 之后能不能构建”这件事失真。干净目录才是严格验证。

验证命令:

mkdir -p ~/verify_day2 cd ~/verify_day2 git clone <远程仓库地址> crossday2 cd crossday2

第一次做验证时,我会用--depth 1浅克隆,只拉最新提交。浅克隆速度快,适合快速确认核心代码是否完整。确认没问题之后,再删掉目录做一次完整克隆,检查提交历史是否完整。

git clone <远程仓库地址> crossday2_full cd crossday2_full git log --oneline | head -5

git log能看到几条最近的提交记录,说明历史正常同步。这里其实不用把提交历史完整核对一遍,只要最新提交哈希与推送时一致即可。

5.2 验证清单:依赖拉取、构建、测试一气呵成

进入克隆目录之后,按顺序执行下面几步。

第一步,检查依赖状态:

flutter pub get

这步会自动读取pubspec.yaml和pubspec.lock。如果锁文件已提交,命令执行后不会对锁文件做任何变动,只输出Because 项目名 depends on ...之类的解析信息。如果控制台提示锁文件被修改,说明仓库内的锁文件缺失或与当前环境不一致,立刻回到第 4.5 节检查。

第二步,静态分析:

flutter analyze

这个命令会扫描代码中的语法、类型问题。输出如果没有异常警示,才算走了个及格线。

第三步,跑测试:

flutter test

我这次工程里带了最基本的 widget 测试,验证时能看到类似All tests passed!的输出。这一步能提前发现“代码在本地构建正常但 clone 后因路径、依赖差异导致行为不一致”的问题。

第四步,构建目标产物。开源鸿蒙场景下,我会调用对应工具链构建 OpenHarmony 应用包,命令大致是:

flutter build hap --debug

如果构建命令在你的环境下不是这个名字,就换成实际使用的构建命令。重点不是命令本身,而是确认从零开始的构建能成功产出包文件。

5.3 用脚本固化验证流程

上面四步手动执行几次没问题之后,我建议把它固化成一个脚本,放在仓库里。这样任何协作者 clone 下来之后,先跑一个命令就能完成验证,省得每次口头沟通“你得先做A再做B再做C”。

Linux/macOS 下的脚本示例:

#!/usr/bin/env bash set -euo pipefail echo "==> 拉取依赖" flutter pub get echo "==> 静态分析" flutter analyze echo "==> 跑测试" flutter test echo "==> 构建产物" flutter build hap --debug echo "==> 验证通过"

在 Windows 环境,可以用 PowerShell 写等价版本,逻辑不变。注意脚本本身要放在仓库里,并确保有可执行权限(参考第 2.3 节的文件权限)。

脚本会让“可复现验证”变成一个有执行标准的过程,而不是依赖某个人记得全部步骤。我在 README 里也写了一句:“完整验证请执行./verify.sh”,把入口固定下来。

5.4 验证结果记录与结论

验证完成后,除了能构建出包,我还会做两件事来确认“上传 + 复现”这件事真正闭环。

第一,检查工作区是否干净:

git status --short

如果执行完标准流程后,工作区出现多余文件(比如 IDE 配置文件、本地缓存),说明.gitignore还有漏洞。理想情况是输入为空,即没有任何多余变更。

第二,在仓库里更新 README 的验证记录。我会简单记下验证日期、验证方式(完整克隆/浅克隆)、依赖版本、构建产物路径。这样一周之后回看,能很清楚地知道“哪次提交、什么环境下验证通过”。

实际验证过程中,我经历了 4.5 节提到的锁文件缺失、SDK 路径缺失和大小写问题。修完这些问题后再跑验证脚本,就能从空目录一路顺利产出构建包。这时候才能说:这个仓库是真的“能复现”,不是碰运气。

6. 常见问题速查表与日常避坑习惯

踩坑踩多了,自然就会想整理一份速查表,方便以后对照。下面这张表是我这次上传过程中遇到的问题浓缩,你可以直接保存下来当“急救手册”。

现象可能原因解决办法优先级
push 提示fetch first远程仓库非空,本地历史无共同祖先创建空仓库;必要时git pull --rebase origin main高
提示Authentication failed用了账号密码而非访问令牌生成令牌,在 git 提示密码时粘贴令牌高
提示Permission denied (publickey)SSH 公钥未添加或不匹配生成密钥对并添加公钥到平台高
push 后远程分支是master或main混乱本地分支名与远程默认分支不一致git branch -M main后重新 push中
clone 后依赖安装报错或锁文件变更pubspec.lock未提交提交锁文件并推送到远程高
clone 后报找不到某个文件文件名大小写不一致统一命名规范,必要时git mv修正中
换行符导致整个文件 diffWindows CRLF 与 Linux LF 混用添加.gitattributes,关闭 autocrlf中
push 速度慢且文件数量异常多构建产物被误提交清理缓存,完善.gitignore高
clone 后本地配置文件缺失SDK 路径等本地配置未提交模板提交示例配置,忽略真实本地配置中
push 被拒绝没有明确原因远程仓库已有保护分支规则检查平台分支保护设置或提合并请求低

最后再补充几条日常习惯,都是这次实践之后我给自己定的规矩:

第一,git status --short是提交前必看的,任何莫名其妙的文件出现在列表里,先搞清楚来源再往仓库里放。第二,提交信息写成“类型: 简述”的格式,让历史变成可搜索的日志。第三,构建产物和本地缓存从建仓第一天就全部 ignore 掉,绝不让它们进入依赖流程。第四,每周至少做一次干净环境克隆验证,把这个成本压缩到最低,避免“能跑”变成幸存者偏差。

我个人在折腾完这一天之后,最大的体会是:版本管理本身不难,难的是把跨平台工程里那些依赖锁定、换行符、大小写、SDK 路径这些细节全部管住。开源鸿蒙跨平台开发的多工具链场景里,代码仓库是整个协作流程的锚点,它不只是一个存代码的地方,更是让“从零可复现”成为可能的基础设施。如果你也刚起步,我强烈建议不要等工程写了很多再回头做版本管理,从第一天就开始推送、标记、验证,后面会省掉大量返工时间。

下一步我准备在这个仓库基础上做更贴近真实项目的验证,把真机构建和目标设备部署跑通,之后再回来更新这个系列。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询