【Git】Linux-ubuntu 22.04 初步認識 -> 安裝 -> 基礎操作

文章目錄

  • Git 初識
  • Git 安裝
    • Linux-centos
    • Linux-ubuntu
    • Windows
  • Git 基本操作
  • 配置 Git
  • 認識工作區、暫存區、版本庫
    • 添加文件 -- 場景一
  • 查看 .git 文件
    • 添加文件 -- 場景二
  • 修改文件
  • 版本回退
  • 撤銷修改
    • 情況一:對于工作區的代碼,還沒有 add
    • 情況二:已經 add ,但沒有 commit
    • 情況三:已經 add ,并且也 commit 了
  • 刪除文件

Git 初識

提出問題
不知道你工作或學習時,有沒有遇到這樣的情況:我們在編寫各種文檔時,為了防止文檔丟失,更改失誤,失誤后能恢復到原來的版本,不得不復制出一個副本,比如:
“報告-v1”
“報告-v2”
“報告-v3”
“報告-確定版”
“報告-最終版”
“報告-究極進化版”

每個版本有各自的內容,但最終會只有一份報告需要被我們使用 。
但在此之前的工作都需要這些不同版本的報告,于是每次都是復制粘貼副本,產出的文件就越來越多,文件多不是問題,問題是:隨著版本數量的不斷增多,你還記得這些版本各自都是修改了什么嗎?
文檔如此,我們寫的項目代碼,也是存在這個問題的!!

如何解決–版本控制器
為了能夠更方便我們管理這些不同版本的文件,便有了版本控制器。所謂的版本控制器,就是能讓你了解到一個文件的歷史,以及它的發展過程的系統。通俗的講就是一個可以記錄工程的每一次改動和版本迭代的一個管理系統,同時也方便多人協同作業。
目前最主流的版本控制器就是 Git 。Git 可以控制電腦上所有格式的文件,例如 doc、excel、dwg、dgn、rvt等等。對于我們開發人員來說,Git 最重要的就是可以幫助我們管理軟件開發項目中的源代碼文件!

注意事項
還需要再明確?點,所有的版本控制系統,Git 也不例外,其實只能跟蹤文本文件的改動,比如 TXT 文件,網頁,所有的程序代碼等等。版本控制系統可以告訴你每次的改動,比如在第5行加了一個單詞 “Linux”,在第8行刪了一個單詞 “Windows”。 而圖片、視頻這些二進制文件,雖然也能由版本控制系統管理,但沒法跟蹤文件的變化,只能把?進制文件每次改動串起來,也就是只知道圖片從100KB改成了120KB,但到底改了啥,版本控制系統不知道,也沒法知道。

Git 安裝

Git 是開放源代碼的代碼托管工具,最早是在Linux下開發的。開始也只能應用于Linux平臺,后面慢慢的被移植到windows下,現在,Git可以在Linux、Unix、Mac和Windows這幾大平臺上正常運行了。

Linux-centos

如果你的的平臺是centos,安裝git相當簡單,以我的centos7.6為例:
首先,你可以試著輸入Git,看看系統有沒有安裝Git:

 $ git-bash: git: command not found

出現像上面的結果,Linux會友好地告訴你Git沒有安裝。

安裝 Git:

 $ sudo yum -y install git

查看 Git 安裝的版本:

 $ git --version

Linux-ubuntu

如果你的的平臺是ubuntu,安裝git相當簡單,以我的ubuntu22.04為例:
首先,你可以試著輸入git,看看系統有沒有安裝Git:

 $ gitCommand 'git' not found, but can be installed with:sudo apt install git

出現像上面的結果,Linux會友好地告訴你Git沒有安裝,還會告訴你如何安裝Git。

安裝 Git:

 $ sudo apt-get install git -y

查看 git 安裝的版本:

 $ git --version

Windows

參考鏈接: Windows安裝Git-點擊即可https://www.bilibili.com/video

Git 基本操作

創建 Git 本地倉庫
要提前說的是,倉庫是進行版本控制的一個文件目錄。我們要想對文件進行版本控制,就必須先創建一個倉庫出來。
創建一個 Git 本地倉庫對應的命令為 git init ,注意命令要在文件目錄下執行,例如:

[root@MyComputer:~]# mkdir gitcode
[root@MyComputer:~]# cd gitcode
[root@MyComputer:gitcode]# pwd
/root/gitcode
[root@MyComputer:gitcode]# git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint:   git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint:   git branch -m <name>
Initialized empty Git repository in /root/gitcode/.git/
[root@MyComputer:gitcode]# ll -a
total 12
drwxr-xr-x  3 root root 4096 Jul 27 23:30 ./
drwx------ 14 root root 4096 Jul 27 23:30 ../
drwxr-xr-x  7 root root 4096 Jul 27 23:30 .git/

我們發現,當前目錄下多了一個 .git 的隱藏文件, .git 目錄是 Git 來跟蹤管理倉庫的,不要手動修改這個目錄里面的文件,不然改亂了,就把 Git 倉庫給破壞了。

