成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何在Git中重置、恢復,返回到以前的狀態

系統 Linux
使用 Git 工作時其中一個鮮為人知(和沒有意識到)的方面就是,如何輕松地返回到你以前的位置 —— 也就是說,在倉庫中如何很容易地去撤銷那怕是重大的變更。在本文中,我們將帶你了解如何去重置、恢復和完全回到以前的狀態,做到這些只需要幾個簡單而優雅的 Git 命令。

[[239838]]

用簡潔而優雅的 Git 命令撤銷倉庫中的改變。

使用 Git 工作時其中一個鮮為人知(和沒有意識到)的方面就是,如何輕松地返回到你以前的位置 —— 也就是說,在倉庫中如何很容易地去撤銷那怕是重大的變更。在本文中,我們將帶你了解如何去重置、恢復和完全回到以前的狀態,做到這些只需要幾個簡單而優雅的 Git 命令。

 

重置

我們從 Git 的 reset 命令開始。確實,你應該能夠認為它就是一個 “回滾” —— 它將你本地環境返回到之前的提交。這里的 “本地環境” 一詞,我們指的是你的本地倉庫、暫存區以及工作目錄。

先看一下圖 1。在這里我們有一個在 Git 中表示一系列提交的示意圖。在 Git 中一個分支簡單來說就是一個命名的、指向一個特定的提交的可移動指針。在這里,我們的 master 分支是指向鏈中最新提交的一個指針。

圖 1:有倉庫、暫存區、和工作目錄的本地環境

圖 1:有倉庫、暫存區、和工作目錄的本地環境

如果看一下我們的 master 分支是什么,可以看一下到目前為止我們產生的提交鏈。

  1. $ git log --oneline
  2. b764644 File with three lines
  3. 7c709f0 File with two lines
  4. 9ef9173 File with one line

如果我們想回滾到前一個提交會發生什么呢?很簡單 —— 我們只需要移動分支指針即可。Git 提供了為我們做這個動作的 reset 命令。例如,如果我們重置 master 為當前提交回退兩個提交的位置,我們可以使用如下之一的方法:

  1. $ git reset 9ef9173

