柚子快報(bào)激活碼778899分享:Git 操作總結(jié)
柚子快報(bào)激活碼778899分享:Git 操作總結(jié)
1. 安裝、Git 環(huán)境配置
1.1 安裝 Git
官方版本可以在 Git 官方網(wǎng)站下載:打開 https://git-scm.com/download/win,選擇相應(yīng)版本即可。
Git 安裝完成后,可以在開始菜單中看到 Git 的三個(gè)啟動(dòng)圖標(biāo)(Git Bash、Git CMD、Git GUI)。Git Bash 是 Git 配套的一個(gè)控制臺(tái),在空白處右鍵,點(diǎn)擊 Open Git Bash here 即可開始使用 Git。
?
1.2 Git 環(huán)境配置:通過(guò) git config 命令配置用戶信息
安裝完 Git 之后,要做的第一件事就是設(shè)置你的用戶名和郵件地址。 這一點(diǎn)很重要,因?yàn)槊恳粋€(gè) Git 提交都會(huì)使用這些信息,它們會(huì)寫入到你的每一次提交中,不可更改。
1.2.1 配置用戶名和郵件地址
git config --global user.name "abigailqin"
git config --global user.email abigailqin@csdn.net
注意:git config --global user.name "xxxx",要有雙引號(hào)。如果使用了 --global 選項(xiàng),那么該命令只需要運(yùn)行一次,因?yàn)橹鬅o(wú)論你在該系統(tǒng)上做任何事情, Git 都會(huì)使用那些信息。
如果想針對(duì)特定項(xiàng)目使用不同的用戶名稱與郵件地址時(shí),可以在那個(gè)項(xiàng)目目錄下運(yùn)行沒有 --global 選項(xiàng)的命令來(lái)配置。
1.2.2 查看配置
(1)使用 git config --list 命令列出 Git 當(dāng)前能找到的所有配置
(2)使用 git config
1.3 SSH Key
SSH Key 是一種用于在 Git 版本控制系統(tǒng)中進(jìn)行安全身份驗(yàn)證的機(jī)制。它是一對(duì)密鑰,包括公鑰和私鑰,公鑰存儲(chǔ)在 Git 服務(wù)器上,而私鑰則存儲(chǔ)在用戶的本地計(jì)算機(jī)上。Git SSH Key 通過(guò)使用加密技術(shù),確保只有具有正確私鑰的用戶才能訪問(wèn) Git 倉(cāng)庫(kù)。SSH Key 允許用戶通過(guò) SSH 連接到 Git 服務(wù)器,而不需要輸入密碼,這種身份驗(yàn)證方式比傳統(tǒng)的基于用戶名和密碼的身份驗(yàn)證更加安全和可靠。
向 Git 服務(wù)器提供 SSH 公鑰的過(guò)程在所有操作系統(tǒng)上都是相似的:首先,需要確認(rèn)自己是否已經(jīng)擁有密鑰。 默認(rèn)情況下,用戶的 SSH 密鑰存儲(chǔ)在其 ~/.ssh 目錄下,進(jìn)入該目錄并列出其中內(nèi)容,便可以快速確認(rèn)自己是否已擁有密鑰。
我們需要尋找一對(duì)以 id_dsa 或 id_rsa 命名的文件,其中一個(gè)帶有 .pub 擴(kuò)展名。 .pub 文件是公鑰,另 一個(gè)則是私鑰。 如果找不到這樣的文件(或者根本沒有 .ssh 目錄),可以通過(guò)運(yùn)行 ssh-keygen 程序來(lái)創(chuàng)建它們。首先 ssh-keygen 會(huì)確認(rèn)密鑰的存儲(chǔ)位置(默認(rèn)是 .ssh/id_rsa),然后它會(huì)要求你輸入兩次密鑰口令,如果你不想在使用密鑰時(shí)輸入口令,將其留空即可。
現(xiàn)在,進(jìn)行了上述操作的用戶需要將各自的公鑰發(fā)送給?Git 服務(wù)器管理員(假設(shè)服務(wù)器正在使用基于公鑰的 SSH 驗(yàn)證設(shè)置),復(fù)制?.pub 文件內(nèi)容,并將其通過(guò)郵件發(fā)送即可。
1.4?定制 Git 環(huán)境
Git 自帶 git config 工具來(lái)幫助設(shè)置控制 Git 外觀和行為的配置變量。
這些 Git 配置變量存儲(chǔ)在三個(gè)不同的位置:
1. /etc/gitconfig 文件(Git 安裝目錄): 包含系統(tǒng)上每一個(gè)用戶及他們倉(cāng)庫(kù)的通用配置。 如果在執(zhí)行 git config 時(shí)帶上 --system 選項(xiàng),那么它就會(huì)讀寫該文件中的配置變量?(由于它是系統(tǒng)配置文件,因此你需要管理員或超級(jí)用戶權(quán)限來(lái)修改它)。
2. ~/.gitconfig 或 ~/.config/git/config 文件:只針對(duì)當(dāng)前用戶。 可以傳遞 --global 選項(xiàng)讓 Git 讀寫此文件,這會(huì)對(duì)你系統(tǒng)上所有的倉(cāng)庫(kù)生效。
3. 當(dāng)前使用倉(cāng)庫(kù)的 Git 目錄中的 config 文件(即 .git/config):針對(duì)該倉(cāng)庫(kù)。 可以傳遞 --local 選項(xiàng)讓 Git 強(qiáng)制讀寫此文件,雖然默認(rèn)情況下用的就是它(當(dāng)然,你需要進(jìn)入這個(gè) Git 倉(cāng)庫(kù)中才能讓該選項(xiàng)生效)。
每一個(gè)級(jí)別會(huì)覆蓋上一級(jí)別的配置,所以 .git/config 的配置變量會(huì)覆蓋 /etc/gitconfig 中的配置變量。
使用?git config --list --show-origin?查看所有的配置以及它們所在的文件。
1.3.1?忽略文件 .gitignore
在 Git 工作區(qū)的根目錄下(與.git 目錄在同一級(jí)別)創(chuàng)建一個(gè)特殊的 .gitignore 文件,然后把要忽略的文件名填進(jìn)去,Git 在每次進(jìn)行提交的時(shí)候就會(huì)自動(dòng)忽略這些文件。我們一般不需要從頭開始編輯?.gitignore 文件,已經(jīng)有各種現(xiàn)成的種配置文件,只需要組合一下就可以使用了。所有配置文件可以直接在線瀏覽:
Python.gitignore · master · GitCode / Gitignore · GitCode
示例:
忽略文件的原則:
忽略操作系統(tǒng)自動(dòng)生成的文件,比如縮略圖等;忽略編譯生成的中間文件、可執(zhí)行文件等,也就是如果一個(gè)文件是通過(guò)另一個(gè)文件自動(dòng)生成的,那自動(dòng)生成的文件就沒必要放進(jìn)版本庫(kù),比如Java編譯產(chǎn)生的.class文件;忽略帶有敏感信息的配置文件,比如存放口令的配置文件。
假設(shè)你在 Windows 下進(jìn)行 Python 開發(fā):
Windows 會(huì)自動(dòng)在有圖片的目錄下生成隱藏的縮略圖文件,如果有自定義目錄,目錄下會(huì)有 Desktop.ini 文件,需要忽略上述 Windows 自動(dòng)生成的垃圾文件;此外,還需忽略 Python 編譯產(chǎn)生的.pyc、.pyo、dist等文件或目錄;再加上你自己定義的文件,得到一個(gè)完整的 .gitignore 文件(內(nèi)容如下),最后一步就是把 .gitignore 也提交到 Git,就完成了。
<.gitignore>
# Windows:
Thumbs.db
ehthumbs.db
Desktop.ini
# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build
# My configurations:
db.ini
deploy_key_rsa
1.3.2?強(qiáng)制添加被忽略文件 git?add -f
有時(shí)候可能想添加一個(gè)文件到 Git,但發(fā)現(xiàn)添加不了,因?yàn)檫@個(gè)文件被 .gitignore 忽略了。如果你確實(shí)想添加該文件,可以用 -f 強(qiáng)制添加到 Git。
$ git add -f App.class
盡管可以用 git add -f 強(qiáng)制將此文件添加進(jìn)去,但建議你添加一條例外規(guī)則:把指定文件排除在 .gitignore 規(guī)則外,寫法是:?!+文件名。
<.gitignore>
# 排除所有 .class 文件
*.class
# 不排除 .App.class 文件
!App.class
如果覺得添加不了是 .gitignore 寫得有問(wèn)題,需要找出來(lái)到底哪個(gè)規(guī)則寫錯(cuò)了,可以用 git check-ignore 命令檢查。
$ git check-ignore -v App.class
.gitignore:3:*.class App.class
# 返回結(jié)果說(shuō)明:.gitignore 的第3行規(guī)則忽略了該文件,因此修訂第3行規(guī)則即可。
1.3.3?配置別名 git config --global alias.xx yyyy?
使用 Git 命令時(shí),可以通過(guò)配置別名的方式簡(jiǎn)化命令。比如,給?git status 命令配置一個(gè)別名: git st,輸入 git st 就比輸入 git status 簡(jiǎn)單方便很多。下述這行命令就是告訴 Git,以后 st 就表示 status,--global參數(shù)是全局參數(shù),表示這個(gè)命令在這臺(tái)電腦的所有 Git 倉(cāng)庫(kù)下都可以使用。
$ git config --global alias.st status
示例-1:用 ci 表示 commit
$ git config --global alias.ci commit
$ git ci -m "sth."
示例-2:用 last 表示 log -1,git last 表示 git log -1,即顯示最近一次的提交
$ git config --global alias.last 'log -1'
$ git last
示例-3:用 unstage 表示?reset HEAD,git unstage
1.5?獲取幫助
如果在使用 Git 時(shí)需要獲取幫助,可以使用 help 命令找到 Git 命令的使用手冊(cè):
$ git help
例如,要想獲得 config 命令的手冊(cè),執(zhí)行 git help config 命令或?git config --help 命令后將跳轉(zhuǎn)到使用手冊(cè)對(duì)應(yīng)頁(yè):
2. Git 倉(cāng)庫(kù)
2.1 工作目錄(working tree\working directory)、暫存區(qū)域(staging area\index)和 Git 倉(cāng)庫(kù)(repository\git repository)
Git 項(xiàng)目有三個(gè)工作區(qū)域的概念:工作目錄、暫存區(qū)域和 Git 倉(cāng)庫(kù)。
Git 倉(cāng)庫(kù)目錄是 Git 用來(lái)保存項(xiàng)目的元數(shù)據(jù)和對(duì)象數(shù)據(jù)庫(kù)的地方。 這是 Git 中最重要的部分,從其它計(jì)算機(jī)克隆倉(cāng)庫(kù)時(shí),拷貝的就是這里的數(shù)據(jù)。工作目錄是對(duì)項(xiàng)目的某個(gè)版本獨(dú)立提取出來(lái)的內(nèi)容,是你在電腦里能看到的目錄。 這些從 Git 倉(cāng)庫(kù)的壓縮數(shù)據(jù)庫(kù)中提取出來(lái)的文件,放在磁盤上供你使用或修改。暫存區(qū)域是一個(gè)文件,保存了下次將提交的文件列表信息,一般在 Git 倉(cāng)庫(kù)目錄中,有時(shí)候也被稱作 ‘索引’(index),不過(guò)一般說(shuō)法還是叫暫存區(qū)域(staging area)。
基本的 Git 工作流程如下:
在工作目錄中修改文件。暫存文件,將文件的快照放入暫存區(qū)域。提交更新,找到暫存區(qū)域的文件,將快照永久性存儲(chǔ)到 Git 倉(cāng)庫(kù)目錄。
如果 Git 目錄中保存著的特定版本文件,就屬于已提交狀態(tài)。 如果作了修改并已放入暫存區(qū)域,就屬于已暫存狀態(tài)。 如果自上次取出后,作了修改但還沒有放到暫存區(qū)域,就是已修改狀態(tài)。
在你的工作目錄下的每一個(gè)文件都不外乎這兩種狀態(tài):已跟蹤或未跟蹤。 已跟蹤的文件是指那些被納入了版本控制的文件,在上一次快照中有它們的記錄,在工作一段時(shí)間后,它們的狀態(tài)可能處于未修改,已修改或已放入暫存區(qū)。 工作目錄中除已跟蹤文件以外的所有其它文件都屬于未跟蹤文件,它們既不存在于上次快照的記錄中,也沒有放入暫存區(qū)。 初次克隆某個(gè)倉(cāng)庫(kù)的時(shí)候,工作目錄中的所有文件都屬于已跟蹤文件,并處于未修改狀態(tài)。
2.2 使用 git init 在現(xiàn)有目錄中初始化倉(cāng)庫(kù)
git init 用于在當(dāng)前目錄下初始化一個(gè)新的 Git 倉(cāng)庫(kù)。初始化后,會(huì)在當(dāng)前目錄下創(chuàng)建一個(gè)名為 .git的隱藏文件夾,其中包含了 Git 倉(cāng)庫(kù)的所有元數(shù)據(jù)和歷史記錄。執(zhí)行該命令后,當(dāng)前目錄下的所有文件和子目錄都會(huì)被納入 Git 的版本控制中,你可以開始添加、修改和提交文件到 Git 倉(cāng)庫(kù)。
2.3 使用 git clone?克隆現(xiàn)有的倉(cāng)庫(kù)
語(yǔ)法:git clone <遠(yuǎn)程倉(cāng)庫(kù)地址>,例如,如果要將 GitHub 上的一個(gè)倉(cāng)庫(kù)復(fù)制到本地,可以使用以下命令:git clone https://github.com/username/repo.git,其中,username?是 GitHub 用戶名,repo?是倉(cāng)庫(kù)名稱。
3. 基礎(chǔ)操作
3.1 檢查文件狀態(tài) git status
要查看哪些文件處于什么狀態(tài),可以用 git status 命令。
該命令顯示了當(dāng)前所在分支(當(dāng)前的分支名是 master,這是默認(rèn)的分支名),并告訴你當(dāng)前工作目錄中哪些文件被修改了、哪些文件被添加或刪除了、哪些文件已經(jīng)被暫存了等等。
git status 命令的輸出十分詳細(xì),但其顯示結(jié)果有些繁瑣。 可以使用 git status -s 命令或 git status --short 命令,得到更為緊湊的格式輸出,示例:
新添加的未跟蹤文件前面有 ?? 標(biāo)記;新添加到暫存區(qū)中的文件前面有 A 標(biāo)記;修改過(guò)的文件前面有 M 標(biāo)記,M 有兩個(gè)可以出現(xiàn)的位置,出現(xiàn)在右邊的 M 表示該文件在工作區(qū)被修改了且沒放入暫存區(qū),出現(xiàn)在靠左邊的 M 表示該文件在工作區(qū)被修改了并放入了暫存區(qū),MM表示此文件在工作區(qū)被修改并提交到暫存區(qū)后又在工作區(qū)中被修改了,所以在暫存區(qū)和工作區(qū)都有該文件被修改了的記錄。
3.2 跟蹤新文件、暫存已修改文件:git add
git add 是一個(gè)多功能命令:可以用它開始跟蹤新文件,或者把已跟蹤的文件放到暫存區(qū),還能用于合并時(shí)把有沖突的文件標(biāo)記為已解決狀態(tài)等。 將這個(gè)命令理解為 “添加內(nèi)容到下一次提交中” 而不是 “將一個(gè)文件添加到項(xiàng)目中” 要更加合適。
3.2.1 跟蹤新文件 git add
git add 命令使用文件或目錄的路徑作為參數(shù);如果參數(shù)是目錄的路徑,該命令將遞歸地跟蹤該目錄下的所有文件。使用 add 后可以再用 git status 查看一下文件狀態(tài),只要在 Changes to be committed 這行下面的,就說(shuō)明是已暫存狀態(tài)。
?可以在 git add?命令后面跟上多個(gè)文件名,用空格隔開。
3.2.2 暫存已修改的文件 git add
出現(xiàn)在 Changes not staged for commit 下面的文件,已跟蹤但內(nèi)容發(fā)生了變化,還沒有放到暫存區(qū),需要運(yùn)行 git add 命令暫存這次更新。
如果在運(yùn)行了 git add 之后又作了修改,需要重新運(yùn)行 git add 把最新版本重新暫存起來(lái)。
3.3 撤銷工作區(qū)修改或撤銷暫存操作 git restore
3.3.1 撤銷工作區(qū)未暫存的修改:git restore
git restore
假如你在工作區(qū)修改了 temp.txt 文件的內(nèi)容,但還沒有將修改暫存到暫存區(qū),如果想撤銷修改,可以使用 git restore 命令:
如果想要將文件或目錄恢復(fù)到指定的提交狀態(tài),可以使用 git restore?命令加上 --source 參數(shù):
git restore --source=
3.3.2 保留工作區(qū)修改撤銷暫存(git reset 可以實(shí)現(xiàn)一樣的功能):git restore --staged?
git restore --staged?
在 Git 中,用 HEAD 表示當(dāng)前倉(cāng)庫(kù)版本,也就是最新的提交,上一個(gè)版本是 HEAD^,上上一個(gè)版本是 HEAD^^,當(dāng)然往上100個(gè)版本寫100個(gè)^比較容易數(shù)不過(guò)來(lái),所以寫成 HEAD~100。
使用 --source 將暫存區(qū)恢復(fù)到指定的提交狀態(tài),不改動(dòng)工作區(qū):
git restore --source=
下面的場(chǎng)景中,先對(duì)兩個(gè)文件使用 mv 命令執(zhí)行重命名操作,并把兩次操作記錄到暫存區(qū)。
如果想把這兩次操作分兩次提交,想撤銷暫存區(qū)中的 renamed temp2.txt -> temp.txt,可使用 --staged,恢復(fù)暫存區(qū)內(nèi)容。HEAD 對(duì)應(yīng)的暫存區(qū)中沒有 temp.txt,執(zhí)行 restore temp.txt 命令后 temp.txt 變成 untracked;HEAD 對(duì)應(yīng)的暫存區(qū)中存在?temp2.txt 文件,但工作區(qū)目錄刪除了此文件,因此執(zhí)行 restore temp2.txt 命令后后顯示 deleted temp2.txt 未加入暫存區(qū)。
3.3.3 撤銷暫存以及工作區(qū)修改(git checkout 可以實(shí)現(xiàn)一樣的功能;git reset --hard HEAD 能恢復(fù)到某個(gè)歷史提交,但不能針對(duì)單個(gè)文件恢復(fù)其內(nèi)容):git restore --staged --worktree
3.3.4 使用 git reset 撤銷工作區(qū)修改或撤銷暫存
參考 3.7 & 3.8?
3.3.5 使用 git checkout 恢復(fù)某個(gè)文件
git checkout
3.4?刪除文件 git rm?
3.4.1 刪除文件 git rm?
使用 git rm 命令從已跟蹤文件清單中移除文件(確切地說(shuō),是從暫存區(qū)域移除),并連帶從工作目錄中刪除指定的文件,執(zhí)行 git rm 后再執(zhí)行 git commit,即可從 Git 中移除文件。
如果只是簡(jiǎn)單地從工作目錄中手工刪除文件,運(yùn)行 git status 時(shí)就會(huì)在 “Changes not staged for commit” 部分(也就是未暫存清單)看到:"deleted: filename",運(yùn)行 git rm 記錄此次移除文件的操作,下一次執(zhí)行 git commit 后,該文件就不再納入版本管理了。
3.4.2 強(qiáng)制刪除文件 git rm -f?
如果文件沒有被添加到 Git 倉(cāng)庫(kù)中,git rm 命令會(huì)報(bào)錯(cuò);如果你嘗試刪除一個(gè)修改過(guò)并且已經(jīng)把修改放到暫存區(qū)的文件,git rm?命令會(huì)提示你需要先將修改提交到 Git 倉(cāng)庫(kù)中。
如果一定要?jiǎng)h除之前修改過(guò)并且已經(jīng)放到暫存區(qū)的文件,或者倉(cāng)庫(kù)中不存在的文件,要用強(qiáng)制刪除選項(xiàng) -f(force 的首字母)。git rm -f?命令可以強(qiáng)制刪除已經(jīng)被 Git 跟蹤的文件,即使該文件被修改過(guò)并且沒有被提交到 Git 倉(cāng)庫(kù)中,使用該命令時(shí)需要小心,它會(huì)永久刪除文件,無(wú)法恢復(fù)。
3.4.3 從暫存區(qū)和 Git 倉(cāng)庫(kù)中刪除但本地不刪除?git rm -cached?
當(dāng)想把文件從 Git 倉(cāng)庫(kù)中刪除(亦從暫存區(qū)域移除),但仍然希望保留在當(dāng)前工作目錄中時(shí),使用 git rm --cached
$ git rm log/\*.log
# 表示刪除 log/ 目錄下擴(kuò)展名為 .log 的所有文件
# 星號(hào) * 之前的反斜杠 \,這是 Git 自己的文件模式擴(kuò)展匹配方式。
$ git rm \*~、
# 表示刪除以 ~ 結(jié)尾的所有文件。
3.5?移動(dòng)文件?git mv
$ git mv README.md README
命令 git mv README.md README,將對(duì)文件改名,運(yùn)行此命令相當(dāng)于運(yùn)行了下面三條命令:
$ mv README.md README
$ git rm README.md
$ git add README
3.6?比較文件內(nèi)容 git diff
比較工作目錄中的文件與最新提交之間的差異:git diff
比較指定文件在工作目錄和最新提交之間的差異:git diff
比較工作目錄中的文件與指定的提交之間的差異:git diff
比較兩個(gè)提交之間的差異:git diff
比較指定文件在兩個(gè)提交之間的差異:git diff
比較兩個(gè)分支之間的差異:git diff
比較指定文件在兩個(gè)分支之間的差異:git diff
?3.7?提交更新 git commit
3.7.1 提交更新-編輯器輸入提交信息?git commit?
如果暫存區(qū)域已經(jīng)準(zhǔn)備妥當(dāng)可以提交了,就可以使用 git commit 命令將修改提交到倉(cāng)庫(kù)。 請(qǐng)一定要確認(rèn)還有什么修改過(guò)的或新建的文件還沒有 git add 過(guò),否則提交的時(shí)候不會(huì)記錄這些還沒暫存起來(lái)的變化,這些修改過(guò)的文件只保留在本地磁盤。 所以,每次準(zhǔn)備提交前,先用 git status 看下,是不是都已暫存起來(lái)了, 然后再運(yùn)行提交命令 git commit。
這種方式將會(huì)啟動(dòng)文本編輯器以便輸入本次提交的說(shuō)明。 (默認(rèn)會(huì)啟用 shell 的環(huán)境變量 EDITOR 所指定的軟件, 一般都是 vim 或 emacs。編輯器顯示的內(nèi)容示例:
第一行是空行,供你輸入提交說(shuō)明。提交消息的注釋行里包含最后一次運(yùn)行 git status 的輸出,其實(shí)完全可以去掉這些注釋行,不過(guò)留著也沒關(guān)系,多少能幫你回想起這次更新的內(nèi)容有哪些。 如果想要更詳細(xì)的,關(guān)于修改了哪些內(nèi)容的提示,可以用 -v 選項(xiàng),這會(huì)將你所做的改變的 diff 輸出放到編輯器中,使你知道本次提交具體做了哪些修改。退出編輯器時(shí),Git 會(huì)丟掉注釋行,用你輸入提交附帶信息生成一次提交。
注:Vim 使用
正常模式 (:)-> 命令模式(內(nèi)置命令如 w wq)
正常模式 (i)-> 插入模式(編輯功能)(Esc)-> 正常模式
先在鍵盤點(diǎn)擊 i 按鍵,進(jìn)入插入模式;然后在首行填寫提交描述,完成后點(diǎn)擊?Esc 退出插入模式;接下來(lái)按 : 進(jìn)入命令模式,輸入 wq 保存并退出。
3.7.2 提交更新-直接輸入提交信息 git commit -m?
可以在 commit 命令后添加 -m 選項(xiàng),將提交信息與命令放在同一行,這樣就不必通過(guò) vim 添加提交信息了。
如果你只需要提交一些小的更改,并且提交信息比較簡(jiǎn)單,可以使用 git commit -m 命令;如果你需要提交一些比較大的更改,并且需要詳細(xì)描述這些更改的內(nèi)容,那么可以使用 git commit 命令,并在編輯器中輸入詳細(xì)的提交信息。
3.7.3 重新提交 git commit --amend -m
如果在提交完才發(fā)現(xiàn)漏掉了幾個(gè)文件沒有添加,或者提交信息寫錯(cuò)了,可以運(yùn)行帶有 --amend 選項(xiàng)的提交命令嘗試重新提交(最終將只有一個(gè)提交)。
修補(bǔ)提交最明顯的價(jià)值是,可以稍微改進(jìn)你最后的提交,而不會(huì)讓 “啊,忘了添加一個(gè)文件”或者 “小修補(bǔ),修正筆誤” 這種提交信息弄亂你的倉(cāng)庫(kù)歷史。
例如,你提交后發(fā)現(xiàn)忘記了暫存某些需要的修改,可以像下面這樣操作:
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend -m 'initial commit with supplements'
文本編輯器啟動(dòng)后,可以看到之前的提交信息, 編輯后保存會(huì)覆蓋原來(lái)的提交信息。
3.7.4 撤銷提交 git reset [--soft/mixed/hard] [
參考 3.7、3.8
3.7.5 為提交打標(biāo)簽 git tag
標(biāo)簽可以用來(lái)標(biāo)識(shí)特定的提交或版本,方便用戶在未來(lái)快速找到這個(gè)提交或版本。Git 主要有兩種類型的標(biāo)簽:輕量標(biāo)簽(lightweight)與附注標(biāo)簽(annotated)。
輕量級(jí)標(biāo)簽只是一個(gè)指向特定提交的引用,它不包含任何其他元數(shù)據(jù),因此比帶注釋的標(biāo)簽(annotated tag)更輕量級(jí),通常用于臨時(shí)標(biāo)記某個(gè)特定的提交。附注標(biāo)簽是存儲(chǔ)在 Git 數(shù)據(jù)庫(kù)中的一個(gè)完整對(duì)象,是可以被校驗(yàn)的,其中包含打標(biāo)簽者的名字、電子郵件地址、日期時(shí)間以及標(biāo)簽信息。 通常建議創(chuàng)建附注標(biāo)簽,這樣你可以擁有以上所有信息;但如果你只是想用一個(gè)臨時(shí)的標(biāo)簽,或者因?yàn)槟承┰虿幌氡4婺切┬畔?,用輕量標(biāo)簽也是可以的。
查看標(biāo)簽和刪除標(biāo)簽
使用 git tag 查看標(biāo)簽,這個(gè)命令以字母順序列出標(biāo)簽,注意,標(biāo)簽不是按時(shí)間順序列出,而是按字母排序的;使用 git show
創(chuàng)建標(biāo)簽
在 Git 中創(chuàng)建標(biāo)簽非常簡(jiǎn)單:切換到需要打標(biāo)簽的分支上,然后運(yùn)行 git tag 命令即可。默認(rèn)標(biāo)簽是打在最新提交的 commit 上的。
創(chuàng)建輕量標(biāo)簽時(shí)只需要提供標(biāo)簽名字,如:git tag v1.4-lw。創(chuàng)建附注標(biāo)簽需要在運(yùn)行 tag 命令時(shí)指定 -a 選項(xiàng),如:git tag -a v1.4 -m 'my version 1.4',-a 選項(xiàng)表示創(chuàng)建一個(gè)附注標(biāo)簽;-m 選項(xiàng)指定了一條將會(huì)存儲(chǔ)在標(biāo)簽中的信息,如果沒有為附注標(biāo)簽指定一條信息,Git 會(huì)運(yùn)行編輯器要求你輸入信息。
后期打標(biāo)簽
如果想對(duì)過(guò)去的提交打標(biāo)簽,可以先運(yùn)行 git reflog 查看歷史提交信息,找到目標(biāo)提交的校驗(yàn)和(或部分校驗(yàn)和),在命令末尾加上它,如:git tag -a v1.2 9fceb02。
共享標(biāo)簽
默認(rèn)情況下,git push 命令并不會(huì)傳送標(biāo)簽到遠(yuǎn)程倉(cāng)庫(kù)服務(wù)器上。 在創(chuàng)建完標(biāo)簽后,你必須顯式地推送標(biāo)簽到共享服務(wù)器上。 這個(gè)過(guò)程就像共享遠(yuǎn)程分支一樣,運(yùn)行 git push origin [tagname]。如果標(biāo)簽已經(jīng)推送到遠(yuǎn)程,要?jiǎng)h除遠(yuǎn)程標(biāo)簽就麻煩一點(diǎn),比如,想刪除 remove 標(biāo)簽,需要先從本地刪除:git tag -d remove,然后,從遠(yuǎn)程刪除,刪除命令也是 push,但是格式如下:git push origin :refs/tags/remove。
3.8?查看提交歷史 git log
3.8.1 git log
默認(rèn)不用任何參數(shù)的話,git log 會(huì)按提交時(shí)間列出所有的更新,最近的更新排在最上面。 這個(gè)命令會(huì)列出每個(gè)提交的哈希值、作者的名字和電子郵件地址、提交時(shí)間以及提交說(shuō)明。
3.8.2 git log --oneline
--oneline:將每個(gè)提交壓縮為一行,是?"--pretty=oneline --abbrev-commit" 的簡(jiǎn)寫形式。
3.8.3 其他常用選項(xiàng)(-p、-n、--stat、--pretty、--graph)
-p 選項(xiàng):用來(lái)顯示每次提交的內(nèi)容差異。
-(n) 僅顯示最近的 n 條提交。
--stat 選項(xiàng):查看每次提交的簡(jiǎn)略的統(tǒng)計(jì)信息。--stat 選項(xiàng)在每次提交的下面列出所有被修改過(guò)的文件、有多少文件被修改了以及被修改過(guò) 的文件的哪些行被移除或是添加了。 在每次提交的最后有一個(gè)總結(jié)。
--pretty:指定使用不同于默認(rèn)格式的方式展示提交歷史。
--pretty 選項(xiàng)有 一些內(nèi)建的子選項(xiàng)可供使用,比如?oneline 表示將每個(gè)提交放在一行顯示,格式為
如果要將輸出保存到文件中,可以使用以下命令:git log --pretty=format:"%H - %an: %s" > log.txt
-S:僅顯示添加或移除了某個(gè)關(guān)鍵字的提交。
可以使用命令:git log -Sfunction_name,找出添加或移除了某一個(gè)特定函數(shù)的引用的提交。
3.8.4 git reflog
git log?顯示的是提交歷史,包括每個(gè)提交的作者、提交時(shí)間、提交信息等等。它可以用于查看項(xiàng)目的提交歷史,了解項(xiàng)目的演進(jìn)情況,以及查找特定提交的信息等等。
Git 會(huì)在后臺(tái)保存一個(gè)引用日志 reflog,每當(dāng)你的 HEAD 所指向的位置發(fā)生了變化,Git 就會(huì)將這個(gè)信息存儲(chǔ)到引用日志這個(gè)歷史記錄里。 通過(guò)這些數(shù)據(jù),你可以很方便地獲取之前的提交歷史,使用 git reflog 來(lái)查看引用日志。
git reflog 顯示的是 Git 引用的歷史,包括分支、標(biāo)簽、HEAD 等等。它記錄了 Git 引用的變更歷史,可以用于恢復(fù)誤刪的分支、標(biāo)簽等引用,或者查找誤操作的歷史記錄等等。
3.9?撤銷提交 git reset
git reset 可用于:
取消暫存,不影響工作區(qū)內(nèi)容,對(duì)應(yīng)下圖 SYNOPSIS 1~3 語(yǔ)句。取消提交:將當(dāng)前分支的 HEAD 指針移動(dòng)到指定的提交,同時(shí)可以選擇是否修改工作區(qū)和暫存區(qū)的內(nèi)容。對(duì)應(yīng)下圖 SYNOOSIS 第4條語(yǔ)句。
3.9.1 保留工作區(qū)修改撤銷暫存(tree-ish 默認(rèn)為 HEAD,即最近一次的提交)
應(yīng)用場(chǎng)景:假設(shè)你對(duì)項(xiàng)目中的 frotz.c 文件做了一些修改,已經(jīng)改好了,接下來(lái)需要修改其他文件,你不想在運(yùn)行 git diff 時(shí)看到關(guān)于 frotz.c 的內(nèi)容,這會(huì)分散你的注意力,所以你使用 add 命令把這部分修改暫存到暫存區(qū)。
這時(shí)有人告訴你其他項(xiàng)目成員做了一些有價(jià)值的修改,建議你拉取最新項(xiàng)目。不過(guò)你現(xiàn)在已經(jīng) ‘弄臟了’ 暫存區(qū),即你當(dāng)前的暫存區(qū)內(nèi)容與 HEAD 不匹配(執(zhí)行 git pull 之前,需要先將暫存區(qū)和 HEAD 同步,否則會(huì)出現(xiàn)沖突),而且你知道將要進(jìn)行的 pull 操作不會(huì)改變 frotz.c 文件,因此你可以考慮先恢復(fù) frotz.c 文件在暫存區(qū)的狀態(tài)(撤銷之前的暫存操作,但保留工作區(qū)文件的改動(dòng)),然后再pull、merge。
?git reset 也可以僅對(duì)一個(gè)文件撤銷暫存操作:
3.9.2 撤銷提交(commit 默認(rèn)為 HEAD,即最近一次的提交)
-soft僅撤銷提交,不撤銷修改。將 HEAD 指針移動(dòng)到指定的提交,并將暫存區(qū)和工作區(qū)的修改保留下來(lái),因此可以直接重新提交。--mixed撤銷提交和暫存區(qū)的修改,但不撤銷工作區(qū)的修改。將 HEAD 指針移動(dòng)到指定的提交,并將暫存區(qū)的修改撤銷,但不影響工作區(qū)的修改,需要手動(dòng)重新標(biāo)記為暫存后再次提交。--hard徹底撤銷提交和修改,回到指定提交的狀態(tài)。將 HEAD 指針、暫存區(qū)和工作區(qū)都移動(dòng)到指定的提交,所有修改都會(huì)被撤銷,慎用。--merge撤銷合并提交,回到合并前的狀態(tài)。撤銷合并提交,回到合并前的狀態(tài),需要指定要回到的提交。--keep撤銷提交,但保留工作區(qū)和暫存區(qū)的修改。
可以通過(guò)回退實(shí)現(xiàn)撤銷提交,這需要知道回到哪個(gè)版本:用 HEAD 表示當(dāng)前版本,即最新的提交,上一個(gè)版本用 HEAD^ 表示,往上100個(gè)版本用?HEAD~100 表示;此外,如前所述 Git 會(huì)記錄每一次提交的信息,可通過(guò) git reflog 查看索引值,用索引值指定要回退的版本。概括來(lái)說(shuō):
索引值(前進(jìn)后退都可以):使用 HEAD 或局部索引值(提交對(duì)象的簡(jiǎn)短哈希字符串,可通過(guò) git reflog 或 git log --pretty=oneline 查看)如:git reset --hard 49e25b6
^ (只能后退):HEAD^^ 表示后退 2 步,如:git reset --hard HEAD^^~ (只能后退):HEAD~n 表示后退 n 步,如:git reset --hard HEAD~n
--hard 永久刪除(本地內(nèi)容也會(huì)刪除)?
3.9.3 git restore 與 git reset
git restore:撤銷工作區(qū)中未提交的修改(從暫存區(qū)或另一個(gè)提交恢復(fù)工作區(qū)中的文件);從另一次提交中恢復(fù)暫存區(qū)或\和工作區(qū)中的文件。
git reset:撤銷已提交的修改。將 HEAD 指針和當(dāng)前分支指向指定的提交,可選擇將暫存區(qū)或\和工作區(qū)恢復(fù)到該提交的狀態(tài)。
?4. 分支管理
使用分支意味著你可以把你的工作從開發(fā)主線上分離開來(lái),以免影響開發(fā)主線。
Git 處理分支的方式可謂是難以置信的輕量,創(chuàng)建新分支這一操作幾乎能在瞬間完成,并且在不同分支之間的切換操作也是一樣便捷。 與許多其它版本控制系統(tǒng)不同,Git 鼓勵(lì)在工作流程中頻繁地使用分支與合并,哪怕一天之內(nèi)進(jìn)行許多次。?
4.1 分支簡(jiǎn)介
4.1.1 文件快照
Git 并不是像其他版本控制系統(tǒng)一樣,把保存的信息看作是一組基本文件和每個(gè)文件隨時(shí)間逐步累積的差異,Git 更像是把數(shù)據(jù)看作是對(duì)小型文件系統(tǒng)的一組快照,你可以理解為每個(gè)快照都包含了代碼庫(kù)中的所有文件和目錄的完整內(nèi)容。Git 對(duì)待數(shù)據(jù)更像是一個(gè)快照流,使用這些快照來(lái)跟蹤文件的歷史記錄,并允許不同版本之間進(jìn)行比較和回滾。
說(shuō)明:Git 的快照是通過(guò)將文件的內(nèi)容轉(zhuǎn)換為一些稱為 “blob” 的二進(jìn)制數(shù)據(jù)對(duì)象來(lái)實(shí)現(xiàn)的。Git 中的每個(gè)文件都被視為一系列 blob 對(duì)象,每個(gè) blob 對(duì)象都包含文件的內(nèi)容,當(dāng)你在 Git 中提交一個(gè)更改時(shí),Git 會(huì)將這些更改的內(nèi)容轉(zhuǎn)換為新的 blob 對(duì)象,并將其存儲(chǔ)在 Git 數(shù)據(jù)庫(kù)中。Git 還會(huì)創(chuàng)建一個(gè)稱為 “tree” 的對(duì)象,該對(duì)象包含指向每個(gè) blob 對(duì)象的指針,以及目錄結(jié)構(gòu)信息。 這些 blob 和 tree 對(duì)象都可以被視為 Git 中的 “快照”,因?yàn)樗鼈儽硎咎囟〞r(shí)間點(diǎn)的文件和目錄結(jié)構(gòu)。
在你每次提交更新,或在 Git 中保存項(xiàng)目狀態(tài)時(shí),Git 會(huì)對(duì)當(dāng)時(shí)的全部文件制作一個(gè)快照并保存這個(gè)快照的索引。 為了高效, 如果文件沒有修改,Git 不再重新存儲(chǔ)該文件,而是只保留一個(gè)鏈接指向之前存儲(chǔ)的文件。
Git 中的絕大多數(shù)操作都只需要訪問(wèn)本地文件和資源,比如,如果 Git 要瀏覽項(xiàng)目的歷史,它不需外連到服務(wù)器去獲取歷史,然后再顯示出來(lái),只需直接從本地?cái)?shù)據(jù) 庫(kù)中讀取,因此你能立即看到項(xiàng)目歷史。
4.1.2 驗(yàn)證文件
哈希是一種算法,它將輸入的數(shù)據(jù)映射到一個(gè)固定長(zhǎng)度的輸出,通常是一個(gè)哈希值。在計(jì)算機(jī)科學(xué)中,哈希經(jīng)常用于快速查找和存儲(chǔ)數(shù)據(jù)。密碼學(xué)中,哈希算法可以把明文加密成密文。
哈希函數(shù)如下特點(diǎn):
(1)同一個(gè)哈希算法得到的加密結(jié)果長(zhǎng)度固定。
(2)哈希算法確定、輸入數(shù)據(jù)確定,輸出數(shù)據(jù)不變;如果哈希算法有變化,或者輸入數(shù)據(jù)變化(即便是很微小的變化),輸出數(shù)據(jù)一定有變化,而且變化很大。輸入數(shù)據(jù)的任何細(xì)微變化都會(huì)導(dǎo)致輸出數(shù)據(jù)的巨大變化。
(3)哈希算法不可逆,不能通過(guò)哈希值恢復(fù)出原始數(shù)據(jù)。
哈希算法可以用于驗(yàn)證文件,Git 中,每個(gè)文件和每個(gè)提交都有一個(gè)唯一的校驗(yàn)和,是一個(gè) SHA-1 哈希值(一個(gè)由 40 個(gè)十六進(jìn)制字符(0-9 和 a-f)組成字符串,示例:24b9da6552252987aa493b52f8696cd6d3b00373),這個(gè)校驗(yàn)和是由文件內(nèi)容和目錄結(jié)構(gòu)計(jì)算出來(lái)的,可以用來(lái)驗(yàn)證文件的完整性和一致性。Git 數(shù)據(jù)庫(kù)中保存的信息都是以文件內(nèi)容的哈希值來(lái)索引,而不是文件名。
4.1.3 Git 分支管理機(jī)制
提交對(duì)象 commit:包含指向前述樹對(duì)象的指針和所有提交信息。
樹對(duì)象 tree:樹對(duì)象包含了每個(gè)文件和子目錄的名稱、類型、權(quán)限和 SHA-1 校驗(yàn)和等元數(shù)據(jù)信息。當(dāng)我們提交一個(gè)新版本的代碼時(shí),Git 會(huì)將所有修改的文件和目錄打包成一個(gè)新的樹對(duì)象,并將其保存到 Git 數(shù)據(jù)庫(kù)中。
文件快照?blob 對(duì)象:當(dāng)前版本的文件快照。
在 Git 中,每次提交都會(huì)生成一個(gè)校驗(yàn)和,這個(gè)校驗(yàn)和是由 Git 對(duì)該提交中所有文件的內(nèi)容計(jì)算出來(lái)的。如果你修改了某些文件并提交了這些修改,Git 會(huì)重新計(jì)算該提交的校驗(yàn)和,并將其與之前的校驗(yàn)和進(jìn)行比較。如果校驗(yàn)和不同,Git 就會(huì)認(rèn)為文件已經(jīng)被修改過(guò)了,并提示你進(jìn)行提交。
當(dāng)你做了一些修改后再次提交,這次產(chǎn)生的提交對(duì)象會(huì)包含一個(gè)指向上次提交對(duì)象(父對(duì)象)的指針。
Git 的分支本質(zhì)上是指向提交對(duì)象的可變指針。 Git 的默認(rèn)分支名字是 master。 在多次提交操作之 后,你其實(shí)已經(jīng)有一個(gè)指向最后那個(gè)提交對(duì)象的 master 分支,它會(huì)在每次的提交操作中自動(dòng)向前移動(dòng)。
Git 的 master?分支并不是一個(gè)特殊分支。 它就跟其它分支完全沒有區(qū)別。 之所以幾乎每一個(gè)倉(cāng)庫(kù)都有 master 分支,是因?yàn)?git init 命令默認(rèn)創(chuàng)建它,并且大多數(shù)人都懶得去改動(dòng)它。
Git 怎么知道當(dāng)前在哪一個(gè)分支上呢? 也很簡(jiǎn)單,它有一個(gè)名為 HEAD 的特殊指針。?在 Git 中,HEAD 是一個(gè)指針,指向當(dāng)前所在的本地分支(注:可以將 HEAD 想象為當(dāng)前分支的別名)。
首次提交產(chǎn)生的提交對(duì)象沒有父對(duì)象,普通提交操作產(chǎn)生的提交對(duì)象有一個(gè)父對(duì)象,由多個(gè)分支合并產(chǎn)生的提交對(duì)象有多個(gè)父對(duì)象。
4.2 分支的查看、創(chuàng)建、切換、刪除
4.2.1 查看分支?git branch (選項(xiàng) -v、-r、-a、--merged、--no-merged)
果不加任何參數(shù)運(yùn)行 git branch,會(huì)得到當(dāng)前所有分支的一個(gè)列表,* 字符代表當(dāng)前所處的那一個(gè)分支(當(dāng)前 HEAD 指針?biāo)赶虻姆种В?/p>
If --list is given, or if there are no non-option arguments, existing branches are listed; the current branch will be highlighted in green and marked with an asterisk.?
使用 git branch -v?顯示本地分支列表,并顯示每個(gè)分支的最新提交的 SHA-1 值和提交信息。
git branch -r?顯示遠(yuǎn)程跟蹤分支列表。
git branch -a?顯示所有分支列表,包括本地分支和遠(yuǎn)程跟蹤分支。
使用 git branch --merged?查看哪些分支已經(jīng)合并到當(dāng)前分支。在這個(gè)列表中分支名字前沒有 * 號(hào)的分支通???以使用 git branch -d 刪除掉;你已經(jīng)將它們的工作整合到了另一個(gè)分支,所以并不會(huì)失去任何東西。
使用 git branch --unmerged?查看所有包含未合并工作的分支。因?yàn)檫@個(gè)列表中的分支包含了還未合并的工作,嘗試使用 git branch -d 命令刪除這些分支時(shí)會(huì)失敗。
下面的例子中,沒有所有分支都已合入到 master 分支。
4.2.2 創(chuàng)建分支 git branch
Git 中,創(chuàng)建分支,即為創(chuàng)建一個(gè)可以移動(dòng)的新的指針。比如,創(chuàng)建一個(gè) testing 分支, 只需要使用 git branch 命令:git branch testing,這會(huì)在當(dāng)前所在的提交對(duì)象上創(chuàng)建一個(gè)指針。git branch 命令僅僅創(chuàng)建一個(gè)新分支,并不會(huì)自動(dòng)切換到新分支中去,因此當(dāng)前你仍然在 master 分支上。
4.2.3 切換分支 git checkout 和 git switch
(1)git checkout
使用 git checkout 命令要切換到一個(gè)已存在的分支,比如,現(xiàn)在要切換到新創(chuàng)建的 testing 分支 去: git checkout testing,這樣 HEAD 就指向 testing 分支了。
如果現(xiàn)在對(duì)項(xiàng)目中某文件做些修改,然后再提交一次,testing 分支將會(huì)向前移動(dòng),但 master 分支不動(dòng),仍然指向運(yùn)行 git checkout 時(shí)所指的對(duì)象。
使用命令 git checkout master,切換回 master 分支。這條命令做了兩件事:(1)使 HEAD 指回 master 分支;(2)是將工作目錄恢復(fù)成 master 分支所指向的快照內(nèi)容。也就是說(shuō),如果現(xiàn)在做修改,是始于一個(gè)較舊的版本,本質(zhì)上來(lái)講,這就是忽略 testing 分支所做的修改,便于向另一個(gè)方向進(jìn)行開發(fā)。
分支切換會(huì)改變你工作目錄中的文件。在切換分支時(shí),一定要注意你工作目錄里的文件會(huì)被改變。 如果是切換到一個(gè)較舊的分支,工作目錄會(huì)恢復(fù)到該分支最后一次提交時(shí)的樣子。 如果 Git 不能干凈利落地完成這個(gè)任務(wù), 它將禁止切換分支。
你可以簡(jiǎn)單地使用 git log 命令查看分叉歷史。 運(yùn)行 git log --oneline --decorate --graph --all,它會(huì)輸出你的提交歷史、各個(gè)分支的指向以及項(xiàng)目的分支分叉情況。
(2)git switch
The command "git branch
在 Git 2.23 版本之前,git checkout?用于切換分支、恢復(fù)文件、創(chuàng)建新分支等多種操作的命令。但是,從 Git 2.23 版本開始,它被拆分成了多個(gè)命令,以避免使用時(shí)的混淆?,F(xiàn)在,git checkout?命令主要用于切換分支和恢復(fù)文件。例如,git checkout master?將當(dāng)前分支切換到 master 分支,git checkout -- file.txt?將 file.txt 文件恢復(fù)到最近一次提交的狀態(tài)。
從 Git 2.23 版本開始,git switch?命令被引入用于切換分支。它的使用方式與 git checkout?類似,但是更加直觀和簡(jiǎn)潔。例如,git switch master?將當(dāng)前分支切換到 master 分支。
如果你使用的是 Git 2.23 及以上版本,建議使用 git switch?命令來(lái)切換分支,以避免混淆。如果你使用的是較老的 Git 版本,可以繼續(xù)使用 git checkout?命令,但需要注意其多種用法可能會(huì)導(dǎo)致一些意外情況。
4.2.4 創(chuàng)建并切換到此分支 git checkout -b
git checkout -b?命令用于創(chuàng)建一個(gè)新的分支并切換到該分支(-b?參數(shù)表示創(chuàng)建一個(gè)新的分支)。比如,帶有 -b 參數(shù)的 git checkout 命令:git checkout -b iss53,實(shí)際上是下面兩條命令的簡(jiǎn)寫:
$ git branch iss53?
$ git checkout iss53
執(zhí)行該命令后,Git 會(huì)將當(dāng)前分支的代碼復(fù)制到新的分支中,并將 HEAD 指向新的分支,你可以在新的分支上繼續(xù)開發(fā)代碼,而不影響當(dāng)前分支的代碼。
4.2.5 刪除分支 git branch -d
刪除未合并的分支需要使用 git branch -D;刪除已合并的分支需要使用 git branch -d。
4.3 分支的合并 git merge、git cherry-pick
使用 git merge 合并分支:先 check out 到想合并入的分支,然后執(zhí)行 git merge。
Case 1:把 hotfix 分支合并入 master 分支
假設(shè)在當(dāng)前項(xiàng)目中,先從?master 分支創(chuàng)建了一個(gè)?hotfix 分支,并在在 hotfix 分支提交了一些修改,現(xiàn)在想把 hotfix 分支修改的內(nèi)容合并到 master。
提交歷史(checkout 到 master,然后執(zhí)行 git merge):
你應(yīng)該注意到了運(yùn)行結(jié)果中的 "快進(jìn)(fast-forward)"這個(gè)詞。 由于當(dāng)前 master 分支所指向的提交是 hotfix 分支的提交的直接上游,所以 Git 只是簡(jiǎn)單的將指針向前移動(dòng)。 即:當(dāng)你試圖合并兩個(gè)分支時(shí),如果順著一個(gè)分支走下去能夠到達(dá)另一個(gè)分支,那么 Git 在合并兩者的時(shí)候,只會(huì)簡(jiǎn)單的將指針向前推 進(jìn)(指針右移),因?yàn)檫@種情況下的合并操作沒有需要解決的分歧——這就叫做 “快進(jìn)(fast-forward)”。
Case 2:把 iss53 分支合并入 master 分支
hotfix 分支上所做的工作并沒有包含到 iss53 分支中,如果需要拉取 hotfix 所做的修改,可以使用 git merge master 命令將 master 分支合并入 iss53 分支;或者你也可以等到 iss53 分支完成其使命, 再將其合并回 master 分支。
在 Case 1 中,master 已經(jīng)合入了 hotfix 分支的內(nèi)容,快照流圖示如下:
如果在 iss53 分支上的工作完成了,可以考慮將其合并入 master 分支?。合并 iss53 分支到 master 分支與之前合并 hotfix 分支所做的工作差不多,只需要 checkout 到你想合并入的分支,然后運(yùn)行 git merge 命令。
可以注意到,返回結(jié)果與之前合并 hotfix 分支的時(shí)候看起來(lái)有一點(diǎn)不一樣,這是因?yàn)椋琲ss53 分支是從更早的地方分叉開的(diverged),master 分支已經(jīng)前進(jìn),master 所在提交已經(jīng)不是 iss53 分支所在提交的直接祖先。 出現(xiàn)這種情況的時(shí)候,Git 會(huì)使用兩個(gè)分支的末端所指的快照(C4 和 C5 )以及這兩個(gè)分支的工作祖先(C2),做一個(gè)簡(jiǎn)單的三方合并。
Case 3:存在沖突
如果在兩個(gè)不同的分支中,對(duì)同一個(gè)文件的同一個(gè)部分進(jìn)行了不同的修改,Git 就沒法干凈的合并它們。 比如,在上述例子中,如果 iss53?和 hotfix 兩個(gè)分支對(duì)同一個(gè)文件的同一處做了修改,合并它們的時(shí)候就會(huì)產(chǎn)生合并沖突。
看一個(gè)簡(jiǎn)單的例子,項(xiàng)目的提交歷史如下:
# 在 master 分支新建一個(gè) file1.txt 文件
$ git add file1.txt
$ git commit -m "master create file1.txt"
# 新建 file2 分支,在這個(gè)分支上新建了 file2.txt 文件,同時(shí)對(duì) file1.txt 追加了一行內(nèi)容
$ git checkout -b file2
$ git add file2.txt
$ git commit -a -m "create file2 and file1 add a line"
# 回到 master分支,對(duì) file1.txt 文件追加一行內(nèi)容
$ git checkout master
$ git commit -a -m "file1 add a line"
# 把 file2 分支的修改內(nèi)容并入到 master 分支
$ git branch -v
$ git merge file2
在當(dāng)前的項(xiàng)目中,有 master 和 file2 兩個(gè)分支,都在 file2.txt 的末尾追加了一段文字,現(xiàn)在想合并這兩個(gè)分支:先 checkout 到 master,然后運(yùn)行?git merge poem-1 命令。 由于兩個(gè)分支在相同的位置做了修改,存在沖突,合并時(shí)不知道采用哪一個(gè),合并失?。?/p>
任何因存在合并沖突而有待解決的文件,都會(huì)以未合并狀態(tài)標(biāo)識(shí)出來(lái),你可以在合并沖突后的任意時(shí)刻使用 git status 命令,查看那些因存在合并沖突而處于未合并 (unmerged)狀態(tài)的文件。Git 會(huì)在有沖突的文件中加入標(biāo)準(zhǔn)的沖突解決標(biāo)記,這樣你可以打開這些包含沖突的文件,然后手動(dòng)解決沖突。?
當(dāng)前的例子中,兩個(gè)分支都對(duì) file2.txt 文件做了修改,打開這個(gè)文件,顯示內(nèi)容如下:
Git 用<<<<<<<,=======,>>>>>>> 標(biāo)記出不同分支的內(nèi)容,上述信息表示:HEAD 指示的版本,在 ======= 的上半部分,而 poem-1 指示的版本在 ======= 的下半部分。
為了解決沖突,你可以選擇使用由 ======= 分割的兩部分中的一個(gè),或者自行合并這些內(nèi)容。根據(jù)實(shí)際需要確定沖突解決方案,完成修改后把 >>>>>>,======= 和 >>>>>>> 這些行完全刪除。
在解決了所有文件里的沖突之后,對(duì)每個(gè)文件使用 git add 命令來(lái)將其標(biāo)記為沖突已解決。 一旦暫存這些原本有沖突的文件,Git 就會(huì)將它們標(biāo)記為沖突已解決,然后再執(zhí)行 commit 提交即可。 ?
Case 4:儲(chǔ)藏現(xiàn)場(chǎng) git stash
git stash?命令可以將當(dāng)前工作目錄中未提交的修改 “儲(chǔ)藏” 起來(lái),具體使用方法如下:
在工作目錄中進(jìn)行一些修改;運(yùn)行 git stash?命令,將修改儲(chǔ)藏起來(lái);在進(jìn)行其他操作之前,可以運(yùn)行 git stash list?命令查看所有儲(chǔ)藏;使用 git stash apply?命令恢復(fù)儲(chǔ)藏內(nèi)容;使用 git stash drop?命令刪除儲(chǔ)藏。
假設(shè)你當(dāng)前有 master 和 dev 兩個(gè)分支,你臨時(shí)接到緊急任務(wù),準(zhǔn)備新建一個(gè) issue-101 分支修復(fù)一個(gè) bug,但是你在 dev 上進(jìn)行的工作還沒有做完,還不能提交,這時(shí),你可以用 git stash,把當(dāng)前的工作現(xiàn)場(chǎng)儲(chǔ)藏起來(lái),等以后恢復(fù)現(xiàn)場(chǎng)繼續(xù)工作。
運(yùn)行過(guò)程:
# 保存現(xiàn)場(chǎng)
$ git stash
Saved working directory and index state WIP on dev: f52c633 add merge
# 現(xiàn)在,用 git status查看工作區(qū),是干凈的(除非有沒有被Git管理的文件)
# 接下來(lái)創(chuàng)建分支修復(fù) bug
$ git checkout master
$ git checkout -b issue-101
$ git commit -m "fix bug 101"
$ git switch master
$ git merge --no-ff -m "merged bug fix 101" issue-101
# 恢復(fù)現(xiàn)場(chǎng)
$ git switch dev
$ git stash list
stash@{0}: WIP on dev: f52c633 add merge
# 工作現(xiàn)場(chǎng)還在,Git 把 stash 內(nèi)容存在某個(gè)地方了,需要恢復(fù):
# 方法1:用 git stash apply 恢復(fù),恢復(fù)后 stash 內(nèi)容并不刪除,需要用 git stash drop 刪除;
# 方法2:用 git stash pop,恢復(fù)的同時(shí)把 stash 內(nèi)容刪除。
$ git stash pop
$ git stash list
# 此時(shí)將看不到任何 stash 內(nèi)容
Case 5:挑選提交合并 git cherry-pick
git merge?可以將兩個(gè)或多個(gè)分支合并成一個(gè)新的分支,它會(huì)將兩個(gè)分支的修改內(nèi)容合并到一起,并生成一個(gè)新的提交記錄。git merge?會(huì)自動(dòng)解決沖突,但有時(shí)會(huì)出現(xiàn)無(wú)法自動(dòng)解決的沖突,需要手動(dòng)解決。
如果你想將一個(gè)分支上的某個(gè)或某幾個(gè)提交記錄,復(fù)制到當(dāng)前分支上,比如,要解決某個(gè) bug 或者應(yīng)用某個(gè)特定的功能,可以使用 git cherry-pick。
git cherry-pick?可以選擇性地將某個(gè)提交記錄合并到當(dāng)前分支,而不會(huì)像 git merge 一樣將整個(gè)分支合并。git cherry-pick 將一個(gè)或多個(gè)提交應(yīng)用到當(dāng)前分支。它的作用是將指定的提交復(fù)制一份到當(dāng)前分支上,相當(dāng)于手動(dòng)合并某個(gè)提交。
更多細(xì)節(jié)參考鏈接:Git 操作補(bǔ)充:cherry-pick、變基-CSDN博客
Case 6:變基 git rebase
在 Git 中,整合來(lái)自不同分支的修改,除了 merge,還有一種方法,變基 rebase。它可以將一個(gè)分支上的修改合并到另一個(gè)分支上。具體來(lái)說(shuō),Git 變基的操作是將當(dāng)前分支的提交 “復(fù)制” 到目標(biāo)分支上,然后將當(dāng)前分支的指針指向目標(biāo)分支的最新提交。這個(gè)過(guò)程中,Git 會(huì)嘗試將當(dāng)前分支上的提交應(yīng)用到目標(biāo)分支上,如果發(fā)現(xiàn)沖突,需要手動(dòng)解決沖突。
與 Git 合并 merge 不同,Git 變基可以重新定義提交歷史,使得提交歷史更加整潔和易于理解。Git 變基的優(yōu)點(diǎn)是可以保持提交歷史的清晰,減少不必要的合并提交,從而更好地追蹤代碼的變化。不過(guò),由于 Git 變基會(huì)修改提交歷史,因此需要謹(jǐn)慎使用,避免對(duì)已經(jīng)共享的分支造成影響。
更多細(xì)節(jié)參考鏈接:Git 操作補(bǔ)充:cherry-pick、變基-CSDN博客
4.5?分支開發(fā)工作流
* 長(zhǎng)期分支
Git 使用簡(jiǎn)單的三方合并,所以就算在一段較長(zhǎng)的時(shí)間內(nèi),反復(fù)把一個(gè)分支合并入另一個(gè)分支,也不是什么難事。 也就是說(shuō),在項(xiàng)目開發(fā)周期內(nèi),你可以同時(shí)擁有多個(gè)開放的分支,定期地把某分支合并入其他分支中。
使用多個(gè)長(zhǎng)期分支的方法并非必要,但是這么做通常很有幫助,尤其是當(dāng)你在一 個(gè)非常龐大或者復(fù)雜的項(xiàng)目中工作時(shí),這樣做可以使你的分支具有不同級(jí)別的穩(wěn)定性,當(dāng)其具有一定程度的穩(wěn)定性后,再把它合并入具有更高級(jí)別穩(wěn)定性的分支中。
例子:只在 master 分支上保留完全穩(wěn)定的代碼——有可能僅僅是已經(jīng)發(fā)布或即將發(fā)布的代碼。 他們還有一些名為 develop 或者 next 的平行分支,被用來(lái)做后續(xù)開發(fā)或者測(cè)試穩(wěn)定性——這些分支不必保持絕對(duì)穩(wěn)定,但是一旦達(dá)到穩(wěn)定狀態(tài),它們就可以被合并入 master 分支了。
* 特性分支(短期分支)
特性分支對(duì)任何規(guī)模的項(xiàng)目都適用。 特性分支是一種短期分支,它被用來(lái)實(shí)現(xiàn)單一特性或其相關(guān)工作。
例子:在 master 分支上工作到 C1,這時(shí)為了解決一個(gè)問(wèn)題 A 而新建 iss91 分支,在 iss91 分 支上工作到 C4,然而對(duì)于問(wèn)題 A 你又有了新的想法,于是你再新建一個(gè) iss91v2 分支試圖用另一種方法解決它,接著你回到 master 分支工作了一會(huì)兒,你又冒出了一個(gè)不太確定的想法,想為項(xiàng)目增加了新功能,便在 C10 的時(shí)候新建一個(gè) dumbidea 分支,并在上面做些實(shí)驗(yàn)。你的提交歷史看起來(lái)像下面這個(gè)樣子:
你最終決定使用在 iss91v2 分支中方案解決問(wèn)題 A,同時(shí),你將 dumbidea 分支拿給你的同事看,大家都覺得這部分內(nèi)容值得保留,這時(shí)你可以拋棄 iss91 分支(丟棄 C5 和 C6 提交),然后把另外兩個(gè)分支合并入主干分支。最終你的提交歷史看起來(lái)像下面這個(gè)樣子:
5. 遠(yuǎn)程倉(cāng)庫(kù)?remote repository
5.1 相關(guān)概念
5.1.1 遠(yuǎn)程倉(cāng)庫(kù) remote repository
Git 的遠(yuǎn)程倉(cāng)庫(kù)是指位于網(wǎng)絡(luò)上的 Git 倉(cāng)庫(kù)(托管在因特網(wǎng)或其他網(wǎng)絡(luò)中的項(xiàng)目版本庫(kù))。
它可以是位于本地局域網(wǎng)內(nèi)的另一臺(tái)計(jì)算機(jī),也可以是位于云端的服務(wù)器。Git 的遠(yuǎn)程倉(cāng)庫(kù)可以讓多個(gè)開發(fā)者在不同的地方協(xié)同開發(fā)同一個(gè)項(xiàng)目,通過(guò)上傳和下載代碼來(lái)實(shí)現(xiàn)代碼的共享和同步。
你可以有好幾個(gè)遠(yuǎn)程倉(cāng)庫(kù),通常有些倉(cāng)庫(kù)對(duì)你只讀,有些則可以讀寫。 與他人協(xié)作涉及管理遠(yuǎn)程倉(cāng)庫(kù)以及根據(jù)需要推送(push)或拉取(fetch)數(shù)據(jù)。
5.1.2 遠(yuǎn)程分支 remote branch
遠(yuǎn)程分支即遠(yuǎn)程倉(cāng)庫(kù)上的分支,要在 Git 中創(chuàng)建遠(yuǎn)程分支,需要使用 git push 命令。以下是創(chuàng)建遠(yuǎn)程分支的步驟如下:
在本地創(chuàng)建一個(gè)新的分支,可以使用 git checkout -b 命令創(chuàng)建并切換到新分支。在本地分支上進(jìn)行了所需的更改。使用 git push 命令將本地分支推送到遠(yuǎn)程倉(cāng)庫(kù)。例如,遠(yuǎn)程倉(cāng)庫(kù)名為 origin,可以使用以下命令將本地分支 mybranch 推送到遠(yuǎn)程分支:git push origin mybranch,如果遠(yuǎn)程倉(cāng)庫(kù)不存在此分支,Git 會(huì)自動(dòng)創(chuàng)建它。使用 git branch -r 命令查看遠(yuǎn)程分支列表,新遠(yuǎn)程分支應(yīng)該出現(xiàn)在列表中。
注意: 在推送分支之前,需要確保你有足夠的權(quán)限在遠(yuǎn)程倉(cāng)庫(kù)中創(chuàng)建分支,如果沒有權(quán)限,需要聯(lián)系倉(cāng)庫(kù)管理員以獲取幫助。
git push 的語(yǔ)法規(guī)則可概括為:git push <遠(yuǎn)程倉(cāng)庫(kù)名> <本地分支名>:<遠(yuǎn)程分支名>
如果你的本地分支與遠(yuǎn)程分支同名,則可以省略遠(yuǎn)程分支名??梢允褂脦疤?hào) “:” 的格式來(lái)推送本地分支到一個(gè)命名不相同的遠(yuǎn)程分支,比如,不想讓遠(yuǎn)程倉(cāng)庫(kù)上的分支叫做 serverfix,可以運(yùn)行 git push origin serverfix:awesomebranch,將本地的 serverfix 分支推送到遠(yuǎn)程倉(cāng)庫(kù)上的 awesomebranch分支。
可以運(yùn)行帶有 --delete 選項(xiàng)的 git push 命令來(lái)刪除一個(gè)遠(yuǎn)程分支,比如,想要從服務(wù)器上刪除 serverfix 分支,運(yùn)行命令:git push origin --delete serverfix
5.1.3 遠(yuǎn)程跟蹤分支 remote-tracking branch
執(zhí)行 clone 后,遠(yuǎn)程倉(cāng)庫(kù)的分支會(huì)被克隆到本地,但是本地倉(cāng)庫(kù)中的分支與遠(yuǎn)程倉(cāng)庫(kù)中的分支的發(fā)展不是完全同步的。為了跟蹤遠(yuǎn)程倉(cāng)庫(kù)中的分支,Git 會(huì)在本地倉(cāng)庫(kù)中創(chuàng)建一個(gè)名為 remotes/remote-name/branch-name?的分支,這個(gè)分支就是 remote-tracking branch。?
remote branch?是指遠(yuǎn)程倉(cāng)庫(kù)上的分支。
remote-tracking branch 遠(yuǎn)程跟蹤分支是遠(yuǎn)程分支狀態(tài)的引用。它們是你不能移動(dòng)的本地引用,當(dāng)你做任何網(wǎng)絡(luò)通信操作時(shí),它們會(huì)自動(dòng)移動(dòng)。 遠(yuǎn)程跟蹤分支像是你上次連接到遠(yuǎn)程倉(cāng)庫(kù)時(shí),那些分支所處狀態(tài)的書簽。它們以 (remote)/(branch) 形式命名。 比如,如果你想要看你最后一次與遠(yuǎn)程倉(cāng)庫(kù) origin 通信時(shí) master 分支的狀態(tài),你可以查看 origin/master 分支。
可以通過(guò) git branch -r?命令來(lái)查看所有遠(yuǎn)程倉(cāng)庫(kù)的分支,通過(guò) git branch -a?命令來(lái)查看所有本地分支和遠(yuǎn)程分支。
clone 遠(yuǎn)程倉(cāng)庫(kù):使用 clone 命令克隆了一個(gè)倉(cāng)庫(kù),命令會(huì)自動(dòng)將其添加為遠(yuǎn)程倉(cāng)庫(kù)并默認(rèn)以 origin?為簡(jiǎn)寫。即 Git 的 clone 命令會(huì)自動(dòng)將這個(gè)遠(yuǎn)程倉(cāng)庫(kù)命名為 origin,拉取它的所有數(shù)據(jù),創(chuàng)建一個(gè)指向此遠(yuǎn)程倉(cāng)庫(kù)?master 分支的指針,并且在本地將其命名為 origin/master(遠(yuǎn)程跟蹤分支),Git 也會(huì)給你一個(gè)與 origin 的 master 分支在指向同一個(gè)地方的本地 master 分支(跟蹤分支),這樣你就有工作的基礎(chǔ)。
遠(yuǎn)程倉(cāng)庫(kù)的名字 origin?與分支名字 master?一樣,在 Git 中并沒有任何特別的含義。 master?是運(yùn)行 git init 時(shí)默認(rèn)的起始分支名字, origin?是運(yùn)行 git clone 時(shí)默認(rèn)的遠(yuǎn)程倉(cāng)庫(kù)名字。 如果運(yùn)行 git clone -o booyah,那么默認(rèn)的遠(yuǎn)程分支名字將會(huì)是 booyah/master。
如果你在本地的 master 分支做了一些工作,然而在同一時(shí)間,其他人推送提交到遠(yuǎn)程倉(cāng)庫(kù),更新了它的 master 分支,那么你的提交歷史將向不同的方向前進(jìn),但只要你不與 origin 服務(wù)器連接,你的 origin/master 指針就不會(huì)移動(dòng)。
5.1.4?跟蹤分支
從一個(gè)遠(yuǎn)程跟蹤分支檢出一個(gè)本地分支會(huì)自動(dòng)創(chuàng)建一個(gè) “跟蹤分支”(有時(shí)候也叫做 “上游分支”)。 跟蹤分支是與遠(yuǎn)程分支有直接關(guān)系的本地分支。 如果在一個(gè)跟蹤分支上輸入 git pull,Git 能自動(dòng)地識(shí)別去哪個(gè)服務(wù)器上抓取、合并到哪個(gè)分支。 當(dāng)克隆一個(gè)倉(cāng)庫(kù)時(shí),它通常會(huì)自動(dòng)地創(chuàng)建一個(gè)跟蹤 origin/master 的 master 分支。
如果需要的話,可以通過(guò)運(yùn)行 git checkout -b [branch] [remotename]/[branch] 設(shè)置其他跟蹤分支、跟蹤此倉(cāng)庫(kù)的其他分支或者為其他倉(cāng)庫(kù)設(shè)置跟蹤分支,這是一個(gè)十分常用的操作所以 Git 提供了 --track 快捷方式。
$ git checkout -b serverfix origin/serverfix Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'
此命令將創(chuàng)建一個(gè)用于工作的本地分支 serverfix,并且起點(diǎn)位于 origin/serverfix。
??
$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'
本地分支與遠(yuǎn)程分支設(shè)置為不同名字,本地分支 sf 會(huì)自動(dòng)從 origin/serverfix 拉取
$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'
可以使用帶有 -u 或 --set-upstream-to 選項(xiàng)的 git branch 顯式地設(shè)置已有的本地分支跟蹤一個(gè)剛剛拉取下來(lái)的遠(yuǎn)程分支,或者修改正在跟蹤的上游分支。
$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
總結(jié):Git 跟蹤分支是指本地倉(cāng)庫(kù)中的分支,是基于本地倉(cāng)庫(kù)中的提交記錄創(chuàng)建的,可以在本地進(jìn)行修改、合并等操作。遠(yuǎn)程跟蹤分支是指遠(yuǎn)程倉(cāng)庫(kù)中的分支,它們是基于遠(yuǎn)程倉(cāng)庫(kù)中的提交記錄創(chuàng)建的,不能直接在本地進(jìn)行修改、合并等操作,需要通過(guò)拉取或推送遠(yuǎn)程分支來(lái)進(jìn)行操作。
5.2?查看遠(yuǎn)程倉(cāng)庫(kù) git remote -v
git remote 顯示當(dāng)前倉(cāng)庫(kù)所關(guān)聯(lián)的遠(yuǎn)程倉(cāng)庫(kù)。git remote -v 顯示詳細(xì)的遠(yuǎn)程倉(cāng)庫(kù)信息,包括遠(yuǎn)程倉(cāng)庫(kù)的名稱、fetch 和 push 的URL地址。git remote show
5.3?添加新的遠(yuǎn)程倉(cāng)庫(kù) git remote add
可以使用?git remote add
可以使用 git remote rename 修改遠(yuǎn)程倉(cāng)庫(kù)的簡(jiǎn)寫名,即遠(yuǎn)程倉(cāng)庫(kù)重命名,比如,想要將 pb 重命名為 paul,可以運(yùn)行:git remote rename pb paul,值得注意的是,這同樣也會(huì)修改你的遠(yuǎn)程分支名字,過(guò)去那些引用 pb/master 的現(xiàn)在會(huì)引用 paul/master。
可以使用 git remote rm 移除遠(yuǎn)程倉(cāng)庫(kù),如:git remote rm paul
5.4?從遠(yuǎn)程倉(cāng)庫(kù)拉取 git fetch
5.4.1 git fetch
如果要同步你的工作,運(yùn)行 git fetch origin 命令。 這個(gè)命令查找 origin?這個(gè)名字對(duì)應(yīng)哪一個(gè)服務(wù)器,從中抓取本地沒有的數(shù)據(jù),并且更新本地?cái)?shù)據(jù)庫(kù),移動(dòng) origin/master 指針指向新的、更新后的位置。
$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb https://github.com/paulboone/ticgit (fetch)
pb https://github.com/paulboone/ticgit (push)
$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit ?
* [new branch] master -> pb/master ?
* [new branch] ticgit -> pb/ticgit
5.4.2 git pull
當(dāng) git fetch 命令從服務(wù)器上抓取本地沒有的數(shù)據(jù)時(shí),git fetch 會(huì)將遠(yuǎn)程倉(cāng)庫(kù)的最新代碼下載到本地,但它并不會(huì)修改工作目錄中的內(nèi)容,它只會(huì)獲取數(shù)據(jù)然后讓你自己合并,想要更新本地分支,你需要手動(dòng)執(zhí)行 git merge 或者 git rebase 命令來(lái)合并最新代碼。
通常來(lái)講,git pull 的含義是一個(gè) git fetch 緊接著一個(gè) git merge 命令。 如果有一個(gè)設(shè)置好的跟蹤分支(不管它是顯式設(shè)置的還是通過(guò) clone 或 checkout 命令創(chuàng)建的),git pull 會(huì)查找當(dāng)前分支所跟蹤的服務(wù)器與分支,從服務(wù)器上抓取數(shù)據(jù)然后嘗試合并入那個(gè)遠(yuǎn)程分支。
總的來(lái)說(shuō),git fetch 更加安全,因?yàn)樗粫?huì)自動(dòng)合并代碼,你可以在合適的時(shí)候手動(dòng)合并;而 git pull 更加方便,因?yàn)樗梢宰詣?dòng)合并代碼,讓你更快地獲取最新的代碼。
5.5?本地分支推送到遠(yuǎn)程倉(cāng)庫(kù) git push
推送分支,就是把該分支上的所有本地提交推送到遠(yuǎn)程庫(kù)。建議在 git push 之前先執(zhí)行 git pull 命令,以確保本地代碼庫(kù)與遠(yuǎn)程代碼庫(kù)同步。
如果遠(yuǎn)程代碼庫(kù)中已經(jīng)存在一些新的提交,而你本地的代碼庫(kù)沒有進(jìn)行更新,那么你的 push 操作會(huì)被拒絕,因?yàn)槟愕谋镜卮a庫(kù)與遠(yuǎn)程代碼庫(kù)不一致。
推送時(shí),要指定本地分支,比如:運(yùn)行 git push origin master,Git 會(huì)把 master 分支推送到遠(yuǎn)程庫(kù)對(duì)應(yīng)的遠(yuǎn)程分支上。如果要推送其他分支,比如 dev,就用:git push origin dev。
多人協(xié)作小結(jié):
首先,可以試圖用 git push origin
如果 git pull 提示 no tracking information,則說(shuō)明本地分支和遠(yuǎn)程分支的鏈接關(guān)系沒有創(chuàng)建,用命令 git branch --set-upstream-to
6. 問(wèn)題記錄
6.1?添加 remote 信息時(shí)報(bào)錯(cuò):unable to get local isser certificate(服務(wù)器上SSL證書未經(jīng)過(guò)第三方機(jī)構(gòu)認(rèn)證)
git config --global http.sslverify false
6.2?git pull fatal: refusing to merge unrelaterd histories
git pull origin master --allow-unrelated-histories
6.3 Pycharm 側(cè)邊欄沒有 Commit
Settings -> Version Control -> Commit -> 勾選 use non-modal commit interface -> Apply
7. 參考鏈接
Git安裝-Git入門-CSDNGit技能樹
Pro Git:Git - Book
柚子快報(bào)激活碼778899分享:Git 操作總結(jié)
參考鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。