首頁 > 開發工具 > Git > 主體

Git命令學習之git-reset詳解

青灯夜游
發布: 2023-03-23 19:33:18
轉載
2882 人瀏覽過

Git命令學習之git-reset詳解

git-reset的作用是重置目前分支的HEAD指針,將HEAD指針指向特定的狀態。

使用概述

git reset [<tree-ish>] [--] <pathspec>
git reset [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]
git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>]
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [<commit>]
登入後複製

前三行reset指令的功能是將指定的內容作為參考依據,然後把內容拷貝到目標的快取區中。

就是像樹一樣的東西,git中是有很多都能組成樹的,例如commit樹或tag樹。

最後一行reset指令的功能是將目前分支的HEAD指標指向,同時可以使用多種可選項來控制是否修改快取區或工作區。

在以上所有的命令形式中,都是把預設為HEAD指標。

git reset [] [--]

##此方法有下列規則:

  • 會將與相符的路徑資源在快取區中重設為中的狀態。

    不了解是什麼?

  • 被提交到快取區中的變更會還原到工作區。

舉個?

假設專案中有一個coffee.txt文件,文件內容如下:

卡布奇诺纳瑞冰-19.9¥
标准美式-14.9¥
香草拿铁-19.9¥
生椰爱摩卡-19.9¥
...
登入後複製
登入後複製

我們使用git的tag指令將當前的版本標記成v1.0.0(這裡使用tag標籤作為)。

隨後修改coffee.txt文件,修改內容如下:

卡布奇诺纳瑞冰-19.9¥ --> 卡布奇诺纳瑞冰-14.9¥
标准美式-14.9¥ --> 标准美式-9.9¥
香草拿铁-19.9¥ --> 香草拿铁-14.9¥
生椰爱摩卡-19.9¥ --> 生椰爱摩卡-14.9¥
...
登入後複製

變更了coffee.txt檔案後,再使用git tag打上了v1.0.1標記。

如果此時想將coffee.txt檔案還原成v1.0.0版本中的文件,就可以使用git reset指令並指定為v1.0.0,操作如下:

git reset v1.0.0 coffee.txt
登入後複製

使用VSCode查看快取區的檔案變更:

Git命令學習之git-reset詳解

可以看到圖中的右側的程式碼改變對比,此時快取區中的coffee.txt檔案已經成功被重置成v1.0.0版本中文件的狀態(規則1)。並且此時v1.0.1已經提交到快取區中的變動也被還原到了工作樹中(規則2)。

Git命令學習之git-reset詳解

可以看出git reset指令與git add指令作用相反,一個是將指定的資源加入到快取區,另一個則是從快取區移除。而這個指令與git restore [--source=] --staged 具有相同的作用,對restore感興趣的可以看看

這篇文章

上面說過了,在使用reset指令後,此時快取區中檔案內容是v1.0.0的,可以配合git restore指令將快取區中的內容還原到工作區中然後進行修改:

git restore coffee.txt --staged
登入後複製

也可以依需求選擇還原工作區的內容:

git restore coffee.txt --worktree
登入後複製

git reset [--pathspec-from-file= [--pathspec -file-nul]] []

在上面的例子中每次進行reset和restore的都是想同的路徑(coffee .txt)。因為該檔案路徑比較簡單,所以每次操作都比較方便輸入。但在某些情況下,可能需要reset比較複雜的路徑,例如專案目錄層次較深,那麼很可能需要輸入一長串的路徑,這樣每次運作都會很麻煩,所以git提供了一個--pathspec-from-file選項,讓我們能夠直接指定一個文件,這個文件就包含了可能需要重複使用的路徑。

這裡有更詳細的用法。

該檔案每一行都是一個,如果有多個使用換行符號作為分隔。當然也可以使用--pathspec-file-nul讓NUL作為每一個的分隔符號。

git reset (--patch | -p) [] [--] []

############################################################################################################################################################ #

交互式的选择与缓存区之间的差异而产生的hunks。这些被选择的hunks将会撤销缓存区中的产生的修改。这里有更详细的--patch选项用法。

git reset [] []

该命令会把当前分支的HEAD指针指向某个,然后由决定是否同时更新缓存区或工作区的内容。默认值是--mixed,且必须是以下几种:

--soft

工作区和缓存区中的文件变动都将被保留,然后将HEAD指针指向

还是以咖啡菜单为?,假如第一次commit到仓库中的文件内容如下:

卡布奇诺纳瑞冰-19.9¥
标准美式-14.9¥
香草拿铁-19.9¥
生椰爱摩卡-19.9¥
...
登入後複製
登入後複製

然后做第二次commit操作,删除标准美式,增加生椰拿铁:

卡布奇诺纳瑞冰-19.9¥
-标准美式-14.9¥
+生椰拿铁-19.9¥
香草拿铁-19.9¥
生椰爱摩卡-19.9¥
...
登入後複製

在commit后,修改卡布奇诺纳瑞冰的价格,添加到缓存区。再修改香草拿铁的价格,保留在工作区:

-卡布奇诺纳瑞冰-19.9¥
+卡布奇诺纳瑞冰-14.9¥ // 添加到缓存区中
生椰拿铁-19.9¥
-香草拿铁-19.9¥
+香草拿铁-14.9¥ // 保留在工作区
生椰爱摩卡-19.9¥
...
登入後複製

