你可能不知道的Git使用方法

使用Git已有很長一段時間端逼,遇到一些痛點問題揖铜,而且大都是網(wǎng)上難以直接查到的,故總結(jié)于此困介。

1.兩幅重要的圖

基礎(chǔ)構(gòu)成
命令原理

以上兩幅圖對理解Git的原理十分重要。

2.基礎(chǔ)命令

首先是一些基礎(chǔ)命令蘸际,這些命令經(jīng)常使用座哩,而少為人知。

  • git add -Agit add --all 把包括修改粮彤、增加根穷、刪除都全部加入暫存區(qū)姜骡。等同于 git add .git add -u兩個命令。

  • git add -p 一段段地把修改提交到暫存區(qū)屿良,每一個修處改都會提示你是否加入暫存區(qū)圈澈。可以按照想要的方式把所有修改分成多個commit尘惧。

  • git commit -am 把已經(jīng)加入暫存區(qū)(Stage)的文件的更改提交到本地版本庫康栈,無論這些更改是否已經(jīng)加入暫存區(qū)。與git commit -m的區(qū)別在于后者只能向本地版本庫提交已經(jīng)加入暫存區(qū)的更改喷橙。如果只是改動某些代碼啥么,而沒有增加或者刪除文件,使用git commit -am一個命令就可以替代git add --allgit commit -m兩個命令贰逾。

  • git commit --amend 修改最后一次commit的提交信息悬荣。注意,是最后一次疙剑,也就是HEAD指向的commit氯迂。

  • git branch -vv 顯示本地分支與遠(yuǎn)程分支的對應(yīng)關(guān)系。執(zhí)行git push(沒有帶分支參數(shù))時代碼被提交到對應(yīng)遠(yuǎn)程分支言缤,就是依據(jù)該對應(yīng)關(guān)系囚戚。這里需要注意Git的simple和matching模式,后者會一次性提交所有的對應(yīng)關(guān)系的分支的代碼到遠(yuǎn)程分支轧简,前者只會提交當(dāng)前所在分支。

  • git stashgit statsh pop 主要用來暫存當(dāng)前的工作匾二。如果需要git pull又不想把當(dāng)前的修改提交commit哮独,則可以先使用git stash把修改暫存。該命令運(yùn)行完后工作區(qū)是干凈的察藐,此時再使用git pull拉新代碼皮璧。完事了后使用git statsh pop恢復(fù)之前的工作狀態(tài)。

  • git reflog 顯示曾經(jīng)的commit分飞。如果我們使用git reset將HEAD指向某個過去的commit了悴务,此時要想回到最開始的commit,使用git log是無法查到最開始的commit的譬猫。但是也不要慌讯檐,git reflog能給你回到最開始的commit的機(jī)會,它會顯示所有的提交記錄染服。

3.使用場景

根據(jù)一些常見的場景給出我自己的解決方法别洪。

3.1 基于遠(yuǎn)程分支建立本地分支

你可能剛?cè)肼殹D愕男峦峦蝗粊G過來一個地址A柳刮,讓你git clone一下代碼挖垛。接著他又丟過來一個分支名dev0.1痒钝,讓你基于該分支進(jìn)行開發(fā)。如果之前只會在master上git pullgit push痢毒,此時就可能有點不知所措了送矩。

你可能首先想到如何把遠(yuǎn)程的dev0.1分支clone下來,因為執(zhí)行git clone A之后哪替,你再用git branch查一下栋荸,發(fā)現(xiàn)本地只有master分支。

這里需要糾正一個問題夷家。git clone A實際上把所有的分支都從遠(yuǎn)程拉下來了蒸其,但是git branch只顯示那些與遠(yuǎn)程保持了追蹤(tracked)的分支。并且git clone A還會創(chuàng)建本地master分支并將其與遠(yuǎn)程(origin)的master建立追蹤(tracked)關(guān)系库快。于是我們最開始使用git branch就只顯示master了摸袁。

那么,問題來了义屏。既然所有分支都已經(jīng)拉下來了靠汁,我們?nèi)绾吻腥雂ev0.1分支并進(jìn)行開發(fā)呢?其實很簡單:

git checkout dev0.1

