最近好几个朋友都在问我同一件事:Windows 下还在用 Android Studio 4.0.0 的老项目,怎么用 GitHub 管理版本,费了半天劲推到一半,又说想换成国内的码云 Gitee。这问题问得挺实在,因为不少老项目的 Gradle 插件、SDK 版本都卡在 4.0.0 这一代,升级新版本的成本太高,不如直接把手头的版本管理链路理清楚。
这篇文章我就把这套流程完整走一遍,从 Git 环境准备、SSH 密钥配置,到 Android Studio 4.0.0 里初始化仓库、推到 GitHub,再给出切换到 Gitee 的几种可行方案。每条命令、每个界面入口我都会写清楚,顺手把 Windows 下常见的中文乱码、推送失败、“git did not exit cleanly”这种报错也一并解决掉。适合刚开始接触版本管理的 Android 开发者,也适合那些早就开始用 Git 但遇到平台切换问题的老手查漏补缺。
1. 项目背景与版本管理思路
1.1 为什么 Android 项目必须引入版本管理
我见过太多没做版本管理的项目,本地文件夹里躺着“项目_final_v2.zip”“项目最终版_改完再也不能动.zip”这种灾难现场。代码出了问题想回退,只能靠记忆手工改;多人协作时更是互相覆盖,谁改了什么完全靠吼。这类项目一旦跑起来,三五个版本之后就彻底失控了。
Git 解决的就是这几件事:每次提交都有历史记录,随时可以回滚到任意节点;分支机制让你可以放心开新功能,实验失败也不影响主分支;多人协作时每个改动都有作者和提交信息,谁动了哪一行一目了然。Android Studio 从很早的版本开始就内置了 Git 插件支持,4.0.0 这个版本哪怕界面和老代码比较旧,也不影响 Git 功能的正常使用,无非是入口叫 VCS(Version Control System),新版本里统一叫 Git。
而且对 Android 项目来说,版本管理的价值不只是代码本身。Gradle 配置、资源文件、版本号管理、release 分支的 tag 标记,全部都可以纳入 Git 的管控范围。比如你发布了 1.0.0,打一个 tag,下次出问题直接切到 tag 上排查,比翻聊天记录找历史包靠谱一百倍。
1.2 GitHub 与 Gitee 怎么选
GitHub 是全球最大的代码托管平台,开源生态、社区讨论、第三方集成都是最全的,很多优秀的 Android 开源库都在上面。但国内网络环境下,GitHub 的访问确实存在不稳定的时候,特别是 clone 和 push 大仓库时,偶尔会卡很久甚至直接失败,这个相信大家都有体会。
Gitee(码云)是国内团队做的托管平台,最大的优势是访问速度快、中文界面、操作习惯更贴近国内开发者,而且私有仓库免费,对个人项目和中小团队非常友好。它的一键导入功能可以直接把 GitHub 仓库拉过来,省去很多手工迁移的步骤。所以现在的常见做法是:开源项目放 GitHub 做展示,同时在 Gitee 放一份镜像方便国内下载;内部项目、公司项目则直接落在 Gitee 上,省心省力。
两套平台的 Git 命令几乎通用,差异只在于仓库地址和认证方式。这意味着你完全可以在两个平台之间来回切换,不需要重新学习工具链。下面我会从零开始把整个链路走一遍,先讲 GitHub,再切到 Gitee。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Windows 环境准备:把 Git 这条路铺平
2.1 安装 Git for Windows 与全局配置
Android Studio 4.0.0 内置的是 Git 插件,但真正执行 Git 操作需要系统里有一个 Git 运行时。很多新手在 Android Studio 里设置 Git 路径时发现选不到,就是因为没装 Git for Windows。安装方法很简单:去 Git 官网下载 Windows 版安装包,一路 Next 就行。
有几个安装界面选项值得注意。第二屏 “Select Components” 里,建议把 “Git from the command line and also from 3rd-party software” 选上,这样不仅命令行能用 Git,Android Studio 这类第三方软件也能找到 git.exe。其他选项保持默认即可,不需要用那些花里胡哨的组件。
装完以后打开 CMD 或者 PowerShell,运行:
bash复制git --version
能看到类似 git version 2.30.1.windows.1 的输出,就说明安装成功。然后设置用户信息,这一步必须做,否则 commit 的时候会报错:
bash复制git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
这两条全局配置会写进当前 Windows 用户下的 .gitconfig 文件,之后所有仓库都默认使用这个身份。如果你在不同平台用不同身份,也可以在单个仓库里用 git config --no-global 临时覆盖。
2.2 SSH 密钥生成:一套密钥打通两个平台
Git 连接远程仓库有两种方式:HTTPS 和 SSH。HTTPS 每次 push 都要输账号密码(或者 Token),SSH 则是一套密钥免密认证,配好之后长期有效。我强烈建议直接用 SSH,省事且安全。
打开 PowerShell 或者 Git Bash,执行:
bash复制ssh-keygen -t ed25519 -C "你的邮箱"
中间会让你选择保存路径和输入 passphrase,直接回车表示使用默认路径(C:\Users\你的用户名\.ssh\id_ed25519),passphrase 留空即可。ed25519 是比 RSA 更短的现代密钥,性能更好,GitHub 和 Gitee 都支持。
生成完成后,把公钥内容复制下来。Windows 下可以用:
bash复制type $env:USERPROFILE\.ssh\id_ed25519.pub
然后分别去两个平台添加公钥:
- GitHub:点击头像 -> Settings -> SSH and GPG keys -> New SSH key,粘贴保存。
- Gitee:点击头像 -> 设置 -> 安全设置 -> SSH 公钥,粘贴保存。
添加完成后测试连接:
bash复制ssh -T git@github.com
ssh -T git@gitee.com
第一次连接会提示确认指纹 Are you sure you want to continue connecting,输入 yes 回车。看到 “Hi xxx! You've successfully authenticated” 类似信息就代表 SSH 通了。这一步直接把后面所有免密问题都解决了。
2.3 Android Studio 4.0.0 里的 Git 设置
打开 Android Studio,进入 File -> Settings -> Version Control -> Git,在 Path to Git executable 里填入 C:\Program Files\Git\bin\git.exe,点 Test 按钮,能弹出版本号就说明 Android Studio 已经能调用 Git 了。
很多人反映 Android Studio 4.0.0 里打开 Settings 特别慢,大部分时候是因为系统在扫描 VCS 映射和插件仓库。可以在 File -> Settings -> Plugins 里把用不到的版本控制相关插件关掉,比如 Mercurial、Perforce。实在不行就等它转完,第一次扫描索引确实比较痛苦,但也算老版本 Android Studio 的常态了。
设置好 Git 之后,Version Control 面板里就能看到当前项目的仓库状态了。如果你的项目还没有任何版本控制,下一步就是初始化本地仓库。
3. 在 Android Studio 4.0.0 中把项目推到 GitHub
3.1 初始化本地仓库与 .gitignore
打开 Android 项目,点击菜单栏 VCS -> Enable Version Control Integration,选择 Git,点 OK。Android Studio 会在项目根目录执行 git init,之后整个项目进入版本控制状态。界面上文件会变成红色或者绿色,红色代表未跟踪,绿色代表新添加。
这里最容易被忽略的文件是 .gitignore。Android Studio 新建项目时一般会自带一份模板,里面应该包含 .gradle/、build/、local.properties、.idea/、*.iml 这些目录和文件。如果没有,自己手动建一个:
code复制*.iml
.gradle/
local.properties
.idea/
.DS_Store
build/
/captures
.externalNativeBuild
.cxx
.gitignore 的作用是告诉 Git 哪些文件不参与版本管理。local.properties 里保存了本地 SDK 路径,不同机器路径不一样,绝不能提交;build 目录是编译产物,提交纯属浪费仓库空间;.idea 目录是 IDE 个人配置,同样不需要进仓库。很多新手不管三七二十一全提交上去,结果同事拉下来一堆冲突,就是这个环节没做好。
3.2 在 GitHub 创建远程仓库
打开 GitHub 官网,登录后点右上角 “+” -> “New repository”。仓库名建议和项目名一致,比如 MyApp。可见性可以选 Private 或者 Public,个人练习选 Private 更稳妥。这里有个关键点:不要勾选 “Add a README file”,也不要在初始化时添加 .gitignore 或者 license,因为本地已经有代码了,远程仓库多了初始提交会导致本地和远程历史不相关,后面 push 容易冲突。
创建完成后页面上会显示仓库地址,包括 HTTPS 和 SSH 两种。我们优先用 SSH 地址,格式类似 git@github.com:你的用户名/MyApp.git。先把这个地址复制下来,下一步要用。
如果你更喜欢用 HTTPS,那后续建议用 Personal Access Token 代替密码。生成路径是 GitHub 头像 -> Settings -> Developer settings -> Personal access tokens -> Tokens (classic) -> Generate new token,勾选 repo 相关权限,生成后复制保存。因为 GitHub 现在已经不支持直接用账号密码进行 Git push 了。
3.3 首次提交和推送:从空仓库到 GitHub
初始化好版本控制以后,回到 Android Studio 菜单栏,VCS -> Commit。在提交界面的左下角会列出所有未提交文件,输入提交信息,比如 init project,然后点击 Commit。
如果是第一次提交,Android Studio 可能会弹窗提示没有 Git 用户信息,它会让你在 Settings 里配置,就是我们在 2.1 里已经配置过的全局信息。如果提示 Empty commit,说明你没勾选任何文件,记得在文件列表里把需要提交的文件打上勾。
提交完成后,接下来把本地仓库和远程 GitHub 仓库关联起来。我推荐在 Android Studio 里操作,也可以命令行,效果一样:
bash复制git remote add origin git@github.com:你的用户名/MyApp.git
然后在菜单栏执行 VCS -> Git -> Push。第一次 push 时,Android Studio 会提示设置远程分支追踪关系。如果你在命令行里操作,用:
bash复制git push -u origin master
-u 参数的意思是设置上游分支,把本地 master 和远程 origin/master 关联起来,后续直接敲 git push 就行。如果是 Git 默认分支名 main,把 master 换成 main 即可。
推到 GitHub 之后,在网页上就能看到你的项目代码了。到这里,GitHub 版本管理链路已经通了。接下来是重头戏:怎么切到 Gitee。
4. 从 GitHub 切到 Gitee:三种方案任选
4.1 为什么要切换到 Gitee
如果你已经顺利推到 GitHub,为什么还要切到 Gitee?最现实的原因有两个:一是国内网络访问 GitHub 不稳定,尤其是 push 大文件或拉取依赖时,偶尔会长时间没响应;二是团队协作时,同事如果访问不了 GitHub,整个发布流程就会卡住。Gitee 在国内的访问速度和稳定性明显好一个档次,私有仓库还免费,基本属于“用了就回不去”的状态。
当然,也不是说必须二选一。很多人把 GitHub 当主仓库,Gitee 当镜像备份,双平台同步,这种方式我也很推荐。下面三个方法按需选择,前两个适合快速切换,第三个适合长期双平台维护。
4.2 方法一:直接改 remote 地址,推送到 Gitee
这是最简单的切换方式。先在 Gitee 上新建一个仓库,进入 Gitee 官网,点右上角 “+” -> “新建仓库”。仓库名建议和本地项目一致,选择私有或公开。这地方有一个热词相关的坑:开源许可证选什么?如果你不确定项目协议,建议先选“MIT”或者“Apache-2.0”,这是最宽松也最常用的两种;如果完全不想开源,直接建私有仓库,许可证就不用管了。
建好 Gitee 仓库后,本地只需要修改一个东西:origin 远程地址。在项目根目录执行:
bash复制git remote set-url origin git@gitee.com:你的用户名/MyApp.git
这条命令的原理是,origin 本身只是本地 Git 配置里一个别名,存储了一个远程地址。set-url 就是换掉这个地址,不删除远程分支,也不影响本地提交历史。执行完后可以用:
bash复制git remote -v
检查当前 origin 指向哪里。确认是 Gitee 地址后,推送:
bash复制git push -u origin master
SSH 密钥如果已经按 2.2 配置好,这里就不需要输任何密码。等 push 完成,Gitee 仓库页面应该能看到和 GitHub 上一模一样的代码和历史记录。这个方案适合那些确定以后只以 Gitee 为主的同学,一份代码,一个远程,简单直接。
4.3 方法二:用 Gitee 的“从 GitHub 导入仓库”
如果你本地项目已经推到 GitHub,但不想在本地折腾 remote 命令,Gitee 提供了一个更省事的入口。新建仓库时,在选择 “导入已有仓库” 的选项卡,填入 GitHub 仓库的 HTTPS 地址,点击创建,Gitee 会自动把 GitHub 上的代码、分支、提交记录全部同步过来。
这个方法最大的优点是快,不用本地操作,几秒钟就能把仓库搬过去。但需要注意两点:一是导入完成后,本地的 origin 还是指向 GitHub 的地址,你需要执行一次 git remote set-url origin git@gitee.com:你的用户名/项目名.git 才能真正切到 Gitee;二是这个导入只是“一次性导入”,不是持续同步。GitHub 上后续的新提交不会自动出现在 Gitee 上,除非你配置 WebHook 或者手动重新导入。
所以这个方案更适合一次性迁移,不适合长期双平台同步。做完导入之后,别忘了把本地 remote 也改了,否则后续 push 还是会走到 GitHub 那边。
4.4 方法三:本地仓库多 remote 双推
有些场景下,你想 GitHub 和 Gitee 都保留,两边同时更新。这时候不用把 origin 改来改去,而是添加一个额外的远程别名。比如 origin 保留 GitHub 地址,再添加一个叫 gitee 的远程:
bash复制git remote add gitee git@gitee.com:你的用户名/MyApp.git
推送时分别推到两个仓库:
bash复制git push origin master
git push gitee master
如果你比较懒,可以写一个简单的批处理脚本 push.bat:
bash复制git push origin master && git push gitee master
这种方法的好处是 GitHub 作为主仓库面向开源社区,Gitee 作为国内镜像方便加速访问,两边互不干扰。坏处是每次要推两次,偶尔会忘记推其中一边,导致两边代码不一致。对我来说,写个脚本放项目根目录,每次提交完顺手执行一下,配合 Gitee 的网页端刷新,体验还算顺畅。
另外补充一点,如果你不想维护两个 remote,也可以在一行 remote 里配置多个 pushurl:
bash复制git remote set-url --add --push origin git@gitee.com:你的用户名/MyApp.git
git remote set-url --add --push origin git@github.com:你的用户名/MyApp.git
这样以后执行 git push origin master 时,Git 会同时往两个地址推送,省掉脚本的麻烦。不过这招对新手来说容易混乱,我还是建议老老实实用两个别名,看得清楚也好排查问题。
4.5 Gitee 免密推送和私有仓库配置
前面已经用 SSH 打通了免密通道,如果你实在想用 HTTPS,Gitee 也支持。但使用 HTTPS 推送时,密码框里输入的不是 Gitee 登录密码,而是私人令牌。路径是 Gitee 设置 -> 安全设置 -> 私人令牌,生成后复制,push 时用于认证。
如果不想每次输令牌,可以配置 Git 的凭据存储:
bash复制git config --global credential.helper store
下次 push 输入一次账号密码后,凭据会以明文形式保存在 Windows 用户目录下的 .git-credentials 里,之后就不会再问密码了。这个功能方便,但要注意自己电脑的安全,公用的机器不建议开。
关于私有仓库,Gitee 的私人仓库对个人免费,适合存放公司内部代码、未开源项目以及各种不愿意公开的实验代码。而公开仓库再配合 Gitee Pages 还能做静态网站托管,展示产品文档、个人主页都很方便。仓库建好之后,这些设置都可以在项目页面里改,不需要推到一半再重建仓库。
5. 实操中高频问题与排查技巧
5.1 “git did not exit cleanly”到底在提示什么
这个报错是 Android Studio 里的常见面孔,尤其在使用 GitHub 或者从 Gitee clone 项目的时候。它本身并不是一个具体的错误,而是 Android Studio 调用 Git 命令后,Git 返回了非零退出码,于是弹窗提示 “git did not exit cleanly(exit code 1)”。
要排查,建议暂时绕过 Android Studio,直接在项目目录打开命令行执行同样的操作,这样能看到真正的底层错误。常见原因有这么几类:
- Git 可执行文件路径没配置对,或者在
C:\Program Files\Git\bin\git.exe这个位置找不到安装文件。重新设置路径即可。 - SSH 密钥没有添加,或者公钥没有配置到 GitHub/Gitee 后台。执行
ssh -T git@github.com测试,不通就去检查公钥。 - 远程仓库地址写错了,多打了一个字母或者少了
.git后缀。用git remote -v看一下。 - 仓库是空的。首次 push 时远程分支不存在,Git 会提示
src refspec master does not match any,说明本地这个分支其实没有任何提交,先 commit 一次再 push。 - 分支名不一致。比如本地是 master,远程默认分支是 main,Git 找不到对应关系也会报错。
把这几个点逐个排除,问题基本都能定位。最怕的是在 Android Studio 的弹窗里来回点,看不到真实日志。记住一条原则:凡是 Android Studio 里的 Git 报错,都去命令行重新执行一遍,错误信息会清楚得多。
5.2 push 报错 401/403 或连接超时
push 到 GitHub 或者 Gitee 时,如果看到类似 remote: Permission denied、fatal: Authentication failed,基本都是认证问题。
GitHub 场景:如果用的是 HTTPS,账号密码已经无效,必须用 Personal Access Token。Token 生成后,在 push 时弹出的认证框里,用户名填你的 GitHub 用户名,密码框粘贴 Token。如果之前输错过,Windows 凭据管理器会记住旧的错误凭据,清理路径是:控制面板 -> 凭据管理器 -> Windows 凭据 -> 找到 github.com 那条,删除后重新 push。
Gitee 场景:HTTPS push 同样要求用户名和密码,密码框填 Gitee 的私人令牌,不是登录密码。如果你配了 SSH,建议直接用 SSH 地址,从根本上绕开认证问题。
至于连接超时,尤其是 push 到 GitHub 时偶尔出现的 Failed to connect to github.com port 443: Timed out,这和你本地代码没有关系,纯粹是网络链路问题。这时候如果公司或团队要求必须用 GitHub,可以等网络好再试,或者干脆把仓库迁到 Gitee——这本来就是我们今天介绍切换方案的原因之一。
5.3 Windows 下中文乱码问题
Windows 下 Git 的中文乱码主要集中在两个地方:一是 git log 里的提交信息显示乱码,二是文件名乱码,比如中文文件名变成一串转义字符。
提交信息乱码的解决办法是告诉 Git 用 UTF-8 编码:
bash复制git config --global i18n.commitencoding utf-8
git config --global i18n.logoutputencoding utf-8
文件名乱码(明明中文名,git status 却显示 \345\274\200\345\217\221 或 "")是因为 Git 默认把非 ASCII 字符转义了。关闭这个转义:
bash复制git config --global core.quotepath false
如果你在 Android Studio 编辑器里看到中文乱码,打开 File -> Settings -> Editor -> File Encodings,把所有文件编码都设成 UTF-8。Windows 自带终端 CMD 对 UTF-8 的支持不太好,建议直接用 Git Bash 或者 JetBrains 自带的终端,乱码概率会低很多。
5.4 分支名不一致导致推送失败
Git 默认初始分支名,早期版本是 master,2020 年后的版本开始默认用 main。GitHub 新建仓库默认分支是 main,Gitee 默认是 master。这就导致一个很尴尬的局面:本地分支可能是 master,远程期待的是 main,push 时会提示找不到对应分支,或者直接把你推到另一个分支上。
解决方式很简单,显式指定分支:
bash复制git branch -M main
git push -u origin main
-M 会把当前分支重命名为 main,然后推送并设置追踪关系。如果你团队规定用 master,那就反过来:
bash复制git branch -M master
git push -u origin master
核心就一句话:本地分支名和远程分支名要匹配,不匹配就重命名,别硬推。
5.5 Pull 时冲突与日常合并小技巧
多人协作时,最常见的报错是:
code复制error: Your local changes to the following files would be overwritten by merge
意思是你本地有未提交的改动,直接 pull 会冲突。新手最容易犯的错误是盲目执行 git pull,然后面对一堆冲突不知所措。
我的建议是养成 pull 前先看一眼状态的习惯:
bash复制git status
如果本地有改动,先 commit 或者 stash(暂存),再 pull。如果经常遇到小冲突,可以改用 rebase 方式拉取:
bash复制git pull --rebase
rebase 会把本地提交挪到远程提交后面,让提交历史线更干净,不像 merge 那样出现多余的 “Merge branch” 节点。当然,rebase 会改写提交历史,适合个人分支或还没推送的分支,已经共享给别人的分支不要轻易 rebase。
如果冲突真的发生了,Android Studio 会在编辑器中用三栏方式展示冲突内容:左侧本地、右侧远程、中间合并结果。手动调整后,右键选择 Mark as resolved,然后 commit 即可。这类操作做一次就熟了,不用怕。
6. 日常工作流的几个建议
每次提交信息写清楚,是成本最低的团队纪律。不要写 fix bug 这种废话,要写类似 修复登录页在低分辨率下按钮溢出、升级Gradle插件到4.1.0并修改对应API调用。这样一个月后回看历史,你依然能明白当时改了什么东西、为什么改。
Android Studio 的图形界面和命令行各有用处。日常 commit、push 用界面操作足够直观,查看日志、改分支、处理冲突时,建议多用命令行配合。遇到搞不清楚的报错时,打开项目目录下的 Terminal 标签页跑一遍 git status 和 git log --oneline --graph --all,通常一眼就能看出问题在哪。
我个人平时喜欢半小时左右提交一次,粒度小、回滚方便,提交信息也不会写完就忘。托管平台我最终选择了 GitHub 和 Gitee 双远程,GitHub 面向更广的社区,Gitee 保证国内团队和访问速度。这套工作流跑顺之后,后面不管是接 CI/CD 自动构建,还是用 Git Flow 管理发布分支,都是顺理成章的事。