此时我想保留工作区和缓存区做的改动,并且将HEAD指针指向第一次commit。这时可以使用--soft选项实现:

git reset HEAD^ --soft // 这里使用HEAD^表示上一个commit,同样也可以使用hash id
登入後複製

使用git log查看当前HEAD指针确实已经指向第一个commit,第二个commit被抛弃了:

Git命令學習之git-reset詳解

同时所有的工作区和缓存区的改动都被保留了:

Git命令學習之git-reset詳解

当前只有两次的commit,是为了方便演示--soft选项的作用。但是在实际开发中,我们可能会commit多次,尤其是在测试环境改几个BUG就要提交到发布平台,这样会导致很多无意义的commit。这时候就可以使用--soft选项,重置HEAD到指定的只保留一到两个重要的commit。

--mixed

重置缓存区,但是会保留工作区的内容,这是的默认值。

相信在理解了--soft作用后,理解--mixed不难,上面例子中如果是使用--mixed那么最终结果如下:

Git命令學習之git-reset詳解

该选项会重置缓存区,但是保留工作区的改动,并将当前指针指向

--hard

重置缓存区和工作区中的所有的变动,并且将指针指向

--hard更加的简单粗暴,我们将--soft例子改为--hard来查看结果:

Git命令學習之git-reset詳解

如图所示,工作区和缓存区的内容都被重置了。不止是如此,就连Untracked文件同样也会被删除。

--merge

该选项的作用,看字面意思就知道大概就是把当前分支和指定的进行合并,规则如下:

  • 重置缓存区,任何已经添加到缓存区的改动都将被抛弃

  • 如果和HEAD之间有文件存在不同(这个不同指的是文件被删除或者新增),那么将会把该文件重置成中的状态(新增或删除)。

  • 如果和HEAD之间有文件存在不同(这个不同是指文件内容的不同),且此时工作区也存在未提交的改动,那么本次的reset将会被终止。

  • 如果一个文件在和HEAD中完全相同,但是它的工作区存与缓存区存在着不同(也就是改动未提交到缓存区),那么该文件在工作区的改动在重置之后就会被保留。

我们举个例子来验证一下以上列出的规则,假设此时的咖啡店项目有如下的几个commit。

第一个commit和文件内容如下:

Git命令學習之git-reset詳解

第一个commit中只有一个coffee.txt菜单文件,此时如果咖啡店引进了新品种开始卖果汁,那么就需要新增果汁菜单文件fruits.txt,于是就有了第二个commit:

Git命令學習之git-reset詳解

此时我们做一些改动来验证1,2,4这几点的规则,改动后的文件如下:

Git命令學習之git-reset詳解

首先修改coffee.txt文件,新增一款生椰拿铁咖啡,保留在工作区中。然后增加咖啡豆菜单文件beans.txt,将其添加到缓存区中。

假设因需求变动,咖啡豆菜单文件在缓存区中需要清除,果汁菜单文件需要删除,只有咖啡菜单中新增的生椰拿铁的改动需要保留。那么就可以使用git reset --merge将HEAD和commit-1进行合并,操作如下:

git reset --merge HEAD^
登入後複製

结果如下:

Git命令學習之git-reset詳解

执行命令reset命令产生了如下效果:

  • 将当前HEAD指针指向了commit-1
  • 将缓存区中的beans.txt文件抛弃(规则1)
  • HEAD(commit-2)和commit-1中的fruits.txt文件存在不同(commit-2中新增fruits.txt),所以会将fruits.txt删除(规则2)
  • coffee.txt文件新增生椰拿铁的改动被保留在工作区中(规则4)

再来验证一下第3点规则,假设咖啡店项目此时第一个commit如下:

Git命令學習之git-reset詳解

接下去同样新增水果茶菜单,然后再修改coffee.txt文件,第二个commit如下:

Git命令學習之git-reset詳解

然后在HEAD中再修改coffee.txt文件,删除掉标准美式品种:

Git命令學習之git-reset詳解

此时,如果我们再使用git reset --merge HEAD^就无法再进行重置,该操作会被git终止(规则3)。并且控制台会进行报错提示:

Git命令學習之git-reset詳解

--keep

该选参的作用和--merge相似,唯一的区别就是缓存区中被重置的会被保留在工作区中。

构造如下第一个commit:

Git命令學習之git-reset詳解

改造第二个commit:

Git命令學習之git-reset詳解

在HEAD中进行修改

Git命令學習之git-reset詳解

使用git reset --keep命令:

Git命令學習之git-reset詳解

从结果上来看,只有fruits.txt文件被删除了,beans.txt文件被重置回了工作区中。coffee.txt文件的改动也被保留了。

--[no-]recurse-submodules

使用该选项可以控制是否递归的重置submdoule。如果想要更详细了解,查看这篇文章

总结

git-reset命令的作用就是重置缓存区和工作区,同时它也提供多个选项来做更具体的控制,使得该命令更加灵活多变。git-reset命令在我们的工作中经常使用,因此熟练掌握该命令是非常重要的。

更多编程相关知识,请访问:编程入门!!

以上是Git命令學習之git-reset詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:juejin.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!