關(guān)于Git,你真的學(xué)會了嗎?

“鋒哥,Git有什么可說的,不就是git add添加,git commit提交嘛” 聽說我要寫一篇Git教程,小明不屑一顧地說。
“..."。

小明是我的一個學(xué)生。目前,是一名Android開發(fā)工程師。

過了幾天,我又再次見到了小明。

“鋒哥,今天,我在Github新建了一個版本庫,本地提交后推送遠程的時候,卻被拒絕了,是怎么回事?”

以下是小明的操作記錄:

git init
git add .
git commit -m "Init commit"
git remote add origin git@github.com:xiaoming/xxx.git
git pull origin master

以上操作觸發(fā)了下面的錯誤:

From git@github.com:xiaoming/xxx.git
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> origin/master
fatal: refusing to merge unrelated histories

“小明,注意看最后一句提示。翻譯成中文的意思是 ‘拒絕合并不相關(guān)的歷史’,這個問題有兩個方案可以處理。"

  • git pull命令其實是觸發(fā)了拉取git fetch和合并git merge兩個操作。而本地的版本庫和遠程版本庫在第一次拉取或推送完成之前是毫不相關(guān)的,Git為了避免不必要的合并,默認不允許進行這樣的操作。但你可以手動添加--allow-unrelated-histories強制進行合并,這是方案一。
git pull origin master --allow-unrelated-histories
  • 再來看方案二,從你上面的操作來看,你只是在本地初始化了一個版本庫,并完成了基礎(chǔ)的提交。接下來,你希望和遠程版本庫建立關(guān)聯(lián),將提交推送到遠程。這種情況下,其實你可能并不需要遠程的默認數(shù)據(jù)(通常是一個空的README文件)。所以,你可以添加-f參數(shù),將提交強制提交并覆蓋遠程版本庫。
git push -f origin master

小明若有所思地點點頭,這是小明第一次遇到Git問題。我想,接下來他應(yīng)該會比較順利了。

沒想到,過了幾天,我又收到了小明的消息。這一次,他發(fā)來的是對Git的抱怨。

“鋒哥,Git好討厭,提交日志出現(xiàn)了錯誤,也不能修改。你知道搜狗輸入法有時候不夠智能,輸入太快不小心就輸錯了...??”

“??,你這孩子,別輕易下結(jié)論哈。其實,Git是允許修改提交記錄的。使用Git最舒服的一點就是:Git永遠都會給你反悔的機會。這一點,其它的版本控制工具是做不到的!”

“哦,原來是這樣??!那快說說看,要怎么做?” 小明已經(jīng)一副迫不及待的表情了。

git commit命令中有一個參數(shù)叫--amend就是為解決這個問題而生的。因此,如果是最近的提交,你只需要按照下面的命令操作即可?!?/p>

git commit --amend -m "這是新的提交日志"

看完我的消息,小明給我發(fā)來一個微笑的表情。小明的抱怨讓我想起一句好氣又好笑的農(nóng)村俗語 “屙屎不出怪茅坑”,哈哈。

本以為一切可以風(fēng)平浪靜了。沒想到,過了一個月左右,突然接到了小明的緊急電話。電話那頭,小明似乎心情很急躁。

“鋒哥,我不小心進行了還原操作,我寫的代碼全丟了。幾千行的代碼啊,明天晚上就要發(fā)版本了,有辦法找回來嗎?”

聽到這個消息,我心里盤算,大約有50%的概率應(yīng)該是找不回來了。這孩子比較粗心,可能根本就沒提交到版本庫。但如果他正好提交到了版本庫,興許還有救。因此,我安慰他說 “小明,別急!你打開TeamViewer,我遠程幫你看看”

連上機器后,我使用history命令看到小明在提交之后使用了git reset --hard xxx命令進行重置。--hardgit reset命令中唯一一個不安全的操作,它會真正地銷毀數(shù)據(jù),以至于你在git log中完全看不到操作日志??墒?,Git真的很聰明,它還保存了另外一份日志叫reflog,這個日志記錄了你每次修改HEAD的操作。因此,你可以通過下面的命令對數(shù)據(jù)進行還原:

git reflog

// 使用這個命令,你看到的日志大概是這樣
c8278f9 (HEAD -> master) HEAD@{0}: reset: moving to c8278f9914a91e3aca6ab0993b48073ba1e41b2b
3e59423 HEAD@{1}: commit: a
c8278f9 (HEAD -> master) HEAD@{2}: commit (amend): v2 update
2dc167b HEAD@{3}: commit: v2
2e342e9 HEAD@{4}: commit (initial): Init commit

可以看到,我們在版本3e59423進行了git reset操作,最新版本是3e59423。因此,我們可以再次通過git reset命令回到這個版本:

git reset --hard 3e59423

以上操作完成后,你會驚喜地發(fā)現(xiàn),丟失的數(shù)據(jù)居然神奇般地回來了。

“?? ?? ??”

“下次別這樣操作了哈。另外,你怎么一次性丟失這么多代碼。一定要記得勤提交?!?小明出現(xiàn)這樣的問題,與平時的不規(guī)范操作也是分不開的。因此,最后我還不忘囑咐了他一句。

“好的,我知道了。對了,我一個還有比較疑惑的問題。git checkoutgit reset到底有啥區(qū)別?我以前用SVN的時候git checkout是用來檢出代碼的,在Git中可以用它切換分支或者指定版本,但git reset同樣可以做到。難道兩者是完全一樣的嗎?” 小明在QQ中給我發(fā)來了回復(fù)消息。

“這是一個比較有深度的問題,解釋這個問題需要一點時間。接下來,你仔細聽”

理解Git工作空間

理解這個問題之前,先來簡單學(xué)習(xí)一些Git基礎(chǔ)知識。Git有三種狀態(tài):

  • 已提交(commited):數(shù)據(jù)已完全保存到本地數(shù)據(jù)庫中
  • 已修改(modified):修改了文件,但還沒有保存到數(shù)據(jù)庫中
  • 已暫存(staged):對一個已修改的文件做了標記,將包含在下一次提交的版本快照中

這三種狀態(tài)對應(yīng)Git三個工作區(qū)域:Git版本庫、暫存區(qū)和工作區(qū)


Git版本庫是Git用來保存項目的元數(shù)據(jù)和對象數(shù)據(jù)庫的地方,使用git clone命令時拷貝的就是這里的數(shù)據(jù)。

工作目錄是對某個版本獨立檢出的內(nèi)容,這些數(shù)據(jù)可以供你使用和修改。

暫存區(qū)在Git內(nèi)部對應(yīng)一個名為index的文件,它保存了下次將要提交的文件列表信息。因此,暫存區(qū)有時候也被叫作 “索引”。

一個基礎(chǔ)的Git工作流程如下:
1)在工作區(qū)修改文件
2)使用git add將文件添加到暫存區(qū),也就是記錄到index文件中
3)使用git commit將暫存區(qū)中記錄的文件列表,使用快照永久地保存到Git版本庫中

理解HEAD

解釋這個問題,你還需要簡單理解HEAD是什么。簡單來說,HEAD是當(dāng)前分支引用的指針,它永遠指向該分支上最后一次提交。為了讓你更容易理解HEAD,你可以將HEAD看作上一次提交數(shù)據(jù)的快照。

如果你感興趣,你可以使用一個底層命令來查看當(dāng)前HEAD的快照信息:

git ls-tree -r HEAD

100644 blob aca4b576b7d4534266cb818ab1191d91887508b9    demo/src/main/java/com/youngfeng/snake/demo/Constant.java
100644 blob b8691ec87867b180e6ffc8dd5a7e85747698630d    demo/src/main/java/com/youngfeng/snake/demo/SnakeApplication.java
100644 blob 9a70557b761171ca196196a7c94a26ebbec89bb1    demo/src/main/java/com/youngfeng/snake/demo/activities/FirstActivity.java
100644 blob fab8d2f5cb65129df09185c5bd210d20484154ce    demo/src/main/java/com/youngfeng/snake/demo/activities/SecondActivity.java
100644 blob a7509233ecd8fe6c646f8585f756c74842ef0216    demo/src/main/java/com/youngfeng/snake/demo/activities/SplashActivity.java

這里簡單解釋一下每個字段的意思:100644表示文件模式,其對應(yīng)一個普通文件。blob表示Git內(nèi)部存儲對象數(shù)據(jù)類型,另外還有一種數(shù)據(jù)類型tree,對應(yīng)一個樹對象,中間較長的字符串對應(yīng)當(dāng)前文件的SHA-1值,這部分不需要記住,簡單了解即可。

所以,簡單來說,HEAD對應(yīng)一個樹形結(jié)構(gòu),存儲了當(dāng)前分支所有的Git對象快照:


我們用一個表格簡單來總結(jié)一下以上知識點:

HEAD Index(暫存區(qū)) 工作區(qū)
上一次提交的快照,下一次提交的父節(jié)點 預(yù)期的下一次提交快照 當(dāng)前正在操作的沙盒目錄

理解git resetgit checkout區(qū)別主要是理解Git內(nèi)部是怎么操作以上三棵樹的。

接下來,我們用一個簡單的例子來看一下使用git reset到底發(fā)生了什么。先創(chuàng)建一個Git版本庫并觸發(fā)三次提交:

git init repo
touch file.txt
git add file.txt
git commit -m "v1"

echo v2 > file.txt
git add file.txt
git commit -m "v2"

echo v3 > file.txt
git add file.txt
git commit -m "v3"

以上操作完成后,版本庫現(xiàn)在看起來是這樣的:


接下來執(zhí)行命令git reset 14ad152看看會發(fā)生什么。以下是命令執(zhí)行完成后看到的結(jié)果:

git log --abbrev-commit --pretty=oneline
### This is output ###
14ad152 (HEAD -> master) v2
bcc49f4 v1

git status -s
### This is output ###
 M file.txt

cat file.txt
### This is output ###
v3

可以看到版本庫中文件版本回退到了V2,工作區(qū)文件內(nèi)容同之前的版本V3一致;為了確認暫存區(qū)發(fā)生了什么變化,我們再使用一個底層命令對比一下暫存區(qū)數(shù)據(jù)和版本庫數(shù)據(jù)是否一致:

# 查看暫存區(qū)信息
git ls-files -s
### This is output ###
100644 8c1384d825dbbe41309b7dc18ee7991a9085c46e 0   file.txt

# 查看版本庫快照信息
git ls-tree -r HEAD
### This is output ###
100644 blob 8c1384d825dbbe41309b7dc18ee7991a9085c46e    file.txt

可以看到當(dāng)前版本庫和暫存區(qū)信息是完全一致的,HEAD指向了v2提交,用一個圖形來表示整個過程,應(yīng)該是這樣:


看一眼上圖,理解一下剛剛發(fā)生的事情:首先,HEAD指針發(fā)生了移動,指向了V2,并撤銷了上一次提交。目前,版本庫和暫存區(qū)都保存的是第二次提交的記錄,工作區(qū)卻保存了最近一次修改。稍微聯(lián)想一下,你就會發(fā)現(xiàn),這次的git reset命令恰好是最近一次提交的逆向操作。讓數(shù)據(jù)完全回到了上一次提交前的狀態(tài)。所以,如果你想撤銷最近一次提交,可以這么做。

增加--soft參數(shù)測試

以上是我們對git reset命令的第一次嘗試,在下一輪嘗試前,先執(zhí)行git help reset看看reset命令的用法:

git reset [-q] [<tree-ish>] [--] <paths>...
git reset (--patch | -p) [<tree-ish>] [--] [<paths>...]
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]

看最后一句發(fā)現(xiàn),reset命令后面還可以接5個不同的參數(shù): --soft、--mixed--hard 、--merge、--keep。這里我們主要關(guān)注前面三個,其中--mixed其實剛剛已經(jīng)嘗試過,它和不帶參數(shù)的git reset命令是同樣的效果。換而言之,--mixedgit reset命令的默認行為。接下來執(zhí)行git reset --soft 14ad152看看會發(fā)生什么。命令執(zhí)行完成后,按照慣例,我們同樣使用基礎(chǔ)命令看看發(fā)生了什么變化:

git log --abbrev-commit --pretty=oneline
### This is output ###
14ad152 (HEAD -> master) v2
bcc49f4 v1

git status -s
### This is output ###
M  file.txt

cat file.txt
### This is output ###
v3

奇怪了?為什么會和上次不帶任何參數(shù)的執(zhí)行結(jié)果完全一致?難道Git出現(xiàn)了設(shè)計錯誤。相信你看到結(jié)果一定會有這樣的疑問,其實不然!因為,這里我用文本粘貼了輸出結(jié)果,忽略了命令的字體顏色,其實這里第二條命令輸出結(jié)果中的M顏色與上一次執(zhí)行結(jié)果是不一樣的。為了讓你看到不同,看下面的截圖:


這個顏色表示:file.txt文件已經(jīng)被添加到了暫存區(qū),使用git commit命令就可以完成提交。為了嚴謹,我們依然使用上面的底層命令看看版本庫和暫存區(qū)信息是否一致。注意:這里的結(jié)果應(yīng)該是不一致才對,因為版本庫記錄的文件版本是v2,而暫存區(qū)記錄的文件版本其實是v3。

