Skip to main content

Git

Git Cheat Sheet.

术语表
  • Git: 一个开源的分布式版本控制系统,Git 是一个开源项目,用于以文本文件跟踪更改。它由 Linux 操作系统的作者编写。
  • GitHub: 一个托管和协作管理 Git 仓库的平台。
  • HEAD: 代表你当前的工作目录。使用 checkout 可移动 HEAD 指针到不同的分支、标记 (tags) 或提交。
  • detached HEAD 游离 HEAD:如果您操作的是游离的 HEAD,Git 将会警告您,这意味着 Git 不指向某个分支,并且您的任何提交都不会出现在提交历史记录中。例如,在检出并非任何特定分支最新提交的任意提交时,您操作的是"游离的 HEAD"。
  • stash 储藏:工作时需要切换其他分支修改 bug 但当前分支任务还未完成不能 commit(log 上会有大量不必要的记录),这样可以使用 git stash,将工作区内所有未提交的修改(包括暂存的和非暂存的)都保存起来形成新的本地储藏推入到 Git 的栈中,用于后续恢复。
  • commit 提交: 一个 Git 对象,是仓库快照的哈希值,包含一个指向暂存内容快照的指针,包含本次提交的作者等相关附属信息,包含零个或多个指向该提交对象的父对象指针:首次提交是没有直接祖先的,普通提交有一个祖先,由两个或多个分支合并产生的提交则有多个祖先。提交或"修订"是对一个文件(或一组文件)的个别更改。在进行提交以保存工作时,Git 会创建唯一的 ID(也称为 "SHA" 或"哈希"),用于记录提交的特定更改以及提交者和提交时间。提交通常包含一条提交消息,其中简要说明所做的更改。
  • SHA 提交 ID:用于识别提交的 40 字符校验和哈希。
  • branch 分支: 一个轻型可移动的 commit 指针,一个包含所指对象校验和(40 个字符长度 SHA-1 字串,外加一个换行符)的文件。分支是仓库的平行版本。它包含在仓库中,但不影响主要或 master 分支,可让您自由工作而不中断"即时"版本。在执行所需的更改后,可以将分支合并回 master 分支以发布更改。
  • checkout 检出:在命令行上使用 git checkout 创建新分支,将当前的工作分支更改为不同的分支,甚至使用 git checkout [branchname] [path to file] 从不同的分支切换到不同版本的文件。"检出"操作会使用对象数据库中的树对象或 blob 更新工作树的全部或部分,以及更新索引和 HEAD(如果整个工作树指向新分支)。
  • rebase 变基/衍合:要将一系列变更从一个分支重新应用到不同的基础分支,并将分支的 HEAD 重置为结果。
  • clone 克隆: 克隆远程仓库,包含所有提交和分支。克隆是指存在于计算机上而非网站服务器其他位置的仓库副本,或者是复制的操作。在克隆时,可在首选编辑器中编辑文件,使用 Git 跟踪更改而无需保持在线。您克隆的仓库仍与远程版本连接,以便当您在线时将本地更改推送到远程,以保持同步。
  • remote 远程: 托管于服务器上的仓库或分支版本。远程版本可以连接到本地克隆,以使更改保持同步,所有用户通过它来交换修改。
  • origin 源:默认上游仓库。大多数项目至少有一个它们跟踪的上游项目。
  • fork 复刻: 其他用户仓库在您的帐户上的个人副本。分叉允许您自由更改项目而不影响原始上游仓库。您也可以在上游仓库中打开拉取请求,并使分叉同步最新的更改,因为两个仓库仍然互相连接。
  • issue 议题:议题是提议的与仓库相关的改进、任务或问题。(对于公共仓库)任何人都可创建议题,然后由仓库协作者调解。每个议题都包含自己的讨论线程。您也可以使用标签将议题归类并分配到某人。
  • pull request 拉取请求: 一处用于比较和讨论分支上引入的差异,且具有评审、评论、集成测试等功能的地方。
  • pull 拉取:拉取是指提取与合并更改。例如,如果有人编辑了您操作的远程文件,您要将这些更改拉取到本地副本,以使其保持最新。
  • fetch 获取:在使用 git fetch 时,您将从远程仓库添加更改到本地工作分支,而不提交它们。与 git pull 不同,提取可让您在更改提交到本地分支之前先进行审查。
  • diff 差异:差异是指两个提交之间的更改或保存的更改之间的区别,它将从视觉上描述文件自上次提交后添加或删除的内容。
  • merge 合并:合并是从一个分支(在相同的仓库中或来自一个分叉)提取更改,然后将其应用到另一个分支。这通常是作为"拉取请求"(可视为请求合并)或通过命令行完成。
  • push 推送:推送是指将提交的更改发送到远程仓库。例如,如果您在本地更改内容,便可推送这些更改,让其他人访问。
  • ssh-key SSH 密钥:SSH 密钥是一种使用加密消息向在线服务器标识自己的方法。就好像您的计算机使用唯一密码登录其他服务一样。GitHub 使用 SSH 密钥将信息安全地传输到您的计算机。
  • license 许可:一种可随附于项目的文档,告知们能够对您的源代码执行哪些操作,不能执行哪些操作。
  • gitignore 忽略文件:gitignore 文件是一种告知 Git 忽略特定文件的方法。例如,您可能希望忽略编译的二进制文件,因为它们可以在任何时候重新生成。

