Git常用命令

今日份雞湯:努力從來不嫌晚,只要你堅(jiān)定開始就可以啦~

進(jìn)入正題:

1、Git ?clone(遠(yuǎn)程項(xiàng)目clone到本地):

參數(shù)挺多,但常用的就幾個(gè):

1> 最簡單直接的命令:git clone xxx.git

2> 如果想clone到指定目錄:git clone xxx.git "指定目錄"

3> clone時(shí)創(chuàng)建新的分支替代默認(rèn)Origin HEAD(master):git clone -b new_branch_name xxx.git

4> clone 遠(yuǎn)程分支

git clone 命令默認(rèn)的只會(huì)建立master分支,如果你想clone指定的某一遠(yuǎn)程分支(如:dev)的話,可以如下:

  A. 查看所有分支(包括隱藏的) ?git branch -a?顯示所有分支,如:

* master

remotes/origin/HEAD -> origin/master

remotes/origin/dev

remotes/origin/master

  B. ?在本地新建同名的("dev")分支,并切換到該分支

git?checkout?-t?origin/dev?該命令等同于:git?checkout?-b?dev?origin/dev

2、分支查看:

1> 查看本地分支:git branch

2> 查看遠(yuǎn)程分支:git branch -r

3> 查看跟蹤分支:git branch -vv

3、git checkout -b(從已有本地分支拉新分支):

開發(fā)過程中經(jīng)常用到從master分支copy一個(gè)開發(fā)分支,下面我們就用命令行完成這個(gè)操作:

1> 切換到被copy的分支(master),并且從遠(yuǎn)端拉取最新版本

git checkout master

git pull

2> 從當(dāng)前分支拉copy開發(fā)分支:git checkout -b dev

執(zhí)行上面的命令后提示 Switched to a new branch 'dev',證明已經(jīng)切換到新的分支上

3> 把新建的分支push到遠(yuǎn)端:git push origin dev

4> 拉取遠(yuǎn)端分支:git pull

執(zhí)行上述命令提示:

There is no tracking information for the current branch.

Please specify which branch you want to merge with.

See git-pull(1) for details.

git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

git branch --set-upstream-to=origin/<branch> dev

經(jīng)過驗(yàn)證,當(dāng)前的分支并沒有和本地分支關(guān)聯(lián),根據(jù)提示進(jìn)行下一步:

5> 關(guān)聯(lián):git branch --set-upstream-to=origin/dev

6> 再次拉取 驗(yàn)證:git pull

看到提示:Already up-to-date,到此完事。

4、git tag(給當(dāng)前分支打標(biāo)簽):

列出tag:

git tag:在控制臺(tái)打印出當(dāng)前倉庫的所有tag

git tag -l 'v0.1.*': 搜索符合模式的Tag

打tag:

git tag分為兩種類型:輕量tag和附注tag。輕量tag是指向提交對(duì)象的引用,附注Tag則是倉庫中的一個(gè)獨(dú)立對(duì)象。建議使用附注Tag。

創(chuàng)建輕量Tag:git tag v0.1.2-light

創(chuàng)建附注Tag:git tag -a v0.1.2 -m "0.1.2版本" (我一般上線前打tag都用這種)

創(chuàng)建輕量Tag不需要傳遞參數(shù),直接指定Tag名稱即可。

創(chuàng)建附注Tag時(shí),參數(shù)a即annotated的縮寫,指定Tag類型,后附Tag名。參數(shù)m指定Tag說明,說明信息會(huì)保存在Tag對(duì)象中。

切換到Tag:git checkout tagName (與切換分支命令相同)

查看Tag信息:git show v0.1.2(用git show命令可以查看Tag的版本信息)

刪除Tag:git tag -d v0.1.2(誤打或需要修改Tag時(shí),需要先將Tag刪除,參數(shù)d即delete的縮寫,意為刪除其后指定的Tag。)

刪除遠(yuǎn)程tag:git?push?origin?--delete?tag tagName

給指定的commit打Tag

打Tag不必要在head之上,也可在之前的版本上打,這需要你知道某個(gè)提交對(duì)象的校驗(yàn)和(通過git log獲?。?/p>

補(bǔ)打Tag:git tag -a v0.1.1 9fbc3d0

Tag推送到服務(wù)器

通常的git push不會(huì)將Tag對(duì)象提交到git服務(wù)器,我們需要進(jìn)行顯式的操作:

git push origin v0.1.2:將v0.1.2 Tag提交到git服務(wù)器

git push origin --tags: 將本地所有Tag一次性提交到git服務(wù)器

注意:如果想看之前某個(gè)Tag狀態(tài)下的文件,可以這樣操作

1> git tag:查看當(dāng)前分支下的Tag

2> git checkout v0.21 :此時(shí)會(huì)指向打v0.21 Tag時(shí)的代碼狀態(tài),(但現(xiàn)在處于一個(gè)空的分支上)

5、git reset(本地版本回滾):

當(dāng)我們?cè)诤洗a的時(shí)候經(jīng)常會(huì)遇到一些問題,這時(shí)候分支就處于merging狀態(tài),這時(shí)候可以用下面的命令撤銷

