Git 推送与拉取

Git 推送与拉取更改

掌握Git推送与拉取更改的完整操作指南,包括推送命令、拉取策略、冲突解决和团队协作最佳实践

开始学习

推送更改到远程仓库

推送操作将本地提交上传到远程仓库,与团队成员共享你的工作成果。

本地仓库

包含你的新提交

推送 (git push)

远程仓库

接收你的新提交

基本推送命令

将本地更改推送到远程仓库:

# 推送当前分支到远程仓库
git push origin main

# 推送并设置上游分支(首次推送)
git push -u origin branch-name

# 推送所有分支到远程
git push --all origin

# 推送标签到远程
git push --tags origin

高级推送选项

使用不同的推送策略:

# 强制推送(谨慎使用)
git push -f origin main

# 强制推送但保留远程分支的孤立提交
git push --force-with-lease origin main

# 删除远程分支
git push origin --delete branch-name

# 推送特定引用
git push origin local-branch:remote-branch

推送工作流程

1. 提交更改

在本地完成工作并提交更改

2. 执行推送

使用git push上传到远程

3. 验证推送

确认推送成功完成

推送前检查清单

  • 检查当前分支 - 确保在正确的分支上推送
  • 查看提交状态 - 使用 git status 确认所有更改已提交
  • 拉取最新更改 - 推送前先拉取远程更新,避免冲突
  • 运行测试 - 确保代码通过所有测试
  • 检查提交信息 - 确认提交信息清晰准确
# 推送前的标准检查流程
git status # 检查状态
git log --oneline -5 # 查看最近提交
git pull origin main # 拉取最新更改
git push origin main # 推送更改

重要警告: 强制推送 (git push -f) 会覆盖远程历史,可能导致团队成员的工作丢失。只应在个人分支上使用,切勿在共享分支上使用强制推送。

从远程仓库拉取更改

拉取操作获取远程仓库的最新更改并合并到本地分支,保持代码同步。

远程仓库

包含团队的新提交

拉取 (git pull)

本地仓库

接收团队的新提交

基本拉取命令

# 拉取远程分支并合并到当前分支
git pull origin main

# 拉取默认远程分支(已设置上游)
git pull

# 拉取但不自动合并
git pull --no-commit origin main

# 拉取特定远程分支到当前分支
git pull origin feature-branch

拉取策略比较

策略 命令 适用场景
合并拉取 git pull 默认策略,创建合并提交
变基拉取 git pull --rebase 保持线性历史,个人分支
仅获取 git fetch 只下载不合并,手动处理

高级拉取选项

# 使用变基方式拉取(推荐)
git pull --rebase origin main

# 仅获取远程更改,不合并
git fetch origin

# 获取所有远程仓库的更新
git fetch --all

# 清理已删除的远程分支跟踪
git fetch -p

# 拉取并压缩远程提交
git pull --squash origin main

最佳实践: 使用 git pull --rebase 可以保持提交历史的线性,避免不必要的合并提交。但在共享分支上要谨慎使用变基。

拉取工作流程

1. 执行拉取

使用git pull获取远程更新

2. 解决冲突

如有冲突,手动解决

3. 完成合并

提交合并结果

推送与拉取工作流程

日常开发工作流

远程 main
本地 main
# 开始新的一天
git checkout main
git pull origin main

# 创建功能分支
git checkout -b feature/new-feature

# 进行开发并提交
git add .
git commit -m "实现新功能"

# 推送功能分支
git push -u origin feature/new-feature

# 创建Pull Request进行代码审查
# ... 在GitHub/GitLab上操作 ...

# 合并后更新本地主分支
git checkout main
git pull origin main

团队协作最佳实践

频繁同步

定期拉取远程更改,避免大型合并冲突:

# 每天开始工作时拉取最新更改
git pull --rebase origin main

# 推送前确保与远程同步
git fetch origin
git rebase origin/main
git push origin main
使用功能分支

每个功能在独立分支开发:

# 基于主分支创建功能分支
git checkout -b feature/description main

# 定期将主分支更新合并到功能分支
git fetch origin
git merge origin/main

# 或使用变基保持历史整洁
git fetch origin
git rebase origin/main
代码审查流程

通过Pull Request进行代码审查:

  1. 在功能分支上完成开发
  2. 推送功能分支到远程
  3. 创建Pull Request
  4. 团队成员进行代码审查
  5. 通过后合并到主分支
  6. 删除功能分支

推送与拉取时机

场景 操作 说明
开始工作前 拉取 获取最新代码,避免冲突
完成功能后 推送 共享工作成果,创建PR
解决冲突后 推送 上传解决后的代码
长时间工作 定期拉取 避免偏离主分支太远
团队协作 频繁推送拉取 保持团队同步

配置优化

设置Git配置提高工作效率:

# 设置默认推送行为
git config --global push.default simple