安装

# Git for All Platforms <http://git-scm.com>

# Mac/Linux (using Homebrew<https://brew.sh/>)
brew install git

# Windows (using Scoop<https://scoop.sh/>)
scoop install git
# Windows (using WinGet<https://github.com/microsoft/winget-cli>)
winget install --id Git.Git

# ubuntu
sudo apt install git -y

初始化

对所有本地仓库的用户信息进行配置。

# 配置 commit 操作设置关联的用户名和邮箱
git config --global user.name "[USERNAME]"
git config --global user.email "[EMAIL]"

# 使用自己喜欢的编辑器(需要本地安装)
## 使用 Visual Studio Code 作为编辑器(VsCode 默认安装时会添加进系统环境变量中,如未设置应该在此添加编辑器路径)
git config --global core.editor "code --wait"
## 使用 Sublime Text 作为编辑器(如果已经将编辑器路径添加到环境变量中,此处可以省略编辑器路径)
git config --global core.editor "'C:/Program FILENAMEs (x86)/sublime text 3/subl.exe' -w"
## 使用 Notepad++ 作为编辑器(如果已经将编辑器路径添加到环境变量中,此处可以省略编辑器路径)
git config --global core.editor "'C:/Program FILENAMEs (x86)/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"

# 开启终端颜色输出
git config --global color.ui auto

# 格式化行结束 ctlf → lf
## MacOS
git config --global core.autocrlf input
## Windows
git config --global core.autocrlf true

# 查看 git 帮助文档
git help <verb>
man git-<verb>

创建仓库

有两种创建 Git 项目仓库的方法。第一种是在现存的目录下,通过导入所有文件来创建新的 Git 仓库。第二种是从已有的 Git 仓库克隆出一个新的镜像仓库。

# 对现有的项目开始用 Git 管理
git init
# 将本地仓库与远程仓库关联
## [URL] 远程仓库地址
## HTTPS 传输协议 URL,如 https://github.com/user/repo.git
## SSH 传输协议 URL,如 git@github.com:user/repo.git
git remote add origin [URL]

# 从远程仓库克隆,包括所有的文件、分支和提交
git clone [URL]

.gitignore 文件

配置 Git 在提交时要忽略文件和目录,和其他用户共享忽略规则。

# 常用 .gitignore 配置 <https://gist.github.com/octocat/9257657>

# 取消跟踪文件
git rm --cached [FILENAME]

# 为计算机上的所有存储库配置忽略的文件
git config --global core.excludesfile [FILENAME]

# 排除本地文件而不创建 .gitignore 文件
code .git/info/exclude

暂存 & 快照

记录每次更新到仓库。将修改过的文件放到暂存区域里(跟踪文件:纳入版本控制管理,添加快照记录),到最后一次性提交所有暂存区文件,记录文件快照到版本历史中。

# 检查当前文件状态
git status

# 跟踪新文件 [FILENAME],进行快照处理
git add [FILENAME]

# 取消已经暂存的文件
git reset [FILENAME]

