Git 核心概念与操作

112 阅读9分钟

Git 是一个分布式版本控制系统,在分布式版本控制系统中,每个开发者都拥有项目代码仓库的完整副本,包括全部的提交历史。这意味着每个人的电脑上都有一个功能齐全的版本库。

一、 Git 基础与本地仓库管理 (git-log 及代码备份)

  • git log:

    • 用途: 查看提交历史。默认情况下,它会显示当前分支的提交记录,包括提交的(版本号)、作者、日期和提交信息。

    • 常用选项:

      • --oneline: 以简洁的一行显示提交信息。
      • --graph: 以图形化的方式显示分支合并历史。
      • --all: 显示所有分支的提交历史。
      • --decorate: 显示分支名和标签名。
      • [分支名]: 查看特定分支的提交历史。
      • -p <文件名>: 查看特定文件的修改历史。
  • 1. 代码备份与版本控制流程

    • 工作区 (Working Directory) : 你在电脑上实际看到的项目文件夹,包含了项目的当前文件。

    • 暂存区 (Staging Area / Index) : 暂存区的信息通常存储在 Git 仓库目录(即项目根目录下的 .git 文件夹)中的一个名为 index 的文件里 (.git/index)。 这个文件是一个二进制文件,它跟踪了工作区中文件的状态,以及哪些文件被标记为下次提交。

    • 本地仓库 (Local Repository) : 存储项目所有版本历史的地方,本地仓库的核心数据都存储在项目根目录下的一个名为 .git 的隐藏文件夹中。当你执行 git init 时,会在项目根目录下创建一个名为 .git 的隐藏文件夹,这个 .git 文件夹就是你的本地仓库。项目工作目录则是除了 .git 文件夹之外的其他所有文件。

    • 主要命令流程:

      1. git add <文件名>git add . : 将工作区的修改添加到暂存区。

        • <文件名>: 指定要添加到暂存区的具体文件。
        • .: 将当前目录下所有已修改或新增的文件(不包括被 .gitignore 忽略的文件)添加到暂存区。
      2. git commit -m "提交信息" : 将暂存区的内容提交到本地仓库,形成一个新的版本。

        • -m "提交信息": 附带一条简短的提交说明,描述本次提交的内容。
    • 回退到之前的版本:

      • git reset --hard <版本号> :

        • <版本号> : 可以在 git log 中查看。
        • --hard: 这个选项会重置工作区、暂存区和 HEAD(当前分支的最新提交)到指定的版本。注意:未提交的本地修改会丢失,请谨慎使用。
        • 其他选项如 --soft(只移动 HEAD,保留暂存区和工作区)和 --mixed(默认,移动 HEAD 并重置暂存区,保留工作区)也有不同用途。
    • 忽略不需要 Git 管理的文件:

      • .gitignore 文件: 这是一个纯文本文件,列出了项目中不需要被 Git跟踪的文件或文件夹模式(例如,编译产生的文件、日志文件、临时文件、敏感信息文件等)。每一行指定一个忽略规则。

二、 分支管理与协同开发

分支是 Git 的核心特性之一,允许多人并行开发不同的功能或修复,而不会互相干扰。

  • 查看有哪些分支:

    • git branch: 列出本地仓库中的所有分支,当前所在的分支会用 * 标记。
    • git branch -r: 列出所有远程跟踪分支。
    • git branch -a: 列出所有本地分支和远程跟踪分支。
  • 创建新的分支:

    • git branch <分支名> : 创建一个新的分支,但不会自动切换到该分支。
  • 切换到某个分支:

    • git checkout <分支名> : 切换到已存在的分支。工作区的文件会更新为该分支最新的内容。
    • git switch <分支名> (较新的 Git 版本推荐): 功能与 git checkout <分支名> 类似,专门用于分支切换。
    • git checkout -b <新分支名>git switch -c <新分支名> : 创建并立即切换到新的分支。
  • 合并分支:

    • git merge <要合并过来的分支名> : 将指定分支的更改合并到当前所在的分支。

      • 通常操作: 先切换到主分支(如 mastermain),然后执行 git merge <特性分支名> 来将特性分支的成果合并到主分支。
  • 删除分支:

    • git branch -d <分支名> : 删除已经合并到其他分支的分支。如果分支包含未合并的更改,Git 会提示错误。
    • git branch -D <分支名> : 强制删除分支,即使它包含未合并的更改(请谨慎使用)。
  • 解决冲突 (Conflict Resolution) :

    • 发生时机: 当合并分支时,如果两个分支都修改了同一个文件的同一部分,Git 无法自动决定使用哪个版本,就会产生合并冲突。

    • 解决步骤:

      1. Git 会在冲突文件中用特殊标记(如 <<<<<<<, =======, >>>>>>>)标出冲突的部分。
      2. 手动解决: 打开冲突文件,仔细阅读冲突内容,手动编辑文件,保留你想要的内容,并删除 Git 添加的冲突标记。
      3. git add <已解决冲突的文件名> : 将解决后的文件标记为已解决。
      4. git commit: (此时通常不需要 -m,Git 会提供一个默认的合并提交信息,你可以修改它)完成合并提交。
  • 常见分支策略:

    • master / main 分支: 通常用于存放稳定、可发布的版本。直接在此分支上开发是不推荐的。
    • develop 分支: 作为主要的开发分支,所有新的功能开发和 Bug 修复都从这个分支开始,并最终合并回这个分支。当 develop 分支达到一个稳定状态并准备发布时,再将其合并到 master / main 分支。
    • 特性分支 (Feature branches) : 例如 feature/user-authenticationfix/login-bug。每个程序员在开发新功能或修复特定问题时,会从 develop 分支创建自己的特性分支。完成后,再将特性分支合并回 develop 分支。

