Git 基础 —— 常用命令
Git 基礎(chǔ)學(xué)習(xí)系列
- Git 基礎(chǔ) —— 安裝 配置 別名 對象
- Git 基礎(chǔ) —— 常用命令
- Git 基礎(chǔ) —— 常見使用場景
- Git基礎(chǔ) —— Github 的使用
git init
創(chuàng)建 Git 本地倉庫
遠端無倉庫,本地無倉庫,本地新建一個倉庫
git init git_learning遠端有倉庫,本地無倉庫,拉取遠端倉庫到本地
git clone git@github.com:Michael728/michael-git.git cd michael-git # 提交一個 readme 文件 touch README.md git add README.md git commit -m "add README" git push -u origin master遠端有空倉庫,本地已有項目文件,關(guān)聯(lián)遠端倉庫
查看我們當前項目有哪些遠程倉庫可以執(zhí)行如下命令:
git remote -v如果發(fā)現(xiàn)沒有關(guān)聯(lián)遠端倉庫,可以這么做:
cd micahel-git git init # 如果本地已經(jīng)是一個 Git 倉庫,這行就跳過 git remote add origin git@github.com:Michael728/michael-git.git # 添加一個遠端主機,并命名為 origin git push -u origin --all # --all 表示 push all branches,-u 選項指定了一個默認主機 git push -u origin --tags # --tags All refs under refs/tags are pushed將本地的master分支推送到origin主機,同時指定origin為默認主機,后面就可以不要再指定遠端主機名 origin 了,直接使用git push。
遠端主機名可以定義為其他,比如 github。通過 git remote add 命令,一個倉庫其實可以與多個遠端倉庫發(fā)生關(guān)聯(lián)的,這時候只要遠端主機名取不一樣的即可區(qū)別。為什么要給遠程倉庫取名字?因為我們可能一個項目有多個遠程倉庫,比如,Github一個,比如公司一個,這樣的話,提交的時候可以提交到不同的遠程倉庫就需要指定不同的倉庫名字了。
參考:
- git push 的 -u 參數(shù)具體適合含義?
- Git遠程操作詳解
git clone
下載一個遠程倉庫:
git clone [-b br_name] <git@github.com:Michael728/michael-git.git> [本地倉庫名]克隆的時候,可以指定下載遠端的分支、自定義本地倉庫的名字。如果不加分支名參數(shù),git clone 命令會默認自動設(shè)置本地 master 分支跟蹤克隆的遠程倉庫的 master 分支(其實是倉庫的默認分支,大部分倉庫默認分支是 master)。同時,默認遠端主機設(shè)置別名為 origin。
git mv
文件重命名:
git mv <old filename> <new filename>git branch
- git branch -r 只顯示遠端分支,
- git branch -a 顯示本地分支和遠程分支
新建分支
新建 develop 分支,并切換到 develop 分支:
git branch develop git checkout develop # 新建并切換分支 git checkout -b develop本地分支推送到遠端倉庫
本地分支推送到遠程服務(wù)器時,遠程分支自動創(chuàng)建,推送本地分支到遠程:
git push --set-upstream <remote_host_name> <local_branch_name>:<remote_branch_name>- <remote_host_name>:遠程 Git 服務(wù)器名稱,一般為origin
- <local_branch_name>:本地分支名稱
- <remote_branch_name>:遠程分支名稱
- --set-upstream參數(shù)用來關(guān)聯(lián)本地分支和遠程分支
一般情況下,本地分支和遠程分支名稱相同,所以可簡化為:
git push --set-upstream <remote_host_name> <branch_name>參考:
- Git創(chuàng)建遠程分支
- 阮一峰--Git遠程操作詳解
查看本地分支:
git branch # 查看本地分支 git branch -r # 查看遠端分支 git branh -av # 查看所有分支,信息詳細點刪除分支:
刪除本地分支:
git branch -d develop git branch -D develop # 強制刪除刪除遠程分支:
git push origin :<remote_branch_name> # 和如下命令等同 git push origin --delete <remote_branch_name>git add
多個場景會用到這個命令:
- 可以用它開始跟蹤新文件
- 把已跟蹤的文件放到暫存區(qū)
- 還能用于合并時把有沖突的文件標記為已解決狀態(tài),這個是在解決沖突時會用到的功能
常用命令:
- git add -u:將文件的修改、文件的刪除,添加到暫存區(qū),用-u有個好處,避免把工作區(qū)沒準備好的新文件直接加到暫存區(qū)了,用的較多;
- git add .:將文件的修改,文件的新建,添加到暫存區(qū),慎用;
- git add -A/--all:將文件的修改,文件的刪除,文件的新建,添加到暫存區(qū),慎用;
git add -A相對于git add -u命令的優(yōu)點 : 可以提交所有被刪除、被替換、被修改和新增的文件到數(shù)據(jù)暫存區(qū),而git add -u只能操作跟蹤過的文件。
git diff
比較工作區(qū)和暫存區(qū)的差異
將工作區(qū)和暫存區(qū)所有文件進行比較:
git diff只對某些文件和暫存區(qū)進行比較:
git diff -- README.md [filename ...]比較暫存區(qū)和 HEAD 之間的差異
git diff --cached # 或者 git diff --staged比較的是工作區(qū)和HEAD之間的差異
git diff HEAD比較兩個分支的差異
git diff master temp只關(guān)心這兩個分支中某個文件的差異:
git diff master temp -- index.html其實,分支名就是一個指針,就是一種引用,可以直接使用 commit id 比較:
$ git diff 622a8 7e7a -- index.html注意了:git diff A B 比較的結(jié)果可以看做是 B-A 的差集,調(diào)換 A B 順序,正負號會有變化的。
git reset
暫存區(qū)文件的恢復(fù)
暫存區(qū)全部文件恢復(fù)成和 HEAD 一樣:
git reset HEAD- reset 命令不加 --hard,則暫存區(qū)的內(nèi)容恢復(fù)成HEAD對應(yīng)的內(nèi)容,工作區(qū)的變更繼續(xù)保留;
- 如果加了 --hard,則不管工作區(qū)還是暫存區(qū),內(nèi)容都變回HEAD對應(yīng)的內(nèi)容,危險的命令,會讓你在工作區(qū)的修改丟失;
git reset 有三個參數(shù):
- --soft 這個只是把 HEAD 指向的 commit 恢復(fù)到你指定的 commit,暫存區(qū) 工作區(qū)不變
- --hard 這個是 把 HEAD, 暫存區(qū), 工作區(qū) 都修改為 你指定的 commit 的時候的文件狀態(tài)
- --mixed 這個是不加時候的默認參數(shù),把 HEAD,暫存區(qū) 修改為 你指定的 commit 的時候的文件狀態(tài),工作區(qū)保持不變
怎樣取消暫存區(qū)部分文件的修改?
git reset HEAD style.css將工作區(qū)和暫存區(qū)保持一致
有時候修改了文件,已經(jīng)保存到暫存區(qū),之后又在工作區(qū)進行了修改,此時,發(fā)現(xiàn)工作的效果不如暫存區(qū)的效果好,想要將工作區(qū)和暫存區(qū)保持一致。
git checkout -- <file>...其實,git status 都有友好的提示的:
- 如果想要變更工作區(qū)的內(nèi)容,那么要想到和 checkout 命令相關(guān);
- 如果想要變更暫存區(qū)的內(nèi)容,那么要想到和reset 命令相關(guān);
消除最近的幾次提交
丟棄一些 commit,直接HEAD 指向了你指定的某個 commit,同時,暫存區(qū)和工作區(qū)也恢復(fù)到哪個 commit 時的狀態(tài):
git reset --hard <commitid>有些 commit 會丟失,是條危險的命令,要慎用。但是當你明確了你的需求,需要將工作區(qū)暫存區(qū)提交記錄明確恢復(fù)到某個 commit 狀態(tài)時,可以執(zhí)行這個命令。
git commit
「提交」操作。當你前面采用 add 命令將文件添加到暫存區(qū)跟蹤后,需要通過commit將暫存區(qū)的內(nèi)容提交到當前分支:
git commit -m "test"當一些已被追蹤的文件修改后,常常需要git add file,然后再git commit -m "xxxx",其實這兩個步驟可以合二為一:
git commit -am "test"這么寫個人覺得挺好,可以有效避免有些懶人git add .的方式,將一切文件都添加到了暫存區(qū),導(dǎo)致最后多余文件提交入庫。
amend
修改最近一次 commit 的 message:
git commit --amend修改完 message 信息之后,保存退出即可
git commit --amend命令本質(zhì)上是用新的 commit 應(yīng)該是替代了上一次的提交,不只是修改 message。比如上一次提交時有幾個文件沒有 add 以及 commit,可以重新進行 add 之后再 commit --amend 提交。但這次提交之后,在分支的 git log 中,不會增加一次新的 commit(因為被替換了嘛),看著效果相當于在父 commit 的基礎(chǔ)上進行的修改。
修改歷史提交的 message 信息:
如圖,想要修改 be4c 這次提交的 message 信息,那么可以使用 git rebase 命令,因為 be4c 這次提交會被新的提交替換掉,所以,「變基」操作的「基」要選擇它的父提交,85807:
- -i 會進入交互模式,有一系列指令操作對應(yīng)的 commit,不要用 pick 命令,而是使用 reword 命令操作 add ref 那次 commit,然后保存,就進入修改 message 的窗口,修改完再保存,最后就會 OK 了。
git log -3 查看最近的3次提交,變?yōu)檫@樣了,會發(fā)現(xiàn),倒數(shù)第二次的 message 信息修改 OK 了,最新一次的 message 雖然沒變,但其實,commit id 都發(fā)生了變化,「替換」的概念要記得。
git rebase 工作的過程中,就是用了「分離頭指針」。rebase 意味著基于新 base 的 commit 來變更部分 commits。它處理的時候,把 HEAD 指向base 的 commit,此時如果該 commit 沒有對應(yīng)branch,就處于分離頭指針的狀態(tài),然后重新一個一個生成新的 commit,當rebase 創(chuàng)建完最后一個 commit 后,結(jié)束分離頭狀態(tài),Git 讓變完基的分支名指向 HEAD
PS:對于團隊中公用的分支,例如發(fā)布分支等,禁用 rebase,因為這樣會破壞歷史的 commit 信息的,將來要溯源、基于構(gòu)建歷史拉取補丁分支等就會帶來極大不便。
連續(xù)多個 commit 合并
目前 commit 還在本地,沒有 push 到團隊分支上,想要將網(wǎng)頁相關(guān)的 commit 合并成一個,就是從圖中 55a9 開始的6個 commit 合成一個:
變基過程中有可能會遇到?jīng)_突的,只要解決沖突即可,解決沖突的時候,只需要先修改有沖突的文件的內(nèi)容,然后執(zhí)行 git add <file_with_conflict>即可,不要再 git commit,否則多出來 commit 的,然后接著 git base --continue即可,參考簡書-git rebase解決合并沖突
歷史中不連續(xù)的 commit 合并
將歷史中和 readme 相關(guān)的 commit 合并,就是下圖中52af 7e7a 03be 這三個 commit。
最終整理成了兩個 commit:
有意思的發(fā)現(xiàn),有兩個 commit 是沒有祖先的:
如果將 temp 分支、js01 tag 刪掉,Git 會清理掉下面那個樹。
git pull
git pull命令的作用是,取回遠程主機某個分支的更新,再與本地的指定分支合并。它的完整格式稍稍有點復(fù)雜:
git pull <遠程主機名> <遠程分支名>:<本地分支名>比如,取回 origin 主機的 next 分支,與本地的master分支合并:
git pull origin next:master如果遠程分支是與當前分支合并,則冒號后面的部分可以省略:
git pull origin next # 等價于下面兩個命令 git fetch origin git merge origin/next參考:
- 阮一峰-Git遠程操作詳解
git push
git push命令用于將本地分支的更新,推送到遠程主機:
$ git push <遠程主機名> <本地分支名>:<遠程分支名>如果省略遠程分支名,則表示將本地分支推送與之存在"追蹤關(guān)系"的遠程分支(通常兩者同名),如果該遠程分支不存在,則會被新建。
$ git push origin master上面命令表示,將本地的 master 分支推送到 origin 主機的 master 分支。如果后者不存在,則會被新建。
不管是否存在對應(yīng)的遠程分支,將本地的所有分支都推送到遠程主機,這時需要使用 --all 選項:
$ git push --all origingit push 不會推送標簽(tag),除非使用 --tags 選項:
$ git push origin --tags可能會遇到 rejected 的 error,因為遠端包含了一些本地是沒有的變更,比如,創(chuàng)建遠端倉庫時,在遠端倉庫的 master 分支上新建了文件,比如 License,而本地是沒有這次提交的:
把遠端拉取下來:
語法:
git fetch <遠端主機名> <遠端分支名>non-fast-forward 表示,你本地 master 分支的演進不是基于遠端 master 分支進行的,二者是割裂的,經(jīng)過 fetch 之后,通過 gitk --all 可以看到:
解決這個問題,可以通過 rebase 或者 merge 的方式解決,現(xiàn)在先采用 merge 的方式:
上面 fetch 和 merge 方式,和如下 pull 命令等效:
$ git pull github master --allow-unrelated-histories現(xiàn)在合并之后,分支演進如下:
可以看到merge 這種方式新生成的 commit 有兩個父親。
現(xiàn)在重新啟動將本地的 master 分支 push 到遠端:
git push github mastergit rm
從 Git 中移除某個文件,就必須從已跟蹤的文件清單中刪除(從暫存區(qū)域移除文件),然后提交。可以使用 git rm 命令完成此項工作,并連帶從工作目錄中刪除指定的文件,以后這個文件就不會出現(xiàn)在 Git 庫中了。
當我們先把某文件從 Git 庫中刪除(亦即從暫存區(qū)移除),但仍然希望保留在當前工作目錄中。比如當你忘記在.gitignore文件中將一些文件忽略,但是卻不小心把大的日志文件添加到暫存區(qū)域時,這一做法很有用:
# --cached 將 README 文件從暫存區(qū)移除,但是工作區(qū)目錄仍然保留 git rm --cached READMEgit checkout
基于某分支創(chuàng)建新分支:
git checkout -b <new_branch_name> <base_branch_name>這里的 base_branch_name 是指創(chuàng)建分支時的「基」。
- 當省略時,就是基于當前分支創(chuàng)建;
- 當這個「基」是遠端分支名時,就實現(xiàn)了在本地基于遠端分支創(chuàng)建分支。
還可以可以在checkout命令中使用 Hash 值作為起點創(chuàng)建分支:
git checkout -b <name_of_branch> <commit id>除了有“切換”的意思,checkout還有一個撤銷的作用。
舉個例子,假設(shè)我們在一個分支開發(fā)一個小功能,剛寫完一半,這時候需求變了,而且是大變化,之前寫的代碼完全用不了,好在你剛寫,甚至都沒有 git add 進暫存區(qū),這個時候很簡單的一個操作就直接把原文件還原:
git checkout <filename>參考:在git中checkout歷史版本
git log
查看版本演變歷史:
git log --pretty=oneline # 檢查提交日志,都在一行:<commit id> <message> git log --oneline # 與上面命令等價查看某人的提交:
git log --author=michael- 一個常用的選項是-p,用來顯示每次提交的內(nèi)容差異;
- 可以加上-2或者-n2來僅顯示最近兩次提交:
列出最近兩周內(nèi)的提交:
git log --since=2.weeks圖形化查看分支演變:
# 加了 --all 表示查看所有分支的歷史,否則只能看到當前分支的演變歷史 git log --all --graph # 只查看指定分支的演變歷史,比如 temp 分支,此時就不能使用參數(shù) --all git log --oneline --graph temp- git log命令全解析,打log還能這么隨心所欲!
- git-scm 2.3 Git 基礎(chǔ) - 查看提交歷史
遠程倉庫的使用
查看遠程倉庫
git remote -v如果想查看遠程倉庫更多的信息,可以使用git remote show <remote-name>命令。
遠程倉庫的移除與重命名:
git remote rename <old-remote-name> <new-remote-name> git remote rename pb paul如果因為一些原因要移除一個遠程倉庫,可以使用git remote rm <remote-name>。
添加一個新的遠程 Git 倉庫,同時指定一個可以輕松引用的簡寫:
git remote add <remote_host_name> <url>這里的remote_host_name常常取名為origin。所以,常見的origin其實是一個你 Git 倉庫跟蹤的遠程倉庫的簡寫。
拉取遠端倉庫有但你本地沒有的信息:
git fetch <remote_host_name>如果你使用clone命令克隆了一個倉庫,命令會自動將其添加為遠程倉庫并默認以origin為縮寫。
Tag
列出標簽
git tag # 列出所有標簽 git tag -l 'v1.8*' # 列出以 v1.8 開頭的所有標簽創(chuàng)建標簽
Git使用兩種主要類型的標簽:
- 附注(annotated)標簽
- 輕量(ightweight)標簽
前者會包括一些注釋信息,來進一步解釋這個 tag 的作用,而后者就僅僅只是一個 tag 的名字
附注標簽
git tag -a v1.4 -m 'my version 1.4'通過git show <tag-name>命令可以看到標簽信息
輕量標簽
git tag v1.4沒用-a、-m的參數(shù),只需要提供標簽名字
刪除標簽
git tag -d <tagname>補打標簽
假設(shè)忘記給項目打標簽,可以在之后加上:
基于某歷史節(jié)點的commit id補打Tag:
git tag -a v1.2 <commit id>共享標簽
默認情況下,git push命令并不會傳送標簽到遠程服務(wù)器上。在創(chuàng)建完標簽后你必須顯示地推送標簽到共享服務(wù)器上。這個過程就像共享遠程分支一樣,可以運行g(shù)it push origin [tagname]
如果想要一次性推送很多標簽,也可以使用--tags選項的git push:
git push origin --tags檢出標簽
git checkout -b <new_br> <tag_name>參考:
- The Junior Git
- 6 Git 基礎(chǔ) - 打標簽
最后
- Git使用教程筆記
- Pro Git 中文
- Git常用命令備忘
- 掘金-今年下半年,中日合拍的《Git游記》即將正式開機,我將...(上集)
- git術(shù)語解釋staging,index,cache
- pcottle/learnGitBranching 分支演示網(wǎng)站
轉(zhuǎn)載于:https://www.cnblogs.com/michael-xiang/p/10465865.html
總結(jié)
以上是生活随笔為你收集整理的Git 基础 —— 常用命令的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 跋山涉水——深入 Redis 字典遍历
- 下一篇: ES6部分特性小结