git 常用命令之 git checkout

大家好,我是 17。

git checkout 是 git 中最重要最常用的命令之一,本文为大家详细解说一下。

恢复工作区

checkout 的用途之一是恢复工作区。

git checkout .  

checkout . 表示恢复工作区的所有更改,未跟踪的文件不会有变化。

恢复工作区的所有文件风险比较大,会丢失所有工作区的修改,一定要慎用

git checkout -- a.txt

中间加上 – 就安全多了,可以只恢复单个文件。

版本切换

git checkout master   取出 master 分支,HEAD 指向 master
git checkout 907d3ba  取出最后提交为 commit id 为 907d3ba 这个版本,HEAD 转到 907d3ba,和 master 分离。

取出分支的时候 HEAD 会指向当前分支。取出某个版本,HEAD也会跟着指过来,分支不动。这会造成 HEAD 和分支 分离。在分离 HEAD 的情况下,可以查看,提交,做各种试验,如果对结果满意,可以就地打新分支保留这些提交:

git checkout -c <new-branch-name>

如果不满意,什么也不用做,切回当前分支既可。

git checkout master  修正 HEAD 指向 master 分支

如果不知道哪前分支名也没关系 checkout - 同样会修正 HEAD。

git checkout -  

如果要开发新功能,直接在某个提交上打分支即可,为什么要分离 HEAD?原因是这样比较轻量。比如你现在想开发一个功能,但不知道是否可行,所以先试验一下,确认好了再打分支。如果直接打分支,觉得不合适还得删除。因为分支没有合并,还删不掉,删除还得加强制删除参数。

分离头指针的操作相当于 先上车,后补票 。上车后又下车,不用买票,只有到终点才需要补票。

强制拉分支

 git checkout -B dev 

假定 dev 存在,如果没有 -B 参数,会报错,加上 -B 会覆盖原来的 dev 分支,打一个新的 dev 分支出来,并转到 dev 分支。

省得费心起名了。如果并行的只有一个任务,可以每次都用 dev 分支开发。

从某个 commit 打分支

我们打分支的时候,默认会从 HEAD 处开始,对于 master 分支来说,就是 G。

如果从 F 处打分支出来,可以用第二个参数指定

git checkout -b dev F

也可以这样写
git checkout -b dev HEAD^

孤儿分支

有这样一个参数 --orphan, orphan 的英文原意是孤儿,如果我们要打一个设计文档分支出来这样写

git checkout --orphan design

因为设计文档和开发的代码完全是独立的部分,不适合和开发代码放一个分支上。

之所以称为孤儿分支,是因为这个分支是完完全全独立的,和以前所有的分支没有任何关联。和其它分支是平行的,永远不会相交。

就算孤儿分支是从 master 分支打出来的,你在 master 分支 执行 git log --oneline 也找不到任何有关孤儿分支的痕迹。当然更无法 merge 一个孤儿分支,实际上,也没有这个需求。

孤儿分支刚生成的时候,没有父提交,也没有任何提交,完全是空的,暂存区和工作区一般来说会有内容,因为我们要存设计文档,原来的内容都没有用,删除

git rm -rf .

现在我们得到了一个纯净的,独立的分支,可以添加设计文档了,并生成第一个提交。

可能你会有疑问,既然我们要一个孤儿分支,为什么还要初始化内容给我们?因为我们可能还有这样的需求:需要一个起点,而不是从一无所有开始。

试想这样的场景:项目开发半年了,市场反馈却是平平,老板觉得这样下去不是办法,需要另寻出路,但又不想放弃现在的方向。因为这次是方向性的问题,改动比较大,如果打普通分支的话,可能无法向主干合并。于是老板想出了一个办法,新建一个孤儿分支,完全独立来验证新想法,如果新方向正确,就可以代取代原来的方向。

从头来实现项目来验证新想法显然是不实际的,可以从项目中选择合适的节点,比如 F 节点,以这个为基础。

git checkout --orphan laboratory  F

新分支生成后,会把 F 节点的所有内容带到暂存区和工作区,我们全部保留,在这个基础上开发。laboratory 和原来的 master 分支的级别是完全一样的,laboratory 就相当于原来的 master 分支。master 只是提供了一个起点。laboratory 后面如何发展和 master 完全没有关系。

选择合并

git checkout master
git merge dev

merge dev 的时候发生的冲突,这时可以打开冲突文件手动修改,也可以自动修改

git checkout --ours a.txt
git checkout --theirs a.txt

下面举例说明一下如何自动修改。

首先制造一个 merge 冲突的现场。起点在 master 分支。 在 master 分支 和 dev 分支同时修改 a.txt 的第一行,

echo init >a.txt
git add a.txt
git commit -m 'add a.txt'

git checkout -b dev
echo dev >a.txt
git add a.txt
git commit -m 'alter a.txt'

git checkout master
echo master >a.txt
git add a.txt

git merge dev

看下 a.txt 的内容 cat a.txt

<<<<<<< HEAD
master
=======
dev
>>>>>>> dev

上面的是 master 的修改,下面的是 dev 的修改。

如果现在后悔了,想取消合并,恢复到合并前的状态,

git merge --abort

自动修改用 git checkout 命令。我们可以选择保留 master 分支的内容

git checkout --ours -- a.txt

查看 a.txt 内容,已经恢复正常了。

master

如果发现这不是我们要的结果,可以恢复冲突现场

git checkout -m -- a.txt

查看 a.txt ,又恢复到冲突状态了。这次我们选择 dev 的内容。

git checkout --theirs -- a.txt

检查内容无误后,添加到暂存区。

git add a.txt

冲突解决完了,但 merge 还没完成。

git merge --continue

这时弹出编辑器,可以修改提交信息,确认后会自动提交修改的内容。merge 完成。

新加的 git switch

你会发现 checkout 承载了很多分支相关的命令。为了让命令更清晰,新版 git 增加了 switch 命令。
switch 能做的事 checkout 都能做。

switch 命令的功能很纯粹,就是切换分支,如果分支不存在,顺便新建分支。

举两个常见的例子。

switch checkout
git switch master git checkout master
git switch -c dev git checkout -c dev
git switch --orphan git checkout --orphan

切分支的时候建议把工作区和暂存区的内容都提交

新加的 git restore

和增加 git switch 同样的原因,新版本增加了 git resotre 命令。

git resotre 的职责是恢复工作区和暂存区。原来 checkout 能做的,它都能做。它能做的, checkout 可能做不了。

--worktreegit restore 的默认参数

git restore a.txt  把暂存区 a.txt 的内容恢复到工作区
git restore .   恢复工作区的所有内容。

git restore --staged a.txt 把 HEAD 的 a.txt 恢复到暂存区


git restore --source=HEAD --staged --worktree a.txt 恢复工作区和暂存区

–source 表示从哪里来,默认是 HEAD --staged 表示恢复到暂存区,–worktree 表示恢复到工作区。这三个参数有简写方式。

git restore -s HEAD -SW a.txt

当 merge 发生冲突时,也可以用 restore 来解决冲突,用法同 checkout。

猜你喜欢

转载自blog.csdn.net/m0_55635384/article/details/128993409