# 设置拉取使用变基
git config --global pull.rebase true

# 设置自动设置上游分支
git config --global push.autoSetupRemote true

# 设置凭证存储(避免重复输入密码)
git config --global credential.helper store

配置说明: push.default simple 是Git 2.0后的默认行为,只推送当前分支到对应的上游分支,更安全可靠。

常见问题与解决方案

推送被拒绝

当远程有本地没有的新提交时:

# 错误信息
! [rejected] main -> main (non-fast-forward)

# 解决方案:先拉取再推送
git pull origin main
git push origin main

# 或使用变基方式
git pull --rebase origin main
git push origin main

这是因为你的本地分支落后于远程分支,需要先获取远程更新。

合并冲突

拉取时遇到冲突:

# 拉取时出现冲突
git pull origin main
# CONFLICT (content): Merge conflict in file.txt

# 解决冲突步骤:
# 1. 编辑冲突文件,解决冲突
# 2. 标记冲突已解决
git add file.txt
# 3. 完成合并
git commit

冲突标记 <<<<<<<>>>>>>> 之间的内容需要手动解决。

认证失败

推送时出现权限错误:

# 错误信息
Permission denied (publickey).
fatal: Could not read from remote repository.

# 解决方案:检查SSH密钥
# 1. 确保SSH密钥已添加到GitHub/GitLab
# 2. 测试SSH连接
ssh -T git@github.com

# 或使用HTTPS和Personal Access Token
git remote set-url origin https://github.com/user/repo.git

分支不存在

推送时分支不存在:

# 错误信息
error: src refspec main does not match any

# 解决方案:检查分支名称
git branch -a

# 如果分支不存在,先创建提交
git add .
git commit -m "Initial commit"

# 然后推送
git push -u origin main

确保本地有提交后才能推送到远程分支。

紧急情况处理

撤销错误的推送
# 1. 回退到之前的提交
git reset --hard HEAD~1

# 2. 强制推送到远程(谨慎!)
git push -f origin main

# 注意:这会重写远程历史,只应在紧急情况下使用
取消进行中的合并
# 当合并冲突太复杂时
git merge --abort

# 或取消变基操作
git rebase --abort

预防问题的最佳实践

  • 频繁提交 - 使用小的、专注的提交
  • 定期拉取 - 避免长时间偏离主分支
  • 推送前测试 - 确保代码通过所有测试
  • 使用描述性提交信息 - 清晰说明更改内容
  • 保护主分支 - 通过Pull Request合并代码
  • 代码审查 - 所有更改都应经过同行审查

团队协作提示: 建立团队的Git工作流程规范,包括分支命名、提交信息格式、代码审查流程等,可以显著减少推送和拉取时的问题。

实战示例

完整开发周期示例

1. 初始化项目
# 克隆远程仓库
git clone https://github.com/team/project.git
cd project

# 查看远程仓库配置
git remote -v

# 创建开发分支
git checkout -b feature/user-authentication
2. 日常开发流程
# 每天开始工作前
git checkout main
git pull --rebase origin main
git checkout feature/user-authentication
git rebase main

# 进行开发工作
# ... 编辑文件 ...

# 提交更改
git add .
git commit -m "实现用户登录功能"

# 定期推送进度
git push origin feature/user-authentication

团队协作场景

3. 处理团队更新
# 当团队有其他提交时
git fetch origin

# 查看远程更新
git log origin/main

# 将团队更新合并到功能分支
git merge origin/main

# 或使用变基
git rebase origin/main

# 解决可能的冲突
# ... 编辑冲突文件 ...
git add .
git rebase --continue
4. 完成功能并推送
# 完成所有开发后
git add .
git commit -m "完成用户认证功能"

# 确保与主分支同步
git fetch origin
git rebase origin/main

# 推送功能分支
git push origin feature/user-authentication

# 在GitHub/GitLab创建Pull Request
# 等待代码审查和合并

实用命令别名

设置Git别名提高工作效率:

# 添加到 ~/.gitconfig
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.pl "pull --rebase"
git config --global alias.ps push
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

# 使用别名示例
git co main # git checkout main
git st # git status
git pl origin main # git pull --rebase origin main
git ps origin main # git push origin main

自动化脚本

创建脚本简化日常操作:

每日开始工作脚本
#!/bin/bash
# daily-start.sh
echo "开始每日工作..."
git checkout main
git pull --rebase origin main
echo "主分支已更新"
git status
推送前检查脚本
#!/bin/bash
# pre-push-check.sh
echo "运行测试..."
npm test
echo "检查代码格式..."
npm run lint
echo "拉取最新更改..."
git pull --rebase origin main
echo "准备推送..."
git status

效率提示: 将常用的Git命令序列封装为脚本或别名,可以显著提高开发效率。特别是对于日常的推送拉取操作,创建自动化脚本可以减少重复劳动。