?git reset --hard HEAD(這個(gè)實(shí)際工作場景確實(shí)用過幾次)

1> git reset HEAD^ :回退版本,一個(gè)^表示一個(gè)版本,可以多個(gè),另外也可以使用 git reset HEAD~n這種形式。?      

如果HEAD指針指向的是master分支,那么HEAD還可以換成master,如果知道特定的commit-id,那么還可以直接使用 git reset commit-id 如果不加參數(shù),實(shí)際上使用的是默認(rèn)的參數(shù)mixed,

我們可以使用git log -3來查看最近三次的提交,形如 git log -n ,n就是想要輸出的個(gè)數(shù),可以看到commit-id,author,date等信息

下面介紹三種參數(shù):

(1) soft 參數(shù):git reset --soft HEAD~1 意為將版本庫軟回退1個(gè)版本,所謂軟回退表示將本地版本庫的頭指針全部重置到指定版本,且將這次提交之后的所有變更都移動(dòng)到暫存區(qū)

(2) 默認(rèn)的mixed參數(shù):git reset HEAD~1 意為將版本庫回退1個(gè)版本,將本地版本庫的頭指針全部重置到指定版本,且會(huì)重置暫存區(qū),即這次提交之后的所有變更都移動(dòng)到未暫存階段

(3) hard參數(shù):git reset --hard HEAD~1 意將版本庫為回退1個(gè)版本,但是不僅僅是將本地版本庫的頭指針全部重置到指定版本,也會(huì)重置暫存區(qū),并且會(huì)將工作區(qū)代碼也回退到這個(gè)版本 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?       

了解這三個(gè)參數(shù)已足夠我們?nèi)粘i_發(fā)使用了, 注意soft參數(shù)與默認(rèn)參數(shù)都不會(huì)修改工作區(qū)代碼,只有hard參數(shù)才會(huì)修改工作區(qū)代碼。

2> git reset 配合 git commit 追加提交?

什么時(shí)候會(huì)用到追加提交,追加提交有什么優(yōu)點(diǎn)?

(1)對(duì)未merge的版本庫中的提交不滿意,希望修改其中的某些信息,如代碼,如提交描述等,可以使用git commit --amend進(jìn)行追加提交,優(yōu)點(diǎn)是不會(huì)產(chǎn)生新的commit-id

(2)修改方法:如果想修改的不是最新一版的提交,那么可以通過git reset --hard HEAD~n將版本回退到需要的那版,如果想修改代碼,那么直接在工作區(qū)進(jìn)行代碼修改,

修改完之后git add到暫存區(qū)而不必再git pull,而如果是修改其他信息,那么可以直接使用git commit --amend進(jìn)行追加提交,git commit --amend命令會(huì)打開一個(gè)編輯器,可以修改其中的信息,

如果修改了代碼而不修改其他信息,則直接 Ctrl + X離開編輯器,再git push推送到遠(yuǎn)程服務(wù)器,如果也修改了其他信息,那么需要先使用Ctrl + M寫入信息,再Ctrl + X離開編輯器,再推送。

3> 查看幫助:git reset -h | git reset --help?

6、刪除分支:

git 刪除本地分支:git branch -D branchName

git 刪除遠(yuǎn)程分支:git push origin :branchName? (origin 后面有空格)

在Git v1.7.0 之后,可以使用這種語法刪除遠(yuǎn)程分支:git?push?origin?--delete branchName

7、git 遠(yuǎn)程分支回滾

簡單的辦法:

先用git log 查找出commit_id

? ? git?reset?--hard commit_id

????git push origin HEAD --force

其他:

????根據(jù)–soft –mixed –hard,會(huì)對(duì)working tree和index和HEAD進(jìn)行重置:

????git reset –mixed:此為默認(rèn)方式,不帶任何參數(shù)的git reset,即時(shí)這種方式,它回退到某個(gè)版本,只保留源碼,回退commit和index信息

????git reset –soft:回退到某個(gè)版本,只回退了commit的信息,不會(huì)恢復(fù)到index file一級(jí)。如果還要提交,直接commit即可

????git reset –hard:徹底回退到某個(gè)版本,本地的源碼也會(huì)變?yōu)樯弦粋€(gè)版本的內(nèi)容

????HEAD 最近一個(gè)提交

????HEAD^ 上一次

? ? <commit_id>?每次commit的SHA1值.?可以用git?log?看到,也可以在頁面上commit標(biāo)簽頁里找到.