這個命令的含義是將dev0.1分支從本地版本庫取到工作區(qū)來(參考上面的兩幅圖中的第二幅)闽铐,并將工作區(qū)切換到該分支蝶怔。此時一個本地名為dev0.1的分支與遠(yuǎn)程(origin)的dev0.1分支就建立了追蹤關(guān)系。我們就可以基于dev0.1進(jìn)行開發(fā)了兄墅。試試git branch看看會不會顯示出dev0.1踢星。

假如遠(yuǎn)程分支中并沒有一個叫dev0.1的分支,我們運(yùn)行以上命令隙咸,就會發(fā)現(xiàn)這樣的錯誤提示:

error: pathspec 'dev0.1' did not match any file(s) known to git.

此時我們可以看看到底有哪些遠(yuǎn)程分支沐悦,請使用git branch -r。當(dāng)然git branch -a顯示的信息就多一些五督,它顯示全部本地分支和遠(yuǎn)程分支藏否。

但我通常并不這樣做。而是用以下命令:

git checkout -b dev origin/dev0.1

它的含義是新建一個本地分支dev充包,且讓這個分支與遠(yuǎn)程dev0.1分支保持追蹤關(guān)系副签。這樣做的好處在于可以自己取一個本地分支名。

3.2 分支開發(fā)模式同步Master分支代碼

你可能基于本地的dev0.1分支寫了一些代碼基矮,測試后并提交到本地倉庫中了淆储。你們團(tuán)隊代碼主干分支是master,且基于這個分支進(jìn)行發(fā)布愈捅。這就面臨著一個問題遏考,你的新寫的代碼如何提交到主干分支上。

1.如果的本地dev0.1分支與遠(yuǎn)程(origin)dev0.1分支保持了追蹤關(guān)系蓝谨,且如果你們團(tuán)隊使用類似github/gitlab這樣的git倉庫托管服務(wù)灌具,則可以直接在本地dev0.1分支上操作:

  • git pull origin dev0.1拉下遠(yuǎn)程代碼青团,以防有更新。 如果git是simple模式咖楣,則可以直接使用git pull[目前git2.0及以上版本都默認(rèn)為simple模式]督笆。
  • 如果有更新則會自動合并,合并如果失敗诱贿,則會要求手動處理沖突娃肿。處理完后將這次修改提交到本地倉庫。
  • 使用git push origin dev0.1向遠(yuǎn)程倉庫dev0.1分支提交代碼珠十。git 2.0及以上版本直接git push即可料扰。
  • 在github/gitlab的界面上操作,由dev0.1分支向master分支提交merge請求焙蹭。負(fù)責(zé)master分支維護(hù)的同事合并你的分支代碼到master即可晒杈。

2.如果本地dev0.1分支是基于master分支新建的,即在本地master上使用git checkout -b dev0.1命令---它會創(chuàng)建一個dev0.1的本地分支孔厉,并切換到該分支拯钻,但它不會設(shè)置與遠(yuǎn)程分支的追蹤關(guān)系。這時候如何將該分支的新代碼合并到master分支呢撰豺?

  • 首先dev0.1分支要合并到本地master上去粪般。先使用git checkout master切換到主干分支,在主干分支上操作污桦。
  • 合并dev0.1分支亩歹。使用git merge dev0.1 --no-ffgit merge dev0.1命令。這兩者的區(qū)別可用以下圖片說明:
兩個命令的區(qū)別

前者帶有分支記錄凡橱,后者沒有捆憎。

  • 然后將master分支的代碼提交到遠(yuǎn)程master:git pull拉新代碼,解決沖突梭纹,git push推到遠(yuǎn)程。
  • 如果dev0.1分支沒用處了致份,就可以直接刪掉:git branch -d dev0.1变抽。
3.3 將工作區(qū)恢復(fù)成干凈的狀態(tài)

如果開發(fā)了一陣子,修改了一些代碼氮块,但沒控制好绍载,把工作區(qū)搞成了一堆亂麻。這時候就想滔蝉,要是能把工作區(qū)恢復(fù)成最開始的樣子就好了击儡。

  • 首先確定要恢復(fù)成的最初狀態(tài)。一般來講就是將工作區(qū)恢復(fù)成當(dāng)前本地倉庫中HEAD所指向的commit蝠引。不過如果你之前提交到本地的一些commit你也不想要了阳谍,那么先用git log查一下你要恢復(fù)到的commitID蛀柴,復(fù)制下來。

  • 使用git reset --hard HEAD/commitID命令矫夯。運(yùn)行完畢之后鸽疾,用git status查一下狀態(tài)。一般狀態(tài)下會顯示

