【Git】一篇文章帶你入門Git

1. 初識 Git

1.1 Git 是什么?

Git 是一個開源的分布式版本控制系統,用于高效地跟蹤和管理項目代碼的變更歷史(不僅僅是代碼,還有其它格式也是可以的~)

1.2 為什么要有 Git

在學習或者是工作的時候,比如編寫各種文檔,為了防止文檔丟失,更改失誤,我們不得不復制出一個副本,保留歷史記錄,方便找回歷史記錄,比如:

“設計文檔-v1”
“設計文檔-v2”
“設計文檔-v3”
“設計文檔-確定版”
“設計文檔-最終版”

每個版本有各自的內容,但最終會只有?份文檔是需要被使用的,在此之前的?作都需要這些不同版本的報告,于是每次都是復制粘貼副本,文件就越來越多,不僅文件多,更重要的是,隨著版本數量的不斷增多,我們可能記不太清每一個版本具體修改的哪些內容,文檔如此,我們編寫的項目代碼也如此!

那么,如何解決呢?

答:版本控制器?,記錄每次修改以及版本迭代的一個管理系統,目前,最主流的版本控制器就是 Git,可以控制電腦上所有格式的文件

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

【注意事項】
所有的版本控制系統,Git也不例外,其實只能跟蹤文本文件的改動,比如 txt文件,網頁,所有的程序代碼等等,版本控制系統可以告訴你每次的改動,比如在第10行加了"name",在第12行刪除了一個"Windows",而圖片、視頻等這些二進制文件,雖然也能由版本控制系統管理,但沒辦法跟蹤文件的變化,只能把?進制文件每次改動串起來,即只知道圖片從90KB改成了100KB,但到底改了啥,版本控制系統無法記錄,所有并不知道,也沒法知道~

2.?安裝 Git

接下來,我們來進行實操!安裝 Git ~

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

2.1 Linux-Ubuntu?安裝 Git

這里介紹 Ubuntu 下的安裝(因為?Centos?現在不維護了~,因此,本文不作過多介紹)

在 Ubuntu 安裝 git 相當簡單~ 一起來看看!

  • 首先查看系統有沒有安裝過 Git,輸入命令:git --version
  • 如果出現 git 版本號已經安裝:

  • 如果出現這類提示,則沒安裝
Command 'git' not found, but can be installed with:
sudo apt install git
  • 沒有則進行安裝,輸入安裝命令:sudo apt-get install git -y(在安裝過程中,出現了圖形化界面,回車即可~)
    再次輸入?git --version,就可以看到 git 版本號啦!此時,安裝完成!(是不是非常簡單!)

2.2 Windows 安裝 Git

Git 官網直接下載:Git 下載官網

  • 選擇 Windows 操作系統

  • 根據自己的電腦選擇相應的下載

下載完成后,找到下載到的文件,進行雙擊進行安裝

  • 接著,按照指示,一步步安裝~

非常簡單的~ 按照指示點下一步就好啦(勇敢牛牛,不怕困難!)

  • 檢測是否安裝好 Git,打開 Git Bash
  • 檢測是否安裝好 Git,打開 Git Bash

輸入:git -- verison,出現對應安裝的 git 版本號,就是安裝成功啦!!!

3. Git 初始化與配置

Git 的安裝是很簡單的,現在我們來看看 Git 的初始化與配置~

3.1 創建 Git 本地倉庫

可以將倉庫理解成是進行版本控制的一個文件目錄,如果我們想要對文件進行版本控制,就必須先創建一個倉庫出來!

創建?個 Git 本地倉庫對應的命令為?git init?,注意命令要在文件目錄下執行,例如:

3.2 配置 Git

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

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

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

查看配置命令為:

git config -l

刪除對應的配置命令為:

git config?[--global]?--unset user.name

git config?[--global]?--unset user.email

4. Git 工作流程 - 認識工作區、暫存區、版本庫

  • 工作區:是在電腦上要寫的代碼或者是文件的目錄

  • 暫存區(stage/index):一般存放在 .git 目錄下的 index 文件(.git/index)中,把暫存區有時也叫作索引(index)

  • 版本庫(repository):也叫倉庫,工作區有?個隱藏目錄 .git ,它不算工作區,而是 Git 的版本庫,這個版本庫里面的所有文件都可以被 Git管理起來,每個文件的修改、刪除,Git 都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可以"還原"

  • 左側為工作區,右側為版本庫,Git 的版本庫里存放了很多東西,其中最重要的是暫存區
  • 在創建版本庫的時候, Git 會自動為我們自動創建一個唯一的 master 的分支,以及指向 master 的一個指針 HEAD (分支與HAED后續介紹)
  • 當對工作區修改或者是新增的文件,執行?git add?命令,暫存區目錄樹的文件索引會被更新
  • 當執行提交操作?git commit?時,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,由????完成,這部分內容絕對不能省略,并要好好描述,是?來記錄你的提交細節,是給我們?看的。

例如:

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