麻煩的辦法:

這個(gè)是重點(diǎn)要說的內(nèi)容,過程比本地回滾要復(fù)雜

應(yīng)用場景:自動(dòng)部署系統(tǒng)發(fā)布后發(fā)現(xiàn)問題,需要回滾到某一個(gè)commit,再重新發(fā)布

原理:先將本地分支退回到某個(gè)commit,刪除遠(yuǎn)程分支,再重新push本地分支

操作步驟:

1>、git checkout the_branch

2>、git pull

3>、git branch the_branch_backup //備份一下這個(gè)分支當(dāng)前的情況

4>、git reset --hard the_commit_id //把the_branch本地回滾到the_commit_id

5>、git push origin :the_branch //刪除遠(yuǎn)程 the_branch

6>、git push origin the_branch //用回滾后的本地分支重新建立遠(yuǎn)程分支

7>、git push origin :the_branch_backup //如果前面都成功了,刪除這個(gè)備份分支

如果使用了gerrit做遠(yuǎn)程代碼中心庫和code review平臺(tái),需要確保操作git的用戶具備分支的push權(quán)限,并且選擇了 Force Push選項(xiàng)(在push權(quán)限設(shè)置里有這個(gè)選項(xiàng))

另外,gerrit中心庫是個(gè)bare庫,將HEAD默認(rèn)指向了master,因此master分支是不能進(jìn)行刪除操作的,最好不要選擇刪除master分支的策略,換用其他分支。如果一定要這樣做,可以考慮到gerrit服務(wù)器上修改HEAD指針。。。不建議這樣做

8、git stash(git 儲(chǔ)藏工具)

儲(chǔ)藏(Stashing)

經(jīng)常有這樣的事情發(fā)生,當(dāng)你正在進(jìn)行項(xiàng)目中某一部分的工作,里面的東西處于一個(gè)比較雜亂的狀態(tài),而你想轉(zhuǎn)到其他分支上進(jìn)行一些工作。問題是,你不想提交進(jìn)行了一半的工作,否則以后你無法回到這個(gè)工作點(diǎn)。解決這個(gè)問題的辦法就是git stash命令。

“‘儲(chǔ)藏”“可以獲取你工作目錄的中間狀態(tài)——也就是你修改過的被追蹤的文件和暫存的變更——并將它保存到一個(gè)未完結(jié)變更的堆棧中,隨時(shí)可以重新應(yīng)用。

儲(chǔ)藏你的工作

為了演示這一功能,你可以進(jìn)入你的項(xiàng)目,在一些文件上進(jìn)行工作,有可能還暫存其中一個(gè)變更。如果你運(yùn)行?git status,你可以看到你的中間狀態(tài):

$ git status

# On branch master

# 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

現(xiàn)在你想切換分支,但是你還不想提交你正在進(jìn)行中的工作;所以你儲(chǔ)藏這些變更。為了往堆棧推送一個(gè)新的儲(chǔ)藏,只要運(yùn)行?git stash:

$ git stash

Saved working directory and index state \

"WIP on master: 049d078 added the index file"

HEAD is now at 049d078 added the index file

(To restore them type "git stash apply")

你的工作目錄就干凈了:

$ git status

# On branch master

nothing to commit, working directory clean

這時(shí),你可以方便地切換到其他分支工作;你的變更都保存在棧上。要查看現(xiàn)有的儲(chǔ)藏,你可以使用?git stash list:

$ 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

在這個(gè)案例中,之前已經(jīng)進(jìn)行了兩次儲(chǔ)藏,所以你可以訪問到三個(gè)不同的儲(chǔ)藏。你可以重新應(yīng)用你剛剛實(shí)施的儲(chǔ)藏,所采用的命令就是之前在原始的 stash 命令的幫助輸出里提示的:git stash apply。如果你想應(yīng)用更早的儲(chǔ)藏,你可以通過名字指定它,像這樣:git stash apply stash@{2}。如果你不指明,Git 默認(rèn)使用最近的儲(chǔ)藏并嘗試應(yīng)用它:

$ git stash apply

# On branch master

# Changes not staged for commit:

# (use "git add <file>..." to update what will be committed)

# modified: index.html

# modified: lib/simplegit.rb

你可以看到 Git 重新修改了你所儲(chǔ)藏的那些當(dāng)時(shí)尚未提交的文件。在這個(gè)案例里,你嘗試應(yīng)用儲(chǔ)藏的工作目錄是干凈的,并且屬于同一分支;但是一個(gè)干凈的工作目錄和應(yīng)用到相同的分支上并不是應(yīng)用儲(chǔ)藏的必要條件。你可以在其中一個(gè)分支上保留一份儲(chǔ)藏,隨后切換到另外一個(gè)分支,再重新應(yīng)用這些變更。在工作目錄里包含已修改和未提交的文件時(shí),你也可以應(yīng)用儲(chǔ)藏——Git 會(huì)給出歸并沖突如果有任何變更無法干凈地被應(yīng)用。