nothing to commit, working directory clean

但是如果你最開始時新增了一些文件训貌,且沒有將其加入暫存區(qū)制肮,那么就不是這種提示了。你需要把你新增的那些文件刪掉递沪,git status才會恢復(fù)成以上狀態(tài)豺鼻。主要原因是git reset無法重置那些沒有加入暫存區(qū)的更改。

如果你只是需要把某個文件B恢復(fù)成倉庫里上一次提交的狀態(tài)款慨,那么有以下兩種可能:1.這個文件沒有任何修改提交到暫存區(qū)儒飒;2.這個文件有一部分修改提交到暫存區(qū)了,但是想把暫存區(qū)的修改也恢復(fù)成HEAD指向的版本樱调。

  • 1情況下直接使用git checkout B恢復(fù)工作區(qū)的文件B约素。
  • 2情況下先使用git reset HEAD B撤銷暫存區(qū)里面對B的修改,再使用git checkout B恢復(fù)工作區(qū)中的修改笆凌。
3.4 修改某次的提交信息

這個場景并不常見圣猎,而有的時候又一定用的到。例如你開發(fā)一段時間了乞而,卻發(fā)現(xiàn)公司的gitlab要求你push的時候必須使用公司的郵箱送悔,而你之前的commit都用的是你自己的郵箱。我之前就遇到過這個問題爪模,在這兒記錄一下解決方案欠啤。

首先,git commit --amend只能對最新提交的Comment內(nèi)容或郵箱的修改屋灌,并不能對中間提交的Comment或者郵箱進(jìn)行修改洁段。如果只是修改最新提交的信息:

  • git commit --amend 直接進(jìn)入修改提交信息的模式。
  • git commit --amend --author="chenyi <chenyi@xxx.com>" 可以修改作者信息共郭。

如果需要修改中間某一次的提交信息祠丝,則需要按照一定的方法操作。以下是一個修改示列除嘹。

原始記錄

如上圖写半,第二個提交的郵箱同其他提交不一樣,我們需要將它修改成與其他一樣的尉咕。

  1. 先進(jìn)入第二個提交:git rebase -i preCommitID叠蝇,這里preCommitID就是第二個提交的下面的一個ID,即ff4e24年缎。

進(jìn)入修改模式

我們可以看到悔捶,列表里面顯示了我們想要修改的commit的ID铃慷,即c1c6685。將其前面的pick更改為edit炎功,保存并退出枚冗。

提示

當(dāng)我們從第2步的編輯過程中退出后,git會提示我們可以用的兩個命令git commit --amendgit rebae --continue蛇损。這兩個命令在后面都會用到赁温。

修改模式

我們目前已經(jīng)處于c1c6685commit上了。此時我們只需要使用git commit --amend --author="chyoo <chyoo1991@gmail.com>"修改該提交的作者信息淤齐。上圖就是運(yùn)行該命令后進(jìn)入修改的界面股囊。

退出之后的結(jié)果
退出第4步的修改模式之后爹脾,git給的提示信息携取。接下來我們只需要運(yùn)行git rebase --continue繼續(xù)rebase就可以完成目標(biāo)了。

3.5 將Commit記錄變成直線模式

通常很多人合作寫代碼時穗熬,希望將遠(yuǎn)程master分支維護(hù)成直線的形式祭务,這樣commit干凈明確内狗,檢查問題時能省不少事。而一般合并最新代碼時用的git pull會將生成一個merge commit义锥,這將導(dǎo)致推送到遠(yuǎn)程分支的代碼也是各種分支交叉柳沙,一點也不干凈明確。

那么拌倍,該如何實現(xiàn)這個目的呢赂鲤?

首先這里要上一份干貨,就是git mergegit rebase的區(qū)別柱恤,需要注意到git pull實際上是調(diào)用git merge進(jìn)行代碼的合并数初。->干貨在此

