版本控制就是控制版本,版本控制系统帮助控制(管理)某个事物(通常指源代码)的不同版本 现在流行的版本控制:
版本控制系统的主要目的是帮助你保留项目的详细历史记录,并且能够在不同的版本上进行工作。保留详细的项目历史记录很重要,因为这样可以看出一段时间内项目的进度。如果需要,你还可以回到项目的某个阶段,并恢复数据或文件。
e2adf8ae3e2e4ed40add75cc44cf9d0a869afeb6
# 设置你的 Git 用户名
git config --global user.name "<Your-Full-Name>"
# 设置你的 Git 邮箱
git config --global user.email "<your-email-address>"
# 确保 Git 输出内容带有颜色标记
git config --global color.ui auto
# 对比显示原始状态
git config --global merge.conflictstyle diff3
git config --list
最后一个配置步骤是让 Git 能与你的代码编辑器结合使用。以下是三个最热门的代码编辑器。如果你使用的是其他编辑器,则在 Google 中搜索“修改 Git 默认编辑器为 X 编辑器”(将 X 替换为你的代码编辑器的名称)。 Atom Editor 设置
git config --global core.editor "atom --wait"
Sublime Text 设置
git config --global core.editor "'C:/Program Files/Sublime Text 2/sublime_text.exe' -n -w"
VSCode 设置
git config --global core.editor "code --wait"
在对 Git 仓库进行 commit 或执行任何其他操作之前,需要一个实际存在的仓库。要使用 Git 新建一个仓库,我们将使用 git init
命令。
init
子命令是"initialize"(初始化)的简称,这个命令很有用,因为它将进行所有仓库初始设置
ls
- 用来列出文件和目录mkdir
- 用来新建目录cd
- 用来更改目录rm
z- 用来删除文件和目录使用 cd 可以更改工作目录,使用 ls(单独使用)会列出工作目录下的文件。如果你忘记 shell 的当前工作目录,可以使用 pwd 命令(表示 print working directory 输出工作目录)输出该目录的名称。
运行 git init 命令会初始化 Git 跟踪所有内容会用到的所有必要文件和目录。所有这些文件都存储在叫做 .git(注意开头有个 .,表示在 Mac/Linux 上,它将是一个隐藏目录)的目录下。这个 .git 目录是一个库!Git 会将所有 commit 记录在这里,并跟踪所有内容
在 Git 上进行克隆的方法是调用我们将在终端上运行的命令 git clone
,然后传入要克隆的 Git 仓库的路径(通常是 URL)。
验证终端位置 提示:在克隆任何内容之前,确保命令行工具已定位于正确的目录下。克隆项目会新建一个目录,并将克隆的 Git 仓库放在其中。问题是无法创建嵌套的 Git 仓库。因此,确保终端的当前工作目录没有位于 Git 仓库中。如果当前工作目录没有在 shell 的提示符中显示,输入 pwd 输出工作目录。
git-status
On branch master
– 这部分告诉我们 Git 位于 master 分支上。你已在术语表中获取了对分支的介绍,那么这是"master"分支(也就是默认分支)。我们将在第 5 节课深入了解分支。Your branch is up-to-date with 'origin/master'
. – 因为我们使用 git clone 从另一台计算机上复制了此仓库,因此这部分告诉我们项目是否与所复制的仓库保持同步状态。我们不会在其他计算机上处理该项目,因此这一行可以忽略。nothing to commit, working directory clean
– 表示没有任何待定的更改。可以将这一输出结果看作“休息状态(resting state)”(这并不是官方解释,只是我喜欢这么理解!)。因为没有新的文件、没有对文件作出更改、暂存区没有任何需要 commit 的内容……没有更改或操作,因此我喜欢将其称为休息状态。 该命令将:
git log
显示有关现有提交信息
git show
显示有关给定提交的信息,需要向其提交ID,也就是SHA
显示内容:
commit 消息 - 这是 commit 消息最重要的部分…我们通常都希望看到此信息,如何使输出结果更简短呢
git log
命令有一个选项,可以用来更改仓库信息的显示方式。该选项为 --oneline:
此命令:
git log --stat
简介此命令会:
git log -p
git log
命令具有一个可用来显示对文件作出实际更改的选项。该选项是 --patch,可以简写为 -p:
显示特定 commit 的详情,而不用关心仓库中的所有其他内容 实际上有两种实现方式!
git log -p fdf5493
通过提供 SHA,git log -p 命令将从这条 commit 开始!无需滚动并逐条查阅!注意,它还会显示在所提供的 SHA 之前提交的所有 commit 信息。git show
运行上述示例命令将仅显示最近的 commit。通常,将 SHA 作为最后一个参数提供给命令:git show fdf5493
git show 命令将仅显示一个 commit。因此,如果你看不到任何其他 commit,不要惊慌。它只显示一个 commit。git show 命令的输出和 git log -p 命令的完全一样。因此默认情况下,git show 会显示:但是,git show 可以与我们了解过的大部分其他选项一起使用:
要将所有文件提交到仓库中,首先需要将这些文件从工作目录移到暂存区。我们将使用 git add 命令将这三个文件移到暂存区。
使用 git add
将index.html
添加到暂存区:
git add index.html
输出结果中现在出现了全新的区域:"Changes to be committed"区域!这一新的"Changes to be committed"区域显示了位于暂存区的文件!目前只显示了 index.html 文件,因此暂存区只有这个文件。
git rm --cached
与 shell 的rm
命令不同。git rm --cached
不会破坏任何属于你的文件,它只是从暂存区删掉了文件。
此外,帮助文本中出现了"unstage"(撤消暂存)字眼。将文件从工作目录移到暂存区叫做"staging"(暂存)。如果已移动文件,则叫做"staged"(已暂存)。从暂存区将文件移回工作目录将"unstage"(撤消暂存)。如果你阅读的文档中提示“stage the following files”,则表明你应该使用 git add 命令。
index.html 文件已暂存。我们再暂存另外两个文件。现在我们可以运行以下命令:
$ git add css/app.css js/app.js
句点 . 句点指代当前目录,可以用来表示所有文件和目录(包括所有嵌套文件和目录!)。
$ git add css/app.css js/app.js
# 等同于
$ git add .
第一段精确地告诉了我们需要执行的操作 - 我们需要为该 commit 提供一条消息。此外 ,任何以字符 # 开头的行将被忽略。在后面还提示:这将是初始 commit。最后,给出了将提交 commit 的文件列表。
因为这是存储库的第一个 commit,我们将使用 commit 消息 "Initial commit"。文本 "Initial commit" 并不特殊,只是第一个 commit 的常用消息。如果你想使用其他消息,完全可以!
关键在于使每个 commit 都有其侧重点。每个 commit 应该记录一项更改。这种说法可能比较主观(完全没问题),但是每个 commit 应该只对项目的一个方面做出更改。
此命令:
然后使用 git log
检查你刚刚提交的 commit!
git diff
命令可以用来查看已被加入但是尚未提交的更改。
如果你想将某个文件保留在项目的目录结构中,但是确保它不会意外地提交到项目中,可以使用名称特殊的文件 .gitignore(注意文件名开头的点,很重要!)。将此文件添加到 new-git-project项目根目录。你只需列出希望 git ignore(忽略,不跟踪)的文件名,git 将忽略这些文件。
note: 可以使用touch .gitigore
创建该文件
通配符允许你使用特殊的字符来表示某些格式/字符。在 .gitignore 文件中,你可以使用
运行 git tag -a v1.0 将为最近的 commit 添加标签。但是如果你想向仓库中很久之前的 Commit 添加标签呢? 只需提供要添加标签的 commit 的 SHA 即可!
$ git tag -a v1.0 a87984
git branch 命令用来与 git 的分支进行交互:
要创建分支,只需使用 git branch 并提供要创建的分支对应的名称。因此,如果你想创建一个叫做"sidebar"的分支,只需运行以下命令:
$ git branch sidebar
注意,在进行 commit 时,该 commit 将添加到当前分支上。虽然我们创建了新的 sidebar 分支,但是没有向其添加新的 commit,因为我们尚未切换到该分支。如果我们现在进行 commit 的话,该 commit 将添加到 master 分支,而不是 sidebar 分支。我们已经在演示中看到这一情况,要在分支之间进行切换,我们需要使用 git 的 checkout 命令。
$ git checkout sidebar
请务必了解该命令的工作方式。运行该命令将:
日志中的分支
提示符中的分支信息很有用,但是最清晰的查看方式是查看git log
的输出结果。就像我们需要使用 --decorate
选项来显示 git 标签一样,我们也需要该选项来显示分支。
$ git log --oneline --decorate
活跃分支
提示符将显示活跃分支。但这是我们对提示符进行的特殊自定义,如果你使用的是不同的计算机,判断活跃分支的最快速方式是查看 git branch
命令的输出结果。活跃分支名称旁边会显示一个星号
删除分支
分支用来进行开发或对项目进行修正,不会影响到项目(因为更改是在分支上进行的)。在分支上做出更改后,你可以将该分支组合到 master 分支上(这种“分支组合过程”叫做“合并”(merge),稍后将详细讲解)
合并了分支的更改后,你可能不再需要该分支了。如果你想删除分支,可以使用 -d 选项。下面的命令包含 -d 选项,告诉 git 删掉给出的分支(这里是"sidebar"分支)。
$ git branch -d sidebar
注意,无法删除当前所在的分支。因此要删除 sidebar 分支,你需要切换到 master 分支,或者创建并切换到新的分支。
删除内容让人比较紧张。但是不用担心。如果某个分支上有任何其他分支上都没有包含的 commit(也就是这个 commit 是要被删除的分支独有的),git 不会删除该分支。如果你创建了 sidebar 分支,向其添加了 commit,然后尝试使用 git branch -d sidebar 删除该分支,git 不会让你删除该分支,因为你无法删除当前所在的分支。如果你切换到 master 分支并尝试删除 sidebar 分支,git 也不会让你删除,因为 sidebar 分支上的新 commit 会丢失!要强制删除,你需要使用大写的 D 选项 - git branch -D sidebar。
$ git log --oneline --decorate --graph --all
--graph 选项将条目和行添加到输出的最左侧。显示了实际的分支。--all 选项会显示仓库中的所有分支。
当你在主题分支上做出更改后,如果觉得不想要该分支上的更改,则可以删掉该分支,或者你决定要保留更改,则可以将该分支上的更改与其他分支上的更改合并。
将分支组合到一起称为合并 注意 git 中的两种合并:普通合并和快进合并。
但是如果你在错误的分支上进行了合并,可以使用以下命令撤消合并:
git reset --hard HEAD^
在我们的项目中,我们检出了 master 分支,我希望它拥有 footer 分支上的更改。用语言描述的话就是“我想要合并 footer 分支。”。注意表述“合并…”;在进行合并时,另一个分支上的更改将出现在当前检出的分支上。
我再强调下,当我们合并时,我们将其他分支合并到当前(检出的)分支上。我们不是将两个分支合并到一个新的分支上。也不是将当前分支合并到其他分支上。
因为 footer 直接在 master 前面,因此这种合并最简单。将 footer 合并到 master 中将导致快进合并(Fast-forward merge)。快进合并将使当前检出的分支向前移动,直到它指向与另一个分支(这里是 footer)指向的 commit 一样为止。
要合并 footer 分支,运行:
$ git merge footer
现在我们将进行更常见的合并,其中两个分支完全不一样。你会惊讶地发现,实际合并 sidebar 这样的独特分支,操作是完全一样的!
要合并 sidebar 分支,确保你位于 master 分支上,并运行:
$ git merge sidebar
因为合并的是两个完全不一样的分支,因此将提交 commit。在进行 commit 时,需要提供 commit 消息。因为这是合并 commit,因此已经提供了默认消息。你也可以更改消息,但通常都会直接使用默认的合并 commit 消息。因此当你的代码编辑器打开并包含该消息时,直接关闭编辑器以确认使用该 commit 消息。
合并冲突指示符解释 编辑器具有以下合并冲突指示符:
解决合并冲突 git 使用合并冲突指示符来告诉你两个不同分支上的哪些行导致了合并冲突,以及原始行是什么。要解决合并冲突,你需要:
借助 --amend 选项,你可以更改最近的 commit。
$ git commit --amend
当你告诉 git 还原(revert) 具体的 commit 时,git 会执行和 commit 中的更改完全相反的更改。我们详细讲解下。假设 commit A 添加了一个字符,如果 git 还原 commit A,那么 git 将创建一个新的 commit,并删掉该字符。如果删掉了一个字符,那么还原该 commit 将把该内容添加回来! 现在我创建了一个包含一些更改的 commit,我可以使用 git revert 命令还原它
$ git revert <SHA-of-commit-to-revert>
因为最近的 commit 的 SHA 是 db7e87a,要还原该 commit: 我需要运行 git revert db7e87a
(随即弹出代码编辑器,以便编辑/确认提供的 commit 消息)
初看,重置(reset) 似乎和 还原(revert) 相似,但它们实际上差别很大。还原会创建一个新的 commit,并还原或撤消之前的 commit。但是重置会清除 commit!
git reset 命令用来重置(清除)commit:
可以用来: