为什么要学习Git
协同工作:业界绝大多数公司都是基于Git进行代码管理,因此git是一个程序员的必备技能
开源社区:目前绝大多数的开源项目都是基于Git维护的,参与这些项目的开发都需要使用Git
Git是什么
Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency
Git是一个免费开源的分布式版本控制系统,旨在快速高效地处理从小型到大型项目的所有内容(百度翻译)
版本控制是什么?
一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统
为什么需要版本控制?
更好的关注变更,了解到每个版本的改动是什么,方便对改动的代码进行检查,预防事故发生:也能够随时切换到不同的版本,回滚误删误改的问题代码
Git基本使用方式
Git基本命令
git init: 在当前目录初始化一个新的Git仓库。git clone[repository]: 克隆一个远程仓库到本地。git add [file]: 将文件添加到暂存区,准备提交。git commit -m "message": 提交暂存区的文件变更到本地仓库,并添加提交信息。git push: 将本地仓库的修改推送到远程仓库。git pull: 从远程仓库拉取最新的修改到本地仓库。git branch: 显示所有的分支。git checkout [branch]: 切换到指定的分支。git merge [branch]: 合并指定的分支到当前分支。git status: 显示当前仓库的状态,包括已修改、已暂存和未跟踪的文件。git log: 显示提交历史记录。git diff: 显示工作区和暂存区之间的差异。git remote add [name] [url]: 添加一个远程仓库。git remote -v: 显示远程仓库的详细信息。git rm [file]: 从版本控制中删除文件。git config:用于配置 Git 环境的命令,可以设置和查询 Git 的各种配置选项,包括用户名、邮箱、编辑器、远程仓库等。
常见Git配置
设置全局用户信息
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
这样设置后,你在提交代码时就会被标记为相应的用户名和邮箱。
查询已设置的用户信息:
git config --global user.name
git config --global user.email
设置当前仓库的用户信息:
如果你想为当前仓库设置特定的用户名和邮箱,可以在不加 --global 参数的情况下运行 git config 命令,并在仓库目录中运行该命令。
添加远程仓库:
git remote add <name> <url>
这个命令会将远程仓库的地址和一个别名
<name> 关联起来,方便后续使用。
HTTP Remote 免密配置
使用以下命令启用 Git 凭据存储功能:
git config --global credential.helper store
这将配置 Git 使用一个基于文件的凭据存储来保存用户名和密码。
执行第一次推送或拉取操作时,Git 会提示输入用户名和密码,并将其保存在凭据存储中。例如,执行一次推送操作:
git push origin master
此时,Git 会提示输入用户名和密码,并将其保存到凭据存储中。
之后,再次进行推送或拉取操作时,Git 将自动使用之前保存的凭据,无需再次输入用户名和密码。
SSH Remote 免密配置
生成 SSH 密钥对:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
这将生成一个 RSA 类型的 SSH 密钥对,并要求你提供一个电子邮件地址。通常你可以留空或提供你的个人或工作邮箱。
在你的远程仓库托管服务商(如 GitHub、GitLab 等)的帐户设置中,添加你的公钥。
复制公钥内容:
cat ~/.ssh/id_rsa.pub
将复制的内容粘贴到远程仓库托管服务商提供的相关界面中的 SSH 密钥设置中。
验证 SSH 密钥是否设置成功:
ssh -T git@github.com
这将测试与远程仓库的 SSH 连接并验证身份。如果一切正常,你将收到一条欢迎信息。
Objects
"Objects"(对象)是指存储在 Git 数据库中的核心数据单元。它们是构成 Git 版本控制系统的基础。
Git 中的 Objects 由以下三种类型组成:
- Blob(文件对象):Blob 对象代表一个文件的内容。它存储着文件的数据,并使用 SHA-1 哈希作为其唯一标识符。每次文件的内容发生变化时,都会创建一个新的 Blob 对象。
- Tree(目录对象):Tree 对象代表一个目录(或文件夹)。它存储了目录结构以及每个文件或子目录所对应的 Blob 或 Tree 对象的引用。通过递归地组织 Tree 对象,可以表示整个项目的目录结构。
- Commit(提交对象):Commit 对象代表一个代码提交点。它包含了与提交相关的元数据,如作者、时间戳、提交信息等,以及一个指向表示项目状态的 Tree 对象的引用。通过连接一系列 Commit 对象,可以形成项目的版本历史。
这些 Objects 将以压缩形式存储在 Git 数据库(.git 目录)中。Git 使用一种称为「内容寻址」的机制,根据对象的内容计算出 SHA-1 哈希值,并将哈希值作为对象的唯一标识符。这样,在 Git 中可以根据哈希值来获取特定的对象。
Objects 扮演了 Git 版本控制系统的基础角色,通过管理文件内容、目录结构和版本历史信息,使得 Git 能够高效地跟踪和管理项目的变化。
Refs
"Refs"(引用)是指用于标识和引用特定 Git 对象的指针。它们通常用于表示分支、标签、远程跟踪分支等。
Refs 可以理解为指向 Commit 对象的具名指针,它们提供了一种便捷的方式来引用和操作 Git 数据库中的对象。每当进行提交、创建分支或打标签等操作时,Refs 会被更新以反映最新的对象状态。
在 Git 中,有几种常见的 Refs 类型:
- Branches(分支):分支是指向某个 Commit 对象的 Refs,它代表了项目的一个开发线路。当创建新的分支时,实际上是创建了一个指向当前提交的新的 Refs。
- Tags(标签):标签是指向某个 Commit 对象的具名引用,用于标记项目中的重要版本或里程碑。与分支不同,标签是静态的,一旦创建就不会自动移动。
- HEAD:HEAD 是一个特殊的 Refs,它代表了当前工作树所关联的分支或提交。通过 HEAD,Git 可以确定当前工作树的状态和所处位置。
- Remote Tracking Branches(远程跟踪分支):远程跟踪分支是指向远程仓库分支的本地 Refs。它们用于记录远程仓库的状态和更新,并在本地进行相应的同步操作。
Refs 存储在 Git 数据库的 refs 目录下,按照一定的命名规则组织。例如,分支的 Refs 保存在 refs/heads/ 目录下,标签的 Refs 保存在 refs/tags/ 目录下。
通过操作 Refs,我们可以在项目中切换分支、查看历史版本、创建标签等。Git 提供了一系列的命令和 API 来管理和操作 Refs。
Annotation Tag
"Annotation Tag"(注解标签)是一种特殊类型的标签,用于为特定的 Commit 对象添加更详细的注释和信息。
Annotation Tag 可以被视为一个指向特定 Commit 对象的引用,同时它还附带了一些额外的元数据,如标签作者、标签日期、注释等。与 Lightweight Tag(轻量标签)相比,Annotation Tag 提供了更多的信息。
使用 Annotation Tag 可以为项目中的重要版本或里程碑添加注释或说明,以便更好地理解和追溯代码的历史。这些注释可以包括版本号、变更内容、重要修复等。
在 Git 中,创建 Annotation Tag 的命令是 git tag -a,其中 -a 选项表示创建一个带注解的标签。创建 Annotation Tag 时,Git 会弹出一个文本编辑器,供你输入标签的注释信息。
示例命令:
git tag -a v1.0 -m "Release version 1.0"
上述命令将创建一个名为 "v1.0" 的 Annotation Tag,注释为 "Release version 1.0"。
通过使用 git show 命令,可以查看 Annotation Tag 的详细信息和对应的 Commit。
示例命令:
git show v1.0
Annotation Tags 默认会被推送到远程仓库,以便与团队成员共享和参考。
使用 Annotation Tag 可以更好地组织和注释项目的版本历史,方便开发者之间的交流和代码的追溯。
Git Clone&Pull&&Fetch
git clone:该命令用于将远程仓库完整地复制(克隆)到本地,创建一个与远程仓库相同的副本。语法如下:
git clone <远程仓库地址>
克隆操作会将整个远程仓库的历史记录、分支以及所有文件和目录复制到本地,并自动创建一个与远程仓库相同名称的文件夹用于存储代码。
git pull:该命令用于从远程仓库拉取最新的代码并合并到当前分支中。语法如下:
git pull <远程主机名> <远程分支名>
拉取操作会自动下载远程仓库的最新代码,并尝试将其合并到当前分支。通常情况下,git pull 等效于运行 git fetch 后紧接着运行 git merge。
git fetch:该命令用于从远程仓库获取最新的代码,但不自动合并到当前分支。语法如下:
git fetch <远程主机名>
获取操作会将远程仓库的最新代码下载到本地仓库,但不会自动合并到当前分支。这样可以让你在查看远程代码变更后,决定如何处理和合并。
在运行 git fetch 后,如果需要将远程代码合并到当前分支,可以使用 git merge 或 git rebase 命令手动完成合并操作。
Git Push
git push 是 Git 的一个命令,用于将本地代码推送(上传)到远程仓库。
语法如下:
git push <远程主机名> <本地分支名>:<远程分支名>
解释说明:
<远程主机名>:指定要推送到的远程仓库,通常是一个 URL 或者远程仓库的别名。
<本地分支名>:指定要推送的本地分支。
<远程分支名>:指定远程仓库中接收推送的分支名。
在执行 git push 命令时,根据指定的远程主机、本地分支和远程分支,Git 会将指定的本地分支上的提交推送到对应的远程分支上。如果远程分支不存在,则会自动创建该分支。
示例:
git push origin master:main
上述命令将本地 master 分支的提交推送到名为 origin 的远程仓库的 main 分支。
需要注意的是,如果你在推送之前没有先拉取远程仓库的最新代码,可能会导致推送失败。这是因为其他人可能已经对远程分支进行了修改。在这种情况下,你可以先运行 git pull 命令来获取最新的远程代码,并解决任何冲突,然后再运行 git push 命令进行推送。
另外,还可以使用一些参数来进一步控制 git push 命令的行为,如 --force 参数用于强制推送,--tags 参数用于推送标签等。