Git 新功能 Switch 和 Restore

发布时间 2021年10月12日 • 2 分钟 读完 • 331 字
分享链接

介绍 git 命令中 git restore 和 git switch 的区别

Git 新功能 Switch 和 Restore
Photo by Karl Fredrickson on Unsplash

1200px-Git-logo.svg.png

令我惊讶的是,最近发现高级命令列表中新增了2个高级命令:git restore 和 git switch

当我看到一个 push 标志时,我首先会使用 pull 来消除冲突 – 神秘的匿名者

对于那些工作使用过 Git 一段时间的人,并不能经常发现它的新东西,如果你排除了管道命令行,这可能是我们大多数人不记得的最好做法。给我惊喜的是,我最近发现在高级命令列表中新增了两个新命令。

  • git restore
  • git switch

不理解它们为什么存在,先让我们拜访下我们的老朋友 git checkout

git-checkout.jpeg

Checkout 命令

Git checkout 让新手感到困惑的众多原因之一,是因为他的作用取决于上下文环境。大多数人用它是在本地仓库切换活跃的分支。更确切的说,是切换 HEAD 指向的分支。例如,如果你在 main 分支,你能切换到 develop 分支。

git checkout develop

你也可以让 HEAD 头指向到一个特定的提交ID,而不是一个分支(达到所谓的分离 HEAD 状态):

git checkout f8c540805b7e16753c65619ca3d7514178353f39

事情变的棘手的是,如果你提供一个文件作为参数而不是一个分支或提交ID,它将丢弃你对该文件的本地更改,并还原到修改前状态。例如,如果你切换到 develop 分支并对 test.txt 文件做了一些修改,然后你可以恢复这个文件到未修改前,也就是到这个分支的最后一次提交。

git checkout -- test.txt,以下这个命令操作演示(熟悉的童鞋可跳过):

1.develop 分支 test.txt 文件状态和内容

➜ git:(develop) git status
On branch develop
nothing to commit, working tree clean
➜ git:(develop) cat test.txt
test.txt file on develop

2.修改 test.txt 文件内容,并查看当前文件状态

➜ git:(develop) ✗ git status
On branch develop
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")
➜ git:(develop) ✗ cat test.txt
test.txt file on develop
test.txt file on develop
➜ git:(develop)

3.执行恢复命令,并查看恢复后文件状态

➜ git:(develop) ✗ git checkout -- test.txt
➜ git:(develop) git status
On branch develop
nothing to commit, working tree clean
➜ git:(develop) cat test.txt
test.txt file on develop
➜ git:(develop)

一种疯狂的做法

如果你第一次知道这个命令有这两种行为,可能认为那是说不通的,为什么一个命令会做两个不同的操作?其实事情要更微妙一些。如果我们看 Git 官方文档,我们会发现这个命令有一个额外的参数,这个参数通常被省略。

git checkout <tree-ish> -- <pathspec>

<tree-ish> 是什么?它能理解为许多不同的事情,但是通常的它的意思是一个提交的哈希值(CommitID)或者分支名称。把当前分支看作默认值,但是它可以是任何分支或提交的哈希值。例如,如果你在 develop 分支,想要将 test.txt 文件更改为来自main分支的版本,你可以这么做:

git checkout main -- text.txt

命令操作演示:

➜ git:(main) git status
On branch main
nothing to commit, working tree clean
➜ git:(main) cat test.txt
test.txt file on main
test.txt file on main
➜ git:(main) git checkout develop
Switched to branch 'develop'
➜ git:(develop) cat test.txt
test.txt file on develop
➜ git:(develop) git checkout main -- test.txt
➜ git:(develop) ✗ cat test.txt
test.txt file on main
test.txt file on main

考虑到这一点,也许事情开始变的有意义。当你仅仅提供一个分支名或者CommitID作为 git checkout 参数时,然后它会把你所有的文件修改成相应版本的状态,但是如果你明确指定一个文件名,它仅仅更改这一个文件。

git-switch-restore.jpeg

新来的小孩

所以再阅读了前面段落的后,事情开始变的有意义,我们必须承认对于新手它仍然是令人困惑的,那是因为在 git 2.23 版本,两个新命令的引进替换掉了老的 git checkout(它仍然是可以用的,但是新版本 git 的人,最好开始使用新命令)。如你所料,他们基本上都实现了前面描述的两种行为,将 git Checkout 分成两部分。

Switch

当只一个分支名作为git checkout参数运行时,swtich 实现了 git checkout 的这个行为。所以你可以使用它在分支或提交之间切换。

git switch develop

当你使用 git checkout 时,你可以切换到一个提交ID并进入到分离 HEAD 状态,默认情况下 git switch 不允许那样做,你需要通过使用 -d 参数:

git switch -d f8c540805b7e16753c65619ca3d7514178353f39

git checkout 另一个不同之处在于,你可以使用 -b 参数在一个命令中创建并切换到新的分支:

git checkout -b new_branch

在新的命令 switch 中同样的做法是使用 -c 参数:

git switch -c new_branch

Restore

当一个文件作为 git checkout 参数运行时,你可以使用 restore,顾名思义,修订一个文件到指定版本(默认为当前分支)

git restore -- test.txt

结尾

这些方法仍处于试验阶段,他们既然存在,但无论如何,我都鼓励大家开始使用,因为他们在你的脑海中可能变的更有意义,而且它可能会让 git 新用户少一些困惑。

关于这两个命令的更多详情,可以在 git 的官方文档中找到:

译自原文:https://www.banterly.net/2021/07/31/new-in-git-switch-and-restore/


评论

关注我

我的工作是编码和发布开发者表情包