Skip to main content

Git 远程仓库:协作与备份

到目前为止,我们所有的操作(提交、创建分支、合并)都发生在你的本地仓库(你电脑上的 .git 目录)中。为了与他人协作开发项目,或者仅仅是为了在另一台服务器上备份你的工作,你需要与远程仓库 (Remote Repositories) 进行交互。 远程仓库是托管在网络服务器上的项目仓库副本。常见的托管平台有 GitHub, GitLab, Gitee (码云), Bitbucket 等,你也可以自己搭建 Git 服务器。

理解远程仓库与别名 (origin)

当你克隆一个仓库时 (git clone),Git 会自动为你添加一个指向你克隆来源的远程仓库的引用。默认情况下,Git 会给这个远程仓库起一个别名 (shortname),叫做 origin
  • origin 只是一个约定俗成的默认别名,它本身没有任何特殊含义。你可以添加多个远程仓库,并为它们取不同的别名(例如 upstream, backup)。
  • 这个别名让你在与远程仓库交互时,不必每次都输入完整的 URL。

查看已配置的远程仓库 (git remote)

  • 列出远程仓库别名:
    git remote
    
    输出通常会是 origin (如果你是克隆的仓库)。
  • 显示别名及其对应的 URL:
    git remote -v
    
    你会看到每个别名对应的 fetch (拉取) 和 push (推送) 的 URL。通常它们是相同的。

添加新的远程仓库 (git remote add)

如果你是使用 git init 在本地创建的仓库,或者想关联到另一个远程仓库(例如,添加一个指向原始项目(上游)的链接),可以使用 git remote add 命令:
# 语法: git remote add <别名> <仓库URL>
git remote add upstream https://github.com/original-author/project.git
现在你就有了一个名为 upstream 的远程仓库引用。你可以使用 git remote -v 来验证。

理解远程跟踪分支 (origin/main)

与远程仓库交互的核心在于理解远程跟踪分支 (Remote-Tracking Branches)
  • 当你执行 git fetchgit clone 时,Git 会在你的本地仓库中创建并更新一些特殊的只读指针,例如 origin/main, origin/develop, upstream/main 等。
  • 这些分支不是你本地的工作分支 (main, develop),而是代表了远程仓库上对应分支在你上次与服务器通信时的状态
  • 它们让你可以在本地查看远程仓库的进展,而无需直接连接网络。git fetch 的主要作用就是更新这些远程跟踪分支。
Git 远程跟踪分支 本地仓库包含本地分支和远程跟踪分支,后者反映了远程仓库的状态

从远程仓库获取更新

有两种主要方式将远程仓库的更新同步到你的本地仓库:fetchpull

1. 获取但不合并 (git fetch)

git fetch <远程别名> 命令会连接到指定的远程仓库,下载你本地尚未拥有的所有提交和对象,并更新对应的远程跟踪分支 (例如 origin/main)。
# 获取 origin 仓库的所有更新,并更新本地的 origin/* 分支
git fetch origin
关键点:
  • git fetch 不会修改你本地的工作分支(如 main)。
  • 不会自动合并任何代码到你的工作目录。
  • 它是一种安全的操作,让你先查看远程的更改 (git log origin/main, git diff main origin/main),然后再决定如何整合。
Git fetch 操作 fetch 操作更新本地的远程跟踪分支,但不会修改本地工作分支 何时使用 fetch? 当你想要查看远程仓库的最新进展,但暂时不想将其合并到你的本地工作分支时。

2. 获取并尝试合并 (git pull)

git pull <远程别名> <远程分支名> 命令本质上是 git fetchgit merge 两个命令的组合。
# 拉取 origin 仓库的 main 分支,并尝试将其合并到当前所在的本地分支
git pull origin main
工作流程:
  1. Git 执行 git fetch origin,下载更新并移动 origin/main 指针。
  2. Git 尝试将 origin/main 指向的提交合并 (merge) 到你当前签出 (checkout) 的本地分支。
简化用法: 如果你的当前本地分支设置了跟踪 (track) 一个远程分支(克隆时通常会自动设置 main 跟踪 origin/main),你可以直接运行:
git pull
这会自动拉取并合并当前分支所跟踪的上游分支。 Git pull 操作 pull 操作先执行 fetch 更新远程跟踪分支,然后将其合并到本地工作分支 注意:
  • 如果本地有未提交的修改与将要合并的远程修改冲突,pull 可能会失败。
  • 如果本地分支和远程分支的历史产生了分叉(即在你上次 pull 之后,本地和远程都有了新的提交),pull 会执行一次合并操作,并可能产生合并冲突,需要你手动解决。
pullrebase: 有时开发者更喜欢使用 rebase 而不是 merge 来整合远程更改,以保持线性的提交历史。可以通过 git pull --rebase 实现。这会先 fetch,然后将你本地尚未推送到远程的提交“变基”到最新的远程分支之上。

推送本地更改到远程仓库 (git push)

当你想要将本地仓库中的提交分享给他人(即上传到远程仓库)时,使用 git push 命令。
# 语法: git push <远程别名> <本地分支名>:<远程分支名>
# 将本地 main 分支推送到 origin 远程仓库的 main 分支
git push origin main:main
简化用法:
  • 如果本地分支名和远程分支名相同,可以省略冒号和远程分支名:
    git push origin main
    
  • 如果当前本地分支设置了跟踪 (upstream) 远程分支,可以进一步简化:
    git push
    
推送新创建的本地分支: 当你第一次推送一个本地新创建的分支(例如 feature-login)到远程仓库时,需要明确指定远程仓库和分支名,并使用 -u (或 --set-upstream) 选项来建立跟踪关系:
# 推送本地 feature-login 分支到 origin,并在 origin 上创建同名分支,同时设置跟踪关系
git push -u origin feature-login
设置跟踪关系后,未来在该分支上就可以直接使用 git pushgit pull 了。 Git push 操作 push 操作将本地分支的新提交发送到远程仓库,与 pull 操作方向相反 处理推送被拒绝 (Rejected Push): 如果你尝试推送时,远程仓库在你上次拉取之后已经有了新的提交(即远程分支比你的本地副本更新),Git 会拒绝你的推送,以防止覆盖他人的工作。 标准解决流程:
  1. 获取远程最新更改: git fetch origin
  2. 整合远程更改:
    • git merge origin/<你的分支名> (合并远程更改到本地)
    • 或者 git rebase origin/<你的分支名> (将本地提交变基到远程更改之上)
  3. 解决冲突: 如果合并或变基过程中出现冲突,手动解决它们,然后 git add 并完成 commitrebase --continue
  4. 再次推送: git push origin <你的分支名>

查看远程仓库详细信息 (git remote show)

要查看某个远程仓库(如 origin)的更详细信息,包括它的 URL、跟踪的远程分支以及本地分支与远程分支的对应关系:
git remote show origin

重命名和移除远程仓库

  • 重命名远程仓库别名:
    # 将 origin 重命名为 github
    git remote rename origin github
    
  • 移除远程仓库引用:
    # 移除名为 upstream 的远程仓库引用
    git remote remove upstream
    # 或者 git remote rm upstream
    
    这只会移除本地仓库对远程仓库的引用和相关的远程跟踪分支,并不会影响远程仓库本身。

掌握与远程仓库的交互是使用 Git 进行团队协作、代码分享和备份的基础。理解 fetch, pull, push 以及远程跟踪分支的概念至关重要。