ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Git常用命令实战指南:从安装配置到疑难杂症排查

Git常用命令实战指南:从安装配置到疑难杂症排查 聊到 Git 常用命令很多人第一反应是“网上教程一大把背下来就行”。但实际用起来却常常卡在几个不起眼的地方装是装好了克隆仓库却报错连不上提交代码后才发现把不该提交的文件加进去了改完分支合并时冲突堆了一屏幕。这篇文章不打算做命令字典而是把我自己从安装配置、日常提交、分支合并到大文件、疑难杂症排查的完整套路走一遍所有命令都在命令行实测过。适合刚入门的开发者也适合用了几年 Git 但总在“能用就行”边缘徘徊的老手查漏补缺。1. 先把环境收拾利索Git安装与全局配置1.1 Windows / Linux 装 Git 的正确姿势先泼一盆冷水很多 Git 报错根本不是命令问题是环境没装好。Windows 上最稳妥的方式是从官网下载安装包一路 Next 没有坑。安装界面里有几个选项容易被忽略比如“调整 PATH 环境变量”默认选的是推荐项不用改Git Bash 组件默认勾选强烈建议保留。Git Bash 是 Windows 下最接近 Linux 终端的交互环境后续很多命令比如ssh-keygen、grep、cat在 Git Bash 里跑比 CMD 和 PowerShell 稳定得多。很多人习惯双击 Git GUI其实命令行才是日常效率最高的入口。Linux 上用包管理器装更快Debian/Ubuntu 系执行sudo apt update sudo apt install -y gitCentOS/RHEL 系执行sudo yum install -y git或者sudo dnf install -y git。装完先别急着建仓库第一件事是验证版本git --version。如果提示 “command not found”大概率是 PATH 没配好Windows 安装时没选“加入 PATH”重新装一遍或者手动加环境变量即可。这里强调一句新版 Git 功能差异不大不用追求最新能稳定拉取远程代码就够用。下载安装教程网上很多但核心其实是两点装完能执行git命令以及能顺利连接远程仓库。1.2 user.name 和 user.email提交记录的身份证安装完成后第一件事是设置全局身份不然后续 commit 会报Please tell me who you are。命令是git config --global user.name 你的昵称 git config --global user.email 你的邮箱这两项会写入用户主目录下的.gitconfig以后所有仓库的提交记录都带上这个身份。为什么强调“全局”而不是每个仓库单独设置因为绝大多数人只有一个常用身份信息全局设置可以避免新克隆的仓库因为缺身份而提交失败。如果你在不同平台用了不同身份可以用仓库级配置覆盖在某个仓库内执行git config user.name xxx仓库级配置会优先于全局配置。查看当前配置用git config --list能看到所有生效项。如果发现配置不对直接编辑主目录下.gitconfig即可。这里有个经验邮箱最好用真实常用的邮箱因为提交记录里会公开别人可以通过邮箱联系你不要临时乱填后面改历史非常麻烦。另外一个容易忽略的点是文件大小写.gitconfig写错参数名不会报错但不会生效所以改完最好再执行一次git config --list确认。1.3 SSH 密钥与免密拉取配置每次 push 都要输账号密码很痛苦SSH 密钥是最常用的免密方案。生成密钥用ssh-keygen -t rsa -b 4096 -C 你的邮箱一路回车会在用户主目录生成~/.ssh/id_rsa和~/.ssh/id_rsa.pub。然后把.pub文件内容加到代码托管平台的 SSH 公钥列表里比如 Gitee、GitHub 的设置页面都有 “SSH keys” 入口。加完之后务必测试连接ssh -T gitgitee.comGitee 会返回类似 “Hi xxx! Youve successfully authenticated” 的信息。这一步能提前暴露很多隐藏问题如果提示Permission denied (publickey)先看~/.ssh目录权限Windows Git Bash 下一般不用管Linux 下需要chmod 700 ~/.ssh和chmod 600 ~/.ssh/id_rsa如果提示Host key verification failed多半是首次连接需要确认指纹手动连接一次确认即可。克隆代码时候选择 SSH 地址形如gitgitee.com:user/repo.git之后 push/pull 就不会每次要密码了。这里再分享一个小坑如果你的机器上存在多个 SSH 密钥Git 默认会先尝试id_rsa如果托管平台上没注册这个公钥就会认证失败。解决办法是在~/.ssh/config里为不同域名指定不同的IdentityFile比如给 Gitee 单独写一段 Host 配置。很多“Git 免密不生效”的问题最后都是出在这个细节上。2. 日常必用的核心命令拆解2.1 clone 和 remote先搞清楚仓库从哪里来日常工作 95% 从 clone 开始。git clone 地址会把远程仓库完整拉下来默认就会建立远程分支跟踪。如果是自己本地从零开始用git init初始化空仓库然后git remote add origin 地址关联远程名字不一定要叫 origin但这是业内约定俗成后续所有命令都不用改。查看远程信息用git remote -v这个命令会显示所有远程仓库的 fetch 和 push 地址排查远程配置问题时非常有用。很多人不管三七二十一直接git push报错no upstream branch时才想起来远程关联问题这时候可以用git push -u origin main把当前分支推上去并设置本地分支跟踪 origin/main。-u 参数的含义是 “upstream”一次性解决后续裸输 push 的烦恼。我在实际项目里见过一种错误直接把别人仓库的地址 clone 下来改完代码后往自己远程仓库推送结果 push 到原仓库没有权限。正确做法是先在托管平台 fork 到自己名下再 clone fork 后的地址如果已经 clone 错了用git remote set-url origin 新地址修改远程地址即可不需要重新下载代码。2.2 status、log、diff、stash把工作区看明白改完代码别急着提交先养成看状态的习惯。git status会告诉你三件事哪些文件已暂存、哪些已修改未暂存、哪些是未跟踪文件。新手最容易犯的错是搞混工作区和暂存区工作区是你肉眼看到的文件暂存区是git add之后进入的一个缓冲区git commit提交的是暂存区里的内容不是工作区全部内容。这个认知非常关键很多提交“不完整”的怪问题都是因为改完文件忘了git add。git log --oneline --graph --all是我最常用的历史查看命令一行一个提交带分支图和所有引用能快速理清仓库演进。想看某个文件谁改过用git log -p 文件名相当于带着补丁看历史。git diff默认比较工作区和暂存区之间的差异git diff --cached比较暂存区与最后提交之间的差异。提交前我习惯先执行git diff --cached检查一遍防止把调试日志或临时文件带进提交。git stash则是临时“收衣服”的命令正在写一半的代码不想提交又需要切分支干别的事执行git stash会把当前修改保存到堆栈工作区恢复干净回来后git stash pop恢复。这里有个细节git stash默认不保存未跟踪文件需要git stash -u才能连新文件一起保存。踩过坑的人应该都知道stash 之后找不到新文件有多慌。另外git stash list可以看堆栈里有几条记录git stash drop可以清理某条记录避免堆栈越积越多。2.3 commit --amend 与 reset 回滚改了提交别慌提交代码后发现 message 写错了或者少加了一个文件不需要推翻重来。git commit --amend能修改最近一次提交它会把暂存区内容合并进上一次提交并重新打开提交信息编辑器。典型用法git add 忘记的文件 git commit --amend -m 修正后的提交信息执行后你会发现提交记录里只有一条而不是多出一条“fix”。因为--amend本质是创建了一个新提交替换旧提交旧的会被丢弃。注意amend 相当于改写了历史如果这个提交已经推送到远程且别人也在用千万不要 amend否则双方历史会分叉要 force push 才能对齐非常麻烦。git reset是回滚操作但参数不同后果差很多git reset --soft HEAD~1回退到上一个提交但保留暂存区和工作区改动适合发现提交信息写错了、想重新提交。git reset --mixed HEAD~1默认回退提交并清空暂存区但工作区改动还在。git reset --hard HEAD~1回退提交并丢弃所有改动不可轻易使用。如果已经 hard reset 后发现改错了别急着崩溃Git 还有一个保命命令git reflog。它记录了 HEAD 的所有移动轨迹能找到任意历史提交的哈希值再用git reset --hard 哈希切回去。我自己的经验是回滚之前先执行git reflog留个备份依据比什么都靠谱。哪怕是你已经认为“彻底删掉”的提交只要 reflog 记录还在就能找回来。2.4 分支与合并merge 和 rebase 怎么选分支是 Git 的灵魂。git branch查看本地分支git branch 新分支名创建分支git checkout 新分支名或git switch 新分支名切换分支。新版 Git 推荐用switch语义更清晰checkout同时承担很多职责容易混。创建并切换分支用git switch -c 新分支名比先 branch 再 checkout 少敲一条命令。分支合并两种思路git merge和git rebase。merge 会把两个分支的历史“捏”在一起产生一个合并提交优点是保留真实历史缺点是一条线上混了一堆 merge commitlog 不好读。rebase 则是把自己分支的提交“挪”到目标分支顶端历史呈线性更干净但本质上改写了自己分支的提交多人协作时不要去 rebase 别人正在使用的分支。我的建议是个人分支尽量 rebase 到最新 main 再合并共享分支老老实实用 merge别整花活。冲突处理是绕不过的坎。执行 merge/rebase 后出现冲突时git status会列出冲突文件编辑器里会出现类似 HEAD、、 branch-name的标记。我处理冲突的顺序是先打开每个冲突文件手动保留需要的代码删掉冲突标记然后git add这些文件最后执行git merge --continue或者git rebase --continue完成收尾。切忌直接 commit很多初学者在这个环节提交出一堆 “Merge branch” 垃圾提交后续回溯时想哭都来不及。3. 进阶场景与命令组合3.1 git lfs 使用大文件别再往仓库塞普通 Git 仓库不适合存大文件默认会有 100MB 左右的限制仓库体积膨胀后 clone 会越来越慢。大文件可以交给 Git LFS。安装后先执行git lfs install在仓库里声明要跟踪的文件类型例如git lfs install git lfs track *.psd git lfs track *.zip然后正常 add、commit、push 即可。.gitattributes文件会被自动更新记录 LFS 跟踪规则。注意git lfs install只需在机器上执行一次它会为当前用户写入全局钩子git lfs track则是每个仓库单独配置。如果换了一台电脑克隆带 LFS 的仓库之前要先装 Git LFS 并执行git lfs install否则会遇到 “could not find lfs” 或文件无法 checkout 的问题。LFS 有一个很容易踩的坑clone 仓库时默认会尝试拉取所有 LFS 文件网络不好或者文件很大时就会卡住。临时跳过 LFS 文件可以设置环境变量GIT_LFS_SKIP_SMUDGE1 git clone 地址之后手动按需拉取git lfs pull。如果你只想让某个仓库不拉取特定 LFS 文件可以用git config --global --unset lfs.fetchexclude清理之前设置的排除项配合lfs.fetchexclude指定文件类型或路径。有时候git lfs clone卡住不是文件多而是某个 LFS 服务器连接不稳定排查时先看命令输出停在哪一步再针对性处理。3.2 .gitignore 不生效多半是你把文件 add 进去了不少人在项目根目录建了.gitignore写了一堆node_modules、*.log结果git status里还是能看到这些文件气得直呼“过滤文件没有作用”。真相是.gitignore对已经被 Git 跟踪的文件是无效的。如果你在写 ignore 规则之前执行过git add文件已经进了暂存区/索引Git 会继续跟踪之后 ignore 规则不会把它移除。解决办法是先撤销跟踪但保留磁盘文件git rm -r --cached node_modules git add . git commit -m 清理已经被跟踪的目录--cached参数的含义是只从 Git 索引里删除不碰工作区文件。执行完再检查git status你会发现 ignore 规则生效了。另外.gitignore的规则匹配有自己的语法目录末尾加/表示只匹配目录*不匹配目录层级**可以跨层级规则里写!是取反。我建议想搞清楚文件为什么没被忽略时用git check-ignore -v 文件名查看是哪条规则在起作用排查效率高很多。还有一个冷知识.gitignore只能忽略未跟踪文件一旦文件已经被跟踪哪怕后来删掉再重新 add依然会被跟踪。3.3 授权测试场景Git目录泄露如何恢复源码这个场景比较特殊但如果做安全测试的同学遇到了会非常头疼。所谓“Git 目录泄露”指的是网站部署时把.git目录一起发布到了 Web 根目录变成静态文件可以被直接访问。访问http://target/.git/config如果能返回内容基本就确认泄露了。这通常意味着目标网站的完整源码、历史提交甚至配置信息都暴露在公网。在获得目标授权的前提下可以尝试把.git目录完整下载到本地然后利用 Git 自身机制恢复工作区文件。简单做法是用工具递归下载.git目录或者用wget/curl带上递归参数如果下载完整本地进入该目录执行git checkout .就能还原当前分支最新代码。如果下载不完整还可以通过git cat-file --batch-all-objects列出所有对象再逐个还原 blob 对象恢复历史文件内容。我把这段话写出来是想提醒两类人对开发者来说部署时务必把.git目录挡在 Web 服务之外比如在 Nginx 或 Apache 配置里禁止点开头目录访问对安全从业者来说只能在授权范围内测试未经授权对任何目标进行探测都属于违法操作。Git 是团队协作工具也是安全边界清单上的一环这个坑比大多数命令问题都严重。很多做渗透测试的老手都遇到过目标站暴露.git的情况利用好了可以直接“抄源码”但务必管住手。3.4 多远程源与子模块进阶除了默认的 origin一个本地仓库可以同时关联多个远程源。比如你从开源项目克隆了一份想保持跟上游更新同时又把自己改动推到自己的仓库可以这样配置git remote add upstream 上游地址 git remote -v # 查看所有远程 git fetch upstream git merge upstream/main这种场景在代码维护中很常见本地仓库既能用origin推自己的分支又能用upstream同步上游修复。注意 fetch 和 pull 的区别fetch 只把远程更新下载到本地引用不会合并到工作区pull 等于 fetch merge。多人协作时我建议手动 fetch 后查看git log HEAD..upstream/main的差异再决定怎么合并避免被 pull 的默认行为带乱节奏。如果只是想看看上游改了哪些文件git diff HEAD..upstream/main --stat比直接 merge 更安全。子模块git submodule用于在一个仓库里引另一个仓库的固定版本。git submodule add 地址 路径添加克隆含子模块的仓库时用git clone --recurse-submodules 地址否则子模块目录是空的需要git submodule update --init --recursive拉取。这块命令不多但坑在于子模块的更新机制是“指针式”的主仓库只记录子模块的 commit 哈希不在主仓库里存内容所以忘执行 update 是最常见的问题。如果你发现子模块目录为空先别急着重新 clone先执行那串 update 命令往往就解决了。4. 常见问题排查实录4.1 SSH 认证失败与本地代理残留SSH 认证失败几乎是排行榜第一的 Git 问题。命令提示Permission denied (publickey)原因大致有几类密钥没加到托管平台、本地 ssh-agent 没加载密钥、本机存在多个密钥但 Git 用了错误的那一个、~/.ssh目录权限不对。排查顺序建议先ssh -T gitgitee.com看返回如果还是 publickey执行ssh-add -l查看当前会话加载了哪些密钥没有就ssh-add ~/.ssh/id_rsa。如果使用了非默认文件名需要在~/.ssh/config里写清楚IdentityFile指向同时确认known_hosts没有残留冲突记录必要时删除对应行再连一次。另一个高频报错是git clone时报连接 127.0.0.1 的 7890 端口失败。这个 7890 是本地代理类工具常见的监听端口Git 之所以会去连它是因为全局配置或系统环境变量里残留着代理设置。排查方法分两步git config --global --get http.proxy git config --global --get https.proxy如果输出了代理地址用git config --global --unset http.proxy和git config --global --unset https.proxy清除。再看环境变量env | grep -i proxy如果有HTTP_PROXY、HTTPS_PROXY变量可以用unset HTTP_PROXY HTTPS_PROXY临时去掉或者修正为当前可用代理地址。这类问题本质是 Git 的 http 层走了错误代理和网络本身通不通没关系。我自己遇到时会先用git -c http.proxy clone ...的方式临时覆盖验证确认是代理导致后再去清理持久配置效率很高。还有一种情况是.git/config里仓库级别的代理配置需要进仓库执行git config --unset http.proxy才能清掉。4.2 CRLF 换行符问题让团队不再互相制造 diffWindows 默认用 CRLF回车换行作为行尾Linux/macOS 默认用 LF。如果一个团队混用系统Git 会把“行尾风格不同”也当成文件改动于是出现明明只改了一行diff 里整个文件都标红的情况。Git 的core.autocrlf参数就是干这个的Windows 上设置git config --global core.autocrlf true提交时把 CRLF 转成 LF检出时转回 CRLF照顾 Windows 编辑器。Linux/macOS 上设置git config --global core.autocrlf input只把 CRLF 转成 LF检出不转换。更治本的做法是仓库根目录放一个.gitattributes文件强制指定文件的行尾风格* textauto *.sh text eollf *.bat text eolcrlf.gitattributes随仓库分发所有协作者自动遵守不受本地 config 影响。已经错乱的文件想一次性修正可以用git add --renormalize .按属性重新标准化文件内容再提交一次。我个人的习惯是新仓库先提交.gitattributes旧仓库则先统一团队成员的 core.autocrlf 设置再处理存量文件不然纯靠口头约定总有一天会被同事 Windows 编辑器悄悄“修”一次。如果你看到git status里全是 “warning: CRLF will be replaced by LF” 这类提示不用慌按上面的方式统一规则提示会自然消失。4.3 LFS clone 卡住与拉取仓库指定版本git lfs clone卡住多半是大文件拉取慢或者网络对超大文件不友好。前面提过GIT_LFS_SKIP_SMUDGE1跳过 LFS 文件这里再补充一个场景克隆一个历史很长的仓库只想看某个 tag 或 commit 的代码不需要完整历史。常见做法git clone --depth 1 --branch v1.0.0 仓库地址--depth 1是浅克隆只拉最新一层提交--branch可以指定分支或标签。如果已经完整克隆了指定版本就是用git checkout v1.0.0或git checkout commit哈希查看完后想回到主分支直接git switch main即可。注意 checkout 指定 commit 会进入 detached HEAD 状态此时不要直接在它上面提交建议先创建分支再改代码。如果 LFS 文件拉不下来但代码本身能用也可以临时设置git config --global lfs.fetchexclude *.zip来排除某些 LFS 类型等需要时再git lfs pull --include*.zip单独拉取。按需拉取是处理大仓库的常用策略。还有一种情况明明仓库里没有 LFS 文件但 clone 时提示 “Downloading file”可能是仓库历史上有过 LFS 跟踪后来又取消了这种历史 LFS 对象默认也要拉取同样可以用跳过 LFS 的方式处理。4.4 常用命令速查表与易错点最后整理一份我实际项目里最常用的速查表适合贴在终端旁边操作命令说明查看状态git status查看工作区、暂存区变化查看简洁日志git log --oneline --graph --all分支历史一目了然暂存所有改动git add -A包含新增、修改、删除提交git commit -m 描述提交暂存区内容推送并关联远程git push -u origin main首次推送常用拉取并合并git pull相当于 fetch merge切换分支git switch -c 新分支名创建并切换分支合并分支git merge 分支名把指定分支合入当前分支暂存修改git stash -u连未跟踪文件一起暂存恢复暂存git stash pop恢复并删除堆栈记录修改最近提交git commit --amend -m 新信息只能用于未推送的提交回滚到指定提交git reset --hard 提交哈希慎用会丢改动找回误删提交git reflog查看 HEAD 历史轨迹查看远程地址git remote -v确认 fetch/push 地址易错点再强调三件事第一git pull前先git stash或提交本地改动避免未提交修改和远程更新冲突第二不要git push --force到共享分支如果一定要强刷先在群里喊一声第三提交信息写清楚“为什么改”比写“改了一堆 bug”有用得多。另外有些 IDE 在操作 Git 时会自动带上一长串参数比如git -c diff.mnemonicprefixfalse -c core.quotepathfalse --no-optional-locks ...看到这种命令不要慌它只是在调用 Git 时临时加了配置对仓库本身没有副作用。我个人现在的习惯是任何一台新电脑装完 Git第一件事就是设好全局身份和 SSH 密钥任何新仓库先提交.gitattributes任何重要分支动历史之前先git reflog瞄一眼。这三个习惯帮我在过去几年省掉了大量无效操作。Git 常用命令其实是越用越熟的关键是知道每条命令背后在动哪一部分数据——工作区、暂存区、提交、引用。把这个模型想明白了很多报错你瞄一眼就能猜到原因。这份命令指南就当是我陪你把这些角落都走了一遍后续如果再遇到什么奇葩问题欢迎回来对照排查。
返回列表