Git 工作流程:

  1. 工作區:開發者實際編輯代碼的目錄
  2. 暫存區:通過?git add?將修改添加到暫存區,準備提交
  3. 本地倉庫(Local Repository):通過?git commit?將暫存區的修改保存到本地倉庫,生成一個提交記錄(上述介紹的是本地倉庫)
  4. 遠程倉庫(Remote Repository):通過?git push?將本地提交推送到遠程倉庫,如Gitee、GitHub(后續介紹如何連遠程倉庫)

截??前為?,我們已經更夠將代碼直接提交?本地倉庫了。我們可以使??git log?命令,來查看

下歷史提交記錄:

該命令顯?從最近到最遠的提交?志,并且可以看到我們 commit 時的?志消息。

如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上?--pretty=oneline?參數:

需要說明的是,我們看到的??串類似 5a250e...2111e0?的是每次提交的?commit id?(版本

號),Git 的?commit id?不是1,2,3……遞增的數字,?是?個 SHA1 計算出來的?個?常?的數字,??六進制表示.

查看.git 文件

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

1.index?就是我們的暫存區,add 后的內容都是添加到這?的。

2.HEAD?就是我們的默認指向 master 分?的指針。

?默認的 master 分?,其實就是:

打印的 5a250e9e1895753939dfcf9cba0719ee6d2111e0是什么東西呢?保存的就是當前最新

的?commit id?。

3. objects 為 Git 的對象庫,??包含了創建的各種版本庫對象及內容。當執? git add 命令
時,暫存區的?錄樹被更新,同時?作區修改(或新增)的?件內容被寫?到對象庫中的?個新的
對象中,就位于 ".git/objects" ?錄下,讓我們來看看這些對象有何?處:

查找 object 時要將?commit id?分成2部分,其前2位是?件夾名稱,后38位是?件名稱。

找到這個?件之后,?般不能直接看到??是什么,該類?件是經過?sha?(安全哈希算法)加密過的?件,好在我們可以使? git cat-file?命令來查看版本庫對象的內容:

其中,還有?? tree c9b796e175c00c170f3e2b54ce4e2dd73cf43af9 ,我們使?同樣的?

法,看看結果:

再看 ReadMe 對應的?a0423896973644771497bdc03eb99d5281615b51 :

總結?下,在本地的 git 倉庫中,有?個?件或者?錄很特殊

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

修改文件

Git ?其他版本控制系統設計得優秀,因為 Git 跟蹤并管理的是修改,???件。

什么是修改??如你新增了??,這就是?個修改,刪除了??,也是?個修改,更改了某些字符,也是?個修改,刪了?些?加了?些,也是?個修改,甚?創建?個新?件,也算?個修改。

讓我們將 ReadMe ?件進??次修改:

此時,倉庫中的 ReadMe 和我們?作區的 ReadMe 是不同的,如何查看當前倉庫的狀態呢??git

status?命令?于查看在你上次提交之后是否有對?件進?再次修改。

上?的結果告訴我們,ReadMe 被修改過了,但還沒有完成添加與提交。

?前,我們只知道?件被修改了,如果能知道具體哪些地?被修改了,就更好了。有人會說,我剛改的我知道呀!可是,你還記得你三天前寫了什么代碼嗎?或者沒寫?

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?即可:

版本回退

執??git reset?命令?于回退版本,可以指定退回某?次提交的版本。要解釋?下“回退”本質是

要將版本庫中的內容進?回退,?作區或暫存區是否回退由命令參數決定:

git reset?命令語法格式為:?git reset?[--soft?| --mixed?| --hard] [HEAD]

? HEAD 說明:
? 可直接寫成 commit id,表?指定退回的版本
? HEAD 表?當前版本
? HEAD^ 上?個版本
? HEAD^^ 上上?個版本
? 以此類推...
? 可以使? ?數字表?:
? HEAD~0 表?當前版本
? HEAD~1 上?個版本
? HEAD^2 上上?個版本
? 以此類推...

值得說的是,Git 的版本回退速度?常快,因為 Git 在內部有個指向當前分?(此處是master)的
HEAD 指針, refs/heads/master ?件?保存當前 master 分?的最新 commit id 。當我們
在回退版本的時候,Git 僅僅是給 refs/heads/master 中存儲?個特定的version,可以簡單理解
成如下?意圖:

操作一】提交 version3 后,發現 version3 編寫有誤,想回退到 version2,重新基于 version2 開始寫,這里希望工作區的內容也回退到 version2 版本,因此需要?--hard?參數,如下:

可以看到 Read 文件的內容,已經回退到 version2 了,使用?git log?查看提交?志,也發現 HEAD 指向了 version2

操作二】后悔回退到 version2,想再回到 version3

可以繼續使用 git reset 命令,回退到 version3 版本,but 我們必須要拿到 version3 的 commit id 去指定回退的版本,從上圖中,看到 git log 并不能打印出 version3 的 commit id ,如果運氣好的話,可以在終端找之前的記錄,運氣不好的話,commit id 已經被我們搞丟啦,不過不用擔心!Git 還提供了?個 git reflog 命令,可以補救?下,該命令用來記錄本地的每?次命令!!!

【操作三】在實際開發中,由于長時間開發,導致 commit id 早就找不到了,但是又想回到 version3,貌似現在不可能~