三、 远程仓库 (Remote Repositories)

远程仓库托管在网络服务器上,允许多人共享和协作代码。

  • 常见的远程仓库托管服务:

    • GitHub: 全球最大的代码托管平台,非常适合开源项目和个人项目。
    • Gitee (码云) : 中国领先的代码托管平台,对国内用户访问速度友好。
    • GitLab: 可以自建服务器,也提供托管服务,很多企业内部使用。
  • 获取 SSH 公钥:

    • ssh-keygen -t rsa -C "your_email@example.com" : 生成 SSH 密钥对(公钥和私钥)。

      • -t rsa: 指定加密算法为 RSA。
      • -C "your_email@example.com": 添加一个注释,通常是你的邮箱地址。
    • 生成的公钥文件(通常是 ~/.ssh/id_rsa.pub)的内容需要添加到远程仓库托管服务(如 GitHub、Gitee)的账户设置中,以便通过 SSH 协议安全地与远程仓库通信。

  • 将本地仓库推送到远程仓库:

    • 添加/链接远程仓库:

      • git remote add <远程仓库别名> <远程仓库地址> : 将本地仓库与一个远程仓库关联起来。

        • <远程仓库别名> : 通常使用 origin 作为默认的远程仓库别名。
        • <远程仓库地址> : 例如 git@github.com:username/repository.git (SSH) 或 https://github.com/username/repository.git (HTTPS)。
    • 推送到远程仓库:

      • git push <远程仓库别名> <本地分支名>:<远程分支名> : 将本地分支的提交推送到远程仓库的指定分支。

        • 例如: git push origin master:master (将本地 master 分支推送到远程 originmaster 分支)。
        • 如果本地分支名和远程分支名相同,可以简写为: git push origin master
      • git push --set-upstream <远程仓库别名> <本地分支名>:<远程分支名> (或简写 git push -u origin master):

        • 首次推送一个新创建的本地分支时使用。

        • 作用:

          1. 将本地分支的提交推送到远程仓库。
          2. 在本地分支和远程分支之间建立跟踪关系 (tracking relationship)。
        • 建立跟踪关系后,后续在该本地分支上执行 git push (不带参数) 就会默认推送到关联的远程分支,执行 git pull (不带参数) 就会默认从关联的远程分支拉取更新。

  • 从远程仓库拉取到本地仓库:

    • 克隆远程仓库 (Clone) :

      • git clone <远程仓库地址> : 将整个远程仓库复制到本地。这个操作只需要在一个新项目开始时执行一次。它会自动设置 origin 为远程仓库的别名,并自动检出默认分支(通常是 mastermain)。
    • 抓取远程仓库的更新 (Fetch) :

      • git fetch <远程仓库别名> <远程分支名> : 从远程仓库下载最新的提交历史和对象,但不会自动合并到你当前的本地分支。

        • 例如: git fetch origin master (抓取远程 originmaster 分支的最新更新)。
        • 抓取后,你可以使用 git log origin/master 查看远程分支的更新,然后决定是否以及如何合并 (例如使用 git merge origin/master)。
    • 拉取远程仓库的更新并合并 (Pull) :

      • git pull <远程仓库别名> <远程分支名> : 从远程仓库下载最新的提交历史并自动尝试将其合并到你当前的本地分支。

        • 例如: git pull origin master (拉取远程 originmaster 分支的更新并合并到当前本地分支)。
        • git pull 实际上是 git fetchgit merge 两个命令的组合。如果本地有未提交的修改,或者自动合并产生冲突,git pull 可能会失败或需要你解决冲突。

四、 重要注意事项

  • !!!切换分支前,务必将当前分支的修改提交 (commit) 或储藏 (stash)!!!

    • 原因: 如果在工作区有未提交的修改时切换分支,这些修改可能会被带到新的分支,或者与新分支的内容产生冲突,甚至可能丢失。
    • git stash: 可以临时保存当前工作区的修改(不包括新增的未被追踪的文件,除非使用 git stash -u),并将工作区恢复到上次提交的状态。之后可以切换到其他分支,完成工作后,再切换回来使用 git stash popgit stash apply 恢复之前保存的修改。