對(duì)文件的變更被重新應(yīng)用,但是被暫存的文件沒有重新被暫存。想那樣的話,你必須在運(yùn)行?git stash apply?命令時(shí)帶上一個(gè)?--index?的選項(xiàng)來告訴命令重新應(yīng)用被暫存的變更。如果你是這么做的,你應(yīng)該已經(jīng)回到你原來的位置:

$ git stash apply --index

# On branch master

# 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

apply 選項(xiàng)只嘗試應(yīng)用儲(chǔ)藏的工作——儲(chǔ)藏的內(nèi)容仍然在棧上。要移除它,你可以運(yùn)行?git stash drop,加上你希望移除的儲(chǔ)藏的名字:

$ 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)

你也可以運(yùn)行?git stash pop?來重新應(yīng)用儲(chǔ)藏,同時(shí)立刻將其從堆棧中移走。

取消儲(chǔ)藏(Un-applying a Stash)

在某些情況下,你可能想應(yīng)用儲(chǔ)藏的修改,在進(jìn)行了一些其他的修改后,又要取消之前所應(yīng)用儲(chǔ)藏的修改。Git沒有提供類似于?stash unapply?的命令,但是可以通過取消該儲(chǔ)藏的補(bǔ)丁達(dá)到同樣的效果:

$ git stash show -p stash@{0} | git apply -R

同樣的,如果你沒有指定具體的某個(gè)儲(chǔ)藏,Git 會(huì)選擇最近的儲(chǔ)藏:

$ git stash show -p | git apply -R

你可能會(huì)想要新建一個(gè)別名,在你的 Git 里增加一個(gè)?stash-unapply?命令,這樣更有效率。例如:

$ git config --global alias.stash-unapply '!git stash show -p | git apply -R'

$ git stash apply

$ #... work work work

$ git stash-unapply

從儲(chǔ)藏中創(chuàng)建分支

如果你儲(chǔ)藏了一些工作,暫時(shí)不去理會(huì),然后繼續(xù)在你儲(chǔ)藏工作的分支上工作,你在重新應(yīng)用工作時(shí)可能會(huì)碰到一些問題。如果嘗試應(yīng)用的變更是針對(duì)一個(gè)你那之后修改過的文件,你會(huì)碰到一個(gè)歸并沖突并且必須去化解它。如果你想用更方便的方法來重新檢驗(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è)很棒的捷徑來恢復(fù)儲(chǔ)藏的工作然后在新的分支上繼續(xù)當(dāng)時(shí)的工作。

9、git rebase(git 合并多個(gè) Commit)

在使用 Git 作為版本控制的時(shí)候,我們可能會(huì)由于各種各樣的原因提交了許多臨時(shí)的 commit,而這些 commit 拼接起來才是完整的任務(wù)。那么我們?yōu)榱吮苊馓嗟?commit 而造成版本控制的混亂,通常我們推薦將這些 commit 合并成一個(gè)。

首先假設(shè)我們有3個(gè) commit,用git log -3命令來查看。

我們需要將 2dfbc7e8 和 c4e858b5 合并成一個(gè) commit,那么我們輸入如下命令

其中,-i 的參數(shù)是不需要合并的 commit 的 hash 值,這里指的是第一條 commit, 接著我們就進(jìn)入到 vi 的編輯模式

可以看到其中分為兩個(gè)部分,上方未注釋的部分是填寫要執(zhí)行的指令,而下方注釋的部分則是指令的提示說明。指令部分中由前方的命令名稱、commit hash 和 commit message 組成。

當(dāng)前我們只要知道 pick 和 squash 這兩個(gè)命令即可。

pick 的意思是要會(huì)執(zhí)行這個(gè) commit

squash 的意思是這個(gè) commit 會(huì)被合并到前一個(gè)commit

我們將 c4e858b5 這個(gè) commit 前方的命令改成 squash 或 s,然后輸入:wq以保存并退出

這是我們會(huì)看到 commit message 的編輯界面

其中, 非注釋部分就是兩次的 commit message, 你要做的就是將這兩個(gè)修改成新的 commit message。

輸入wq保存并推出, 再次輸入git log查看 commit 歷史信息,你會(huì)發(fā)現(xiàn)這兩個(gè) commit 已經(jīng)合并了。

注意事項(xiàng):如果這個(gè)過程中有操作錯(cuò)誤,可以使用 git rebase --abort來撤銷修改,回到?jīng)]有開始操作合并之前的狀態(tài)。

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

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