Git 进阶使用
原理
工作区、暂存区、远程仓库
-
工作区(Working Directory)概念
工作区就是你在电脑上能看到的实际的项目目录,包含了项目的所有文件和文件夹,是你日常进行代码编辑、文件修改等操作的地方。例如,你新建一个本地的代码项目文件夹,在里面编写代码、增减文件等操作所处的这个文件夹范围就是工作区。
-
暂存区(Staging Area)概念
暂存区又被称作索引(Index),它像是一个过渡区域,用于临时存放你打算提交到版本库的修改内容。当你在工作区对文件进行了修改后,使用 git add 命令可以将这些修改添加到暂存区,这一步相当于告诉 Git,你选择了哪些修改是准备纳入下一次版本提交中的内容。
-
远程仓库(Remote Repository)概念
远程仓库通常是存放在远程服务器上的项目仓库,比如常见的放在 GitHub、GitLab、Bitbucket 等代码托管平台上的仓库。它主要用于团队协作开发或者备份本地仓库等用途,团队成员可以将各自本地仓库的修改推送(push)到远程仓库,也可以从远程仓库拉取(pull)其他人提交的最新修改到自己的本地仓库,实现代码的共享与同步。
之间的关系如下图所示
- 从工作区到暂存区:
当在工作区对文件进行修改、新增或者删除操作后,通过
git add
命令把相应的改动添加到暂存区,此时这些改动就从工作区进入到暂存区等待下一步被提交到本地仓库中。 - 从暂存区到本地仓库:
使用
git commit
命令可以将暂存区中的内容提交到本地仓库(.git 目录下,这是 Git 真正管理版本的地方),完成一次版本记录的创建,这个过程就是把暂存区的修改正式固化为一个版本节点。 - 本地仓库与远程仓库的交互:
通过
git push
命令,可以将本地仓库的提交记录(也就是各个版本的修改内容)推送到远程仓库,让远程仓库的版本与本地保持同步更新;而git pull
命令则是从远程仓库获取最新的修改内容并合并到本地仓库中,确保本地仓库的代码是最新的状态,方便团队成员之间代码的协作与共享。
版本回退详解
git reset
git reset 是一个强大的命令,用于撤销已经提交(commit)或者添加到暂存区(staging area)的更改。它主要用于修改 Git 的历史记录,调整仓库的状态。这个命令可以根据不同的参数,作用于工作区、暂存区和本地仓库。
注意:
因为 git reset 是直接删除 commit 记录,从而会影响到其它开发人员的分支,所以不要在公共分支比如(develop)做这个操作
命令格式和参数
基本格式为
git reset [--soft | --mixed | --hard] [commit-hash]。
–soft 参数
仅仅影响本地仓库(也叫历史记录区)
当使用git reset --soft [commit-hash]
时,它会将 HEAD 指针(指向当前分支的最新提交)移动到指定的 commit-hash,但是不会改变暂存区和工作区的内容。
例如,如果你已经提交了三个更改(commit1、commit2、commit3),当前在 commit3 状态,并且你想撤销最后一个提交,但是希望保留在暂存区的更改,你可以使用 git reset –soft HEAD1。这里 HEAD1 表示上一个提交。这样,最后一个提交被撤销,但是暂存区的内容仍然是之前准备提交的内容。
–mixed 参数(默认情况)
影响本地仓库(也叫历史记录区) + 暂存区
git reset --mixed [commit-hash]
(如果不指定参数,默认是–mixed)不仅会将 HEAD 指针移动到指定的 commit-hash,还会将暂存区的内容更新为指定提交时的状态,但工作区的内容保持不变。
例如,你添加了一些文件到暂存区并提交了一次,然后又添加了一些其他文件到暂存区,现在你想撤销到上一个提交,并且清除刚刚添加到暂存区的文件。你可以使用 git reset HEAD~1(这里默认是–mixed),这样 HEAD 指针回到上一个提交,暂存区的文件被更新为上一个提交时的状态,工作区的文件不变。
–hard 参数
影响本地仓库(也叫历史记录区) + 暂存区 + 工作区
git reset --hard [commit-hash]
是最具 “破坏性” 的选项。它会将 HEAD 指针、暂存区和工作区的内容都更新为指定提交时的状态。
例如,如果你想完全丢弃最近的几个提交,并且不想保留工作区和暂存区的相关更改,你可以使用 git reset –hard HEAD~n(n 为想要回退的提交次数)。使用这个参数需要非常谨慎,因为它会永久删除工作区和暂存区中未提交的更改,这些更改将无法恢复。
git checkout – <file>
仅仅影响工作区的文件
把 file 文件在工作区的修改全部撤销,这里有两种情况:
-
一种是 file 自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态
-
一种是 file 已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态
总之,就是让这个文件回到最近一次 git commit 或 git add 时的状态
git checkout <commit-id> – <file>
影响暂存区和工作区
使用指定的 commit-id 的 file 文件替换暂存区和工作区,替换之后如果 commit-id 不是 HEAD,那么需要进行 commit 提交
小技巧
如何让 git 命令的输出支持中文
-
设置 Git 的 core.quotepath 选项为 false,这样 Git 就不会对非 ASCII 字符的文件名进行 quote,从而可以正确显示中文。
git config --global core.quotepath false
-
如果你使用的是 Windows 系统,还需要设置 i18n.commitEncoding 和 i18n.logOutputEncoding 为 utf-8,以确保提交信息和日志输出的编码正确
git config --global i18n.commitEncoding utf-8 git config --global i18n.logOutputEncoding utf-8
如何让 git 暂时忽略本地的更改
git update-index --assume-unchanged <文件路径>
git update-index --no-assume-unchanged <文件路径>
git update-index --skip-worktree <文件路径>
git update-index --no-skip-worktree <文件路径>
变基 rebase
TODO
暂存 stash
TODO