git ls-tree -r HEAD
### This is output ###
100644 blob 8c1384d825dbbe41309b7dc18ee7991a9085c46e    file.txt

git ls-files -s
### This is output ###
100644 29ef827e8a45b1039d908884aae4490157bcb2b4 0   file.txt

可以看到,兩個命令執(zhí)行輸出的SHA-1并不一致,驗證了我們的猜想。

這里我們可以得出一個結(jié)論:--soft和默認行為(--mixed)不一樣的地方是:--soft會將工作區(qū)的最新文件版本再做一步操作,添加到暫存區(qū)。使用這個命令可以用來合并提交。即:如果你在某一次提交中有未完成的工作,而你反悔了,你可以使用這個命令撤銷提交,等工作做完后繼續(xù)一次性完成提交。

增加--hard參數(shù)測試

接下來我們對最后一個參數(shù)進行測試,這也是小明在使用過程出現(xiàn)問題的一個參數(shù)。執(zhí)行命令git reset --hard 14ad152,看看發(fā)生了什么:

git log --abbrev-commit --pretty=oneline
### This is output ###
14ad152 (HEAD -> master) v2
bcc49f4 v1

git status -s
### This is output ###
>>> No output <<<

cat file.txt
v2

注意看,這次使用git status -s完全看不到輸出,這就證明:當(dāng)前工作區(qū),暫存區(qū),版本庫數(shù)據(jù)是完全一致的。查看文件內(nèi)容,發(fā)現(xiàn)文件回到了v2版本。通常情況下,如果你看到這種情況,一定會嚇一跳,你最近一次提交的數(shù)據(jù)居然完全丟失了。的確,這是Git命令中少有的幾個真正銷毀數(shù)據(jù)的命令之一。除非你非常清楚地知道自己在做什么,否則,請盡量不要使用這個命令!

我們依然用一張圖,完整地描述這個命令到底發(fā)什么了什么:


可以看到,相對于默認行為,--hard將工作區(qū)的數(shù)據(jù)也還原到了V2版本,以至于V3版本的提交已經(jīng)完全丟失。

git checkout

接下來看git checkout, 按照慣例,先執(zhí)行git checkout 14ad152看看會發(fā)生什么:

git log --abbrev-commit --pretty=oneline
### This is output ###
14ad152 (HEAD -> master) v2
bcc49f4 v1

git status -s
### This is output ###
>>> No output <<<

cat file.txt
v2

可以看到,又出現(xiàn)了神奇的一幕,這一次git checkout命令的執(zhí)行結(jié)果的確和git reset --hard完全一致。這是否意味著兩者就沒有任何區(qū)別了呢?當(dāng)然也不是。嚴格來說,兩者有兩個“本質(zhì)”的區(qū)別:

  • 相對而言,git checkout對工作目錄是安全的,它不會將工作區(qū)已經(jīng)修改的文件還原,git reset則不管三七二十一一股腦全部還原。
  • 另外一個比較重要的區(qū)別是,git checkout并不移動HEAD分支的指向,它是通過直接修改HEAD引用來完成指針的指向。

第二個不同點相對比較難理解,我們用一張圖來更直觀地展示二者的區(qū)別:


簡單來說,git reset會通過移動指針來完成HEAD的指向,而git checkout則通過直接修改HEAD本身來完成指向的移動。

命令作用于部分文件

git resetgit checkout還可以作用于一個文件,或者部分文件,即帶文件路徑執(zhí)行。這種情況下,兩個命令的表現(xiàn)不太一樣。我們來試試看,先執(zhí)行git reset 14ad15 -- file.txt命令嘗試將文件恢復(fù)到V2版本。命令執(zhí)行完成,按照慣例用一些基礎(chǔ)命令來看看發(fā)生了什么:

git log --abbrev-commit --pretty=oneline
### This is output ###
4521405 (HEAD -> master) v3
14ad152 v2
bcc49f4 v1

git status -v
### This is output ###
diff --git a/file.txt b/file.txt
index 29ef827..8c1384d 100644
--- a/file.txt
+++ b/file.txt
@@ -1 +1 @@
-v3
+v2

cat file.txt
v3