# 查看工作目录文件和暂存区文件的差异(还未暂存的变动)
git diff
# 查看暂存区文件和上次提交时快照之间的差异
git diff --staged

# 提交更新(暂存区文件)到仓库区,记录文件快照到版本历史中
## [DESCRIPTION MESSAGE] 本次提交说明
git commit -m "[DESCRIPTION MESSAGE]"

分支 & 合并

分支是使用 Git 工作的一个重要部分。你做的任何提交都会发生在当前 "checked out" 到的分支上。使用 git status 查看当前工作在哪个分支。

# 列出当前项目所有分支的清单(* 表示当前所在分支)
git branch

# 查看各个分支最后一个提交对象的信息
git branch -v

# 新建 [BRANCH-NAME] 分支
git branch [BRANCH-NAME]

# 切换到 [BRANCH-NAME] 分支
git checkout [BRANCH-NAME]

# 新建 [BRANCH-NAME] 分支并切换到 [BRANCH-NAME] 分支
git checkout -b [BRANCH-NAME]

# 合并 [BRANCH-NAME] 分支到当前分支
git merge [BRANCH-NAME]

# 查看哪些分支已被并入当前分支(哪些分支是当前分支的直接上游)
git branch --merged

# 查看当前分支的提交历史(会按提交时间列出所有的更新,最近的更新排在最上面)
git log

检查 & 比较

浏览并检查项目文件的发展。

# 查看当前分支的提交历史
git log

# 列出 [FILENAME] 文件(包括文件重命名)的提交历史
git log --follow [FILENAME]
git whatchanged [FILENAME]

# 查看在 branchA 分支存在但在 branchB 分支不存在的提交记录
git log branchB..branchA

# 查看在 branchB 分支存在但在 branchA 分支不存在的提交记录
git log branchB...branchA
git log branchB ^branchA

# 查看两个分支间的差异
git diff branchB...branchA

# 查看 [SHA] 单次提交的信息(元数据和内容变化)
git show [SHA]

跟踪路径变化

版本控制文件删除和路径更改。

# 删除工作区文件,并且将这次删除放入暂存区
git rm [FILENAME]

# 停止追踪指定文件,但该文件会保留在工作区
git rm --cached [FILENAME]

# 改名文件,并且将这个改名放入暂存区
git mv [existing-path] [new-path]

# 显示提交历史,包括每次提交时修改的文件
git log --stat -M

共享 & 更新

从另一个存储库检索更新并更新本地存储库。

# 添加远程仓库并命名
git remote add [alias] [url]

# 获取远程仓库所有改动
git fetch [alias]

# 合并仓库指定分支到当前分支
git merge [alias]/[branch-name]

# 上传本地 [branch-name] 分支到远程仓库
git push [alias] [branch-name]

# 删除远程仓库中的 [branch-name] 分支
git push [alias] --delete [branch-name]
git branch -dr [alias]/[branch-name]

# 拉取远程仓库所有改动后合并到当前分支
# git pull 是 git fetch 和 git merge 的结合
git pull [alias] [branch-name]

重做提交

重写分支,清除错误和构建用于替换的历史。

# 将[feature-branch] 分支的提交应用到 [branch] 分支
git rebase [branch] [feature-branch]

# 将当前分支的部分提交记录应用到 [branch-name] 分支中
## [startpoint] [endpoint] 则指定了一个编辑区间
## 如果不指定 [endpoint],则该区间的终点默认是当前分支 HEAD 所指向的 commit
## 该区间指定的是一个前开后闭的区间
git rebase [startpoint]^ [endpoint] --onto [branch-name]

# 撤销所有 [commit] 后的的提交,在本地保存更改
git reset [commit]

# 放弃所有历史,改回指定提交。!!!小心,更改历史可能带来不良后果!!!
git reset --hard [commit]

临时提交

临时存储修改过的跟踪文件以更改分支。

# 将工作区内所有未提交的修改(包括暂存的和非暂存的)都保存起来形成新的本地储藏,用于后续恢复
git stash

# 查看之前缓存的工作区列表
git stash list

# 查看之前缓存的工作区内修改
git stash show

# 恢复之前缓存的工作区
git stash pop

# 丢弃之前缓存的工作区
git stash drop

相关资源

软件

教程

代码托管平台