先说说我为什么会对这个场景特别有感触。前阵子在家用台式机改了一个项目的小功能,改完已经凌晨,顺手commit完就睡了。第二天到公司打开笔记本准备继续,一摸口袋——U盘没带,想想网盘上传慢、微信传压缩包又容易解压出一堆乱码,整个人直接愣在工位上。后来我在公司电脑上敲了两条命令,代码就整整齐齐地出现在眼前。那一刻我才真正意识到,Git不仅是团队协作的工具,它本身就是一台电脑到另一台电脑之间最优雅的代码"传送带"。
这篇文章就是围绕"git使用场景->在两台不同的电脑进行代码互传"这个具体的应用场景展开的。不管你是刚接触Git的小白,还是用过一段时间但从来没在两台设备之间同步过代码,这篇文章都能给你一套可以直接照做的方案:从环境准备、SSH免密配置,到第一次推送、拉取、分支合并,再到我踩过的那些坑,一次性讲透。
1. 为什么我最终选择了"Git中转"而不是U盘和网盘
在两台电脑之间挪代码,大部分人第一反应是U盘、网盘或者聊天工具传文件。这几个方案看起来都行,但真用到项目开发上,各有各的难受。
1.1 拷贝式方案的三个痛点
先说U盘。表面上是"拷过去就行",实际上你很快会发现:项目文件夹里混着编译产物、缓存、第三方依赖库,拷过去动辄几个G;更麻烦的是版本冲突——你在一台电脑上改了某个文件,另一台电脑上的还是旧版本,等你想合并两边的改动时,连谁新谁旧都说不清。"最终版"、"最终版2"、"真最终版"这种文件名,我相信大家都见过。
再说网盘。同步是能同步,但上传下载速度不稳定,而且网盘本质上是"文件同步"逻辑,不是"版本管理"逻辑。同步到另一台电脑后,你无法知道这个文件上一次改动是什么时候、改了什么、为什么改。最尴尬的是网盘会把项目里那种几万个文件的node_modules目录也同步过去,光是等索引就够你喝一壶的。
聊天工具传压缩包就更不用说了,你甚至无法确定对方(或者另一台电脑上的自己)收到的到底是哪一个压缩包版本。
1.2 Git中转的核心逻辑:远程仓库当作"事实源"
用Git做代码互传,本质上是换了一个思路:不直接在两台电脑之间传文件,而是让两台电脑都和一个远程仓库同步。
这个远程仓库(比如GitHub、GitLab或任何你自己搭建的Git服务器)就是一个"事实源",两台电脑都只跟它对话。你在A电脑上改完代码,push上去;到B电脑上,pull下来继续改,改完再push回去。整个过程不需要任何物理介质,历史记录清清楚楚,每一行改动都能追溯。
而且这个方案有个额外的好处:远程仓库天然就是备份。哪怕你某台电脑硬盘坏了,代码也不会丢。
我后来在给团队做内部培训时经常说一句话:Git就是你两小时前那台电脑上的自己,给现在这台电脑上的自己发的一封带完整时间线的信。这句话虽然朴素,但很多完全没接触过Git的同事听完就理解了。
2. 环境准备:Git安装和远程仓库创建,一次做完不留尾巴
工欲善其事必先利其器,要把两台电脑的代码串起来,得先在两台电脑上都把Git环境装好,并且让它们能跟远程仓库正常通信。
2.1 不同操作系统下的Git安装
先说Windows。最省心的方式是去Git官网下载安装包,一路默认安装即可。需要注意的只有一个点:安装过程中会让你选默认编辑器,如果你平时用VS Code,就选"Use Visual Studio Code as the default editor"。另外安装完成后,右键菜单里会出现"Git Bash Here",后续操作我建议统一在Git Bash里执行,因为它模拟的是Linux终端环境,命令提示符风格和macOS/Linux保持一致,习惯不用来回切换。
macOS可以走Homebrew:
brew install gitLinux(Ubuntu/Debian系)走APT:
sudo apt update && sudo apt install git -y装完之后不管哪个系统,先验证一下:
git --version看到版本号输出就说明装好了。
2.2 全局身份配置,这一步别漏
Git记录每次提交都会带上"作者信息",这个信息并不自动取自操作系统,必须手动配置一次(每台电脑都要配):
git config --global user.name "你的名字" git config --global user.email "你的邮箱"这里的邮箱最好和你远程仓库平台的邮箱保持一致,这样提交记录上显示的头像和用户名会正常关联。如果你在两台电脑上配置的姓名不一致,将来翻历史时会出现"同一个人显示成两个作者"的情况,虽然不影响功能,但观感很乱。
2.3 创建远程仓库:README加不加的决定
到代码托管平台(GitHub、GitLab等都可以,流程类似)上新建一个仓库。有几个细节会影响后面操作的顺畅度:
- 仓库名建议和本地项目文件夹同名,避免认知混乱。
- 创建时是否初始化README?我的建议是:如果你是先有本地项目、再创建远程仓库,不要勾选README、不要添加.gitignore、不要选License。因为一旦远程仓库里有了这些文件,你第一次本地
push时就会因为两边历史不一致而报错,还得先处理冲突,凭空多一道手续。 - 如果远程仓库是空的,你本地怎么推都顺。
等仓库创建好,你会看到两个远程仓库地址,一个是HTTPS形式的https://github.com/用户名/仓库名.git,一个是SSH形式的git@github.com:用户名/仓库名.git。这里就引入了下一步的关键问题:到底用哪个地址?我强烈建议用SSH,下面详细说。
3. SSH免密配置:一次配好,两行命令搞定认证
热搜词里有一个高频问题叫"ssh认证失败 git",这个坑我当年也踩过。先说结论:SSH免密配置成功后,你从任意一台电脑git pull或git push时,Git会自动用你本地的私钥完成身份验证,不再需要输密码。这是两台电脑代码互传体验顺畅的核心前提。
3.1 生成密钥对:ed25519还是RSA
在电脑的终端里执行:
ssh-keygen -t ed25519 -C "你的邮箱"一路回车即可(不建议额外设置口令,否则每次用密钥还会让你输密码,反而违背了免密初衷)。默认会在~/.ssh目录下生成两个文件:id_ed25519是私钥(自己留着,绝不外传),id_ed25519.pub是公钥(要放到远程仓库平台上去)。
如果你用的Git版本或者平台对ed25519支持不好,可以用传统RSA算法:
ssh-keygen -t rsa -b 4096 -C "你的邮箱"生成的文件名会变成id_rsa和id_rsa.pub,后续操作完全一样。我个人优先推荐ed25519,它更安全、速度也更快。
3.2 把公钥放到远程仓库平台上
利用命令查看公钥内容(Windows的Git Bash同样支持这条命令):
cat ~/.ssh/id_ed25519.pub复制完整输出,进入代码托管平台的个人设置页面,找到"SSH and GPG keys"(不同平台叫法略有差异),新建一个SSH key,标题随便起,比如"A电脑"或者"Work Laptop",这样以后你能分清这个公钥对应的是哪台设备。把公钥粘贴进去保存即可。
3.3 验证免密是否生效
在终端执行:
ssh -T git@github.com第一次连接会提示确认主机指纹,输入yes回车。如果看到类似"Hi 用户名! You've successfully authenticated",说明SSH免密已经通了。
3.4 ssh认证失败的完整排查链路
如果这一步报错,不要慌,按下面顺序排查,90%的问题都能定位:
- 公钥是不是完整复制了。
ssh-ed25519 AAAA...这串非常长,复制时漏掉末尾字符或者多了换行,都会导致认证失败。检查方法:再cat一次,重新复制。 - 确认你在远程平台上粘贴的是"公钥"而不是"私钥"。很多人会把两个文件搞混,私钥出现在平台上是非常危险的,平台也会拒绝。
- 检查你用的仓库地址是不是SSH格式。如果你本地
git remote里配的是HTTPS地址,那么SSH免密配得再好也没用,因为Git走的根本不是SSH通道,它只会弹窗让你输账号密码。查看方式:
git remote -v如果显示https://github.com/...,你需要改一下:
git remote set-url origin git@github.com:用户名/仓库名.git- 确认你当前操作的用户目录下有正确的密钥。仔细看
ls ~/.ssh,如果存在多个密钥文件,且名称不是默认的id_ed25519或id_rsa,Git默认不会自动识别。这类场景一般是开发者给不同平台生成过不同密钥,此时可以手动指定:
ssh -i ~/.ssh/你的密钥名称 -T git@github.com如果这个能通,你就需要在家目录下新建/修改~/.ssh/config文件,给不同域名指定各自的密钥:
Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519- 网络层面排查。如果以上都没问题但SSH还是超时或连接被拒,有可能是你所处的网络环境对22端口有限制。一个绕开办法是让SSH走HTTPS端口(443),GitHub等平台是支持这个方式的。在
~/.ssh/config里加一行:
Host github.com HostName ssh.github.com Port 443或者退一步直接改用HTTPS地址配合系统自带的凭据管理器,虽然每次首次连接会要求输入账号密码或Token,但之后Windows凭据管理器或macOS钥匙串会帮你记住,体验也不差。热搜词里"git免密"指向的具体操作,核心就是上面这些。
4. 从clone到push的双向闭环:两台电脑的完整互传流程
准备工作都做完,下面进入正题。假设你有一台主力电脑(A)和一台便携电脑(B),用Git把代码在它们之间传起来,只需要掌握下面几个动作。
4.1 A电脑:首次推送,把本地项目交到远程仓库
A电脑上如果已经是一个普通项目目录,但还没有用Git管理,依次执行:
cd 你的项目目录 git init git add . git commit -m "initial commit"这三步的含义分别是:初始化仓库、把所有文件加入暂存区、生成第一个提交记录。注意git add .会把当前目录下所有文件都纳入版本管理,所以建议提前准备一个.gitignore文件(后面会细说),把不需要跟踪的目录(比如node_modules、build、dist)排除掉。
接着把本地仓库和远程仓库关联起来:
git remote add origin git@github.com:用户名/仓库名.git git push -u origin main-u的意思是设置上游分支,等价于在本地main分支和远程origin/main分支之间建立默认关联。之后在A电脑上再执行git push,就可以不用带参数了。
如果你的默认分支叫master而不是main,把上面命令里的main替换成master即可。现在新版本的Git很多时候已经默认初始化为main,具体分支名可以执行git branch查看。
4.2 B电脑:首次拉取,一条clone到达现场
到了B电脑,什么都不用想,执行:
git clone git@github.com:用户名/仓库名.gitGit会在当前目录下创建一个和仓库同名文件夹,里面就是A电脑推送的全部内容,以及完整的提交历史。这一条命令同时完成了"下载代码"和"初始化仓库"两步,是我在所有Git命令里觉得最爽的一条。
如果你用的IDE是IDEA这类集成工具,新建项目时也可以选择直接从一个Git仓库拉取(对应热搜词里"idea创建新项目拉取git"的场景),本质上是把clone这一步图形化了,填的地址就是你仓库的SSH地址。
4.3 日常修改回传:B电脑改完,A电脑怎么拿到
这是使用频率最高的流程,在B电脑上继续开发:
# 先看当前状态 git status # 把改动加入暂存区 git add . # 写清楚的提交说明 git commit -m "fix: 修复登录页按钮样式" # 推送出去 git push然后回到A电脑,只需要:
git pullA电脑上的代码就同步成B电脑刚推上去的版本了。整个闭环就是:B改 -> push -> A pull -> A改 -> push -> B pull,无限循环。
这里有三个非常重要的习惯,我在带人时反复强调:
- 开工先pull。坐下一台电脑开始干活前,先
git pull,确保自己拿到的是最新版本。不然你在一份旧代码上改了半天,推上去才发现和别人改冲突了,就很被动了。 - 多敲git status。每次执行
add或commit前,都看一眼当前状态,这个习惯能避免90%的"我明明改了但好像没提交上去"的困惑。 - 提交信息写清楚。比如"fix: xxx"、"feat: xxx",一个月后你翻日志,能立刻知道那台电脑上的改动意图。热搜词里专门提到"git commit 提交注释"和"git commit --amend怎么使用",说明很多人提交完才发现注释写错了。补救方法是用
git commit --amend -m "新的注释"来修改最后一次提交的说明,这个命令只适合"还没推送出去"的提交,如果已经push了,再amend会导致两台电脑的提交历史不一致,反而麻烦。
4.4 一台电脑上git pull遇到本地未提交的修改怎么办
你可能会碰到这种情况:在B电脑上改到一半,突然想起A电脑上有新提交需要拉下来看看。此时直接git pull会报错,提示工作区不干净。处理思路有两种:
- 如果B电脑上这些改动已经用不上了,直接放弃:
git checkout .- 如果还想保留,先临时存起来:
git stash git pull git stash popstash就像临时寄存柜,把工作区里的改动放进去,等你拉取完新代码再取出来。
5. 两台电脑互传时的分支管理和冲突处理:我建议你从一开始就别偷懒
只用一条main分支、在A和B之间来回push/pull,确实能跑通,但等代码量上来,你会发现事情没那么简单。
5.1 为什么两机互传场景下也要开分支
很多人在"自己一个人、两台电脑"的场景下觉得开分支是多余的。但实际开发中,"临时改个bug"和"继续写未完成的功能"这两件事经常混在一起。如果你所有改动都直接在main上提交,A电脑写了一上午还没写完的半成品,不小心push上去了;到B电脑想拉取一个稳定版拿出去演示,却发现拉下来的是个编译不过的半成品。
正确的做法是给每个任务开一个分支:
git checkout -b feature/xxx在B电脑上想拿到A电脑某个分支的代码:
git pull git checkout feature/xxx本地会直接基于origin/feature/xxx创建一个追踪分支。热搜词里有一个很典型的提问:"我在master上写的代码怎样剪切到dev上"。这个场景本质上就是分支合并:
# 先把master上的改动提交掉 git add . git commit -m "完成某功能" # 切换到dev分支 git checkout dev # 把master上的提交合并过来 git merge master分支的意义在于隔离不稳定的改动,互传场景下"半成品"和"可用版本"并存时,分支是唯一优雅的解。哪怕只有你自己在两台电脑上开发,我仍然建议按功能开分支,改完测试无误再合并回主分支。
5.2 冲突是怎么出现的:"两个人同时改了同一行"
这里说的"两个人"可能是你和同事,也可能是你昨天在A电脑上的自己、和今天在B电脑上的自己。冲突的本质很简单:同一份文件的同一处地方,被两个不同的提交改成了不同的内容。
举个具体例子:A电脑上你删掉了配置文件里的timeout = 30,改成timeout = 60并push。而B电脑在你pull这个改动之前,也把timeout = 30改成了timeout = 45,并且直接commit。当B电脑执行git pull时,Git发现没法自动判断"到底听谁的",于是停下来告诉你:CONFLICT (content): Merge conflict in 某个文件。
打开冲突文件,你会看到类似这样的标记:
<<<<<<< HEAD timeout = 45 ======= timeout = 60 >>>>>>> origin/main<<<<<<< HEAD下面是当前分支(B电脑)的内容,>>>>>>> origin/main上面是远程分支(A电脑)的内容,=======是分界线。解决冲突的正确姿势:
- 手动编辑文件,把标记和不要的内容都删掉,保留你想要的那一行。
- 保存文件。
- 执行
git add 该文件告诉Git冲突已解决。 - 执行
git commit完成这次合并提交。
如果是自己两台电脑之间出现冲突,大概率是"改完忘push就去另一台电脑接着改"造成的。破局习惯是通过git log --oneline --graph先看清两边的提交历史再动手合并。
5.3 merge还是rebase:互传场景下我的选择
把A电脑的分支代码合并到B电脑时,有人会问用git merge还是git rebase。我的建议是:刚接触Git时只用merge,原因很简单——merge生成的历史是真实发生过的,rebase会改写历史,在两台电脑互传场景下极容易造成"本地历史与远程历史不一致"后再push被拒的混乱。等把Git玩熟了,再按需学习rebase也来得及。热搜词里还有"git pick和fetch有什么区别"这类问题,放在互传场景下:git fetch只是把远程的最新状态下载到本地,但还没动你的工作区,git pull等同于fetch + merge。
6. 几个真实踩过的坑:换行符、大文件、.gitignore失效
最后分享几个在两机互传过程中很典型、但绝大多数教程不会写清楚的坑。这些坑我都实打实踩过,写出来帮你省点时间。
6.1 Windows和macOS/Linux混传时,换行符把diff搞花
如果A电脑是Windows,B电脑是macOS或者Linux,Git的自动换行符转换机制很可能让你见识一次"什么都没改、但整个文件都是变动"的诡异现象。
根源是:Windows文本文件行尾是CRLF,Unix/Linux/macOS是LF。Git为了协作方便,默认会在提交时把CRLF转成LF、检出时再转回CRLF(取决于core.autocrlf配置)。当两台电脑的配置不一致时,你拉下来的文件和本地文件在换行符层面不一样,git diff就会显示每一行都变了。
我的做法是给仓库加一个.gitattributes文件,统一行为:
* text=auto *.js text eol=lf *.json text eol=lf这样无论在哪个系统上检出,代码文件的换行符都被强制成LF,避免了两端各改各的问题。这个文件一旦加上并提交,所有平台都按规矩来,互传体验会顺畅很多。
6.2 大文件让push直接失败,别硬扛
热搜词里有一条"git 无法提交大文件",这问题我熟。之前往仓库里塞了一个300MB的二进制资源包,结果git push跑到一半直接被平台拒绝。大多数代码托管平台对单文件大小有硬性限制(GitHub超过100MB直接拒收),更重要的是,大文件一旦进入Git历史,即便以后删了,它依然在.git对象库里占着空间,clone会痛苦到爆炸。
在互传场景下如果想同时传输大资源文件,我的建议是:代码走Git,大文件走网盘或者NAS,并在.gitignore里把这些目录排除掉。另外,开发中常见的临时生成物、编译输出、日志文件,也全部不进Git。
6.3 .gitignore"不生效"的真正原因
说到.gitignore,很多人会遇到"明明加进去了,文件还是出现在git status里"的情况。准则是:如果这个文件已经被Git跟踪过,那么.gitignore对它无效。Git的规则只对"尚未被跟踪"的文件生效。
解决办法是把它从跟踪列表里移除,但保留本地文件:
git rm --cached 文件名比如日志目录:
git rm -r --cached logs/然后提交这个变更,再重新把.gitignore加上规则,后面就不会再跟踪这些文件了。这个命令不会删除你本地的文件,只是告诉Git"我不再管理它",可以放心用。
6.4 两机互传的常用命令速查
最后给一张我自己的命令速查表,贴在工位旁边那种:
| 动作 | 命令 |
|---|---|
| 下载代码到新电脑 | git clone <SSH地址> |
| 查看当前状态 | git status |
| 查看变更内容 | git diff |
| 提交全部改动 | git add . |
| 提交并写注释 | git commit -m "说明" |
| 推送到远程 | git push |
| 拉取远程更新 | git pull |
| 临时寄存改动 | git stash/git stash pop |
| 新建并切换分支 | git checkout -b <分支名> |
| 合并分支到当前 | git merge <分支名> |
| 查看提交历史 | git log --oneline --graph |
| 修改上一次提交注释 | git commit --amend -m "新注释" |
| 修改远程仓库地址 | git remote set-url origin <新地址> |
6.5 如果你总是忘push,有一个小技巧
我自己在长时间多任务切换时,也经常遇到"以为push过结果没push"的尴尬。后来我养成了一个习惯:在A电脑准备合上盖子走人之前,强制执行一次git status,如果工作区不干净,就立刻git commit并git push;在B电脑打开盖开始干活之前,先执行git pull。这两条不是技术问题,是纪律问题。多台电脑互传代码,最大的不确定因素从来不是Git本身,而是"哪台电脑上的代码是最新的"这个记忆问题。把"走之前push、来之后pull"变成肌肉记忆,比你用再复杂的工具都管用。