可以看到,版本庫和工作區(qū)的數(shù)據(jù)都沒有發(fā)生變化。唯一發(fā)生變化的是暫存區(qū),暫存區(qū)記錄下一次提交的改動將導(dǎo)致數(shù)據(jù)從V3恢復(fù)到V2版本!


這里我們可以這樣理解:執(zhí)行這條命令后,Git先將暫存區(qū)和工作區(qū)的文件版本恢復(fù)到V2,再將工作區(qū)的文件版本恢復(fù)到V3。與--hard不一樣的地方是:這個命令并不會覆蓋工作區(qū)已經(jīng)修改的文件,是安全操作。

執(zhí)行帶路徑的git checkout命令和git reset命令有一些細微的差別,相對于git reset,git checkout帶路徑執(zhí)行會覆蓋工作區(qū)已經(jīng)修改的內(nèi)容,導(dǎo)致數(shù)據(jù)丟失,是一個非安全操作。

針對上面的所有實驗,我們用一個簡單的表格來總結(jié)他們的區(qū)別,以及操作是否安全:

不帶路徑執(zhí)行

命令行 HEAD 暫存區(qū) 工作區(qū) 目錄安全
git reset [--mixed] YES YES NO YES
git reset --soft YES YES NO YES
git reset --hard YES YES YES NO
git checkout Modify YES YES YES

帶路徑執(zhí)行

命令行 HEAD 暫存區(qū) 工作區(qū) 目錄安全
git reset -- NO YES NO YES
git checkout NO YES YES NO

注意:執(zhí)行非目錄安全的命令操作的時候,一定要慎重,除非你非常清楚自己在做什么!

“小明,你明白了嗎?” 消息發(fā)送過去之后,等了很久卻一直沒有響應(yīng)。
“哎,這孩子!估計聽睡著了... ??”

自從這次問到Git的問題后,已經(jīng)兩年過去了,小明再沒有問到關(guān)于Git的問題。而就在昨天,突然又收到了小明的消息。

也許你應(yīng)該試試Git Flow

“鋒哥,我現(xiàn)在已經(jīng)是Android Leader了?,F(xiàn)在安卓團隊一共6個人,我們現(xiàn)在在做一個社交類應(yīng)用,在Git管理方面我還是發(fā)現(xiàn)了一些問題。其中一個問題就是,現(xiàn)在版本庫有好多分支,其中開發(fā)主要在develop分支。主干分支是master主要用于版本發(fā)布??蛇€有一些分支卻顯得非?;靵y,有什么辦法改善這種情況嗎?”

“關(guān)于Git的分支設(shè)計,目前有一個公認比較好的設(shè)計叫 Git Flow模型。關(guān)于Git Flow模型,你可以查看這篇文章 http://nvie.com/posts/a-successful-git-branching-model/ 了解一下"

一個idea,一次提交

"好的!還有一個困擾了我很久的問題是,大家的提交日志寫的比較籠統(tǒng)。在查找問題的時候非常不便,而且大部分同學(xué)一次性提交好多文件,導(dǎo)致解決問題的時候不能準確定位到具體是哪一次提交導(dǎo)致的。我告訴大家,一次提交改動要盡可能小。但當(dāng)別人問到具體的提交規(guī)則的時候我又不知道從何說起..."

“這是一個很好的問題 。中國程序員普遍存在的一個問題是,恨不得把這輩子能提交的代碼一次性搞定。甚至有人用多次提交太麻煩的借口來搪塞問責(zé)人。簡單來說,可以用一句話概括提交原則:一個idea,一次提交。另外,你說的沒錯,提交必須盡可能小,注釋必須盡可能表述準確!”

給小明講了這么多Git,我忍不住半開玩笑地問他,“小明,你現(xiàn)在還覺得Git簡單嗎?”

小明發(fā)了一個無奈的表情!說道,“以前是我才疏學(xué)淺,略知皮毛,不知道Git原來還有這么多玩法,忍不住為Git的發(fā)明者點贊了。對了,鋒哥,Git到底是誰開發(fā)的?”

Git的最大功臣,其實不是Linus