從干貨文章中我們可以發(fā)現(xiàn)梗顺,能夠使用git rebase命令用打補(bǔ)丁的方式來實現(xiàn)commit保持直線的目的泡孩。我們這樣操作:

  1. git fetch origin master 用這個命令將遠(yuǎn)程(origin)的master分支最新提交取到本地。

  2. git rebase origin/master 使用rebase 進(jìn)行pack打補(bǔ)丁寺谤,將我們自己提交的本地代碼以補(bǔ)丁的方式放在最新代碼的后面珍德。這個過程中可能會出現(xiàn)沖突,修改完了之后使用git rebase --continue繼續(xù)pack矗漾,直到完成rebase。如果出現(xiàn)無法解決的問題薄料,想回到最開始敞贡,可以使用git rebase --abort

  3. git push提交代碼到遠(yuǎn)程master分支摄职。

這里要求開發(fā)協(xié)作的每一個人都用這種方式操作和提交代碼誊役,這樣才能保持遠(yuǎn)程master分支的干凈整潔和直線性获列。

->這一篇文章講了為什么這樣做的原理。

3.6 為一個本地倉庫設(shè)定多個遠(yuǎn)程倉庫

這個看起來是有點奇怪的需求蛔垢。不過前不久gitlab的員工刪除了它們的數(shù)據(jù)庫击孩,導(dǎo)致很大部分項目受影響,這讓我們覺得如果能多一份代碼保障或許更好鹏漆。

使用git clone時巩梢,會自動設(shè)定遠(yuǎn)程地址,一般都是以origin指代艺玲。如果我們有特殊需求括蝠,需要將代碼提交到另一個遠(yuǎn)程倉庫,這時就要設(shè)定新的遠(yuǎn)程倉庫地址了饭聚。

git remote add hegel http://xxxx.git 這個命令就可以給當(dāng)前的本地庫設(shè)置一個遠(yuǎn)程倉庫hegel忌警。以后我們想推拉代碼到這個遠(yuǎn)程庫時,就需要用git push hegel mastergit pull hegel master了秒梳。

4.快捷設(shè)定

有一些比較有用的設(shè)定法绵,能在寫命令時少了很多麻煩。

  1. 全局設(shè)置user和email
  • git config --global user.name "chenyi"
  • git config --global user.emali "chenyi@xxx.com"
  1. 給常用命令起一個簡單的名字
  • git config --global alias.co checkout
  • git config --global alias.st status
  • git config --global alias.br branch
  • git config --global alias.ci commit

后續(xù)就可以使用git co/git ci等命令了酪碘,是不是簡潔了很多朋譬?

3.更好看的git log

git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

配置了這個之后,使用git lg簡直眼前一亮婆跑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末此熬,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子滑进,更是在濱河造成了極大的恐慌犀忱,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扶关,死亡現(xiàn)場離奇詭異阴汇,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)节槐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門搀庶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人铜异,你說我怎么就攤上這事哥倔。” “怎么了揍庄?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵咆蒿,是天一觀的道長。 經(jīng)常有香客問我,道長沃测,這世上最難降的妖魔是什么缭黔? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮蒂破,結(jié)果婚禮上馏谨,老公的妹妹穿的比我還像新娘。我一直安慰自己附迷,他們只是感情好惧互,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挟秤,像睡著了一般壹哺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上艘刚,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天管宵,我揣著相機(jī)與錄音,去河邊找鬼攀甚。 笑死箩朴,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的秋度。 我是一名探鬼主播炸庞,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼荚斯!你這毒婦竟也來了埠居?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤事期,失蹤者是張志新(化名)和其女友劉穎滥壕,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體兽泣,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡绎橘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了唠倦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片称鳞。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖稠鼻,靈堂內(nèi)的尸體忽然破棺而出冈止,到底是詐尸還是另有隱情,我是刑警寧澤候齿,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布熙暴,位于F島的核電站苫亦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏怨咪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一润匙、第九天 我趴在偏房一處隱蔽的房頂上張望诗眨。 院中可真熱鬧,春花似錦孕讳、人聲如沸匠楚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芋簿。三九已至,卻和暖如春璃饱,著一層夾襖步出監(jiān)牢的瞬間与斤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工荚恶, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留撩穿,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓谒撼,卻偏偏與公主長得像食寡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子廓潜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容