一.什么是Git
在學習工作中,我們經常會遇到改文檔的場景。一個文檔可能會被我們修改多次,而最終真正使用的可能是最先的幾版。而如果我們直接在原文檔上修改,就會導致無法找到最先的幾次。這也就導致我們要對我們所有的版本進行維護,而Git就是一個版本控制器。
git會為我們創建一個倉庫,用來保存、管理、記錄我們對各種格式資源的修改。而這個git倉庫是要依托于一個目錄的。
二.git安裝
centos:sudo yum -y install git
ubuntu:sudo apt-get install git -y安裝成功使用:git --version查看git版本
三.初始化本地git倉庫
1.創建本地倉庫
要想建立一個本地的git倉庫,我們首先得有一個目錄,在該目錄內創建git倉庫。
git init
創建成功后,會在當前目錄下創建一個隱藏目錄
xsc@xsc-VMware-Virtual-Platform:~/code/git$ ll
總計 12
drwxrwxr-x 3 xsc xsc 4096 7月 31 14:56 ./
drwxrwxr-x 5 xsc xsc 4096 7月 31 14:56 ../
drwxrwxr-x 7 xsc xsc 4096 7月 31 14:56 .git/
這個隱藏目錄,才是真正的git倉庫。不要手動對該隱藏目錄做任何修改。?
xsc@xsc-VMware-Virtual-Platform:~/code/git$ tree .git
.git
├── branches
├── config
├── description
├── HEAD
├── hooks
│?? ├── applypatch-msg.sample
│?? ├── commit-msg.sample
│?? ├── fsmonitor-watchman.sample
│?? ├── post-update.sample
│?? ├── pre-applypatch.sample
│?? ├── pre-commit.sample
│?? ├── pre-merge-commit.sample
│?? ├── prepare-commit-msg.sample
│?? ├── pre-push.sample
│?? ├── pre-rebase.sample
│?? ├── pre-receive.sample
│?? ├── push-to-checkout.sample
│?? ├── sendemail-validate.sample
│?? └── update.sample
├── info
│?? └── exclude
├── objects
│?? ├── info
│?? └── pack
└── refs├── heads└── tags10 directories, 18 files
2.配置本地倉庫
git config [--global] user.name "your name"
git config [--global] user.email "your email"--global:表示該配置在該機器上的所有倉庫有效
不帶則只在當前倉庫有效
使用git config -l查看當前git配置
sc@xsc-VMware-Virtual-Platform:~/code/git$ git config -l
user.name=夏思成
user.email=3330826680@qq.com
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
取消某個配置,如果但是以global配置的,則取消配置也要帶上global
git config --unset user.name/user.email
四.工作區、暫存區、版本庫
git倉庫是要依托于目錄的。
- 工作區:git倉庫所屬的目錄,git倉庫不會主動追蹤工作區中的修改
- 暫存區:版本庫中的一段臨時空間,可以理解為待提交的修改清單
- 版本庫:Git 用來存儲所有版本歷史記錄的地方,是 Git 的核心。本地版本庫位于工作區目錄下的?
.git
?隱藏文件夾中(不要手動修改里面的內容)
當我們創建一個本地倉庫,git會為我們創建一個唯一的master分支,head指針指向master分支。
我們想要讓git幫我們管理文件,不是說放在工作區,git就幫我們管理了,我們需要通過git add將需要追蹤的文件添加到暫存區,然后通過git commit將暫存區的內容進行提交,此時git就能幫我們追蹤這些文件了。?
而被追蹤的文件其實是被保存到了objects分區,也是.git隱藏目錄下一個目錄中。暫存區和master分支存儲的其實都是索引,真正的內容存放在objects中。
五.git基本操作?
我們這里新建一個readme文件,并初始化為hello git
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
1.git status
查看倉庫狀態
- 紅色文件:在工作區,未添加到暫存區;
- 綠色文件:在暫存區,未提交到版本庫;
- 無特殊標記:已提交到版本庫(工作區與版本庫一致)。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master尚無提交未跟蹤的文件:(使用 "git add <文件>..." 以包含要提交的內容)readme提交為空,但是存在尚未跟蹤的文件(使用 "git add" 建立跟蹤)
2.git add
將文件添加到暫存區中,該文件必須是被修改的(新增,刪除,修改)。add之后,會在objects中新增一個git對象,該對象描述的就是本次的修改。
git add [file1] [file2]... // 將一個/多個文件同時添加到暫存區
git add . // 將當前目錄下所有修改的文件添加到暫存區
xsc@xsc-VMware-Virtual-Platform:~/code/git$ tree .git/
.git/
├── branches
├── config
├── description
├── HEAD
├── hooks
│?? ├── applypatch-msg.sample
│?? ├── commit-msg.sample
│?? ├── fsmonitor-watchman.sample
│?? ├── post-update.sample
│?? ├── pre-applypatch.sample
│?? ├── pre-commit.sample
│?? ├── pre-merge-commit.sample
│?? ├── prepare-commit-msg.sample
│?? ├── pre-push.sample
│?? ├── pre-rebase.sample
│?? ├── pre-receive.sample
│?? ├── push-to-checkout.sample
│?? ├── sendemail-validate.sample
│?? └── update.sample
├── index
├── info
│?? └── exclude
├── objects
│?? ├── 8d
│?? │?? └── 0e41234f24b6da002d962a26c2495ea16a425f
│?? ├── info
│?? └── pack
└── refs├── heads└── tags11 directories, 20 files
?當我們提交之后,在查看倉庫狀態,此時就沒有未跟蹤的文件,而是沒有提交的變更。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master尚無提交要提交的變更:(使用 "git rm --cached <文件>..." 以取消暫存)新文件: readme
使用git reset filename 可以將暫存區中的文件刪除,退回到工作區
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git reset readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master尚無提交未跟蹤的文件:(使用 "git add <文件>..." 以包含要提交的內容)readme提交為空,但是存在尚未跟蹤的文件(使用 "git add" 建立跟蹤)
3.git commit
將暫存區的內容提交到本地倉庫
git commit -m "提交描述"
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "add readme"
[master (根提交) 5b1b851] add readme1 file changed, 1 insertion(+)create mode 100644 readmexsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
無文件要提交,干凈的工作區
4.git log
查看該倉庫的歷史提交記錄
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git log
commit 5b1b8515d2f8355d8f7cfa59e07ffdb1c34b0819 (HEAD -> master)
Author: 夏思成 <3330826680@qq.com>
Date: Thu Jul 31 15:32:02 2025 +0800add readme
5..git目錄中的HEAD指針
當我們完成一次提交之后再來查看git倉庫
xsc@xsc-VMware-Virtual-Platform:~/code/git$ tree .git/
.git/
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── hooks
│?? ├── applypatch-msg.sample
│?? ├── commit-msg.sample
│?? ├── fsmonitor-watchman.sample
│?? ├── post-update.sample
│?? ├── pre-applypatch.sample
│?? ├── pre-commit.sample
│?? ├── pre-merge-commit.sample
│?? ├── prepare-commit-msg.sample
│?? ├── pre-push.sample
│?? ├── pre-rebase.sample
│?? ├── pre-receive.sample
│?? ├── push-to-checkout.sample
│?? ├── sendemail-validate.sample
│?? └── update.sample
├── index
├── info
│?? └── exclude
├── logs
│?? ├── HEAD
│?? └── refs
│?? └── heads
│?? └── master
├── objects
│?? ├── 4b
│?? │?? └── 825dc642cb6eb9a060e54bf8d69288fbee4904
│?? ├── 5b
│?? │?? └── 1b8515d2f8355d8f7cfa59e07ffdb1c34b0819
│?? ├── 6e
│?? │?? └── 84d6a5ed71a327ba3376cac9801558d9ea2e80
│?? ├── 8d
│?? │?? └── 0e41234f24b6da002d962a26c2495ea16a425f
│?? ├── info
│?? └── pack
└── refs├── heads│?? └── master└── tags17 directories, 27 files
HEAD指針指向的其實是master分支,而master分支其實保存的是最近一次的commit id。該id是通過哈希算法計算而來的。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat .git/HEAD
ref: refs/heads/master
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat .git/refs/heads/master
5b1b8515d2f8355d8f7cfa59e07ffdb1c34b0819
而我們使用git cat-file -p來查看這個commit id的內容,其實就是我們的最新一次提交
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git cat-file -p 5b1b8515d2f8355d8f7cfa59e07ffdb1c34b0819
tree 6e84d6a5ed71a327ba3376cac9801558d9ea2e80
author 夏思成 <3330826680@qq.com> 1753947122 +0800
committer 夏思成 <3330826680@qq.com> 1753947122 +0800add readme
git倉庫追蹤的并不是一個文件,而是該文件的修改,而文件的修改包括,新增/刪除/修改。當一個文件被修改時,我們可以使用git diff file 來查看工作區與版本庫之間的差異:
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme hello git hello world xsc@xsc-VMware-Virtual-Platform:~/code/git$ git diff readme diff --git a/readme b/readme index 8d0e412..05fe86c 100644 --- a/readme +++ b/readme @@ -1 +1,2 @@hello git +hello world
此時我們將本地修改,添加到暫存區,再進行提交
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status 位于分支 master 尚未暫存以備提交的變更:(使用 "git add <文件>..." 更新要提交的內容)(使用 "git restore <文件>..." 丟棄工作區的改動)修改: readme修改尚未加入提交(使用 "git add" 和/或 "git commit -a") xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add readme xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "modify readme" [master fbffb1c] modify readme1 file changed, 1 insertion(+)
?6.版本回退
git reset [--soft | --mixed | --hard] cimmit id?
- soft:只將版本庫中的內容回退
- mixed:只回退版本庫和暫存區 (默認行為)
- hard:全部回退,慎用
git reset HEAD/*表示當前版本,即最新;帶^表示上一個版本*/? [filename]
當前我們對readme文件進行了兩次修改,版本1只有hello git,版本2還新增了hello world。
當我們使用soft,此時提示我們一個為提交的修改,因為此時我們只回退了版本庫,暫存區與工作區一致。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git reset --soft 5b1b8515d2f8355d8f7cfa59e07ffdb1c34b0819 xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status 位于分支 master 要提交的變更:(使用 "git restore --staged <文件>..." 以取消暫存)修改: readmexsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme hello git hello world
?如果我們回退錯了,想回到沒有回退之前,只要我們知道之前的commit id就可以回到回退之前。但是當我們回退之后,其實git log就會丟棄最新的幾次日志。沒有commid id就無法撤銷回退。但其實git還有一個git reflog,可以查看歷史上git命令的commit id。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git reflog
5b1b851 (HEAD -> master) HEAD@{0}: reset: moving to HEAD
5b1b851 (HEAD -> master) HEAD@{1}: reset: moving to 5b1b8515d2f8355d8f7cfa59e07ffdb1c34b0819
fbffb1c HEAD@{2}: commit: modify readme
5b1b851 (HEAD -> master) HEAD@{3}: commit (initial): add readme
我們通過這些短的commit id依舊可以撤銷回退。
?值得說的是,Git版本回退速度非常快,因為git在內部維護了一個指向當前分支的head指針,refs/heads/master分支存儲的就是最新一次的commit id。當我們進行版本回退的時候,可以簡單的理解為,只是將master分支指向了之前的commit id而已。
7.撤銷修改?
當我們完成一個功能后,提交了修改之后。產品經理又提了新要求,此時我們就需要在對代碼進行修改,但是我們越寫越亂,最后導致之前的邏輯都出了問題。所以,我們就打算從上一次的提交版本開始重新寫。
如果我們直接手動刪的話,代碼量一多,就有可能誤刪。我們可以使用git來幫助我們來撤銷這一次的修改。
如果本次修改還未add:git checkout -- filename
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme hello git hello world xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme hello git hello world aaaa xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -- readme xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme hello git hello world
如果已經add,還沒commit:git reset? 使用默認選項即可
git reset HEAD readme // 回退到當前版本,即最新的一次,然后我們看到暫存區為空,即回到了上一種情況,我們在使用git checkout -- readme即可
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git reset HEAD readme 重置后取消暫存的變更: M readmexsc@xsc-VMware-Virtual-Platform:~/code/git$ git status 位于分支 master 尚未暫存以備提交的變更:(使用 "git add <文件>..." 更新要提交的內容)(使用 "git restore <文件>..." 丟棄工作區的改動)修改: readme修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
已經add,并且commit:前提條件是沒有被push到遠程倉庫
我們可以直接使用 git reset --hard HEAD readme,將工作區,暫存區,版本庫,都回退到最新版本
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status 位于分支 master 無文件要提交,干凈的工作區xsc@xsc-VMware-Virtual-Platform:~/code/git$ git reset --hard HEAD^ HEAD 現在位于 d8afe07 md readmexsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme hello git hello world
?8.刪除文件
在git中,刪除文件也是修改的一種,刪除文件有兩種原因:不小心刪除了;確實不想管理該文件了。
對于不小心刪除了,我們直接使用git checkout -- filename,即可將本次刪除修改,撤銷
xsc@xsc-VMware-Virtual-Platform:~/code/git$ ll
總計 16
drwxrwxr-x 3 xsc xsc 4096 7月 31 16:19 ./
drwxrwxr-x 5 xsc xsc 4096 7月 31 14:56 ../
drwxrwxr-x 8 xsc xsc 4096 7月 31 16:19 .git/
-rw-rw-r-- 1 xsc xsc 22 7月 31 16:19 readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ rm readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
尚未暫存以備提交的變更:(使用 "git add/rm <文件>..." 更新要提交的內容)(使用 "git restore <文件>..." 丟棄工作區的改動)刪除: readme修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -- readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ ll
總計 16
drwxrwxr-x 3 xsc xsc 4096 7月 31 16:22 ./
drwxrwxr-x 5 xsc xsc 4096 7月 31 14:56 ../
drwxrwxr-x 8 xsc xsc 4096 7月 31 16:22 .git/
-rw-rw-r-- 1 xsc xsc 22 7月 31 16:22 readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
無文件要提交,干凈的工作區
xsc@xsc-VMware-Virtual-Platform:~/code/git$
如果我們是真的想要刪除該文件,則我們還要提交刪除修改。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ rm readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
尚未暫存以備提交的變更:(使用 "git add/rm <文件>..." 更新要提交的內容)(使用 "git restore <文件>..." 丟棄工作區的改動)刪除: readme修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "delete readme"
[master c9237b9] delete readme1 file changed, 2 deletions(-)delete mode 100644 readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
無文件要提交,干凈的工作區
如果直接使用git rm file則不需要add,只用commit即可。?
六.分支管理
1.理解分支
你出生在斗宗村,這個村子里面的人都會分身。而在你的世界中,每個人從10歲開始就修行功法,并且只能修煉一門。而村子里的人8歲就可以分身了,你在10歲的時候,一邊學習焚決,一邊又讓你的分身學習煉藥術,然后修行完畢后,你有進行了合體。這樣,你就有了兩種功法,天下無敵了。
而對于我們直接所有的提交來說,都只有一個master主分支,而head直線master主分支,master指向最新的一次提交。?
所以,我們要理解haed和master的區別。head指向當前正在使用的分支,而master指向自己最新的一次提交。
所以,我們也可以在master主分支上創建分支,在該分支上進行提交。但是需要注意的是,在該分支上提交的東西,并不會影響主分支,主分支看不到新分支上的修改。除非主分支主動merge新分支。
2.創建分支?
使用git branch 可以查看當前倉庫的分支,*表示當前處于哪個分支上,即head指向那個分支
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
* master
創建分支:git branch 分支名
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch dev
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branchdev
* master
創建分支后,.git/refs/heads/就會多一個dev分支
└── refs├── heads│?? ├── dev│?? └── master└── tags
新建的分支可以看到master分支之前所有的提交,且是最新的。
3.切換分支?
git checkout dev
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout dev
切換到分支 'dev'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
* devmaster
我們在dev分支上,新建一個readme文件,添加hello git并提交。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ echo hello git > readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ ls
readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "touch readme"
[dev d0cad69] touch readme1 file changed, 1 insertion(+)create mode 100644 readme
我們趕緊切換為master分支,查看當前目錄下,卻沒有readme這個文件,這是為什么?文件怎么丟了?
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切換到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ ll
總計 12
drwxrwxr-x 3 xsc xsc 4096 7月 31 16:50 ./
drwxrwxr-x 5 xsc xsc 4096 7月 31 14:56 ../
drwxrwxr-x 8 xsc xsc 4096 7月 31 16:50 .git/
這是為什么呢?dev上面能看見,master分支上卻看不見。
這是因為我們進行一次提交之后,dev分支的時間線已經變了,而master的時間線還是原來的,這就導致master看不到最新的變化。
4.合并分支?
為了讓master分支可以看到dev分支做出的提交,這就需要將dev分支合并到master分支上。想讓master合并dev,需要先切換到master分支上,然后使用git merge dev進行合并。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branchdev
* master
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge dev
更新 c9237b9..d0cad69
Fast-forwardreadme | 1 +1 file changed, 1 insertion(+)create mode 100644 readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ ll
總計 16
drwxrwxr-x 3 xsc xsc 4096 7月 31 16:54 ./
drwxrwxr-x 5 xsc xsc 4096 7月 31 14:56 ../
drwxrwxr-x 8 xsc xsc 4096 7月 31 16:54 .git/
-rw-rw-r-- 1 xsc xsc 10 7月 31 16:54 readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
我們可以看到合并的時候出現了一個Fast-forward,這是本次合并所使用的模式——快進模式,該模式只是將master指向dev的當前提交,所以合并速度非常快。
5.刪除分支?
合并完分支后,dev分支對我們來說就沒有用了,此時直接使用git branch -d dev刪除掉該分支。刪除分支時,不能處于要刪除的分支上。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branchdev
* master
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -d dev
已刪除分支 dev(曾為 d0cad69)。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
* master
因為創建、合并和刪除分??常快,所以Git?勵你使?分?完成某個任務,合并后再刪掉分?,這和 直接在master分?上?作效果是?樣的,但過程更安全?
6.合并沖突?
當我們首次創建分支時,此時master分支和dev分支都指向最新的提交。但如果此時dev分支和master分支同時對某個文件進行修改時,在合并時就會發送沖突。
創建dev分支,并修改readme,我們可以使用git checkout -b dev 來創建并切換到一個新分支上
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -b dev
切換到一個新分支 'dev'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
dev modify readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "dev md readme"
[dev 70ef405] dev md readme1 file changed, 1 insertion(+)
切換到master分支,看到的是舊版本,復合預期,然后對readme文件繼續修改
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切換到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
master modify readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "master md readme"
[master 84a1ed8] master md readme1 file changed, 1 insertion(+)
此時,我們提交之后,master和head就處于這種狀態:
此時,我們直接合并,就會合并失敗,提醒我們手動處理沖突:
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge dev
自動合并 readme
沖突(內容):合并沖突于 readme
自動合并失敗,修正沖突然后提交修正的結果。
?我們打開readme文件,就會出現以下格式:<~=表示當前分支內容,=~>表示合并分支內容,我們需要手動選擇保留那些內容,刪除那些內容。我們這里選擇保留兩者
hello git
<<<<<<< HEAD
master modify readme
=======
dev modify readme
>>>>>>> dev
hello git
dev modify readme
master modify readme
解決完沖突后,需要我們重新add,commit
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "merge readme"
[master 130148d] merge readme
我們可以使用git log的參數,來打印同樣的合并圖
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git log --graph --pretty=oneline --abbrev-commit
* 130148d (HEAD -> master) merge readme
|\
| * 70ef405 (dev) dev md readme
* | 84a1ed8 master md readme
|/
* d0cad69 touch readme
* c9237b9 delete readme
* d8afe07 md readme
* 7ef8d0f add
* 5b1b851 add readme
重新提交之后,master分支指向最新的提交,dev分支仍指向自己剛才的提交
此時如何想要和dev同步,則切換到dev分支,重新進行merge?
?最后不要忘記,刪除dev分支。
7.合并策略?
當我們新創建的分支dev是master分支的直接后繼,即master分支沒有提交新內容,dev有新內容,此時直接合并就會默認使用Fast-forward模式,直接將master指針指向dev最新提交,最終合并之后還是一個線性結構。
但是使用Fast-forward模式,當我們刪除了分支之后,我們無法知道最新的提交是正常提交的,還是合并進來的。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -b dev
切換到一個新分支 'dev'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "aaaaaaaaaaaaaa"
[dev 40faff8] aaaaaaaaaaaaaa1 file changed, 1 insertion(+)
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切換到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge dev
更新 130148d..40faff8
Fast-forwardreadme | 1 +1 file changed, 1 insertion(+)
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -d dev
已刪除分支 dev(曾為 40faff8)。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git log --graph --pretty=oneline --abbrev-commit
* 40faff8 (HEAD -> master) aaaaaaaaaaaaaa
* 130148d merge readme
|\
| * 70ef405 dev md readme
* | 84a1ed8 master md readme
|/
* d0cad69 touch readme
* c9237b9 delete readme
* d8afe07 md readme
* 7ef8d0f add
* 5b1b851 add readme
而在我們產生沖突的時候,此時合并時,會要求我們重新進行一次提交,我們很明顯可以知道時合并進來的。
為了可以更好的追溯提交記錄和保存分支結構,我們可以在合并的時候,指定--no-ff合并,這樣會要求我們在合并之后進行提交。
新建dev并提交:
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
* devmaster
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
dev modify readme
master modify readme
aaaaaaaaaaaaaaaaaaaaaa
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
dev modify readme
master modify readme
aaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbb
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "bbbb"
[dev a8dd2d2] bbbb1 file changed, 1 insertion(+)
切換master,進行--no-ff,進行合并 并 提交:
我們可以看到,即使我們刪除了dev分支,并且沒有發生合并沖突,使用-no-ff合并時,在打印日志時,我們可以看出這是一個合并提交?
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
* devmaster
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切換到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
dev modify readme
master modify readme
aaaaaaaaaaaaaaaaaaaaaa
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge --no-ff dev -m "merge no-ff"
Merge made by the 'ort' strategy.readme | 1 +1 file changed, 1 insertion(+)
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -d dev
已刪除分支 dev(曾為 a8dd2d2)。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git log --graph --pretty=oneline --abbrev-commit
* ae48c12 (HEAD -> master) merge no-ff
|\
| * a8dd2d2 bbbb
|/
* 40faff8 aaaaaaaaaaaaaa
* 130148d merge readme
|\
| * 70ef405 dev md readme
* | 84a1ed8 master md readme
|/
* d0cad69 touch readme
* c9237b9 delete readme
* d8afe07 md readme
* 7ef8d0f add
* 5b1b851 add readme
8.分支策略?
在生產過程中,master分支是最穩定的,它是真正用來發行的版本。所以,我們在日常開發過程中,應該避免直接對master主分支進行修改,而是創建其他分支,在其他分支上進行開發,等到開發的這部分測試通過了,我們再將其合并到master主分支上。
9.bug分支
當我們正在dev分支開發新功能時,master分支出現了bug,但我們此時 dev分支上的代碼還沒有寫完,此時我們先修復bug,再繼續開發。我們解決bug也和開發一樣,要重新新建分支,用來修復bug,當測試該bug解決后,然后合并回去。
0x1.dev下開發代碼
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -b dev
切換到一個新分支 'dev'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
i am coding TODO
?
0x2.出現bug,將dev下還未寫完的代碼利用git stash命令將dev下工作區的修改臨時存儲起來,此時git status查出來工作區就是干凈的,然后切回master分支,創建新分支,修改bug
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git stash
保存工作目錄和索引狀態 WIP on dev: b7845cf history
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 dev
無文件要提交,干凈的工作區
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切換到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -b fix/bug
切換到一個新分支 'fix/bug'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
fix bug!!!!
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "fix bug"
[fix/bug 7fc1656] fix bug1 file changed, 1 insertion(+)
?
0x3.bug修復后,將fix/bug分支與master分支進行合并。但為了避免合并沖突,我們可以先讓fix/bug合并master,然后再讓master合并fix/bug。
我們在合并的時候,發現已經是最新的了,所以就可以放心讓master合并fix/bug了。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge master
已經是最新的。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切換到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge fix/bug
更新 b7845cf..7fc1656
Fast-forwardreadme | 1 +1 file changed, 1 insertion(+)
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
fix bug!!!!
?
0x4.修復完bug后,刪除fix/bug分支
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -d fix/bug
已刪除分支 fix/bug(曾為 7fc1656)。
?0x5.繼續開發dev,發現開發區是干凈的,我們使用git stash list查看臨時區列表,發現有東西,我們使用git stash pop取出臨時區的內容,并刪除臨時區
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout dev
切換到分支 'dev'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 dev
無文件要提交,干凈的工作區
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git stash list
stash@{0}: WIP on dev: b7845cf history
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git stash pop
位于分支 dev
尚未暫存以備提交的變更:(使用 "git add <文件>..." 更新要提交的內容)(使用 "git restore <文件>..." 丟棄工作區的改動)修改: readme修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
丟棄了 refs/stash@{0}(8f49e00fb32b95e957f5a775d360af9f305f8168)
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git stash list
xsc@xsc-VMware-Virtual-Platform:~/code/git$
0x6.繼續開發,開發完畢進行提交
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
i am coding TODO
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
i am coding TODO
Done
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "develop over"
[dev fca3cba] develop over1 file changed, 2 insertions(+)
0x7.合并時與合并bug時一致,避免沖突,先讓dev合并master,然后master合并dev
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge master
自動合并 readme
沖突(內容):合并沖突于 readme
自動合并失敗,修正沖突然后提交修正的結果。hello git
hello world
<<<<<<< HEAD
i am coding TODO
Done
=======
fix bug!!!!
>>>>>>> masterxsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
fix bug!!!!
i am coding TODO
Donexsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "merge over"
[dev bc3f194] merge overxsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切換到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge --no-ff dev
Merge made by the 'ort' strategy.readme | 2 ++1 file changed, 2 insertions(+)
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
fix bug!!!!
i am coding TODO
Done
?
?master合并dev時,會出現下面的界面,這樣表示合并成功,直接ctrl+x返回
0x8.刪除dev分支?
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -d dev
已刪除分支 dev(曾為 bc3f194)。
10.刪除臨時分支
當我們在開發過程中,有了一個新需求,我們并不直接在master分支上修改,而是創建一個新分支feature,在該分支上進行開發。但是開發了一半,經理說不需要該功能了,此時我們就需要將這個分支給刪除掉。
但是因為這個分支上有了修改,并且我們沒有merge,此時直接git branch -d 刪除不掉
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -b feature/1
切換到一個新分支 'feature/1'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
fix bug!!!!
i am coding TODO
Donenew feature11111xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "new feature"
[feature/1 06ff531] new feature1 file changed, 2 insertions(+)突然叫停,不需要該功能了刪除該分支
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切換到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -d feature/1
error: the branch 'feature/1' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature/1'
我們使用git branch -D 來刪除該分支
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -D feature/1
已刪除分支 feature/1(曾為 06ff531)。
七.小結
分?在實際中有什么?呢?假設你準備開發?個新功能,但是需要兩周才能完成,第?周你寫了50% 的代碼,如果?刻提交,由于代碼還沒寫完,不完整的代碼庫會導致別?不能?活了。如果等代碼全部寫完再?次提交,?存在丟失每天進度的巨??險。 現在有了分?,就不?怕了。你創建了?個屬于你??的分?,別?看不到,還繼續在原來的分?上 正常?作,?你在??的分?上?活,想提交就提交,直到開發完畢后,再?次性合并到原來的分? 上,這樣,既安全,?不影響別??作。 并且Git?論創建、切換和刪除分?,Git在1秒鐘之內就能完成!?論你的版本庫是1個?件還是1萬個 ?件。