Git
git 是一个分布式版本控制软件,其作者是 Linus,没错就是那个 Linux 的 Linus。
git 最初是为开发 Linux 内核时的版本管理而设计的,用以取代其他的闭源方案。如今,成熟的 IDE 如 VSCode 和 JetBrains IDEs 均已经内建对 git 的支持,这使得我们无需记住所有繁琐的 git 命令,也能熟练地使用 git 进行项目的版本控制。
git 基本工作流程
首先,git 是用于项目管理的版本控制软件,因此你需要在一个项目中使用 git。
创建仓库
你可以将你已有的本地项目使用 git 管理,只需要在项目根目录下建立 git 仓库。
git init或者,也可以从在线仓库克隆,这会在你的本地创建一个与在线仓库一模一样的仓库,包括仓库的完整历史记录。
git clone <url> [path][path] 是可选的,如果不提供的话则会克隆到当前目录下。例如,若仓库的名称为 Code,运行 git clone <url> 会将仓库克隆到当前目录下的 Code 子目录中;运行 git clone <url> path/to/Code 则会将仓库克隆到 path/to/Code 中。
分支
一个 git 仓库可以有多个分支(branch)。
在最佳实践中,我们建议每个仓库都至少保有两个分支:主分支往往名为 main 或 master,另外设置一个开发分支 dev。每一条分支都是仓库的一个副本,包含仓库内的所有文件。
你可以使用 checkout 命令切换当前分支,此命令又名「签出」。在 git 2.23 版本及以后,可以使用新的 switch 命令切换分支。
这样表述可能又抽象了,举例说明:
你手中的项目是一个软件的源代码仓库,拥有 main 和 dev 两个分支,其中 main 是已发布的正式版本的代码,而 dev 是正在开发新功能的代码。
如果需要构建该软件的稳定版本,那么你需要在 main 分支下执行构建,由于此时仓库中的所有代码都是正式版本的代码,因此你将构建出该软件的正式版本。
如果需要构建最新的开发版本(尝鲜嘛),那么你需要在 dev 分支下执行构建,此时构建得到的软件会包含 dev 中正在开发的新功能。
对于开发软件的人来说同理。新的代码永远被首先写在 dev 分支中,在完成新版本的所有功能开发之后,将 dev 分支合并到 main 分支,让 main 成为新的正式版本,然后 dev 可以继续用于开发下一个版本。
分支功能是 git 与众不同的特色功能,其强大在仓库中的每一个分支都可以进行修改。还是以刚才的例子为例,如果 dev 分支的新版本正开发到一半时,软件 main 分支上的最新正式版代码被发现了严重漏洞,必须立刻进行修复的话……
可以在 dev 分支内进行修复,但是由于新版本只开发到一半,不可能把半成品合并到 main 分支内让所有用户都用只开发到一半的软件吧?所以需要在 main 分支内直接进行漏洞修复,然后就地发布新版本。
此时,main 分支与 dev 分支之间就出现了分叉,日后当 dev 的新版本终于开发完毕时,再将 dev 合并到 main 的时候就可能会出现冲突。git 会自动解决可以解决的部分冲突,剩余的需要你来进行定夺。
可以使用以下命令切换分支,两种命令效果是等价的:
# 切换到 main 分支
git checkout main
git switch main
# 切换到 dev 分支
git checkout dev
git switch main可以使用如下命令创建新分支,新分支的状态完全基于当前分支。
git checkout -b new_branch_name
git switch -c new_branch_name可以使用如下命令查看当前仓库的所有分支。加 * 符号的是当前分支。
git branch提交
git 会管理仓库中所有已添加的文件的历史记录,这是基于被称为「提交」(commit)的操作进行的。
提交是由你(程序员)执行的操作,意味着你完成了对代码的修改,并将这些修改提交给当前分支。提交时可以附带一些消息(Message),这些消息会在仓库的 commit 历史中被记录,并显示。
在此之前,我们需要先了解如何让 git 管理我们的代码文件。刚创建的新仓库是空白仓库,其中没有任何文件,你需要首先告诉 git 哪些文件需由仓库管理,告诉的方式就是:
git add .此命令会将目录下的所有文件都添加(add)到 git 的暂存区中。暂存区是一个由 git 管理的中间状态,在暂存区中的文件会被提交到分支中。git 会追踪暂存区中的所有文件的变化,包括你在他们中增加、删除、编辑代码。git 也会尝试追踪文件名的变化,例如文件的重命名和移动。
如果不想添加所有文件,可以:
# 添加名为 filename 的文件
git add filename
# 添加所有后缀为 .js 的文件
git add *.js将一个文件添加到暂存区之后,你仍然可以继续编辑这个文件,无需在编辑之后再重复添加。换言之,将文件添加到暂存区之后,git 就已经开始矜矜业业地追踪其变化了,无需你再操心。
然后,只要在编辑告一段落之后运行提交命令,这会将暂存区中的所有文件都提交到当前分支。提交之后,当前分支会被更新,你可以在分支的历史记录中找到这次提交。
# 提交暂存区中的所有文件
git commit
# 建议附带提交消息
git commit -m "commit_message"你不应该在暂存区存在内容时签出分支,这会导致暂存区被重置,同时可能引发奇怪的冲突。
如果添加错文件了,可以一键重置,或者从中移除指定的文件。
# 重置暂存区。HEAD 指代的是仓库的当前分支,此命令即将暂存区重置为当前分支
git reset HEAD
# 或者从暂存区中移除文件 filename
git rm --cache filename推送与拉取
以上操作都发生在我们的本地,而 git 仓库中可以存在本地分支和远程分支。本地分支位于我们本地,而远程分支则位于服务器。
如果你的仓库是使用 git clone <url> 克隆到本地的,那么远程分支已经存在于仓库中。
如果你的仓库是使用 git init 创建的,那么需要使用 git remote 命令来设置远程仓库。
git remote add <remote_name> <remote_url>一般而言,remote_name 被设置为 origin,便于记忆。一般来说,远程仓库和本地仓库的分支情况是完全一致的,省事。
然后,可以使用 git pull 和 git push 来拉取、推送更新。
# 从远程仓库获取 [branch_name] 的更新
git pull origin [branch_name]
# 如果不提供 [branch_name] 则获取所有分支的更新
git pull origin
# 将本地仓库 branch_name 分支的更新推送到远程仓库的 branch_name 分支。
git push origin <branch_name>在 IDE 中使用 git
IDE 为 git 设计简明易懂的可视化支持,因此一般来说无需清除地记住所有的命令。
JetBrains IDEs
JetBrains 的 IDE 均已经内置了对 git 的支持。
MangoFanFan_