”關(guān)于Git的故事,互聯(lián)網(wǎng)上其實已經(jīng)爛大街了。我簡單給你介紹一下吧!Git的誕生其實是一個偶然,其初始使命是為Linux內(nèi)核代碼管理服務(wù)的。早年的時候Linux內(nèi)核源碼是用Bitkeeper版本控制工具管理的??墒?,后來因為某些利益關(guān)系,Bitkeeper要求Linux社區(qū)付費使用。這一舉動激怒了Linus,也就是Linux的創(chuàng)始人,他決定自己開發(fā)一個分布式版本控制系統(tǒng)。幾周時間下來,Git的雛形就誕生了,并且開始在Linux社區(qū)中應(yīng)用開來。雖然Linus是Git的創(chuàng)始人,可是背后的最大功臣卻是一個日本人 Junio C Hamano。Linus在Git開源版本庫的提交只有258次,而Junio C Hamano卻提交了4000多次。也就是說,在Linus開發(fā)后不久項目的管理權(quán)就交給了這個日本人。關(guān)于 Junio C Hamano,你感興趣的話可以Google了解一下。他現(xiàn)在在Google工作,如同Linus一樣非常低調(diào)。“

“這個故事也告訴我:不要用技術(shù)去挑戰(zhàn)一個程序員 @_@ ”

這個故事講完,小明與Git的故事就已經(jīng)告一段落了。其實,還有一些比較常見的問題,小明并沒有問到過。這里,我為你準備了一個附錄,給你介紹一些常用的小命令幫你解決日常小問題。它很有用,一定要拿筆記下來,或者收藏這篇文章備用。

常見問題

問題一:公司的Git服務(wù)器是搭建在一個內(nèi)網(wǎng)服務(wù)器上面的,我想把代碼同時提交到OsChina上面,以便在家拉取代碼,遠程辦公,怎么辦?
Git本身是一個分布式的版本管理系統(tǒng),實現(xiàn)這個需求非常簡單,使用git remote add命令添加多個遠程版本庫關(guān)聯(lián)即可。

git remote add company git@xxx
git remote add home git@xxx

問題二:在拉取遠程代碼的時候,如果本地有代碼還沒有提交,Git就會提示先提交代碼到版本庫??蓵簳r我又不想提交,怎么辦?
針對這個問題,Git提供了一個臨時區(qū)域用于保存不想提交的記錄,對應(yīng)的命令是git stash。通常情況下,你可以這樣操作:

# 將暫時還不想提交的數(shù)據(jù)保存到臨時區(qū)域,保存成功后,工作區(qū)將和版本庫完全一致
git stash
# 還原stash數(shù)據(jù)到工作區(qū)
git stash apply
# 以上操作完成后,stash數(shù)據(jù)依然保存在臨時區(qū)域中,為了刪除這部分數(shù)據(jù),使用如下命令即可。
git stash drop
# 如果你想在還原數(shù)據(jù)的同時從臨時區(qū)域刪除數(shù)據(jù),可以這樣操作:
git statsh pop
# 以上兩個命令如果不接任何參數(shù)將刪除掉所有的臨時區(qū)域數(shù)據(jù),如果你只想刪除其中一條記錄,指定對應(yīng)索引數(shù)據(jù)即可。
git stash pop/drop stash@{index}
# 查看臨時區(qū)域所有數(shù)據(jù),使用如下命令:
git stash list

問題三:作為項目負責(zé)人,我希望迅速找出問題代碼的“元兇”,有什么辦法嗎?
針對這個問題,最好的答案是git blame,使用這個命令并指定具體文件它將顯示文件每一行代碼的最近修改記錄,你可以清晰地看到最近代碼的修改人。

問題四:部分Team Leader會要求使用git rebase合并代碼,這有什么好處嗎?
我們用一個簡單的思維來理解這個問題,最常見的合并操作是使用git merge,而這樣操作會在合并分支生成一次新的提交,并且會嚴格記錄分支提交日志,在長期開發(fā)過程中,日志就會呈現(xiàn)多條線路展示,給閱讀帶來一定的障礙。而使用git rebase會使整體代碼提交記錄始終像在單一分支開發(fā)一樣,僅使用一條線路展示。但使用git rebase是有一定陷阱的,這個問題需要一定的時間才能說清楚,如果需要了解兩個命令的詳細區(qū)別,我推薦你閱讀這篇文章 Rebase 代替合并。

總結(jié)

Git是一個非常優(yōu)秀的版本控制系統(tǒng),我極力推薦你在日常開發(fā)中使用。這篇文章從小明的角度解釋了幾個常見問題的解決方案,毫無懸念地,你可能還會遇到其它的一些問題。遇到問題,你可以嘗試使用Google搜索解決方案;也可以在文章下方給我留言,我非常樂意為你解答Git問題。


我是歐陽鋒,版本控制,我使用Git。了解歐陽鋒,從這里開始:歐陽鋒檔案館。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容