一、
1、git status查看文件提交狀態(tài)
該分支本地代碼未提交commit
如果新增文件
如果已經(jīng)提交了 但還沒(méi)有push到遠(yuǎn)程
該分支本地代碼和遠(yuǎn)程代碼一致
2、日志顯示 tip:空格向下翻頁(yè),b向上翻頁(yè),q退出
git log:查看歷史提交
git log --pretty=oneline:以漂亮的一行顯示,包含全部哈希索引值
git log --oneline:以簡(jiǎn)潔的一行顯示,包含簡(jiǎn)潔哈希索引值
git reflog:以簡(jiǎn)潔的一行顯示,包含簡(jiǎn)潔哈希索引值,同時(shí)顯示移動(dòng)到某個(gè)歷史版本所需的步數(shù)
3.版本控制
git reset --hard 簡(jiǎn)潔/完整哈希索引值:回到指定哈希值所對(duì)應(yīng)的版本
git reset --hard HEAD:強(qiáng)制工作區(qū)、暫存區(qū)、本地庫(kù)為當(dāng)前HEAD指針?biāo)诘陌姹?/span>
git reset --hard HEAD^:后退一個(gè)版本
tip:一個(gè)^表示回退一個(gè)版本
git reset --hard HEAD~1:后退一個(gè)版本
tip:波浪線~后面的數(shù)字表示后退幾個(gè)版本
4.比較差異
git diff:比較工作區(qū)和暫存區(qū)的所有文件差異
git diff <file name>:比較工作區(qū)和暫存區(qū)的指定文件的差異
git diff HEAD|HEAD^|HEAD~|哈希索引值?<file name>:比較工作區(qū)跟本地庫(kù)的某個(gè)版本的指定文件的差異
?
5.分支操作
git branch -v:查看所有分支
git branch -d <分支名>:刪除本地分支
git branch <分支名>:新建分支
git checkout <分支名>:切換分支
git merge <被合并分支名>:合并分支
tip:如master分支合并 hot_fix分支,那么當(dāng)前必須處于master分支上,然后執(zhí)行 git merge hot_fix 命令
tip2:合并出現(xiàn)沖突
①刪除git自動(dòng)標(biāo)記符號(hào),如<<<<<<< HEAD、>>>>>>>等
?、谛薷牡綕M意后,保存退出
?、踘it add <file name>
④git commit -m "日志信息",此時(shí)后面不要帶文件名
?
?
二、本地庫(kù)跟遠(yuǎn)程庫(kù)交互:
git clone <遠(yuǎn)程庫(kù)地址>:克隆遠(yuǎn)程庫(kù)
功能:①完整的克隆遠(yuǎn)程庫(kù)為本地庫(kù),②為本地庫(kù)新建origin別名,③初始化本地庫(kù)
git remote -v:查看遠(yuǎn)程庫(kù)地址別名
git remote add <別名> <遠(yuǎn)程庫(kù)地址>:新建遠(yuǎn)程庫(kù)地址別名
git remote rm <別名>:刪除本地中遠(yuǎn)程庫(kù)別名
git push <別名> <分支名>:本地庫(kù)某個(gè)分支推送到遠(yuǎn)程庫(kù),分支必須指定
git pull <別名> <分支名>:把遠(yuǎn)程庫(kù)的修改拉取到本地
tip:該命令包括git fetch,git merge
git fetch <遠(yuǎn)程庫(kù)別名> <遠(yuǎn)程庫(kù)分支名>:抓取遠(yuǎn)程庫(kù)的指定分支到本地,但沒(méi)有合并
git merge <遠(yuǎn)程庫(kù)別名/遠(yuǎn)程庫(kù)分支名>:將抓取下來(lái)的遠(yuǎn)程的分支,跟當(dāng)前所在分支進(jìn)行合并
git fork:復(fù)制遠(yuǎn)程庫(kù)
tip:一般是外面團(tuán)隊(duì)的開發(fā)人員fork本團(tuán)隊(duì)項(xiàng)目,然后進(jìn)行開發(fā),之后外面團(tuán)隊(duì)發(fā)起pull request,然后本團(tuán)隊(duì)進(jìn)行審核,如無(wú)問(wèn)題本團(tuán)隊(duì)進(jìn)行merge(合并)到團(tuán)隊(duì)自己的遠(yuǎn)程庫(kù),整個(gè)流程就是本團(tuán)隊(duì)跟外面團(tuán)隊(duì)的協(xié)同開發(fā)流程,Linux的團(tuán)隊(duì)開發(fā)成員即為這種工作方式。
三、什么是tag
tag是git版本庫(kù)的一個(gè)標(biāo)記,指向某個(gè)commit的指針。
tag主要用于發(fā)布版本的管理,一個(gè)版本發(fā)布之后,我們可以為git打上 v.1.0.1 v.1.0.2 ...這樣的標(biāo)簽。
tag感覺跟branch有點(diǎn)相似,但是本質(zhì)上和分工上是不同的:
tag 對(duì)應(yīng)某次commit, 是一個(gè)點(diǎn),是不可移動(dòng)的。
branch 對(duì)應(yīng)一系列commit,是很多點(diǎn)連成的一根線,有一個(gè)HEAD 指針,是可以依靠 HEAD 指針移動(dòng)的。
所以,兩者的區(qū)別決定了使用方式,改動(dòng)代碼用 branch ,不改動(dòng)只查看用 tag。
tag 和 branch 的相互配合使用,有時(shí)候起到非常方便的效果,例如:已經(jīng)發(fā)布了 v1.0 v2.0 v3.0 三個(gè)版本,這個(gè)時(shí)候,我突然想不改現(xiàn)有代碼的前提下,在 v2.0 的基礎(chǔ)上加個(gè)新功能,作為 v4.0 發(fā)布。就可以檢出 v2.0 的代碼作為一個(gè) branch ,然后作為開發(fā)分支。
1.創(chuàng)建tag:
創(chuàng)建 tag 是基于本地分支的 commit,而且與分支的推送是兩回事,就是說(shuō)分支已經(jīng)推送到遠(yuǎn)程了,但是你的 tag 并沒(méi)有,如果把 tag 推送到遠(yuǎn)程分支上,需要另外執(zhí)行 tag 的推送命令。
git tag <tagName> //創(chuàng)建本地tag
git push origin <tagName> //推送到遠(yuǎn)程倉(cāng)庫(kù)
若存在很多未推送的本地標(biāo)簽,你想一次全部推送的話:
git push origin --tags
以上是基于本地當(dāng)前分支的最后的一個(gè)commit 創(chuàng)建的 tag ,但是如果不想以最后一個(gè),只想以某一個(gè)特定的提交為tag ,也是可以的,只要你知道commit 的id。
git log --pretty=oneline //查看當(dāng)前分支的提交歷史?里面包含 commit id
git tag -a <tagName> <commitId>
2.查看標(biāo)簽
查看本地某個(gè) tag 的詳細(xì)信息:
git show <tagName>
查看本地所有 tag:
git tag 或者?git tag -l
查看遠(yuǎn)程所有 tag:
git ls-remote --tags origin
3.刪除標(biāo)簽
本地 tag 的刪除:
git tag -d <tagName>
遠(yuǎn)程 tag 的刪除:
git push origin :<tagName>
4.檢出標(biāo)簽
git checkout -b <branchName> <tagName>
因?yàn)?tag 本身指向的就是一個(gè) commit,所以和根據(jù)commit id 檢出分支是一個(gè)道理。
但是需要特別說(shuō)明的是,如果我們想要修改 tag檢出代碼分支,那么雖然分支中的代碼改變了,但是 tag標(biāo)記的 commit還是同一個(gè),標(biāo)記的代碼是不會(huì)變的,這個(gè)要格外的注意。
其它
命令git tag -a <tagname> -m "XXX..."?可以指定標(biāo)簽信息。
命令git tag -a v0.1.0 -m "release 0.1.0 version"?創(chuàng)建附注標(biāo)簽。
命令git checkout [tagname]?切換標(biāo)簽。
五、Rebase
假設(shè)你現(xiàn)在基于遠(yuǎn)程分支"origin",創(chuàng)建一個(gè)叫"mywork"的分支。
$ git checkout -b mywork origin
現(xiàn)在我們?cè)谶@個(gè)分支做一些修改,然后生成兩個(gè)提交(commit).
$ vi file.txt $ git commit $ vi otherfile.txt $ git commit ...
但是與此同時(shí),有些人也在"origin"分支上做了一些修改并且做了提交了. 這就意味著"origin"和"mywork"這兩個(gè)分支各自"前進(jìn)"了,它們之間"分叉"了。
在這里,你可以用"pull"命令把"origin"分支上的修改拉下來(lái)并且和你的修改合并;結(jié)果看起來(lái)就像一個(gè)新的"合并的提交"(merge commit):
但是,如果你想讓"mywork"分支歷史看起來(lái)像沒(méi)有經(jīng)過(guò)任何合并一樣,你也許可以用?git rebase:
$ git checkout mywork $ git rebase origin
這些命令會(huì)把你的"mywork"分支里的每個(gè)提交(commit)取消掉,并且把它們臨時(shí) 保存為補(bǔ)丁(patch)(這些補(bǔ)丁放到".git/rebase"目錄中),然后把"mywork"分支更新 到最新的"origin"分支,最后把保存的這些補(bǔ)丁應(yīng)用到"mywork"分支上。
當(dāng)'mywork'分支更新之后,它會(huì)指向這些新創(chuàng)建的提交(commit),而那些老的提交會(huì)被丟棄。如果運(yùn)行垃圾收集命令(pruning garbage collection), 這些被丟棄的提交就會(huì)刪除. (請(qǐng)查看?git gc)
現(xiàn)在我們可以看一下用合并(merge)和用rebase所產(chǎn)生的歷史的區(qū)別:
在rebase的過(guò)程中,也許會(huì)出現(xiàn)沖突(conflict). 在這種情況,Git會(huì)停止rebase并會(huì)讓你去解決 沖突;在解決完沖突后,用"git-add"命令去更新這些內(nèi)容的索引(index), 然后,你無(wú)需執(zhí)行 git-commit,只要執(zhí)行:
$ git rebase --continue
這樣git會(huì)繼續(xù)應(yīng)用(apply)余下的補(bǔ)丁。
在任何時(shí)候,你可以用--abort參數(shù)來(lái)終止rebase的行動(dòng),并且"mywork" 分支會(huì)回到rebase開始前的狀態(tài)。
$ git rebase --abort
六、restash
今天在看一個(gè)bug,之前一個(gè)分支的版本是正常的,在新的分支上上加了很多日志沒(méi)找到原因,希望回溯到之前的版本,確定下從哪個(gè)提交引入的問(wèn)題,但是還不想把現(xiàn)在的修改提交,也不希望在Git上看到當(dāng)前修改的版本(帶有大量日志和調(diào)試信息)。因此呢,查查Git有沒(méi)有提供類似功能,就找到了git stash的命令。
綜合下網(wǎng)上的介紹和資料,git stash(git儲(chǔ)藏)可用于以下情形:
發(fā)現(xiàn)有一個(gè)類是多余的,想刪掉它又擔(dān)心以后需要查看它的代碼,想保存它但又不想增加一個(gè)臟的提交。這時(shí)就可以考慮git stash。
使用git的時(shí)候,我們往往使用分支(branch)解決任務(wù)切換問(wèn)題,例如,我們往往會(huì)建一個(gè)自己的分支去修改和調(diào)試代碼, 如果別人或者自己發(fā)現(xiàn)原有的分支上有個(gè)不得不修改的bug,我們往往會(huì)把完成一半的代碼commit提交到本地倉(cāng)庫(kù),然后切換分支去修改bug,改好之后再切換回來(lái)。這樣的話往往log上會(huì)有大量不必要的記錄。其實(shí)如果我們不想提交完成一半或者不完善的代碼,但是卻不得不去修改一個(gè)緊急Bug,那么使用git stash就可以將你當(dāng)前未提交到本地(和服務(wù)器)的代碼推入到Git的棧中,這時(shí)候你的工作區(qū)間和上一次提交的內(nèi)容是完全一樣的,所以你可以放心的修Bug,等到修完Bug,提交到服務(wù)器上后,再使用git stash apply將以前一半的工作應(yīng)用回來(lái)。
經(jīng)常有這樣的事情發(fā)生,當(dāng)你正在進(jìn)行項(xiàng)目中某一部分的工作,里面的東西處于一個(gè)比較雜亂的狀態(tài),而你想轉(zhuǎn)到其他分支上進(jìn)行一些工作。問(wèn)題是,你不想提交進(jìn)行了一半的工作,否則以后你無(wú)法回到這個(gè)工作點(diǎn)。解決這個(gè)問(wèn)題的辦法就是git stash命令。儲(chǔ)藏(stash)可以獲取你工作目錄的中間狀態(tài)——也就是你修改過(guò)的被追蹤的文件和暫存的變更——并將它保存到一個(gè)未完結(jié)變更的堆棧中,隨時(shí)可以重新應(yīng)用。
git stash用法
1. stash當(dāng)前修改
git stash會(huì)把所有未提交的修改(包括暫存的和非暫存的)都保存起來(lái),用于后續(xù)恢復(fù)當(dāng)前工作目錄。
比如下面的中間狀態(tài),通過(guò)git stash命令推送一個(gè)新的儲(chǔ)藏,當(dāng)前的工作目錄就干凈了。
$ git status On branch master Changes to be committed: new file: ? style.css Changes not staged for commit: modified: ? index.html $ git stash Saved working directoryandindex state WIP onmaster: 5002d47 our new homepageHEADisnowat 5002d47 our new homepage $ git statusOn branch masternothingtocommit, working tree clean
需要說(shuō)明一點(diǎn),stash是本地的,不會(huì)通過(guò)git push命令上傳到git server上。
實(shí)際應(yīng)用中推薦給每個(gè)stash加一個(gè)message,用于記錄版本,使用git stash save取代git stash命令。示例如下:
$ git stash save "test-cmd-stash"Saved working directory and index state On autoswitch: test-cmd-stash HEAD 現(xiàn)在位于 296e8d4 remove unnecessary postion reset in onResume function $ git stash list stash@{0}: On autoswitch: test-cmd-stash
2. 重新應(yīng)用緩存的stash
可以通過(guò)git stash pop命令恢復(fù)之前緩存的工作目錄,輸出如下:
$ git status On branch master nothing to commit, working tree clean $ git stash popOn branch masterChanges to be committed: ? ?newfile: ? style.css Changes not staged forcommit: ? ?modified: ? index.html Dropped refs/stash@{0} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)
這個(gè)指令將緩存堆棧中的第一個(gè)stash刪除,并將對(duì)應(yīng)修改應(yīng)用到當(dāng)前的工作目錄下。
你也可以使用git stash apply命令,將緩存堆棧中的stash多次應(yīng)用到工作目錄中,但并不刪除stash拷貝。命令輸出如下:
$ git stash applyOn branch master Changes to be committed: ? ?new file: ? style.css Changes not staged for commit: ? ?modified: ? index.html
3. 查看現(xiàn)有stash
可以使用git stash list命令,一個(gè)典型的輸出如下:
$ git stash list stash@{0}: WIP on master: 049d078 added the index file stash@{1}: WIP on master: c264051 Revert "added file_size"stash@{2}: WIP on master: 21d80a5 added number to log
在使用git stash apply命令時(shí)可以通過(guò)名字指定使用哪個(gè)stash,默認(rèn)使用最近的stash(即stash@{0})。
4. 移除stash
可以使用git stash drop命令,后面可以跟著stash名字。下面是一個(gè)示例:
$ git stash list stash@{0}: WIP on master: 049d078 added the index file stash@{1}: WIP on master: c264051 Revert "added file_size"stash@{2}: WIP on master: 21d80a5 added number to log$ git stash drop stash@{0} Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
或者使用git stash clear命令,刪除所有緩存的stash。
5. 查看指定stash的diff
可以使用git stash show命令,后面可以跟著stash名字。示例如下:
$ git stash show index.html | 1 + style.css | 3 +++ 2 files changed, 4 insertions(+)
在該命令后面添加-p或--patch可以查看特定stash的全部diff,如下:
$ git stash show -p diff --git a/style.css b/style.css new file mode 100644 index 0000000..d92368b--- /dev/null+++ b/style.css@@ -0,0 +1,3 @@+* {+ ?text-decoration: blink;+}diff --git a/index.html b/index.html index 9daeafb..ebdcbd2 100644--- a/index.html+++ b/index.html@@ -1 +1,2 @@+<link rel="stylesheet" href="style.css"/>
6. 從stash創(chuàng)建分支
如果你儲(chǔ)藏了一些工作,暫時(shí)不去理會(huì),然后繼續(xù)在你儲(chǔ)藏工作的分支上工作,你在重新應(yīng)用工作時(shí)可能會(huì)碰到一些問(wèn)題。如果嘗試應(yīng)用的變更是針對(duì)一個(gè)你那之后修改過(guò)的文件,你會(huì)碰到一個(gè)歸并沖突并且必須去化解它。如果你想用更方便的方法來(lái)重新檢驗(yàn)?zāi)銉?chǔ)藏的變更,你可以運(yùn)行 git stash branch,這會(huì)創(chuàng)建一個(gè)新的分支,檢出你儲(chǔ)藏工作時(shí)的所處的提交,重新應(yīng)用你的工作,如果成功,將會(huì)丟棄儲(chǔ)藏。
$ git stash branch testchanges Switched to a new branch "testchanges"# On branch testchanges# Changes to be committed:# ? (use "git reset HEAD <file>..." to unstage)## ? ? ?modified: ? index.html## Changes not staged for commit:# ? (use "git add <file>..." to update what will be committed)## ? ? ?modified: ? lib/simplegit.rb#Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359)
這是一個(gè)很棒的捷徑來(lái)恢復(fù)儲(chǔ)藏的工作然后在新的分支上繼續(xù)當(dāng)時(shí)的工作。
7. 暫存未跟蹤或忽略的文件
默認(rèn)情況下,git stash會(huì)緩存下列文件:
添加到暫存區(qū)的修改(staged changes)
Git跟蹤的但并未添加到暫存區(qū)的修改(unstaged changes)
但不會(huì)緩存一下文件:
在工作目錄中新的文件(untracked files)
被忽略的文件(ignored files)
git stash命令提供了參數(shù)用于緩存上面兩種類型的文件。使用-u或者--include-untracked可以stash untracked文件。使用-a或者--all命令可以stash當(dāng)前目錄下的所有修改。
至于git stash的其他命令建議參考Git manual。
8、
場(chǎng)景如下,你正在開發(fā)需求1時(shí),突然線上發(fā)現(xiàn)了一個(gè)bug,需要立即修復(fù)。需求1的代碼因?yàn)椴煌晟?,也沒(méi)經(jīng)過(guò)測(cè)試,所以你希望針對(duì)需求1所做的修改先暫時(shí)隱藏,這樣就可以使用 stash功能了。
VCS-->git -->stash
這個(gè)時(shí)候針對(duì)需求1做的修改都會(huì)隱藏掉?,F(xiàn)在假設(shè)你處理bug完畢。需要繼續(xù)開發(fā)需求,現(xiàn)在需要unstash
VCS-->git-->Unstash,選中你剛剛的stash,選中Pop stash。點(diǎn)擊pop stash即可。如下圖:
但是我這里遇到個(gè)問(wèn)題,屏幕右下角有如下提示:
點(diǎn)擊View them,發(fā)現(xiàn)是.DS_store 文件,這個(gè)我已經(jīng)在.gitignore中聲明忽略該文件了。所以我的localChanges中并沒(méi)有該文件。
沒(méi)辦法,只有先修改.gitignore,不忽略.DS_store.然后執(zhí)行g(shù)it status 能看到兩個(gè)文件被修改了
然后執(zhí)行g(shù)it checkout --? ../.DS_Store 即回滾 .DS_store。然后重新unstash,ok。
然后也需要回滾.gitignore