(使用一個絕對的提交 SHA1 值 9ef9173

或:

  1. $ git reset current~2

(在 “current” 標簽之前,使用一個相對值 -2)

圖 2 展示了操作的結果。在這之后,如果我們在當前分支(master)上運行一個 git log 命令,我們將看到只有一個提交。

  1. $ git log --oneline
  2.  
  3. 9ef9173 File with one line

圖 2:在 reset 之后

圖 2:在 reset 之后

git reset 命令也包含使用一些選項,可以讓你最終滿意的提交內容去更新本地環境的其它部分。這些選項包括:hard 在倉庫中去重置指向的提交,用提交的內容去填充工作目錄,并重置暫存區;soft 僅重置倉庫中的指針;而 mixed(默認值)將重置指針和暫存區。

這些選項在特定情況下非常有用,比如,git reset --hard <commit sha1 | reference> 這個命令將覆蓋本地任何未提交的更改。實際上,它重置了(清除掉)暫存區,并用你重置的提交內容去覆蓋了工作區中的內容。在你使用 hard 選項之前,一定要確保這是你真正地想要做的操作,因為這個命令會覆蓋掉任何未提交的更改。

 

恢復

git revert 命令的實際結果類似于 reset,但它的方法不同。reset 命令(默認)是在鏈中向后移動分支的指針去“撤銷”更改,revert 命令是在鏈中添加一個新的提交去“取消”更改。再次查看圖 1 可以非常輕松地看到這種影響。如果我們在鏈中的每個提交中向文件添加一行,一種方法是使用 reset 使那個提交返回到僅有兩行的那個版本,如:git reset HEAD~1。

另一個方法是添加一個新的提交去刪除第三行,以使最終結束變成兩行的版本 —— 實際效果也是取消了那個更改。使用一個 git revert 命令可以實現上述目的,比如:

  1. $ git revert HEAD

因為它添加了一個新的提交,Git 將提示如下的提交信息:

  1. Revert "File with three lines"
  2.  
  3. This reverts commit b764644bad524b804577684bf74e7bca3117f554.
  4.  
  5. # Please enter the commit message for your changes. Lines starting
  6. # with '#' will be ignored, and an empty message aborts the commit.
  7. # On branch master
  8. # Changes to be committed:
  9. #       modified:   file1.txt
  10. #

圖 3(在下面)展示了 revert 操作完成后的結果。

如果我們現在運行一個 git log 命令,我們將看到前面的提交之前的一個新提交。

  1. $ git log --oneline
  2. 11b7712 Revert "File with three lines"
  3. b764644 File with three lines
  4. 7c709f0 File with two lines
  5. 9ef9173 File with one line

這里是工作目錄中這個文件當前的內容:

  1. $ cat <filename>
  2. Line 1
  3. Line 2

圖 3 revert 操作之后

圖 3 revert 操作之后

 

恢復或重置如何選擇?

為什么要優先選擇 revert 而不是 reset 操作?如果你已經將你的提交鏈推送到遠程倉庫(其它人可以已經拉取了你的代碼并開始工作),一個 revert 操作是讓他們去獲得更改的非常友好的方式。這是因為 Git 工作流可以非常好地在分支的末端添加提交,但是當有人 reset 分支指針之后,一組提交將再也看不見了,這可能會是一個挑戰。

當我們以這種方式使用 Git 工作時,我們的基本規則之一是:在你的本地倉庫中使用這種方式去更改還沒有推送的代碼是可以的。如果提交已經推送到了遠程倉庫,并且可能其它人已經使用它來工作了,那么應該避免這些重寫提交歷史的更改。

總之,如果你想回滾、撤銷或者重寫其它人已經在使用的一個提交鏈的歷史,當你的同事試圖將他們的更改合并到他們拉取的原始鏈上時,他們可能需要做更多的工作。如果你必須對已經推送并被其他人正在使用的代碼做更改,在你做更改之前必須要與他們溝通,讓他們先合并他們的更改。然后在這個侵入操作沒有需要合并的內容之后,他們再拉取最新的副本。

你可能注意到了,在我們做了 reset 操作之后,原始的提交鏈仍然在那個位置。我們移動了指針,然后 reset 代碼回到前一個提交,但它并沒有刪除任何提交。換句話說就是,只要我們知道我們所指向的原始提交,我們能夠通過簡單的返回到分支的原始鏈的頭部來“恢復”指針到前面的位置:

  1. git reset <sha1 of commit>

當提交被替換之后,我們在 Git 中做的大量其它操作也會發生類似的事情。新提交被創建,有關的指針被移動到一個新的鏈,但是老的提交鏈仍然存在。

 

變基

現在我們來看一個分支變基。假設我們有兩個分支:master 和 feature,提交鏈如下圖 4 所示。master 的提交鏈是 C4->C2->C1->C0 和 feature 的提交鏈是 C5->C3->C2->C1->C0

圖 4:master 和 feature 分支的提交鏈

圖 4:master 和 feature 分支的提交鏈

如果我們在分支中看它的提交記錄,它們看起來應該像下面的這樣。(為了易于理解,C 表示提交信息)

  1. $ git log --oneline master
  2. 6a92e7a C4
  3. 259bf36 C2
  4. f33ae68 C1
  5. 5043e79 C0
  6.  
  7. $ git log --oneline feature
  8. 79768b8 C5
  9. 000f9ae C3
  10. 259bf36 C2
  11. f33ae68 C1
  12. 5043e79 C0

我告訴人們在 Git 中,可以將 rebase 認為是 “將歷史合并”。從本質上來說,Git 將一個分支中的每個不同提交嘗試“重放”到另一個分支中。

因此,我們使用基本的 Git 命令,可以變基一個 feature 分支進入到 master 中,并將它拼入到 C4 中(比如,將它插入到 feature 的鏈中)。操作命令如下:

  1. $ git checkout feature
  2. $ git rebase master
  3.  
  4. First, rewinding head to replay your work on top of it...
  5. Applying: C3
  6. Applying: C5

完成以后,我們的提交鏈將變成如下圖 5 的樣子。

圖 5:rebase 命令完成后的提交鏈

圖 5:rebase 命令完成后的提交鏈

接著,我們看一下提交歷史,它應該變成如下的樣子。

  1. $ git log --oneline master
  2. 6a92e7a C4
  3. 259bf36 C2
  4. f33ae68 C1
  5. 5043e79 C0
  6.  
  7. $ git log --oneline feature
  8. c4533a5 C5
  9. 64f2047 C3
  10. 6a92e7a C4
  11. 259bf36 C2
  12. f33ae68 C1
  13. 5043e79 C0

注意那個 C3'C5'— 在 master 分支上已處于提交鏈的“頂部”,由于產生了更改而創建了新提交。但是也要注意的是,rebase 后“原始的” C3C5 仍然在那里 — 只是再沒有一個分支指向它們而已。

如果我們做了這個變基,然后確定這不是我們想要的結果,希望去撤銷它,我們可以做下面示例所做的操作:

  1. $ git reset 79768b8

由于這個簡單的變更,現在我們的分支將重新指向到做 rebase 操作之前一模一樣的位置 —— 完全等效于撤銷操作(圖 6)。

圖 6:撤銷 rebase 操作之后

圖 6:撤銷 rebase 操作之后

如果你想不起來之前一個操作指向的一個分支上提交了什么內容怎么辦?幸運的是,Git 命令依然可以幫助你。用這種方式可以修改大多數操作的指針,Git 會記住你的原始提交。事實上,它是在 .git 倉庫目錄下,將它保存為一個特定的名為 ORIG_HEAD 的文件中。在它被修改之前,那個路徑是一個包含了大多數最新引用的文件。如果我們 cat 這個文件,我們可以看到它的內容。

  1. $ cat .git/ORIG_HEAD
  2. 79768b891f47ce06f13456a7e222536ee47ad2fe

我們可以使用 reset 命令,正如前面所述,它返回指向到原始的鏈。然后它的歷史將是如下的這樣:

  1. $ git log --oneline feature
  2. 79768b8 C5
  3. 000f9ae C3
  4. 259bf36 C2
  5. f33ae68 C1
  6. 5043e79 C0

在 reflog 中是獲取這些信息的另外一個地方。reflog 是你本地倉庫中相關切換或更改的詳細描述清單。你可以使用 git reflog 命令去查看它的內容:

  1. $ git reflog
  2. 79768b8 HEAD@{0}: reset: moving to 79768b
  3. c4533a5 HEAD@{1}: rebase finished: returning to refs/heads/feature
  4. c4533a5 HEAD@{2}: rebase: C5
  5. 64f2047 HEAD@{3}: rebase: C3
  6. 6a92e7a HEAD@{4}: rebase: checkout master
  7. 79768b8 HEAD@{5}: checkout: moving from feature to feature
  8. 79768b8 HEAD@{6}: commit: C5
  9. 000f9ae HEAD@{7}: checkout: moving from master to feature
  10. 6a92e7a HEAD@{8}: commit: C4
  11. 259bf36 HEAD@{9}: checkout: moving from feature to master
  12. 000f9ae HEAD@{10}: commit: C3
  13. 259bf36 HEAD@{11}: checkout: moving from master to feature
  14. 259bf36 HEAD@{12}: commit: C2
  15. f33ae68 HEAD@{13}: commit: C1
  16. 5043e79 HEAD@{14}: commit (initial): C0

你可以使用日志中列出的、你看到的相關命名格式,去重置任何一個東西:

  1. $ git reset HEAD@{1}

一旦你理解了當“修改”鏈的操作發生后,Git 是如何跟蹤原始提交鏈的基本原理,那么在 Git 中做一些更改將不再是那么可怕的事。這就是強大的 Git 的核心能力之一:能夠很快速、很容易地嘗試任何事情,并且如果不成功就撤銷它們。 

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2018-12-27 13:35:11

MySQLMySQL 8重置密碼

2020-08-31 07:30:28

UbuntuRoot密碼

2022-03-28 19:53:24

Linux恢復文件意外刪除文件

2017-03-17 15:25:54

LinuxMySQLroot密碼

2019-07-19 16:35:34

Windows 10恢復游戲

2015-06-24 09:54:38

Git撤銷

2018-11-29 11:39:25

恢復重置Windows 10

2021-06-16 09:49:14

Windows 11微軟動態磁貼

2018-06-15 10:07:32

Windows 10Windows回收站

2017-11-06 15:21:17

DRHCI超融合

2017-07-21 13:25:33

LinuxMD5哈希恢復文件

2018-01-30 12:18:08

Linux儲存器USB設備

2015-08-07 10:10:18

LinuxDocker容器

2018-12-27 10:00:37

Windows10Office文檔

2018-05-24 14:40:04

2016-11-22 19:37:54

Linux恢復文件

2022-05-20 08:18:24

Git存儲哈希值

2020-11-09 11:45:38

云計算災難恢復DR

2021-11-16 19:37:03

緩存

2021-04-02 15:18:13

智慧城市物聯網
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 在线午夜 | 韩国精品在线观看 | 福利网址 | 日韩欧美在线视频 | 99re6在线视频 | av大片在线观看 | 欧美国产日韩在线观看 | 亚洲乱码一区二区三区在线观看 | 日韩成人在线播放 | 美国av毛片 | 天天人人精品 | 久久69精品久久久久久久电影好 | 成人久久18免费网站 | 青青草社区 | 国产精品一区二区不卡 | 日韩精品一区二区三区第95 | 亚洲天堂中文字幕 | 日韩中文字幕一区 | 亚洲精品亚洲人成人网 | 四虎成人免费电影 | 久久九九色 | 欧美一区不卡 | 亚洲黄色视屏 | 欧美国产一区二区 | 欧美性猛交一区二区三区精品 | 国产日韩欧美一区二区在线播放 | 国产蜜臀 | 久久久www成人免费精品 | 欧美a v在线 | 国产精品久久久久一区二区三区 | 日韩精品视频在线 | 国产精品久久久久久久久久久久冷 | 综合网中文字幕 | 日韩电影一区二区三区 | 亚洲精品日韩一区二区电影 | 日韩免费av| 精品久久久久久红码专区 | 久久亚洲一区二区 | 亚洲视频免费观看 | 久久亚洲一区二区三区四区 | 国产精品久久久久久久久久久久久 |