我們要知道 Git 版本回退速度非常快,因為 Git 在內部有個指向當前分支,這里是 HEAD 指針默認指向 master 分支,在.git 隱藏文件中refs/heads/master 文件里面保存了當前 master 分支的最新 commit id,當我們在回退版本的時候, Git 僅僅是給 refs/heads/master 中存儲?個特定的 version,可以簡單理解為下圖:

可以查看 refs/heads/master 文件內容,保存了最新的 commit id,如下:

如果是操作二,回退到 version3 版本,則保存的 commit id 為 version3 的

撤銷修改

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

萬幸!才寫了一行內容,就發現需要刪除了,萬一寫了很多,一直都沒有提交,可能都忘記自己新增的哪些內容了,那如何刪除呢?

Git 為我們提供了更好的方式!!!

我們可以使??git checkout -- [file]?命令讓?作區的

?件回到最近?次?add?或?commit?時的狀態。 要注意?git checkout -- [file]?命令中的

--?很重要,切記不要省略,?旦省略,該命令就變為其他意思了

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

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

讓我們來回憶?下學過的?git reset?回退命令,該命令如果使??--mixed?參數,可以將暫存區

的內容退回為指定的版本內容,但?作區?件保持不變。那我們就可以回退下暫存區的內容了!!

我們可以講版本回退到當前版本庫版本

git reset --mixed HEAD File

git reset? --hard? HEAD File

情況三:已經 add ,并且也 commit 了
不要擔?,我們可以 git reset --hard HEAD^ 回退到上?個版本!不過,這是有條件的,就是
你還沒有把??的本地版本庫推送到遠程。

?刪除本地倉庫中的文件

在 Git 中,刪除也是一個修改操作

下面演示刪除 file4 文件:

使用?rm file4??

這樣直接刪除是沒有用的,此時只是刪除了工作區的 file4,git status 會告訴你哪些文件被刪除了,但是,這個時候,工作區和版本庫就不一致了,要刪除文件,除了要刪除工作區的文件,還要清除版本庫的文件

到這里,有兩種情況:

情況一確實需要從版本庫刪除該文件

使用?git rm [文件名],將文件從工作區和暫存區中刪除,并且 commit ~

情況二刪錯了

使用?git checkout -- file4?來恢復, 刪除也是修改哦,這是剛剛學過的命令~

5.Git分支管理

在版本回退?,每次提交,Git都把它們串成?條時間線,這條時間線就可以理解為是?個分?。截?到?前,只有?條時間線,在Git?,這個分?叫主分?,即 master 分?。

再來理解?下HEAD,HEAD 嚴格來說不是指向提交,?是指向master,master才是指向提交的,所以,HEAD 指向的就是當前分?。

每次提交,master分?都會向前移動?步,這樣,隨著你不斷提交,master分?的線也越來越?,?HEAD只要?直指向master分?即可指向當前分?。

通過查看當前的版本庫,我們也能清晰的理出思路:

cat .git/HEAD
---》ref: refs/heads/master
cat .git/refs/heads/master
----》5476bdeb12510f7cd72ac4766db7988925ebd302

創建分支

Git ?持我們查看或創建其他分?,在這?我們來創建第?個??的分??dev?,對應的命令為:

 git branch #查看當前本地所有分?
----》* master
git branch dev #新建分?dev
git branch
---》dev
---》* master

當我們創建新的分?后,Git 新建了?個指針叫 dev,?*?表?當前?HEAD?指向的分?是?master?分

?。另外,可以通過?錄結構發現,新的?dev?分?:

ls .git/refs/heads/
---》dev master
cat .git/refs/heads/*
-》5476bdeb12510f7cd72ac4766db7988925ebd302
-》5476bdeb12510f7cd72ac4766db7988925ebd302

發現?前 dev 和 master 指向同?個修改。并且也可以驗證下 HEAD ?前是指向?master?的。

cat .git/HEAD
---》ref: refs/heads/master

切換分支

那如何切換到 dev 分?下進?開發呢?使??git checkout?命令即可完成切換,?例如下:

git checkout dev
-》Switched to branch 'dev'
git branch
-》* dev
-》master
cat .git/HEAD
-》ref: refs/heads/dev

我們發現 HEAD 已經指向了 dev,就表?我們已經成功的切換到了 dev 上!

接下來,在?dev?分?下修改 ReadMe ?件,新增??內容,并進??次提交操作:

 vim ReadMecat ReadMe
-》hello bit
-》write aaa for new branchgit add .git commit -m"modify ReadMe"
-》[dev 3740dce] modify ReadMe
-》1 file changed, 1 insertion(+)

現在,dev 分?的?作完成,我們就可以切換回 master 分?:

 git checkout master
-》Switched to branch 'master'
cat ReadMe
-》hello bit

切換回 master 分?后,發現ReadMe?件中新增的內容不?了!!

但是在 dev 分?上,內容還在。為什么會出現這個現象呢?我們來看看 dev 分?和 master 分?指向,發現兩者指向的提交是不?樣的:

因為我們是在dev分?上提交的,?master分?此刻的提交點并沒有變,此時的狀態如圖如下所示:

當切換到 master 分?之時,HEAD 就指向了 master,當然看不到提交了!?

合并分支

為了在 master 主分?上能看到新的提交,就需要將?dev?分?合并到?master?分?,?例如下:

 git branch
-》* dev
-》mastergit checkout master # 切換到 master 上進?合并
-》Switched to branch 'master'
git merge dev # 合并 dev 分?
-》Updating 16623e1..3740dce
-》Fast-forward
-》ReadMe | 1 +
-》1 file changed, 1 insertion(+)
cat ReadMe
-》hello bit
-》write aaa for new branch

git merge?命令?于合并指定分?到當前分?。合并后,master 就能看到 dev 分?提交的內容

了。此時的狀態如圖如下所?。

Fast-forward 代表“快進模式”,也就是直接把master指向dev的當前提交,所以合并速度?常快。
當然,也不是每次合并都能 Fast-forward。
刪除分支
合并完成后, dev 分?對于我們來說就沒?了, 那么dev分?就可以被刪除掉,注意如果當前正處于某分?下,就不能刪除當前分?,如:

git branch
-》* dev
-》master
git branch -d dev
-》error: Cannot delete branch 'dev' checked out at '/home/hyb/gitcode'

?可以在其他分?下刪除當前分?,如

 git checkout master
Switched to branch 'master'
git branch -d dev
Deleted branch dev (was bdaf528).

因為創建、合并和刪除分??常快,所以Git?勵你使?分?完成某個任務,合并后再刪掉分?,這和直接在master分?上?作效果是?樣的,但過程更安全.
合并沖突
可是,在實際分?合并的時候,并不是想合并就能合并成功的,有時候可能會遇到代碼沖突的問題。為了演?這問題,創建?個新的分? dev1 ,并切換??標分?,我們可以使? git checkout -
b dev1 ?步完成創建并切換的動作,?例如下

 git checkout -b dev1
Switched to a new branch 'dev1'git branch
* dev1
master

在?dev1?分?下修改?ReadMe??件,更改?件內容如下,并進??次提交,如:

 cat ReadMe
hello bit
write bbb for new branch # 將 aaa 該為 bbbgit add .git commit -m"modify ReadMe"
[dev1 0854245] modify ReadMe
1 file changed, 1 insertion(+), 1 deletion(-)

切換??master?分?,觀察?ReadMe??件內容:

git checkout master

Switched to branch 'master'

?cat ReadMe

hello bit

write?aaa?for new branch

我們發現,切回來之后,?件內容由變成了?的版本,這種現象很正常,我們現在也完全能理解。

此時在 master 分?上,我們對 ReadMe ?件再進??次修改,并進?提交,如下:

[wmh@hcss-ecs-1036 gitcode]$ git branch
dev1
* master
[wmh@hcss-ecs-1036 gitcode]$ vim ReadMe
[wmh@hcss-ecs-1036 gitcode]$ cat ReadMe
hello bit
write ccc for new branch
[wmh@hcss-ecs-1036 gitcode]$ git add .
[wmh@hcss-ecs-1036 gitcode]$ git commit -m"modify ReadMe"
[master c10f6d0] modify ReadMe
1 file changed, 1 insertion(+), 1 deletion(-)

現在,?master?分?和?dev1?分?各?都分別有新的提交,變成了這樣:

這種情況下,Git 只能試圖把各?的修改合并起來,但這種合并就可能會有沖突,如下所?:

[wmh@hcss-ecs-1036 gitcode]$ git merge dev1
Auto-merging ReadMe
CONFLICT (content): Merge conflict in ReadMe
Automatic merge failed; fix conflicts and then commit the result.
[wmh@hcss-ecs-1036 gitcode]$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: ReadMe
no changes added to commit (use "git add" and/or "git commit -a")

發現 ReadMe ?件有沖突后,可以直接查看?件內容,要說的是 Git 會? <<<<<<<,=======,

>>>>>>> 來標記出不同分?的沖突內容,如下所?:

此時我們必須要?動調整沖突代碼,并需要再次提交修正后的結果!!(再次提交很重要,切勿忘

記)

到這?沖突就解決完成,此時的狀態變成了:

分支管理策略

通常合并分?時,如果可能,Git 會采??Fast forward?模式。還記得如果我們采??Fast

forward?模式之后,形成的合并結果是什么呢?

在這種?Fast forward?模式下,刪除分?后,查看分?歷史時,會丟掉分?信息,看不出來最新提

交到底是 merge 進來的還是正常提交的。

但在合并沖突部分,我們也看到通過解決沖突問題,會再進??次新的提交,得到的最終狀態為:

那么這就不是?Fast forward?模式了,這樣的好處是,從分?歷史上就可以看出分?信息。例如我

們現在已經刪除了在合并沖突部分創建的?dev1?分?,但依舊能看到 master 其實是由其他分?合并得到

Git ?持我們強制禁??Fast forward?模式,那么就會在 merge 時?成?個新的?commit?,這樣,

從分?歷史上就可以看出分?信息

git merge --no-ff -m "msg" branch_name

bug分支

假如我們現在正在 dev2 分?上進?開發,開發到?半,突然發現 master 分?上?有 bug,需要
解決。在Git中,每個 bug 都可以通過?個新的臨時分?來修復,修復后,合并分?,然后將臨時分?刪除。
可現在 dev2 的代碼在?作區中開發了?半,還?法提交,怎么辦?

Git 提供了?git stash?命令,可以將當前的?作區信息進?儲藏,被儲藏的內容可以在將來某個時

間恢復出來。

[wmh@hcss-ecs-1036 gitcode]$ git stash

Saved working directory and index state WIP on dev2: 41b082f modify ReadMe
[wmh@hcss-ecs-1036 gitcode]$ git status
On branch dev2
nothing to commit, working tree clean

? git status 查看?作區,就是?凈的(除?有沒有被 Git 管理的?件),因此可以放?地創建分
?來修復bug。
儲藏 dev2 ?作區之后,由于我們要基于master分?修復 bug,所以需要切回 master 分?,再新
建臨時分?來修復 bug,?例如下:

[wmh@hcss-ecs-1036 gitcode]$ git checkout master # 切回master
Switched to branch 'master'
[wmh@hcss-ecs-1036 gitcode]$ git checkout -b fix_bug # 新建并切換到 fix_bug 分?
Switched to a new branch 'fix_bug'
[wmh@hcss-ecs-1036 gitcode]$ vim ReadMe
[wmh@hcss-ecs-1036 gitcode]$ cat ReadMe
hello bit
write bbb for new branch
a,b,c,d,e # 修復bug--忘記寫e
[wmh@hcss-ecs-1036 gitcode]$ git add ReadMe # 重新add,commit
[wmh@hcss-ecs-1036 gitcode]$ git commit -m"fix bug"
[fix_bug 4bbc0c4] fix bug
1 file changed, 1 insertion(+), 1 deletion(-)

修復完成后,切換到?master?分?,并完成合并,最后刪除?fix_bug?分?。

?此,bug 的修復?作已經做完了,我們還要繼續回到?dev2?分?進?開發。切換回?dev2?分?

[wmh@hcss-ecs-1036 gitcode]$ git checkout dev2
Switched to branch 'dev2'
[wmh@hcss-ecs-1036 gitcode]$ git status
On branch dev2
nothing to commit, working tree clean

?作區是?凈的,剛才的?作現場存到哪去了???git stash list?命令看看

[wmh@hcss-ecs-1036 gitcode]$ git stash list
stash@{0}: WIP on dev2: 41b082f modify ReadMe

?作現場還在,Git 把 stash 內容存在某個地?了,但是需要恢復?下,如何恢復現場呢?我們可以使? git stash pop?命令,恢復的同時會把 stash 也刪了,?例如下:

[wmh@hcss-ecs-1036 gitcode]$ git stash pop
On branch dev2
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: ReadMe
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (4f873250b3503687b5efd26196776aee7e3724c2)

再次查看的時候,我們已經發現已經沒有現場可以恢復了。

但我們注意到了,修復 bug 的內容,并沒有在?dev2?上顯?。此時的狀態圖為:

Master 分??前最新的提交,是要領先于新建 dev2 時基于的 master 分?的提交的,所以我們
在 dev2 中當然看不?修復 bug 的相關代碼。
我們的最終?的是要讓 master 合并 dev2 分?的,那么正常情況下我們切回 master 分?直接合
并即可,但這樣其實是有?定?險的。
是因為在合并分?時可能會有沖突,?代碼沖突需要我們?動解決(在 master 上解決)。我們?法保證對于沖突問題可以正確地?次性解決掉,因為在實際的項?中,代碼沖突不只?兩?那么簡單,有可能??上百?,甚?更多,解決的過程中難免?誤出錯,導致錯誤的代碼被合并到 master 上。 此時的狀態為:

解決這個問題的?個好的建議就是:最好在??的分?上合并下?master?,再讓?master?去合并

dev?,這樣做的?的是有沖突可以在本地分?解決并進?測試,?不影響?master?。此時的狀態

為:.

6.Git遠程操作

下面演示在gitee上創建遠程倉庫

創建遠程倉庫

上面的.gitignore是為了在上傳時過濾掉不重要的文件,分支模型選單分支模型就夠用了,或者選生產/開發模型。

當然,如果創建倉庫的時候沒有添加.gitignore文件,可以在本地倉庫創建.gitignore文件

將遠程倉庫克隆到本地

下面僅介紹兩種方式:HTTPS,SSH

SSH

然后查看是否有 id_rsa 和 id_rsa.pub這兩個文件

如果沒有的話,需要創建ssh.key

ssh-keygen -t rsa -C "your_email@example.com"

注意:上面的郵箱要和gitee上綁定的郵箱一致

如果有的話,打開看一下

將上面的內容全部復制下來,然后再打開gitee的設置

配置SSH公鑰

三板斧

git?add

git commit -m "XXX"

git push

當我們從遠程倉庫克隆后,實際上 Git 會?動把本地的 master 分?和遠程的 master 分?對應起來,并且,遠程倉庫的默認名稱是?origin?。在本地我們可以使??git remote?命令,來查看遠程庫的

信息,如:

git remote

或者,??git remote -v?顯?更詳細的信息:

git remote -v? origin

提交時要注意,如果我們之前設置過全局的 name 和 e-mail,這兩項配置需要和 gitee 上配置的用戶名和郵箱?致,否則會出錯。或者從來沒有設置過全局的 name 和 e-mail,那么我們第?次提交時也 會報錯。這就需要我們重新配置下了,同樣要注意需要和 gitee 上配置的??名和郵箱?致。如何配置 已講過,在這?就不再贅述。

到這?我們已經將內容提交?本地倉庫中,如何將本地倉庫的內容推送?遠程倉庫呢,需要使??git? push 命令,該命令?于將本地的分?版本上傳到遠程并合并,命令格式如下:

拉取遠程倉庫內容

給命令配置起別名

在我們使? Git 期間,有些命令敲的時候著實讓?頭疼(太?了。。),幸運的是,git?持對命令進?簡化!

舉個例?,將?git status?簡化為?git st?,對應的命令為:

git config --global alias .st status

--global?參數是全局參數,也就是這些命令在這臺電腦的所有Git倉庫下都有?。如果不加,那只

針對當前的倉庫起作?。

標簽管理

標簽 tag ,可以簡單的理解為是對某次 commit 的?個標識,相當于起了?個別名。例如,在項?
發布某個版本的時候,針對最后?次 commit 起?個 v1.0 這樣的標簽來標識?程碑的意義。
這有什么?呢?相較于難以記住的 commit id , tag 很好的解決這個問題,因為 tag ?定要給?
個讓?容易記住,且有意義的名字。當我們需要回退到某個重要版本時,直接使?標簽就能很快定位到。

創建標簽
在Git中打標簽?常簡單,?先,切換到需要打標簽的分?上
然后,敲命令 git tag [name] 就可以打?個新標簽
可以?命令 git tag 查看所有標簽
可以? git show [tagname] 查看標簽信息。

當然,并非只能給最新的提交打標簽,使用如下命令查看commit id,然后在git tag [版本] [commit id]

Git 還提供可以創建帶有說明的標簽,?-a指定標簽名,-m指定說明?字,格式為:

git tag -a [name] -m "XXX" [commit_id]

刪除標簽

因為創建的標簽都只存儲在本地,不會?動推送到遠程。所以,打錯的標簽可以在本地安全刪除。

推送標簽

如果要推送某個標簽到遠程,使?命令

git push origin <tagname>

當然,如果你本地有很多標簽,也可以?次性的全部推送到遠端:

git push origin --tags

本地刪除遠程標簽

git push origin --delete <標簽名>

7.多人協作一

目標:遠程?master?分支下 file.txt 文件新增代碼 “aaa”,“bbb”
實現:由開發者1新增aaa,開發者2新增bbb
條件:在一個分支下協作完成

我們創建一個分支 dev,在分支 dev 上完成這些操作

git branch?查看本地分支,只有一個 master ;git branch -r?查看遠程分支,我們可以看到遠程里面也只有 master,沒有新創建的 dev

將 dev 分支從遠程拉取下來

在?windows?上面模擬開發者2,首先需要將倉庫克隆到 windows 下,隨便選取一個目錄,shift + 右鍵

此時我們準備工作完成,接下來我們讓開發者1新增 aaa,開發者2新增 bbb

我們可以分別用Linux機器和Windows機器來模擬開發者1和開發者2,依舊是采用我們上面已經創建的倉庫?remote-gitcode

1. 開發者1 創建一個分支dev

開發者1 創建一個分支?dev,然后開發者1和開發者2都同時在這個分支上進行操作。

👉 你在哪個分支上工作,就從那個分支 push 自己:

2. 開發者2 拉取遠程倉庫

打開 bash 進行 clone 遠程倉庫:

當 clone 的時候,本地倉庫就只有?master?分支,那么就要獲取?dev?分支。如果本地還沒有?dev,Git 會自動從遠程的?origin/dev?創建一個對應的本地分支,并自動追蹤它

git checkout -b dev origin/dev

將本地?dev?分支和遠程的?dev?分支進行建立鏈接,開發者2的本地也具有?dev?分支了。

3. 開發者1 對遠程倉庫進行推送

切換到開發者2中,可以看到正常的進行對?file.txt?文件進行修改,可是 push 的時候卻發生錯誤,提示當前的本地與遠程倉庫有區別!

我們應該先進行 pull 來更新本地倉庫!

git pull origin dev

再次 push 又會發現失敗,出現合并沖突問題,需要手動進行解決!!!

解決完沖突后,這里要特別注意,要重新進行?add .?和?commit -m?來重新進行推送,再次進行 push 就可以上傳成功,開發者2 新添加的?bbb?內容成功推送。

此時可以在遠程的?dev?分支上看到我們想要得到的結果:file.txt?文件內有開發者1添加的“aaa”,有開發者2添加的?bbb

接下來就可以用?master?來合并?dev?分支!!!

可以看到?master?分支上沒有這兩行代碼!

4. 將內容合并至 master

4.1 提交 Pull?Request

開發者1 和開發者2 在遠程倉庫創建一個 Pull Request,提交合并請求。

4.2 本地操作:
  • 在?dev?分支和?master?分支上,執行如下命令:
git checkout master
git merge dev
git push origin master

由于在?master?上進行?merge?dev,可能會導致沖突,因此應該在本地的?dev?上進行 merge?master。這樣就算有沖突,也可以在本地解決。解決完沖突后,再用?master?來 merge?dev,就不會有問題。

步驟如下:

這樣就可以看到?master?分支上的?file.txt?被同步更新了。
在這里插入圖片描述

完成后,可以同時讓開發者1和開發者2對?dev?分支進行刪除。
在這里插入圖片描述

8.多人協作二

1. 本地創建分支

要保證本地的?master?是最新的,先?pull?操作,然后再次創建?dev?分支。

開發者1 操作

開發者2 操作

可以看到每次開發都是自己創建的分支,然后進行 push,每次都能成功,不會遇到沖突的問題。因為我們是在最新的?master?上創建的分支,然后自己創建的分支只有自己開發的時候能夠用上,所以不會出現 push 沖突的問題。

2. 拉取遠程的 feature-2 分支

突然,開發者2生病了,開發者1需要擔起開發?feature-2?分支的重任!這時需要從遠程拉取?feature-2?分支進行開發。此時,我們又回到了多人開發一中的情形,開發者1和開發者2在同一個分支開發。

拉取遠程分支內容

使用如下命令拉取遠程?feature-2?分支的內容:

git pull origin feature-2

拉取到遠程的?origin/feature-2?分支后,本地沒有這個分支,所以需要創建并切換至?feature-2?分支。

git checkout -b feature-2 origin/feature-2

此時,開發者1就能夠在?feature-2?分支上繼續開發

3. 合并 feature-1 和 feature-2 至 master

現在就是又遇到了合并feature-1的問題,為了避免沖突 我們就還是再feature-1分支上來合并master

每次feature-1合并master之前 就要先保證master是最新的,所以要切換到master進行pull再用master進行合并merge

當我們merge master的時候跳轉到當前頁面就說明沒用任何問題,沒用產生沖突,ctrl + x 就會退出該頁面!
在這里插入圖片描述

?最后,開發者1和開發者2將各自的?feature-1?和?feature-2?分支合并到?master?分支上。

4. 刪除遠程分支

刪除遠程分支后,本地仍然可以看到已刪除的遠程分支。此時,可以使用以下命令移除遠程已刪除的分支記錄:

git remote prune origin

以上就是Git企業常用的內容了,需要我們勤加聯系!!!!

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

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

相關文章

8 基于機器學習進行遙感影像的地物分類-以隨機森林為例

目錄 1 讀取數據 2 數據預處理 3 模型訓練 4 精度分析 5 模型預測 1 讀取數據 1.右鍵數據所在文件夾,用pycharm打開為項目 2.在settings中設置python環境為先前配置的帶GDAL和sklearn的環境 3.新建一個文件夾命名為code來存放代碼,在code文件夾中新建一個rfc.py

極簡版 Nginx 反向代理實驗步驟

以下是最核心的反向代理實現步驟&#xff0c;專注于 “客戶端→Nginx 代理→后端服務” 的基礎轉發功能&#xff1a;一、準備 2 臺服務器角色IP 示例需安裝軟件代理服務器192.168.1.10Nginx后端服務器192.168.1.11Nginx/Apache二、后端服務器配置&#xff08;192.168.1.11&…

Windsurf 插件正式登陸 JetBrains IDE:讓 AI 直接在你的 IDE 里“打工”

那天你說,我們可以永遠在一起——成了我聽到的最高興的,而后知后覺的謊言。 而今天,AI 說:“我可以幫你寫完這段代碼。” —— 這才是真正的“永遠在一起”。 最近,AI 編程工具賽道迎來一場“潛行式革命”:Windsurf Wave 7 正式發布 JetBrains IDE 插件版本,徹底打破“A…

188. Java 異常 - Java 異常處理規范

文章目錄188. Java 異常 - Java 異常處理規范&#x1f4dc; 什么是“Catch or Specify Requirement”&#xff1f;? 兩種滿足方式方法一&#xff1a;使用 try-catch 捕獲異常方法二&#xff1a;使用 throws 聲明異常? 不遵守規則會怎樣&#xff1f;&#x1f4a1; 哪些異常必須…

泛型通配符 T、E、K、V、?

在Java后端開發中&#xff0c;你一定在寫集合類或工具類時&#xff0c;見過 T、E、K、V、? 這樣的泛型通配符。但你是否有過以下疑惑&#xff1a; T、E、K、V 到底有什么區別&#xff1f;為什么大家都用這些字母&#xff1f;List<?> 和 List 有什么不同&#xff1f;什么…

基于腳手架微服務的視頻點播系統-數據管理與網絡通信部分的預備工作

基于腳手架微服務的視頻點播系統-數據管理與網絡通信部分的預備工作一.數據管理二.網絡通信2.1客戶端通信模塊及測試用例的實現2.2MockServer搭建的相關接口介紹2.3MockServer的搭建示例一.數據管理 在前?的實現中&#xff0c;程序中的數據、以及界?操作等全部攪合在?起&am…

html表單登錄模式代碼

使用的是Content-Typeapplication/x-www-form-urlencoded形式如代碼如下的html&#xff0c;后端沒寫下去&#xff1a;<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>管理員登錄</title><…

NLP:Transformer之self-attention(特別分享3)

本文目錄&#xff1a;一、核心思想&#xff1a;一句話概括二、計算流程的直觀比喻三、分步計算詳解&#xff08;附數字例子&#xff09;第 1 步&#xff1a;創建 Query, Key, Value 向量第 2 步&#xff1a;計算注意力分數第 3 步&#xff1a;縮放并應用 Softmax第 4 步&#x…

25、優化算法與正則化技術:深度學習的調優藝術

學習目標:深入理解各種優化算法的原理和適用場景,掌握學習率調度的方法和策略,學會使用Dropout、批歸一化等正則化技術,理解早停和驗證策略,建立深度學習調優的系統性知識。 深度學習的成功不僅依賴于精巧的模型架構,更在于巧妙的訓練策略。如果說網絡架構是房屋的設計圖…

Netty-01-NIO前置知識

目錄 NIO三大組件 一. ByteBuffer 基本用法 DirectByteBuffer與HeapByteBuffer對比 字符串轉ByteBuffer ByteBuffer.wrap(byte[] ) 粘包與拆包 文件編程 零拷貝transferTo 二. 阻塞與非阻塞Channel 三. Selector SelectionKey&#xff08;重點&#xff09; Select…

知識點17:多Agent系統架構設計模式

知識點17&#xff1a;多Agent系統架構設計模式 核心概念 掌握系統架構思維&#xff0c;理解多Agent系統的設計原則和模式 架構設計核心概念 在構建多Agent系統時&#xff0c;良好的架構設計是系統成功的關鍵。本節將介紹多Agent系統架構設計中的核心概念&#xff0c;包括單點瓶…

數據庫造神計劃第五天---增刪改查(CRUD)(1)

&#x1f525;個人主頁&#xff1a;尋星探路 &#x1f3ac;作者簡介&#xff1a;Java研發方向學習者 &#x1f4d6;個人專欄&#xff1a;《從青銅到王者&#xff0c;就差這講數據結構&#xff01;&#xff01;&#xff01;》、 《JAVA&#xff08;SE&#xff09;----如此簡單&a…

基于Vue3的人工智能生成內容標識服務平臺前端頁面設計

效果圖&#xff1a;素材庫&#xff1a;App.vue<template><div id"app"><!-- 頭部導航 --><Header /><!-- 主要內容區域 --><main class"main-content"><div class"container"><!-- 強制性國家標準…

使用 MyCat 實現 MySQL 主從讀寫分離

文章目錄使用 MyCat 實現 MySQL 主從讀寫分離完整指南一、MySQL 讀寫分離基礎概述1.1 讀寫分離工作原理1.2 為什么需要讀寫分離1.3 讀寫分離的兩種實現方式主流讀寫分離中間件對比二、MyCat 中間件簡介2.1 MyCat 核心功能2.2 MyCat 適用場景三、環境準備與 MyCat 安裝3.1 前提&…

物聯網傳感器檢測實驗

/*------------------------------------------------------------------------------ * @文件名 : handle * @描述 : 用戶處理函數 * @作者 : 物聯網項目組 * @日期 : 2023/04/01 * @版本 : V0.0.2 *****************************…

什么是dirsearch、xray、durpsuite、sqlmap?

你提到的 dirsearch、xray、durpsuite&#xff08;可能為筆誤&#xff0c;推測是 ??Burp Suite??&#xff09;和 sqlmap 均為網絡安全領域中常用的工具&#xff0c;主要用于 Web 應用的安全測試、漏洞檢測或滲透測試。以下分別詳細說明&#xff1a;??1. dirsearch????…

lamp腳本部署

#!/bin/bash #關閉防火墻和selinux systemctl stop firewalld systemctl disable firewalld setenforce 0 #配置yum網絡源 echo “正在配置yum倉庫” rm -rf /etc/yum.repos.d/* wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo &am…

Redis Hash數據類型深度解析:從命令、原理到實戰場景

前言 在Redis的眾多數據結構中&#xff0c;Hash&#xff08;哈希&#xff09;類型占據著至關重要的地位。Redis本身就是一個高性能的鍵值&#xff08;Key-Value&#xff09;數據庫&#xff0c;其底層的鍵值對便是通過哈希方式組織的。而Hash數據類型則更進一步&#xff0c;它允…

【C++實戰?】解鎖C++文件操作:從基礎到實戰的進階之路

目錄一、文件操作的基本概念1.1 文件的分類與打開方式1.2 文件流的概念與相關類&#xff08;ifstream、ofstream、fstream&#xff09;1.3 文件操作的基本流程二、文本文件的讀寫實戰2.1 文本文件的打開與關閉2.2 文本文件的寫入操作&#xff08;<< 運算符、write 函數&a…

從C++開始的編程生活(9)——模板初階

前言 本系列文章承接C語言的學習&#xff0c;需要有C語言的基礎才能學會哦~ 第8篇主要講的是有關于C的模板初階。 C才起步&#xff0c;都很簡單&#xff01;&#xff01; 目錄 前言 模板初階 基本語法 函數模板的實例化 顯式實例化的作用 類模板 基本語法 模板初階 模板…