Git
Git Note
- Git文檔
- Git練習(xí)網(wǎng)站
在 Git Base中復(fù)制粘貼:
- ?復(fù)制?: 使用 Ctrl + Insert 快捷鍵可以復(fù)制選中的文本。
- ?粘貼?: 使用 Shift + Insert 快捷鍵可以粘貼剪貼板中的內(nèi)容。
一. 配置
1.1 查看Git所有的配置以及它們所在的文件
$ git config --list --show-origin
1.2 設(shè)置你的用戶名和郵件地址
$ git config --global user.name "NobodyCares"
$ git config --global user.email 3226234796@qq.com
使用了
--global選項(xiàng),那么該命令只需要運(yùn)行一次,因?yàn)橹鬅o論你在該系統(tǒng)上做任何事情, Git 都會(huì)使用那些信息
1.3 通過輸入 git config <key>: 來檢查 Git 的某一項(xiàng)配置:
$ git config user.name
NobodyCares
1.4 獲取幫助
$ git help <Key>
$ git <Key> --help
// 例如獲取git config 命令手冊(cè)
$ git help config
// 獲取簡明參考幫助
$ git config -h
二. Git基礎(chǔ)
2.1 初始化倉庫
# 在項(xiàng)目中,打開Git Base
$ git init
該命令將創(chuàng)建一個(gè)名為
.git的子目錄,這個(gè)子目錄含有你初始化的 Git 倉庫中所有的必須文件,這些文件是 Git 倉庫的骨干。 但是,在這個(gè)時(shí)候,我們僅僅是做了一個(gè)初始化的操作,你的項(xiàng)目里的文件還沒有被跟蹤。
2.2 克隆倉庫git clone
例如克隆 https://github.com/H-TXSL/Airplane_Games.git
$ git clone https://github.com/H-TXSL/Airplane_Games.git
這會(huì)在當(dāng)前目錄下創(chuàng)建一個(gè)名為 “Airplane_Games” 的目錄,并在這個(gè)目錄下初始化一個(gè)
.git文件夾, 從遠(yuǎn)程倉庫拉取下所有數(shù)據(jù)放入.git文件夾,然后從中讀取最新版本的文件的拷貝。
Git 支持多種數(shù)據(jù)傳輸協(xié)議。
當(dāng)你克隆一個(gè)遠(yuǎn)程倉庫時(shí),Git 通常會(huì)自動(dòng)將該遠(yuǎn)程倉庫命名為 origin
2.3 忽略文件
- 創(chuàng)建一個(gè)名為
.gitignore的文件,列出要忽略的文件的模式
文件 .gitignore 的格式規(guī)范如下:
- 所有空行或者以
#開頭的行都會(huì)被 Git 忽略。 - 可以使用標(biāo)準(zhǔn)的 glob 模式匹配,它會(huì)遞歸地應(yīng)用在整個(gè)工作區(qū)中。
所謂的 glob 模式是指 shell 所使用的簡化了的正則表達(dá)式
- 匹配模式可以以(
/)開頭防止遞歸。 - 匹配模式可以以(
/)結(jié)尾指定目錄。 - 要忽略指定模式以外的文件或目錄,可以在模式前加上嘆號(hào)(
!)取反。
星號(hào)(
*)匹配零個(gè)或多個(gè)任意字符;
[abc]匹配任何一個(gè)列在方括號(hào)中的字符 (這個(gè)例子要么匹配一個(gè) a,要么匹配一個(gè) b,要么匹配一個(gè) c);
問號(hào)(?)只匹配一個(gè)任意字符;
如果在方括號(hào)中使用短劃線分隔兩個(gè)字符, 表示所有在這兩個(gè)字符范圍內(nèi)的都可以匹配(比如[0-9]表示匹配所有 0 到 9 的數(shù)字)。
使用兩個(gè)星號(hào)(**)表示匹配任意中間目錄,比如a/**/z可以匹配a/z、a/b/z或a/b/c/z等
# .gitignore 文件示例
# 忽略所有的 .a 文件
*.a
# 但跟蹤所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a
# 只忽略當(dāng)前目錄下的 TODO 文件,而不忽略 subdir/TODO
/TODO
# 忽略任何目錄下名為 build 的文件夾
build/
# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt
# 忽略 doc/ 目錄及其所有子目錄下的 .pdf 文件
doc/**/*.pdf
2.4 記錄每次更新到倉庫
- 工作目錄下的每一個(gè)文件都不外乎這兩種狀態(tài):已跟蹤 或 未跟蹤
Untracked files下為未跟蹤
Changes not staged for commit下,說明已跟蹤文件的內(nèi)容發(fā)生了變化,但還沒有放到暫存區(qū)。
Changes to be committed下為處于暫存區(qū)
2.4.1 檢查當(dāng)前文件狀態(tài)
$ git status
簡潔輸出
$ git status -s
# 新添加的未跟蹤文件前面有 `??` 標(biāo)記
# 新添加到暫存區(qū)中的文件前面有 `A` 標(biāo)記
# 修改過的文件前面有 `M` 標(biāo)記
# 左欄指明了暫存區(qū)的狀態(tài),右欄指明了工作區(qū)的狀態(tài)
2.4.2 跟蹤新文件或暫存已修改的文件
$ git add <file>
2.4.3 查看已暫存和未暫存的修改
git diff 本身只顯示尚未暫存的改動(dòng),而不是自上次提交以來所做的所有改動(dòng)
- 比較工作區(qū)文件與暫存區(qū)文件的差異
$ git diff
# 此命令比較的是工作目錄中當(dāng)前文件和暫存區(qū)域快照之間的差異
- 比較暫存區(qū)文件與本地Git倉庫的差異
$ git diff --staged ( `--staged` 和 `--cached` 是同義詞)
# 此命令將比對(duì)已暫存文件與最后一次提交的文件差異
2.4.4 提交更新
$ git commit -m "要輸入的提交說明"
- 跳過使用暫存區(qū)域
給
git commit加上-a選項(xiàng),Git 就會(huì)自動(dòng)把所有已經(jīng)跟蹤過的文件暫存起來一并提交,從而跳過git add步驟
$ git commit -a -m "要輸入的提交說明"
2.4.5 移除文件
- 移除工作區(qū)文件
# 直接移除
$ rm <file>
# # 工作目錄中刪除文件,同時(shí)把刪除動(dòng)作記錄到暫存區(qū)
$ git rm <file>
git rm命令后面可以列出文件或者目錄的名字,也可以使用glob模式
-
移除暫存區(qū)文件
# 從暫存區(qū)移除文件, 但不刪除工作區(qū)文件 $ git rm --cached <files> -
移除Git倉庫文件
$ git rm <file> $ git commit -m "移除信息說明"2.4.6 移動(dòng)或重命名文件
git mv命令會(huì)自動(dòng)跟蹤文件# 將 name_1 重命名為 name_2 $ git mv <name_1> <name_2>運(yùn)行
git mv就相當(dāng)于運(yùn)行了下面三條命令:
$ mv README.md README
$ git rm README.md
$ git add README
2.5 查看提交歷史
$ git log命令git log的常用選項(xiàng)- 限制
git log輸出的選項(xiàng)
不傳入任何參數(shù)的默認(rèn)情況下,
git log會(huì)按時(shí)間先后順序列出所有的提交,最近的更新排在最上面。
2.5.1 常用選項(xiàng)
2.5.1.1 顯示每次提交引入的差異
$ git log -p -number
# `-number` 選項(xiàng)來只顯示最近的number次提交
2.5.1.2 快速把握每次提交對(duì)文件的修改概況
$ git log --stat
# 修改增刪匯總
2.5.1.3 使用不同于默認(rèn)格式的方式展示提交歷史
$ git log --pretty=?
# ?為子選項(xiàng):
# oneline 會(huì)將每個(gè)提交放在一行顯示
# short 作者和提交信息
# full 作者,提交者,提交信息
# fuller 作者,提交者,提交作者和提交者的時(shí)區(qū)信息, 提交信息
2.5.1.4 定制記錄的顯示格式
-
git log --pretty=format常用的選項(xiàng)# 例如僅輸出: 作者名 - 作者的電子郵件地址 $ git log --pretty=format:"%an - %ae" -
隱藏合并提交
按照你代碼倉庫的工作流程,記錄中可能有為數(shù)不少的合并提交,它們所包含的信息通常并不多。 為了避免顯示的合并提交弄亂歷史記錄,可以為
log加上--no-merges選項(xiàng)。
2.5.2 查看各個(gè)分支當(dāng)前所指的對(duì)象
# 提供這一功能的參數(shù)是 --decorate
$ git log --oneline --decorate
- 項(xiàng)目分叉歷史
$ git log --oneline --decorate --graph --all
# 輸出你的提交歷史、各個(gè)分支的指向以及項(xiàng)目的分支分叉情況。
2.6 撤銷操作
2.6.1 修改提交信息
$ git commit --amend
# 進(jìn)入文本編譯器中修改提交信息
例如 Vim: 按
i鍵進(jìn)入插入模式,對(duì)提交信息進(jìn)行修改。修改完成后,按Esc鍵退出插入模式,然后輸入:wq并回車,這會(huì)保存修改并退出 Vim
2.6.2 添加遺漏文件到暫存區(qū)的信息到最近一次提交
# 先運(yùn)行 git add <file>
# 再運(yùn)行 git commit --amend
例如Vim: 這里不用修改提交信息內(nèi)容,直接按
Esc鍵退出插入模式(如果處于插入模式的話),然后輸入:wq并回車
2.6.3 取消暫存文件
$ git reset HEAD <file>
2.6.4 撤銷對(duì)文件的修改
將文件還原成上次提交時(shí)的樣子,Git 會(huì)用最近提交的版本覆蓋掉它
$ git checkout -- <file>
2.7 遠(yuǎn)程倉庫的使用
2.7.1 添加遠(yuǎn)程倉庫
$ git remote add origin <url>
# 起別名
$ git remote add <shortname> <url>
# 可以在命令行中使用字符串 <shortname> 來代替整個(gè) URL
# -u:該選項(xiàng)是 --set - upstream 的縮寫。它的作用是在推送本地分支到遠(yuǎn)程倉庫的同時(shí),設(shè)置本地分支跟蹤遠(yuǎn)程分支。
$ git push -u origin "master"
# 更改遠(yuǎn)程倉庫 origin 的 URL 地址
$ git remote set-url origin <url>
2.7.2 查看遠(yuǎn)程倉庫
# 顯示需要讀寫遠(yuǎn)程倉庫使用的 Git 保存的簡寫與其對(duì)應(yīng)的 URL
$ git remote -v
# 列出遠(yuǎn)程倉庫的 URL 與跟蹤分支的信息
$ git remote show <remote>
2.7.3 從遠(yuǎn)程倉庫中抓取與拉取
- 抓取
# 這個(gè)命令會(huì)訪問遠(yuǎn)程倉庫,從中拉取所有你還沒有的數(shù)據(jù)
$ git fetch <remote>
注意 git fetch 命令只會(huì)將數(shù)據(jù)下載到你的本地倉庫——它并不會(huì)自動(dòng)合并或修改你當(dāng)前的工作
當(dāng)抓取到新的遠(yuǎn)程跟蹤分支時(shí),本地不會(huì)自動(dòng)生成一份可編輯的副本(拷貝),只有一個(gè)不可以修改的 <remote>/<branch> 指針
可以運(yùn)行 git merge <remote>/<branch> 將這些工作合并到當(dāng)前所在的分支。
- 拉取
# 這個(gè)命令會(huì)自動(dòng)將從遠(yuǎn)程倉庫抓取的分支合并到當(dāng)前所在的分支
$ git pull <remote> <branch>
如果想要在自己的 branch 分支上工作,可以將其建立在遠(yuǎn)程跟蹤分支之上
$ git checkout -b <branch> <remote>/<branch>
# 這會(huì)給你一個(gè)用于工作的本地分支,并且起點(diǎn)位于遠(yuǎn)程分支<remote>/<branch>
# 這會(huì)使創(chuàng)建的分支為跟蹤分支
# 跟蹤分支是與遠(yuǎn)程分支有直接關(guān)系的本地分支。
# 如果在一個(gè)跟蹤分支上輸入 git pull,Git 能自動(dòng)地識(shí)別去哪個(gè)服務(wù)器上抓取、合并到哪個(gè)分支。
# 跟蹤分支的一個(gè)重要特性是,它們會(huì)自動(dòng)與遠(yuǎn)程分支保持同步。
2.7.4 推送到遠(yuǎn)程倉庫
$ git push <remote> <branch>
# 例如
$ git push origin master
# 推送所有分支
$ git push <remote> --all
# 推送一個(gè)分支到遠(yuǎn)程倉庫,并重命名遠(yuǎn)程分支為 <branch_new_name>
# 如果遠(yuǎn)程倉庫不存在 <branch_new_name> 分支,會(huì)創(chuàng)建一個(gè)新分支;若已存在同名分支,則會(huì)用本地分支的提交更新遠(yuǎn)程分支。
$ git push <remote> <branch>:<branch_new_name>
只有當(dāng)你有所克隆服務(wù)器的寫入權(quán)限,并且之前沒有人推送過時(shí),這條命令才能生效
2.7.5 遠(yuǎn)程倉庫重命名與移除
# 重命名
$ git remote rename <old_name> <new_name>
# 移除別名
$ git remote remove <name>
或
$ git remote rm <name>
一旦你使用這種方式刪除了一個(gè)遠(yuǎn)程倉庫,那么所有和這個(gè)遠(yuǎn)程倉庫相關(guān)的遠(yuǎn)程跟蹤分支以及配置信息也會(huì)一起被刪除
2.8 打標(biāo)簽
Git 可以給倉庫歷史中的某一個(gè)提交打上標(biāo)簽,以示重要。
標(biāo)簽在 Git 中是全局的,并不屬于特定的某個(gè)分支。
Git 支持兩種標(biāo)簽:輕量標(biāo)簽(lightweight)與 附注標(biāo)簽(annotated)
輕量標(biāo)簽很像一個(gè)不會(huì)改變的分支——它只是某個(gè)特定提交的引用。
附注標(biāo)簽是存儲(chǔ)在 Git 數(shù)據(jù)庫中的一個(gè)完整對(duì)象, 它們是可以被校驗(yàn)的,其中包含打標(biāo)簽者的名字、電子郵件地址、日期時(shí)間, 此外還有一個(gè)標(biāo)簽信息,并且可以使用 GNU Privacy Guard (GPG)簽名并驗(yàn)證。
默認(rèn)給當(dāng)前 HEAD 所指向的提交打標(biāo)簽,也就是最近的一次提交
2.8.1 創(chuàng)建標(biāo)簽
- 附注標(biāo)簽
$ git tag -a <tag-name> -m "標(biāo)簽信息"
- 輕量標(biāo)簽
創(chuàng)建輕量標(biāo)簽,不需要使用 -a、-s 或 -m 選項(xiàng),只需要提供標(biāo)簽名字
$ git tag <tag-name>
2.8.2 列出標(biāo)簽
$ git tag
# (可帶上可選的 -l 選項(xiàng) --list)
如果你提供了一個(gè)匹配標(biāo)簽名的通配模式,那么 -l 或 --list 就是強(qiáng)制使用的
$ git tag -l "v1.8.5*"
# 列出所有以 v1.8.5 開頭的標(biāo)簽
2.8.3 查看標(biāo)簽信息
$ git show <tag-name>
2.8.4 后期打標(biāo)簽
可以對(duì)過去的提交打標(biāo)簽
# # <commit-id> 可以是提交的 SHA-1 校驗(yàn)和的前幾位字符
# 打輕量標(biāo)簽
$ git tag <tag-name> <commit-id>
# 打附注標(biāo)簽
# 直接添加標(biāo)簽信息
$ git tag -a <tag-name> -m "標(biāo)簽信息" <commit-id>
# 在文本編輯器中編輯標(biāo)簽信息
$ git tag -a <tag-name> <commit-id>
- 例如在 Vim 中
按
insert鍵進(jìn)入插入模式,填寫標(biāo)簽信息。完成后,按Esc鍵退出插入模式,然后輸入:wq并回車,這會(huì)保存修改并退出 Vim
2.8.5 共享標(biāo)簽
默認(rèn)情況下,git push 命令并不會(huì)傳送標(biāo)簽到遠(yuǎn)程倉庫服務(wù)器上。
創(chuàng)建完標(biāo)簽后你必須顯式地推送標(biāo)簽到共享服務(wù)器上。
$ git push <remote> <tag-name>
# 推送所有標(biāo)簽到遠(yuǎn)程倉庫
$ git push <remote> --tags
使用 git push
--tags 推送標(biāo)簽并不會(huì)區(qū)分輕量標(biāo)簽和附注標(biāo)簽, 沒有簡單的選項(xiàng)能夠讓你只選擇推送一種標(biāo)簽。
2.8.6 刪除標(biāo)簽
- 刪除本地標(biāo)簽
$ git tag -d <tag-name>
- 刪除遠(yuǎn)程標(biāo)簽
$ git push <remote> :refs/tags/<ta-name>
# 上面這種操作的含義是,將冒號(hào)前面的空值推送到遠(yuǎn)程標(biāo)簽名,從而高效地刪除它。
# 更直觀的刪除
$ git push <remote> --delete <tag-name>
2.8.7 檢出標(biāo)簽
查看某個(gè)標(biāo)簽所指向的文件版本
這會(huì)使你的倉庫處于分離頭指針 detached HEAD的狀態(tài)
這種狀態(tài)下,你對(duì)文件所做的修改和提交不會(huì)影響到任何分支,因?yàn)?HEAD 沒有與分支關(guān)聯(lián)。
$ git checkout <tag-name>
- 撤銷分離頭指針狀態(tài)
$ git switch -
- 創(chuàng)建新分支保留提交
如果你想基于當(dāng)前處于 “detached HEAD” 狀態(tài)下的提交創(chuàng)建一個(gè)新分支來保留所做的更改
# -c 選項(xiàng)的作用是創(chuàng)建并切換到一個(gè)新分支
$ git switch -c <new-branch-name>
三. 分支
Git保存數(shù)據(jù)的方式
Git 保存的不是文件的變化或者差異,而是一系列不同時(shí)刻的快照。
- 提交對(duì)象
進(jìn)行提交操作時(shí),Git 會(huì)保存一個(gè)提交對(duì)象(commit object)。
提交對(duì)象包含了作者的姓名和郵箱、提交時(shí)輸入的信息以及指向它的父對(duì)象的指針和一個(gè)指向暫存內(nèi)容快照的指針。
首次提交產(chǎn)生的提交對(duì)象沒有父對(duì)象,普通提交操作產(chǎn)生的提交對(duì)象有一個(gè)父對(duì)象, 而由多個(gè)分支合并產(chǎn)生的提交對(duì)象有多個(gè)父對(duì)象。
使用 git commit 進(jìn)行提交操作時(shí):
- Git 會(huì)先計(jì)算每一個(gè)子目錄的校驗(yàn)和
- 然后將 Git 倉庫中這些校驗(yàn)和保存為樹對(duì)象
- 隨后,Git 便會(huì)創(chuàng)建一個(gè)提交對(duì)象, 它除了包含上面提到的那些信息外,還包含指向這個(gè)樹對(duì)象的指針。
Git 倉庫中有五個(gè)對(duì)象:三個(gè) blob 對(duì)象(保存著文件快照)、一個(gè) 樹 對(duì)象 (記錄著目錄結(jié)構(gòu)和 blob 對(duì)象索引)以及一個(gè) 提交 對(duì)象(包含著指向前述樹對(duì)象的指針和所有提交信息)。
3.0 HEAD指針和^,~引用
分離頭指針
分離頭指針是一種特殊的狀態(tài), 它表示當(dāng)前 Git 倉庫處于一個(gè)沒有任何分支的狀態(tài)。
# 例如:
$ git checkout <commit-id>
# 這會(huì)使你的倉庫處于分離頭指針狀態(tài)。
# 此時(shí),你對(duì)文件所做的修改和提交不會(huì)影響到任何分支,因?yàn)?HEAD 沒有與分支關(guān)聯(lián)。
$ git switch -
# 這會(huì)將 HEAD 指針切換回上一次所在的分支,撤銷進(jìn)入 “分離頭指針” 狀態(tài)的操作,恢復(fù)到之前的工作狀態(tài)。
相對(duì)引用
單一父提交的引用為上一次的提交
多父提交的引用,第一個(gè)父提交是當(dāng)前分支在合并前的狀態(tài),第二個(gè)父提交是被合并分支的狀態(tài) 。
- ^引用
# 例如: 現(xiàn)在提交記錄為上圖
# 現(xiàn)在: HEAD指向master,master指向C3
$ git checkout master^
# 這會(huì)將 HEAD 指針切換到 master 分支的上一個(gè)提交,即 c1。
$ git merge main
# 這會(huì)將當(dāng)前分支(master)與 main 分支合并。
# 合并完成后,HEAD 指針會(huì)指向最新的提交,即 c4。
# 如下圖所示:
$ git checkout master^
# 這會(huì)將 HEAD 指針切換到 master 分支合并前的狀態(tài)提交,即 c3。
# 如下圖所示:
$ git checkout master
# 這會(huì)將 HEAD 指針切換回 master 分支,恢復(fù)到之前的工作狀態(tài)。
$ git checkout master^2
# 這會(huì)將 HEAD 指針切換到被合并分支的狀態(tài)提交,即 c2。
# 也就是之前master分支合并的main分支指向的c2提交
# 如下圖所示:
- ~引用
相對(duì)引用的簡化形式,可以使用 ~ 符號(hào)來代替 ^ 符號(hào)
# 例如分支提交為上圖
# 現(xiàn)在: HEAD指向main,main指向C3
$ git checkout main~number
# number 為 2 時(shí)
$ git checkout main~2
# 這會(huì)將 HEAD 指針切換到 main 分支的上兩個(gè)提交,即 c1。
# number 為 3 時(shí)
$ git checkout main~3
# 這會(huì)將 HEAD 指針切換到 main 分支的上三個(gè)提交,即 c0。
3.1 分支簡介
- Git 的分支,其實(shí)本質(zhì)上僅僅是指向提交對(duì)象的可變指針。
- Git 的默認(rèn)分支名字是 master, 是因?yàn)?git init 命令默認(rèn)創(chuàng)建它
3.2 分支操作
3.2.1 分支創(chuàng)建
- 只創(chuàng)建分支不切換到新分支
$ git branch <new-branch-name>
# 這會(huì)創(chuàng)建一個(gè)指向當(dāng)前提交對(duì)象的指針
只有當(dāng)你在該分支提交后,Git 才會(huì)把這個(gè)指針移動(dòng)到新的提交對(duì)象上。
- 創(chuàng)建新分支并切換到新分支
$ git switch -c <new-branch-name>
------------------------------------
$ git checkout -b <new-branch-name>
# 上面的命令等價(jià)于
$ git branch <new-branch-name>
$ git checkout <new-branch-name>
3.2.2 分支切換
$ git checkout <branch-name>
# 這樣 HEAD 就指向了該分支
分支切換會(huì)改變你工作目錄中的文件
請(qǐng)牢記:當(dāng)你切換分支的時(shí)候,Git 會(huì)重置你的工作目錄,使其看起來像回到了你在那個(gè)分支上最后一次提交的樣子。
- 強(qiáng)制分支指向指定提交
$ git branch -f <branch-name> <commit-id>
# 這會(huì)將分支 <branch-name> 強(qiáng)制指向 <commit-id> 所指向的提交對(duì)象。
3.2.3 列出分支
# 列出所有本地分支
$ git branch
# 查看每一個(gè)分支最后一次提交
$ git branch -v
# 列出所有遠(yuǎn)程分支
$ git branch -r
# 列出所有遠(yuǎn)程分支的最后一次提交
$ git branch -rv
# 列出所有本地分支和遠(yuǎn)程分支
$ git branch -a
# 列出所有本地分支和遠(yuǎn)程分支,以及它們的最后一次提交
$ git branch -av
# 列出哪些分支已經(jīng)合并到當(dāng)前分支
$ git branch --merged
# 列出哪些分支還沒有合并到當(dāng)前分支
$ git branch --no-merged
# 還可以加附加一個(gè)參數(shù)<branch-name>,列出哪些分支還沒有合并到<branch-name>分支或者哪些分支已經(jīng)合并到<branch-name>分支
$ git branch --merged <branch-name>
$ git branch --no-merged <branch-name>
3.2.4 分支合并
- 合并指定分支到當(dāng)前分支
$ git merge <branch-name>
- 合并指定分支到指定分支
# 將 <source-branch> 分支合并到 <target-branch> 分支
$ git merge <source-branch> <target-branch>
若合并過程中沒有沖突,Git 會(huì)自動(dòng)將分支指針向前移動(dòng), 并將其指向被合并分支所指向的提交對(duì)象。
若合并過程中發(fā)生了沖突,Git 會(huì)停止合并過程,并要求你解決沖突。
為了解決沖突,你必須選擇使用由 ======= 分割的兩部分中的一個(gè),或者你也可以自行合并這些內(nèi)容。
解決沖突后,你需要使用 git add 命令將沖突文件添加到暫存區(qū), 然后使用 git commit 命令提交合并。
3.2.5 分支刪除
- 刪除本地分支
$ git branch -d <branch-name>
- 刪除遠(yuǎn)程分支
$ git push origin --delete <branch-name>
# 或者
$ git push origin :<branch-name>
# 這種格式在早期的 Git 版本中較為常用
# 它的含義就是告訴 Git,要把一個(gè)空分支推送到遠(yuǎn)程倉庫的指定分支位置
# 實(shí)際上就相當(dāng)于刪除遠(yuǎn)程分支。
# 或者
$ git push origin -d <branch-name>
# 此操作僅影響遠(yuǎn)程倉庫,本地倉庫中對(duì)應(yīng)的分支仍然存在(如果本地有該分支的話)。
3.3 遠(yuǎn)程分支
遠(yuǎn)程跟蹤分支是遠(yuǎn)程分支狀態(tài)的引用, 它們以 <remote>/<branch> 的形式命名.
Git 的 clone 命令會(huì)為你自動(dòng)將遠(yuǎn)程倉庫命名為 origin,拉取它的所有數(shù)據(jù), 創(chuàng)建一個(gè)指向它的 master 分支的指針,并且在本地將其命名為 origin/master。Git還會(huì)創(chuàng)建一個(gè)與遠(yuǎn)程跟蹤分支指向同一個(gè)提交對(duì)象的本地master分支,這個(gè)本地master分支就是你所在的master分支。
“origin” 并無特殊含義
遠(yuǎn)程倉庫名字 “origin” 與分支名字 “master” 一樣,在 Git 中并沒有任何特別的含義一樣。
同時(shí) “master” 是當(dāng)你運(yùn)行 git init 時(shí)默認(rèn)的起始分支名字,原因僅僅是它的廣泛使用, “origin” 是當(dāng)你運(yùn)行 git clone 時(shí)默認(rèn)的遠(yuǎn)程倉庫名字。
如果你運(yùn)行 git clone -o booyah,那么你默認(rèn)的遠(yuǎn)程分支名字將會(huì)是 booyah/master。
3.3.1 查看遠(yuǎn)程引用
# 列出遠(yuǎn)程倉庫的所有引用信息
# 不僅包括分支(refs/heads/ 下的內(nèi)容),還涵蓋標(biāo)簽(refs/tags/ 下的內(nèi)容)以及其他可能的引用
$ git ls-remote <remote>
# 專門用于列出遠(yuǎn)程倉庫中所有分支(包括本地跟蹤的遠(yuǎn)程分支)的引用信息
$ git ls-remote --heads <remote>
# 獲得遠(yuǎn)程分支的更多信息
$ git remote show <remote>
3.3.2 跟蹤分支
跟蹤分支是一個(gè)指向遠(yuǎn)程分支的本地分支,它會(huì)自動(dòng)更新以反映遠(yuǎn)程分支的狀態(tài)。
在一個(gè)跟蹤分支上輸入 git pull,Git 能自動(dòng)地識(shí)別去哪個(gè)服務(wù)器上抓取、合并到哪個(gè)分支。
3.3.2.1 創(chuàng)建跟蹤分支
# 創(chuàng)建一個(gè)本地分支,該分支會(huì)自動(dòng)跟蹤遠(yuǎn)程倉庫的指定分支
$ git checkout -b <branch> <remote>/<branch>
# 或者
# 這會(huì)創(chuàng)建一個(gè)本地分支,該分支會(huì)自動(dòng)跟蹤遠(yuǎn)程倉庫的指定分支
$ git checkout --track <remote>/<branch>
# 都會(huì)自動(dòng)切換到新的分支
# 更加簡潔的方式
$ git checkout <branch>
# 1. Git 會(huì)先檢查本地是否存在名為 <branch> 的分支
# 2. 如果不存在,Git 接著會(huì)在所有遠(yuǎn)程倉庫中查找是否有唯一與之匹配的遠(yuǎn)程分支.
# 3. 一旦條件滿足,Git 會(huì)自動(dòng)創(chuàng)建一個(gè)本地的 <branch> 分支,并將其設(shè)置為跟蹤遠(yuǎn)程分支的分支,然后立即切換到這個(gè)新創(chuàng)建的本地分支
# 4. 如果遠(yuǎn)程倉庫中也不存在名為 <branch> 的分支,Git 會(huì)報(bào)錯(cuò)
# 這個(gè)快捷方式依賴于遠(yuǎn)程分支名稱的唯一性
# 將本地已有分支與遠(yuǎn)程分支建立跟蹤關(guān)系
# 在已有分支下執(zhí)行
# -u 或 --set-upstream-to
$ git branch -u <remote>/<branch>
3.3.2.2 查看設(shè)置的所有跟蹤分支
$ git branch -vv
3.3.3 刪除遠(yuǎn)程分支
$ git push <remote> --delete <branch>
# 基本上這個(gè)命令做的只是從服務(wù)器上移除這個(gè)指針。 Git 服務(wù)器通常會(huì)保留數(shù)據(jù)一段時(shí)間直到垃圾回收運(yùn)行,所以如果不小心刪除掉了,通常是很容易恢復(fù)的。
3.4 分支改名
3.4.1 本地分支改名
$ git branch -m <old - branch - name> <new - branch - name>
3.4.2 遠(yuǎn)程分支改名
# 先改本地分支名,再推送新名并刪除舊名
# 改本地分支名
$ git branch -m <old - branch - name> <new - branch - name>
# 推送新名分支
$ git push <remote> <new_branch-name>
# 刪除舊名分支
$ git push <remote> --delete <old_branch-name>
3.5 變基
變基操作的目的是將一個(gè)分支的提交歷史“重新應(yīng)用”到另一個(gè)分支上。
無論是通過變基,還是通過三方合并,整合的最終結(jié)果所指向的快照始終是一樣的,只不過提交歷史不同罷了。
變基過程中,原分支的每個(gè)提交都會(huì)在基準(zhǔn)分支的新上下文下重新創(chuàng)建,提交哈希因父節(jié)點(diǎn)變更而更新,故每個(gè)提交對(duì)應(yīng)一個(gè)新對(duì)象。
3.5.1 變基的基本操作:
# 分支初始狀態(tài)如上圖
# 現(xiàn)在處于master分支
# 現(xiàn)要將master分支變基到main分支
$ git rebase main
# 1. 執(zhí)行 git rebase main 時(shí),Git 會(huì)把 master 分支基于 main 分支的共同祖先之后的修改提取出來
# 2.然后在 main 分支的最新提交之上重新應(yīng)用這些修改,從而產(chǎn)生一系列新的提交(可看作產(chǎn)生了一個(gè)基于 main 分支最新狀態(tài)的新提交)
# 3. 并讓 master 分支指針指向這個(gè)新的提交
# 如下圖所示
# 檢出到main分支
$ git checkout main
# 進(jìn)行快進(jìn)合并master分支
$ git merge master
# 1. 因?yàn)?master 分支現(xiàn)在是 main 分支的直接上游(變基后的結(jié)果)
# 2. 所以 main 分支可以直接 “快進(jìn)” 到 master 分支指針?biāo)赶虻奶峤晃恢?# 3. 即將 main 分支指針移動(dòng)到 master 分支最新提交處,完成合并
# 如下圖所示
3.5.2 截取主題分支上的另一個(gè)主題分支,然后變基到其他分支
# 現(xiàn)在有提交記錄如上圖
# 現(xiàn)在處于master分支
# 并且有一個(gè)基于c2提交的主題分支demo_1分支和一個(gè)基于c4提交的主題分支demo_2分支
# 現(xiàn)在要截取主題分支demo_1分支的另一個(gè)主題分支demo_2分支變基到master分支
$ git rebase master demo_1 demo_2
# 執(zhí)行后HEAD指針指向產(chǎn)生的新提交c6`
# 效果如下圖所示
# 切回master分支,進(jìn)行快速合并
$ git checkout master
$ git merge demo_2
# 效果如下圖所示
# 將demo_1分支變基到master
$ git rebase master demo_1
# 并切換到master,進(jìn)行快速合并
$ git checkout master
$ git merge demo_1
# 變基過程中,原分支的每個(gè)提交都會(huì)在基準(zhǔn)分支的新上下文下重新創(chuàng)建,提交哈希因父節(jié)點(diǎn)變更而更新,故每個(gè)提交對(duì)應(yīng)一個(gè)新對(duì)象。
# 此處原分支有 3 個(gè)提交,因此生成 3 個(gè)新提交。
# 效果如下圖所示
3.5.3 變基的注意事項(xiàng)
- 變基操作會(huì)改變提交歷史,因此在變基之前,一定要確保你已經(jīng)備份了所有重要的工作。
- 變基操作可能會(huì)導(dǎo)致提交歷史的混亂,因此在執(zhí)行變基操作之前,一定要確保你已經(jīng)備份了所有重要的工作。
變基也并非完美無缺,要用它得遵守一條準(zhǔn)則:
如果提交存在于你的倉庫之外,而別人可能基于這些提交進(jìn)行開發(fā),那么不要執(zhí)行變基。
3.5.4 用變基解決變基
如果遇到有人推送了經(jīng)過變基的提交,并丟棄了你的本地開發(fā)所基于的一些提交的這種情境
執(zhí)行 git rebase <remote>/<branch> 命令
- 另一種簡單的方法
git pull --rebase命令
該命令會(huì)自動(dòng)執(zhí)行
git fetch命令來獲取遠(yuǎn)程分支的最新提交,然后執(zhí)行git rebase命令來將本地分支的提交歷史重新應(yīng)用到遠(yuǎn)程分支的最新提交之上。
本文來自博客園,作者:Nobody_Cares,轉(zhuǎn)載請(qǐng)注明原文鏈接:http://www.rzrgm.cn/NobodyCares/p/19159332
正在加載今日詩詞....
Git使用指南,涵蓋Git配置、基礎(chǔ)操作(初始化、克隆、忽略文件、記錄更新等)、撤銷操作、遠(yuǎn)程倉庫管理、標(biāo)簽使用以及分支操作(創(chuàng)建、切換、合并、變基等)等核心內(nèi)容,通過命令示例與說明結(jié)合的方式,系統(tǒng)性介紹了Git版本控制系統(tǒng)的關(guān)鍵功能與使用方法。












浙公網(wǎng)安備 33010602011771號(hào)