其中包含 Git 倉庫的諸多細節,有興趣的同學可以進入看看。

[root@MyComputer:gitcode]# tree .git/
.git/
├── HEAD
├── branches
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── fsmonitor-watchman.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-merge-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   ├── push-to-checkout.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs├── heads└── tags

配置 Git

當安裝 Git 后首先要做的事情是設置你的 用戶名稱e-mail 地址,這是非常重要的。配置命令為:

	git config [--global] user.name "Your Name"git config [--global] user.email "email@example.com"# 把 Your Name 改成你的昵稱# 把 email@example.com 改成郵箱的格式,只要格式正確即可。

查看配置命令為:

	git config -l

刪除對應的配置命令為:

	git config [--global] --unset user.namegit config [--global] --unset user.email
[root@MyComputer:gitcode]# git config user.name "lwz" //配置你的名字
[root@MyComputer:gitcode]# git config user.email "2244514959@qq.com"  //配置你的郵箱
[root@MyComputer:gitcode]# git config -l  //查看配置
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.name=lwz
user.email=2244514959@qq.com
[root@MyComputer:gitcode]# git config --unset user.name //重置你的名字 
[root@MyComputer:gitcode]# git config --unset user.email //重置你的郵箱
[root@MyComputer:gitcode]# git config -l //查看配置
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
[root@MyComputer:gitcode]# git config --global user.email "2244514959@qq.com"
[root@MyComputer:gitcode]# git config --global user.name "lwz"
[root@MyComputer:gitcode]# git config -l
user.email=2244514959@qq.com
user.name=lwz
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
[root@MyComputer:gitcode]# git config --global --unset user.email
[root@MyComputer:gitcode]# git config --global --unset user.name
[root@MyComputer:gitcode]# git config -l
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true

其中 --global 是?個可選項。如果使用了該選項,表示這臺機器上所有的 Git 倉庫都會使用這個配置。如果你希望在不同倉庫中使用不同的 name 或 e-mail ,可以不要 --global 選項,但要注意的是,執行命令時必須要在倉庫里。

認識工作區、暫存區、版本庫

  • 工作區:是在電腦上你要寫代碼或文件的目錄。
  • 暫存區:英文叫 stage 或 index。一般存放在 .git 目錄下的 index 文件(.git/index)中,我們把暫存區有時也叫作索引(index)。
  • 版本庫:又名倉庫,英文名 repository 。工作區有一個隱藏目錄 .git ,它不算工作區,而是 Git 的版本庫。這個版本庫里面的所有文件都可以被 Git管理起來,每個文件的修改、刪除,Git都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可以“還原”。

注意!!!!!!這句話一定要看!!!!!!!!!根據上面這個版本庫的定義,我們在這一篇文章中就可以看待成 本地倉庫 == 版本庫 == .git 目錄

下面這個圖展示了工作區、暫存區和版本庫之間的關系:
在這里插入圖片描述

  • 圖中左側為工作區,右側為版本庫。Git 的版本庫里存了很多東西,其中最重要的就是暫存區。

  • 在創建 Git 版本庫時,Git 會為我們自動創建一個唯一的 master 分支,以及指向 master 的一個指針叫HEAD。

  • 當對工作區修改(新增、修改、刪除)的文件執行 git add 命令時,暫存區目錄樹的文件索引會被更新。

  • 當執行提交操作 git commit 時,master 分支會做相應的更新,也就是將暫存區的內容提交到版本庫的master分支,可以簡單理解為暫存區的目錄樹才會被真正寫到版本庫中。

由上述描述我們便能得知:通過新建或粘貼進目錄的文件,并不能稱之為向倉庫中新增文件,而只是在工作區新增了文件。必須要通過使用 git add 和 git commit 命令才能將文件添加到版本庫中進行管理!!!

添加文件 – 場景一

在包含 .git 的目錄下新建一個 ReadMe 文件,我們可以使用 git add 命令可以將文件添加到暫存區:

  • 添加一個或多個文件到暫存區: git add [file1] [file2] …
  • 添加指定目錄到暫存區,包括子目錄: git add [dir]
  • 添加當前目錄下的所有文件改動到暫存區: git add .

再使用 git commit 命令將暫存區內容添加到版本庫中:

  • 提交暫存區全部內容到版本庫中: git commit -m “message”
  • 提交暫存區的指定文件到版本庫中: git commit [file1] [file2] … -m “message”

注意 git commit 后面的 -m 選項,要跟上描述本次提交的 message,由用戶自己完成,這部分內容絕對不能省略,并要好好描述,是用來記錄你的提交細節,是給我們人看的。

例如:

[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
[root@MyComputer:gitcode]# git add ReadMe
[root@MyComputer:gitcode]# git commit -m "commit my first file"
[master (root-commit) 77344dc] commit my first file1 file changed, 2 insertions(+)create mode 100644 ReadMe

git commit 命令執行成功后會告訴我們,1個文件被改動(就是我們新添加的ReadMe文件),插入了兩行內容(ReadMe有兩行內容)。

我們還可以多次 add 不同的文件,而只 commit 一次便可以提交所有文件,是因為需要提交的文件是通通被 add 到暫存區中,然后一次性 commit 暫存區的所有修改。如:

[root@MyComputer:gitcode]# touch file1 file2 file3
[root@MyComputer:gitcode]# git add file1 file2 file3
[root@MyComputer:gitcode]# git commit -m "add 3 file"
[master bd3e2aa] add 3 file3 files changed, 0 insertions(+), 0 deletions(-)create mode 100644 file1create mode 100644 file2create mode 100644 file3

截至目前為止,我們已經更夠將代碼直接提交至版本庫了。我們可以使用 git log 命令,來查看下歷史提交記錄:

[root@MyComputer:gitcode]# git log
commit bd3e2aa98e215d39febbe3c3abd282961525d611 (HEAD -> master)
Author: lwz <2244514959@qq.com>
Date:   Mon Jul 28 10:26:00 2025 +0800add 3 filecommit 77344dcba2ba6304b9a55dc862a83ef555592982
Author: lwz <2244514959@qq.com>
Date:   Mon Jul 28 10:23:31 2025 +0800commit my first file

如果這里不退出,最后一行就一個冒號,在英文輸入狀態下,按 q鍵即可。

該命令顯示從最近到最遠的提交日志,并且可以看到我們 commit 時的日志消息。
如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上 --pretty=oneline 參數:

[root@MyComputer:gitcode]# git log --pretty=oneline
bd3e2aa98e215d39febbe3c3abd282961525d611 (HEAD -> master) add 3 file
77344dcba2ba6304b9a55dc862a83ef555592982 commit my first file

需要說明的是,我們看到的一大串類似 23807c5…56eed6 的是每次提交的 commit id (版本號),Git 的commit id 不是1,2,3……遞增的數字,而是一個 SHA1 計算出來的一個非常大的數字,用十六進制表示(你看到的 commit id 和我的肯定不?樣,以你自己的為準哦)

查看 .git 文件

先來看看我們的 .git 的目錄結構:

在這里插入圖片描述

  1. index 就是我們的暫存區,add 后的內容都是添加到這里的。
  2. HEAD 就是我們的默認指向 master 分支的指針:
[root@MyComputer:gitcode]# cat .git/HEAD
ref: refs/heads/master

而默認的 master 分支,其實就是: 細心的人就知道這是什么了,往上翻一下就看到了,保存的就是當前最新的 commit id

[root@MyComputer:gitcode]# cat .git/refs/heads/master
bd3e2aa98e215d39febbe3c3abd282961525d611

在這里插入圖片描述

  1. objects 為 Git 的對象庫,里面包含了創建的各種版本庫對象及內容。當執行 git add 命令時,暫存區的目錄樹被更新,同時工作區修改(新增、修改、刪除)的文件內容被寫入到對象庫中的一個新的對象中,就位于 “.git/objects” 目錄下,讓我們來看看這些對象有何用處:
[root@MyComputer:gitcode]# ls .git/objects/
25  4f  77  9d  bd  e6  info  pack

查找 object 時要將 commit id 分成2部分,其前2位是文件夾名稱,后38位是文件名稱。
找到這個文件之后,一般不能直接看到里面是什么,該類文件是經過 sha (安全哈希算法)加密過的文件,好在我們可以使用 git cat-file 命令來查看版本庫對象的內容,后面跟一個-p選項指的是打印出來的內容更優雅,更好看,其實就是-pretty:

[root@MyComputer:gitcode]# git cat-file -p bd3e2aa98e215d39febbe3c3abd282961525d611
tree 2546009580cb745d1603d79b29c5dcc1e0b7b6c3
parent 77344dcba2ba6304b9a55dc862a83ef555592982
author lwz <2244514959@qq.com> 1753669560 +0800
committer lwz <2244514959@qq.com> 1753669560 +0800add 3 file # 這就是我們最近?次的提交!

其中,還有一行 tree 2546009580cb745d1603d79b29c5dcc1e0b7b6c3 ,我們使用同樣的方法,看看結果:

[root@MyComputer:gitcode]# git cat-file -p 2546009580cb745d1603d79b29c5dcc1e0b7b6c3
100644 blob 9d261842fd570f4514ec7b8393f3f296b71a3459    ReadMe
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    file1
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    file2
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    file3

在看 ReadMe 對應的 9d261842fd570f4514ec7b8393f3f296b71a3459 :

[root@MyComputer:gitcode]# git cat-file -p 9d261842fd570f4514ec7b8393f3f296b71a3459
Hello lwz
Hello lwz
# 這是我們對ReadMe做的修改!!被git記錄了下來!!

總結一下,在本地的 git 倉庫中,有幾個文件或者目錄很特殊:

  • index: 暫存區, git add 后會更新該內容。
  • HEAD: 默認指向 master 分支的一個指針。
  • refs/heads/master: 文件里保存當前 master 分支的最新 commit id 。
  • objects: 包含了創建的各種版本庫對象及內容,可以簡單理解為放了 git 維護的所有修改。

后面再學習過程中,最好能將常見的 git 操作與 .git 目錄當中的結構內容變化對應起來,這樣有利于我們理解git 細節流程。我們后面還會學習什么分支,標簽什么的,那我想后面就應該學習對應著研究了!

添加文件 – 場景二

學習到這里,我們已經清楚了如何向版本庫中添加文件,并且對于工作區、暫存區、版本庫也有了一定的認識。那么我們再展示一種添加文件的場景,能加深對工作區、暫存區、版本庫的理解,示例如下:

[root@MyComputer:gitcode]# touch file6
[root@MyComputer:gitcode]# git add file6
[root@MyComputer:gitcode]# touch file7
[root@MyComputer:gitcode]# git commit -m "add new file"
[master b26397e] add new file1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 file6

提交后發現打印了 1 file changed, 0 insertions(+), 0 deletions(-) ,意思是只有一個文件改變了,這時我們提出了疑問,不是新增了兩個文件嗎?
再來回憶下, git add 是將文件添加到暫存區, git commit 是將暫存區的內容添加到版本庫中。由于我們并沒有使用 git add file7 ,file7 就不在暫存區中維護,所以我們 commit 的時候其實只是把已經在暫存區的 file6 提交了,而遺漏了工作區的 file7。如何提交 file7 呢?很簡單,再次add , commit 即可。

[root@MyComputer:gitcode]# git add file7
[root@MyComputer:gitcode]# git commit -m "add file7"
[master fa52354] add file71 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 file7

修改文件

Git 比其他版本控制系統設計得優秀,因為 Git 跟蹤并管理的是修改,而非文件。
什么是修改?比如你新增了一行,這就是一個修改,刪除了一行,也是一個修改,更改了某些字符,也是一個修改,刪了一些又加了一些,也是一個修改,甚至創建一個新文件,也算一個修改。
讓我們將 ReadMe 文件進行一次修改:

[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!

此時,版本庫中的 ReadMe 和我們工作區的 ReadMe 是不同的,如何查看版本庫的狀態呢?
git status 命令用于查看在你上次提交之后是否有對文件進行再次修改。

[root@MyComputer:gitcode]# git status
On branch master
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified:   ReadMeno changes added to commit (use "git add" and/or "git commit -a")

上面的結果告訴我們,ReadMe 被修改過了,但還沒有完成添加與提交。
目前,我們只知道文件被修改了,如果能知道具體哪些地方被修改了,就更好了。有人就會說,我剛改的我知道呀!可是,你還記得你三天前寫了什么代碼嗎?或者沒寫?

[root@MyComputer:gitcode]# git diff ReadMe
diff --git a/ReadMe b/ReadMe
index 9d26184..ee54fe7 100644    
--- a/ReadMe                       # 原始文件
+++ b/ReadMe                       # 修改后文件
@@ -1,2 +1,3 @@                 # 原始文件第1行開始的2行 → 修改后第1行開始的3行Hello lwz                        # 未修改行Hello lwz                        # 未修改行
+Hello world!!!!                  # 新增行

git diff [file] 命令用來顯示暫存區和工作區文件的差異,顯示的格式正是Unix通用的diff格式。也可以使用 git diff HEAD -- [file] 命令來查看版本庫和工作區文件的區別。

知道了對 ReadMe 做了什么修改后,再把它提交到本地倉庫就放心多了。

git add 之后,就沒有看到上面 no changes added to commit (use “git add” and/or “git commit -a”) 的消息了。接下來讓我們繼續 git commit 即可:

[root@MyComputer:gitcode]# git add ReadMe
[root@MyComputer:gitcode]# git status
On branch master
Changes to be committed:(use "git restore --staged <file>..." to unstage)modified:   ReadMe[root@MyComputer:gitcode]# git commit -m "Modify ReadMe"
[master 59ac2b9] Modify ReadMe1 file changed, 1 insertion(+)
[root@MyComputer:gitcode]# git status
On branch master
nothing to commit, working tree clean

版本回退

之前我們也提到過,Git 能夠管理文件的歷史版本,這也是版本控制器重要的能力。如果有一天你發現之前的工作做的出現了很大的問題,需要在某個特定的歷史版本重新開始,這個時候,就需要版本回退的功能了。
執行 git reset 命令用于回退版本,可以指定退回某一次提交的版本。要解釋一下“回退”本質是要將版本庫中的內容進行回退,工作區或暫存區是否回退由命令參數決定
git reset 命令語法格式為: git reset [--soft | --mixed | --hard] [HEAD]

  • –mixed 為默認選項,使用時可以不用帶該參數。該參數將暫存區的內容退回為指定提交版本內容,工作區文件保持不變。

  • –soft 參數對于工作區和暫存區的內容都不變,只是將版本庫回退到某個指定版本。

  • –hard 參數將暫存區與工作區都退回到指定版本。切記工作區有未提交的代碼時不要用這個命令,因為工作區會回滾,你沒有提交的代碼就再也找不回了,所以使用該參數前一定要慎重。

  • HEAD 說明:
    ? 可直接寫成 commit id,表示指定退回的版本
    ? HEAD 表示當前版本
    ? HEAD^ 上一個版本
    ? HEAD^^ 上上一個版本
    ? 以此類推…

  • 可以使用 ?數字表示:
    ? HEAD~0 表示當前版本
    ? HEAD~1 上一個版本
    ? HEAD^2 上上一個版本
    ? 以此類推…

在這里插入圖片描述

為了便于表述,方便測試回退功能,我們先做一些準備工作:更新3個版本的 ReadMe,并分別進行3次提交,如下所示:

[root@MyComputer:gitcode]# git add ReadMe
[root@MyComputer:gitcode]# git commit -m "add version1"
[master b1daad2] add version11 file changed, 1 insertion(+)
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# git add ReadMe
[root@MyComputer:gitcode]# git commit -m "add version2"
[master 8d1af5b] add version21 file changed, 1 insertion(+)
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# git add ReadMe
[root@MyComputer:gitcode]# git commit -m "add version3"
[master d68ea84] add version31 file changed, 1 insertion(+)
[root@MyComputer:gitcode]# git log --pretty=oneline
d68ea84a1142d3d517478ff5715b428a5d32657d (HEAD -> master) add version3
8d1af5b1c416062bbf068fa904b83e7dd71edbc7 add version2
b1daad2ede33dd5fdb39fffe4b29383103eacdf4 add version1

現在,如果我們在提交完 version3 后, 發現 version3 編寫錯誤,想回退到 version2,重新基于 version2 開始編寫。由于我們在這里希望的是將工作區的內容也回退到 version2 版本,所以需要用到 --hard 參數,示例如下:

[root@MyComputer:gitcode]# git reset --hard 8d1af5b1c416062bbf068fa904b83e7dd71edbc7
HEAD is now at 8d1af5b add version2

我們驚奇的發現,此時 ReadMe 文件的內容,已經回退到 version2 了!,當前,我們再次用 git log 查看一下提交日志,發現 HEAD 指向了version2,如下所示:

[root@MyComputer:gitcode]# git log --pretty=oneline
8d1af5b1c416062bbf068fa904b83e7dd71edbc7 (HEAD -> master) add version2
b1daad2ede33dd5fdb39fffe4b29383103eacdf4 add version1

到這里一般回退功能就演示完了,但現在如果我后悔了,想再回到 version 3 怎么辦?
我們可以繼續使用 git reset 命令,回退到 version3 版本,但我們必須要拿到 version 3 的 commit id 去指定回退的版本。
但我們看到了 git log 并不能打印出 version3 的 commit id ,運氣好的話我們可以從終端上去找找之前的記錄,運氣不好的話 commit id 已經被我們搞丟了。
Git 還提供了一個 git reflog 命令能補救一下,該命令用來記錄本地的每一次命令。

8d1af5b (HEAD -> master) HEAD@{0}: reset: moving to 8d1af5b1c416062bbf068fa904b83e7dd71edbc7
d68ea84 HEAD@{1}: commit: add version3
8d1af5b (HEAD -> master) HEAD@{2}: commit: add version2
b1daad2 HEAD@{3}: commit: add version1

這樣,你就可以很方便的找到你的所有操作記錄了,但 d68ea84 這個是啥東西?
這個是 version3 的 commit id 的部分。沒錯,Git 版本回退的時候,也可以使用部分 commit id 來代表目標版本。示例如下:

# 退回到version3
[root@MyComputer:gitcode]# git reset --hard d68ea84
HEAD is now at d68ea84 add version3
# 查看log
[root@MyComputer:gitcode]# git log --pretty=oneline
d68ea84a1142d3d517478ff5715b428a5d32657d (HEAD -> master) add version3
8d1af5b1c416062bbf068fa904b83e7dd71edbc7 add version2
b1daad2ede33dd5fdb39fffe4b29383103eacdf4 add version1

可往往是理想很豐滿,現實很骨感。在實際開發中,由于長時間的開發了,導致 commit id 早就找不到了,可突然某一天,我又想回退到 version3,那該如何操作呢?貌似現在不可能了。。。
值得說的是,Git 的版本回退速度非常快,因為 Git 在內部有個指向當前分支(此處是master)的 HEAD 指針, refs/heads/master 文件里保存當前 master 分支的最新 commit id 。當我們在回退版本的時候,Git 僅僅是給 refs/heads/master 中存儲一個特定的version,可以簡單理解成如下示意圖:

在這里插入圖片描述

撤銷修改

如果我們在我們的工作區寫了很長時間代碼,越寫越寫不下上一個版本。

情況一:對于工作區的代碼,還沒有 add

你當然可以直接刪掉你目前在工作區新增的代碼,像這樣:

[root@MyComputer:gitcode]# git status
On branch master
nothing to commit, working tree clean
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
This piece of code is like shit #新增代碼
[root@MyComputer:gitcode]#  git status
On branch master
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified:   ReadMeno changes added to commit (use "git add" and/or "git commit -a")# 直接刪除代碼
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
[root@MyComputer:gitcode]# git status
On branch master
nothing to commit, working tree clean

幸虧我們工作效率不高,才寫了一行代碼就發現不行了,要是你寫了3天,一直都沒有提交,該怎么刪掉呢?你自己都忘了自己新增過哪些,有人會說,我可以 git diff xxx 一下,看看差別在刪啊,那你肯定又要花3天時間刪代碼了,并且很大的概率還會改出bug。一周過去了,你怎么向你的老板交代呢?

Git 其實還為我們提供了更好的方式,我們可以使用 git checkout -- [file] 命令讓工作區的文件回到最近一次 add 或 commit 時的狀態。 要注意 git checkout -- [file] 命令中的 -- 很重要,切記不要省略,一旦省略,該命令就變為其他意思了,后面我們再說。示例如下:

[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
This piece of code is like shit #新增代碼# 恢復到上?次 add 或 commit
[root@MyComputer:gitcode]# git checkout -- ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3

情況二:已經 add ,但沒有 commit

add 后還是保存到了暫存區呢?怎么撤銷呢?

[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
This piece of code is like shit #新增代碼# add 存?暫存區
[root@MyComputer:gitcode]# git add ReadMe
[root@MyComputer:gitcode]# git status
On branch master
Changes to be committed:(use "git restore --staged <file>..." to unstage)modified:   ReadMe

讓我們來回憶一下學過的 git reset 回退命令,該命令如果使用 --mixed 參數,可以將暫存區的內容退回為指定的版本內容,但工作區文件保持不變。那我們就可以回退下暫存區的內容了!!!示例如下:

這個git reset HEAD ReadMe命令作用:

  • 取消暫存:如果之前使用 git add ReadMe 將 ReadMe 文件添加到了暫存區(stage/index),執行 git reset HEAD ReadMe 后,該文件會從暫存區中移除。
  • 工作目錄不受影響:此命令僅修改暫存區,不會改變工作目錄中的文件內容。因此,對 ReadMe 文件的修改仍然存在,只是不再處于待提交狀態。

注意哦,HEAD:表示當前分支master的最新提交。

# --mixed 是默認參數,使?時可以省略
[root@MyComputer:gitcode]# git reset HEAD ReadMe
Unstaged changes after reset:
M       ReadMe

git status 查看一下,發現現在暫存區是干凈的,工作區有修改。

[root@MyComputer:gitcode]# git status
On branch master
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified:   ReadMeno changes added to commit (use "git add" and/or "git commit -a")

還記得如何丟棄工作區的修改嗎?

[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
This piece of code is like shit #新增代碼[root@MyComputer:gitcode]# git checkout -- ReadMe[root@MyComputer:gitcode]# git status
On branch master
nothing to commit, working tree clean[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3

恢復了!

情況三:已經 add ,并且也 commit 了

不要擔心,我們可以 git reset --hard HEAD^ 回退到上一個版本!不過,這是有條件的,就是你還沒有把自己的本地倉庫推送到遠程倉庫。還記得Git是分布式版本控制系統嗎?我們后面會講到遠程倉庫,一旦你推送到遠程倉庫,你就真的慘了……

[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
This piece of code is like shit #新增代碼
[root@MyComputer:gitcode]# git add ReadMe
[root@MyComputer:gitcode]# git commit -m "test quash"
[master 084197a] test quash1 file changed, 1 insertion(+)
[root@MyComputer:gitcode]# git reset --hard HEAD^
HEAD is now at d68ea84 add version3
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3

刪除文件

在 Git 中,刪除也是一個修改操作,我們實戰一下, 如果要刪除 file5 文件,怎么搞呢?如果你這樣做了:

[root@MyComputer:gitcode]# la
.git  ReadMe  file1  file2  file3  file4  file5  file6  file7
[root@MyComputer:gitcode]# rm file5
[root@MyComputer:gitcode]# la
.git  ReadMe  file1  file2  file3  file4  file6  file7

但這樣直接刪除是沒有用的,反而徒增煩惱, git status 命令會立刻告訴你哪些文件被刪除了:

[root@MyComputer:gitcode]# git status
On branch master
Changes not staged for commit:(use "git add/rm <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)deleted:    file5no changes added to commit (use "git add" and/or "git commit -a")

此時,工作區和版本庫就不一致了,要刪文件,目前除了要刪工作區的文件,還要清除版本庫的文件。

一般走到這里,有兩種可能:

  • 確實要從版本庫中刪除該文件
  • 不小心刪錯了

對第二種情況,很明顯誤刪,需要使用 git 來進行恢復,很簡單,我們剛學過(刪除也是修改):

[root@MyComputer:gitcode]# git checkout -- file5
[root@MyComputer:gitcode]# la
.git  ReadMe  file1  file2  file3  file4  file5  file6  file7

對于第一種情況,很明顯是沒有刪完,我們只刪除了工作區的文件。這時就需要使用 git rm 將文件從暫存區和工作區中刪除,并且 commit :

[root@MyComputer:gitcode]# git rm file5
rm 'file5'
[root@MyComputer:gitcode]# git status
On branch master
Changes to be committed:(use "git restore --staged <file>..." to unstage)deleted:    file5[root@MyComputer:gitcode]# git commit -m "deleted file5"
[master fef2e2e] deleted file51 file changed, 0 insertions(+), 0 deletions(-)delete mode 100644 file5
[root@MyComputer:gitcode]# git status
On branch master
nothing to commit, working tree clean

現在,文件就從版本庫中被刪除了。

在這里插入圖片描述
我們刪除的本質就是將工作區、暫存區、版本庫全部同步的內容全部刪除,我們刪除第一個方法就是要三步,第二種方法就是兩步。所以更推薦第二種方法。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/91006.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/91006.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/91006.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

輕量級音樂元數據編輯器Metadata Remote

簡介 什么是 Metadata Remote (mdrm) &#xff1f; Metadata Remote 是一個基于 Web 的音頻元數據編輯工具&#xff0c;旨在簡化在無頭服務器&#xff08;即沒有圖形用戶界面的服務器&#xff09;上編輯音頻文件的元數據。用戶只需使用 Docker 和瀏覽器&#xff0c;無需復雜的…

免費使用|共享服務器上線RTX3080(20GB顯存)

共享服務器也上架GPU啦 生物信息學中有很多用到GPU的場景&#xff0c;例如我們分享過的&#xff1a;利用GPU加速TensorFlow、部署本地DeepSeek&#xff0c;空間轉錄組學習手冊合輯加速。因此多種GPU供大家選擇&#xff1a;RTX5090、4080S、5070顯卡上機。為了讓此前的CPU服務器…

搭建DM數據守護集群

1環境與規劃準備3個kylin 10操作系統的虛擬機&#xff0c;規劃IP、端口、安裝目錄等。說明搭建REALTIME歸檔模式、事務一致性的數據守護名稱項初始主庫機器dm1初始備庫機器dm2監視器機器dmmon外部業務IP192.168.23.129192.168.23.130192.168.23.131內部心跳IP192.168.23.129192…

AUTOSAR進階圖解==>AUTOSAR_SRS_OCUDriver

AUTOSAR OCU驅動程序詳解 AUTOSAR標準輸出比較單元驅動程序架構與實現分析目錄 1. 概述 1.1 OCU驅動程序簡介1.2 功能概述 2. OCU驅動程序架構 2.1 架構圖2.2 層次結構 3. OCU驅動程序組件設計 3.1 組件圖3.2 接口定義 4. OCU驅動程序狀態管理 4.1 狀態圖4.2 狀態轉換 5. OCU驅…

InfluxDB 與 HTTP 協議交互進階(一)

引言 在當今數字化時代&#xff0c;數據處理的高效性和準確性成為了眾多領域關注的焦點。InfluxDB 作為一款開源的時序數據庫&#xff0c;憑借其高性能、易擴展等特性&#xff0c;在時間序列數據處理中占據了重要地位。而 HTTP 協議作為互聯網應用層的核心協議之一&#xff0c…

NAS遠程訪問新解法:OMV與cpolar的技術協同價值

文章目錄前言1. OMV安裝Cpolar2. 配置FTP公網地址3. OMV FTP 配置4. OMV FTP遠程連接前言 當家庭存儲需求突破本地邊界時&#xff0c;傳統NAS方案往往陷入"連接困境"&#xff1a;復雜的端口轉發配置、高昂的公網IP成本、以及始終存在的安全顧慮…開源解決方案OMV雖然…

vue 渲染 | 不同類型的元素渲染的方式(vue組件/htmlelement/純 html)

省流總結&#xff1a;&#xff08;具體實現見下方&#xff09; vue 組件 ——》<component :is組件名> htmlelement 元素 ——》 ref 、★ v-for ref 或是 ★ vue 的 nextTick 純 html 結構——》v-html 另外&#xff0c;當數據異步加載時&#xff0c;vue3中如何渲…

Charles中文版深度解析,輕松調試API與優化網絡請求

在現代軟件開發過程中&#xff0c;調試API、捕獲HTTP/HTTPS流量以及優化網絡性能是開發者不可避免的挑戰。特別是在處理復雜的網絡請求和驗證API接口的數據傳輸準確性時&#xff0c;開發者需要一款強大且易于使用的工具。Charles抓包工具憑借其功能強大、界面簡潔、易于操作的特…

【CF】Codeforces Round 1039 (Div. 2) E1 (二分答案求中位數)

E1. Submedians (Easy Version)題目&#xff1a;思路&#xff1a;經典不過加了點東西對于求中位數&#xff0c;我們必然要想到二分答案&#xff0c;具體的&#xff0c;對于所有大于等于 x 的數我們令其奉獻為 1&#xff0c;小于的為 -1&#xff0c;如果存在某段區間的奉獻和大于…

ESP32-S3學習筆記<8>:LEDC的應用

ESP32-S3學習筆記&#xff1c;8&#xff1e;&#xff1a;LEDC的應用1. 頭文件包含2. LEDC的配置2.1 配置定時器2.1.1 speed_mode/設置速度模式2.1.2 duty_resolution/設置占空比分辨率2.1.3 timer_num/選擇定時器2.1.4 freq_hz/設定PWM頻率2.1.5 clk_cfg/選擇LEDC的外設時鐘源2…

網絡安全第14集

前言&#xff1a;小迪安全14集&#xff0c;這集重點內容&#xff1a;0、什么是js滲透測試&#xff1f;在javascript中也存在變量和函數&#xff0c;存在可控變量和函數就有可能存在在漏洞&#xff0c;js開發的web應用和php、java開發的區別是&#xff0c;js能看得到的源代碼&am…

代碼隨想錄算法訓練營第三十三天

LeetCode.62 不同路徑 題目鏈接 不同路徑 題解 class Solution {public int uniquePaths(int m, int n) {// dp表示到達ij有多少條路徑int[][] dp new int[110][110];dp[1][1] 1;for(int i 0;i<m;i){dp[i][0] 1;}for(int j 0;j<n;j){dp[0][j] 1;}for(int i 1;i…

銀行回單OCR識別技術原理

銀行回單OCR&#xff08;光學字符識別&#xff09;技術通過結合圖像處理、模式識別和自然語言處理&#xff08;NLP&#xff09;技術&#xff0c;將紙質或電子版銀行回單中的非結構化文本&#xff08;如賬號、金額、日期等&#xff09;轉化為結構化數據。以下是其核心原理和關鍵…

Day22-二叉樹的迭代遍歷

昨天學習了遞歸遍歷&#xff1a;遞歸就是一次次的把參數壓入棧中&#xff0c;然后返回的時候還是上一次遞歸保存的參數。今天學習迭代遍歷。迭代遍歷就是用棧去模擬保存二叉樹的節點&#xff0c;然后依次去遍歷&#xff0c;只不過要注意棧的后入先出的規則。前序遍歷&#xff1…

知識蒸餾 - 通過引入溫度參數T調整 Softmax 的輸出

知識蒸餾 - 通過引入溫度參數T調整 Softmax 的輸出 flyfish import torch import torch.nn.functional as F import matplotlib.pyplot as plt import numpy as np# 設置中文字體支持 plt.rcParams["font.family"] [AR PL UMing CN] # Linux plt.rcParams[axes.uni…

Java研學-RabbitMQ(三)

一 消息通信協議 1 AMQP AMQP 是一個開放的、跨語言、跨平臺的消息協議標準&#xff0c;用于在分布式系統中傳遞業務消息。它定義了消息隊列的二進制協議格式和交互模型&#xff08;如交換機、隊列、綁定等&#xff09;&#xff0c;確保不同語言&#xff08;Java、Python、C#等…

http.client 教程-如何使用 Python 標準庫發送 HTTP 請求

http.client 教程-如何使用 Python 標準庫發送 HTTP 請求以下是 http.client 模塊的詳細使用教程&#xff0c;幫助你理解如何使用 Python 標準庫發送 HTTP 請求&#xff1a;1. http.client 概述http.client 是 Python 內置的 HTTP 客戶端庫&#xff0c;提供了底層的 HTTP 協議實…

Android-三種持久化方式詳解

持久化技術分為3種&#xff0c;文件&#xff0c;sharedPreferences存儲&#xff0c;數據庫來存儲&#xff1b; 目錄 文件存儲&#xff1a; 利用SharedPreferences中讀取數據 SQLite創建數據庫 更新 添加 刪除 查找&#xff1a; 文件存儲&#xff1a; 文件存儲是 Andr…

并發安全之鎖機制一

鎖機制一 鎖機制是計算機系統中解決并發沖突的核心工具&#xff0c;其存在和應用場景源于一個根本問題&#xff1a;當多個執行單元&#xff08;線程、進程、分布式節點&#xff09;同時訪問或修改同一份共享資源時&#xff0c;如何保證數據的正確性、一致性和系統可靠性&#x…

結合項目闡述 設計模式:單例、工廠、觀察者、代理

原文鏈接&#xff1a;https://download.csdn.net/blog/column/12433305/133862792#_1613 1、工廠模式應用 C17及之后可編譯 /*日志落地模塊的實現1.抽象落地基類2.派生子類&#xff08;根據不同落地方向進行派生&#xff09;3.使用工廠模式進行創建與表示的分離 */#ifndef _…