Git學習總結

Git學習總結

標籤(空格分隔): git 總結git

1. 基礎 GIT BASICS

1.1 獲取Git倉庫

  • 在已有目錄下初始化倉庫
$ cd path #進入目錄
$ git init #建立.git目錄,含初始化內容

$ git add 文件名 #添加現有文件到暫存區,使用通配符「*」能夠將全部文件都添加進去。支持正則表達式匹配
$ git commit -m"提交註解" #把暫存區的文件都提交到本地倉庫中去
  • 在空目錄下獲取遠程服務器的倉庫
$ git clone URL #獲取URL下的倉庫,會直接下載到當前目錄。若是沒有提早配置git帳號信息,會要求驗證經過纔可下載

$ git clone URL project_new_name #下載遠程倉庫,而且重命名本地的倉庫

也能夠經過SSH方式獲取遠程倉庫,如【user@server:path/to/repo.git】正則表達式

1.2 記錄更新到本地倉庫

  • 查看文件狀態
$ git status #文件狀態包括「未跟蹤」(新建文件就是未跟蹤狀態)、「暫存」、「新建」、「已編輯更改」。注意看列出的詳細解釋。

$ git status -s #做用同上。輸出會有大概如下的內容:
?? a.txt #「??」表示未跟蹤文件
A  b.txt #「A 」已跟蹤文件即已添加到暫存區(注意A右邊有個空格)
 M c.txt #「 M」已修改但未跟蹤(注意M左邊有個空格)
M  d.txt #「M 」已修改且已跟蹤,被添加到暫存區(注意M右邊有個空格)
MM e.txt #已修改且已被跟蹤添加到暫存區後,又被修改了,然後面的更改尚未跟蹤添加暫存區。若是此時提交commit,則只會提交前一次添加到暫存區的內容,新修改不會被提交。
  • 查看提交歷史
$ git log #直接顯示全部提交記錄,含提交時間和提交者

#其餘經常使用的命令
$ git log -p #除了顯示提交時間和提交者外,還顯示提交的註解內容
$ git log --stat #查看提交的統計數據
$ git log --pretty=oneline #以一行輸出提交的信息(部分提交的校驗和、提交註解說明)
$ git log --pretty=format:"%H %cn % ce %s" #格式化輸出提交歷史內容
$ git log -p -n #顯示最近n條提交記錄
$ git log --author=Jack #顯示Jack這個做者(修改文件)相關的記錄
$ git log --committer=Jack #顯示Jack這個提交者(提交文件)提交的記錄
$ git log --before=「2017-12-30」 #顯示2017-12-30以前提交的記錄,「--before」和「--until」同做用
$ git log --after=「2017-12-30」 #顯示2017-12-30以後提交的記錄,「--after」和「--since」同做用
$ git log --grep=「xxx」 #顯示提交註解內容裏和字符串「xxx」相關的提交記錄

其中格式化輸出參數含義以下:數據庫

%H:提交對象(commit)的完整哈希字串
%h:提交對象的簡短哈希字串
%T:樹對象(tree)的完整哈希字串
%t:樹對象的簡短哈希字串
%P:父對象(parent)的完整哈希字串
%p:父對象的簡短哈希字串
%an:做者(author)的名字
%ae:做者的電子郵件地址
%ad:做者修訂日期(能夠用 --date= 選項定製格式)
%ar:做者修訂日期,按多久之前的方式顯示
%cn:提交者(committer)的名字
%ce:提交者的電子郵件地址
%cd:提交日期
%cr:提交日期,按多久之前的方式顯示
%s:提交說明
  • 添加文件到暫存區
$ git add 文件 #可將新建的、已更改的文件添加到暫存區,暫存區的內容能夠被提交到本地倉庫

文件添加到暫存區之後,文件的狀態就又未跟蹤untracked變爲已暫存staged。暫存區其實也只是一個索引文件index,指向相關被跟蹤文件。服務器

  • 忽略特殊文件,不添加到暫存區
$ touch .gitignore #在和.git目錄同級地方新建.gitignore文件
$ vi .gitinore #添加忽略的文件類型,以下。
#臨時的副本文件
*.[oa]
*~

# Eclipse
.classpath
.project
.settings/

# Intellij
.idea/
*.iml
*.iws

# Mac
.DS_Store

# Maven
log/
target/
out/

# Others
bin/
.myeclipse

「*」任意個字符,「**」中間任意目錄,「?」一個字符,「[0-9]」匹配數字0到9,「[abc]」匹配其中一個字符。eclipse

  • 比較文件內容變化
$ git diff #不加參數直接執行該命令

git diff比較的是工做目錄的文件和暫存區的文件之間的差別,若是同一個文件已經被跟蹤添加到了暫存區後又被修改,git diff就會把發生變化的具體內容詳細列出來,很好用。ide

  • 提交更新
    在git add命令後把文件添加到了暫存區,接下來就是要把暫存區的文件提交到本地倉庫中去。
$ git commit -m"本次提交註解說明"

每一次提交都是對本地項目的一個快照,之後能夠回到任何一個快照節點,或者對不一樣快照進行對比。工具

爲了方便,能夠跳過將文件添加到暫存區這一步,直接提交文件到本地倉庫。可是前提條件是這些文件都不是新建的,且以前也已經被跟蹤過,即文件被git add過放到暫存區了,如今作了更改,此時在提交時添加「-a」參數便可讓系統自動添加到暫存區而後一併提交。學習

$ git commit -a -m「本次提交註解說明」

1.3 打標籤 tags

能夠給歷史上任何一次提交打個標籤,說明該次提交的重要性,好比版本發佈時的提交能夠打標籤「v1.0」、「v2.3」等。fetch

$ git tag #列出全部的標籤
$ git tag -l 'v2.3.*' #正則表達式匹配過濾,僅顯示前綴爲「v2.3.」的標籤,根據本身須要能夠更改匹配內容
$ git show 標籤名稱 #列出和標籤相關的提交時的完整信息

$ git tag -a 標籤名稱 -m"關於標籤的描述說明"  #建立一個附註標籤,含提交人和時間等完整信息
$ git tag 標籤名稱 #建立一個輕量標籤,和附註標籤相比,其不含任何信息,只是標記該次提交,即該次提交的引用別名

若是提交已經完成,想要給過去忘了的地方打上標籤,能夠先查看獲得想要打標籤的校驗和或部分校驗和,而後也能夠完成打標籤操做,以下:idea

$ git tag -a 標籤名 校驗和 #在能夠區分其餘提交的時候檢驗和也能夠只是一部分,如可使用完整的校驗和「4682c3261057305bdd616e23b64b0857d832627b」,也可使用前面一部分校驗和「4682c32」 (須要確保惟一)

使用【git push】命令時默認不會把標籤推送到遠程倉庫,須要顯式推送才行。

$ git push [remote_name] [branch_name] 標籤名稱 #推送一個標籤到遠程倉庫
$ git push [remote_name] [branch_name] --tags #推送本地全部的標籤到遠程倉庫

將本地的標籤推送到遠程倉庫以後,其餘人拉取的時候就能夠一同把你推送的標籤獲取下來了。

1.4文件操做

  • 刪除
    狀況1:想要把文件永久刪除,即同時刪除磁盤上的和git本地倉庫內的文件。
$ rm -f 文件名  # -f表示強制執行。先強制刪除磁盤上的文件
$ git -f rm 文件名  # -f表示強制執行。而後強制刪除暫存區內的文件,即從跟蹤文件列表中刪除
$ git commit -m"提交刪除文件xxx" #提交暫存區的變化,即把已刪除文件刪除,再也不歸入版本管理中

狀況2:想要把文件從git本地倉庫刪除,可是保留磁盤上的文件。如不當心把很大的log文件添加到git倉庫,須要從git倉庫中刪除而且不要被跟蹤,可是磁盤上的日誌文件須要保留下來。

$ git rm --cache 文件名  # --cache意思就是刪除暫存區內文件
  • 重命名文件
$ git mv file_old_name file_new_name #重命名文件

上面重命名文件的命令,至關於下面三條命令:

$ mv file_old_name file_new_name # 重命名磁盤上工做目錄的文件
$ git rm file_old_name # 刪除暫存區的文件,即把文件從被跟蹤列表刪除
$ git add file_new_name #從新添加命名後的文件到暫存區,而且標記被跟蹤

注意:git命令中的「mv」並無【移動】文件的功能,不像其餘VCS系統或者Linux系統能夠移動文件的位置。

1.5 撤銷修改 UNDOING CHANGES

  • 反悔了-要從新提交
    要從新修改前一次提交的狀況,好比要新建一個文件(新建後添加到暫存區),或要修改前一次提交的註解內容,或者須要增長提交幾個文件,就能夠執行下面命令:
$ git commit --amend #「撤銷」前一次提交,從新完成提交操做,新提交操做會覆蓋前一次提交

執行命令後會打開文件修改註解內容,默認是vi的方式。上面的命令能夠理解爲「撤銷」前一次提交,從新完成提交操做,新的提交操做會覆蓋前一次提交。

  • 取消暫存的文件
$ git reset HEAD file_name #對文件取消暫存,即取消「git add file_name」的操做。
  • 撤銷對磁盤文件的修改
$ git checkout -- file_name

危險!!上面的操做會直接撤銷磁盤上該文件的全部修改,會回到上次提交的狀態或剛放進工做目錄樣子。【分支】會很好的幫你處理相似的風險問題。
在Git中任何提交過的東西都幾乎能夠恢復,可是未提交的內容不會,因此涉及刪除、撤銷等操做是要格外地注意。

1.6 遠程倉庫 REMOTE REPOSITORIES

  • 查看本地相關聯的遠程倉庫
$ git remote -v # 查看遠程倉庫名稱和URL
$ git remote show [remote-name]  #查看詳細信息
  • 添加遠程倉庫與本地倉庫關聯起來
$ git remote add 起個備註別名 遠程倉庫URL #從此可使用備註別名表明這個遠程倉庫URL進行操做
  • 拉取遠程倉庫數據到本地倉庫
$ git fetch [遠程倉庫備註別名(默認origin)或URL] #不會自動合併本地內容
$ git pull [遠程倉庫備註別名(默認origin)或URL] #會自動合併本地內容

注意git fetch僅僅是拉取遠端倉庫新的數據,並不會自動合併本地內容,須要手動從此合併,而git pull 則會自動合併。

  • 推送本地倉庫到遠程倉庫
$ git push [remote_name] [branch_name]
  • 遠程倉庫重命名和移除
$ git remote rename old_name new_name #重命名遠程倉庫
$ git remote rm remote_name #移除遠程倉庫

1.7 別名

編輯config配置文件來完成別名的設置。

$ git config --global alias.別名名稱 被替代的命令 #被替代的命令若是包含空格須要使用單引號把整個被替代的命令包含起來

舉例:

$ git config --global alias.co checkout #設置後「co」等價於「checkout」
$ git config --global alias.br branch #設置後「br」等價於「branch」
$ git config --global alias.ci commit #設置後「ci」等價於「commit」
$ git config --global alias.st status #設置後「st」等價於「status」
$ git config --global alias.unstage 'reset HEAD --' #取消暫存,設置後「unstage」等價於「reset HEAD --」
$ git config --global alias.last 'log -1 HEAD' #使用last別名查看上一次提交記錄

2 Git分支模型 GIT BRANCHES

每次提交都是一次完整的項目文件快照(以對象的形式),並不是僅記錄變化。每次提交到Git倉庫後,都會建立三類對象:blog對象(文件快照對象)、樹對象(記錄目錄結構和blog對象索引)、提交對象(記錄提交信息、樹對象索引和前一次提交對象/父對象索引)。Git分支,本質上就是僅僅指向提交對象的可變指針。因此建立分支,就只是建立一個可移動的指針。

2.1 分支操做

  • 建立、切換分支
$ git branch 分支名稱 #建立分支

HEAD指針指向當前所在分支。建立新分支後,並不會自動切換到新分支上去,須要手動操做。

$ git checkout 分支名稱 #切換到新分支,這樣後HEAD就會指向切換的分支

若是想要建立分支而且立刻切換過去,可使用下面命令:

$ git checkout -b 新分支名字 #建立分支,而且切換過去
  • 刪除分支
$ git branch -d 分支名稱 #刪除已合併的分支
$ git branch -D 分支名稱 #強制刪除分支(不論是否合併)
  • 合併分支
$ git merge 分支名字 #要先進入到想要合併到的分支,而後再把其餘分支合併進來。能夠把「master」合併到小分支上。

兩個合併的分支中有一個是直接祖先時,會使用「fast-forward」快進合併,僅僅是把指針移動。若是不是直接祖先關係,公共祖先在更加久遠的時刻,這時候要進行三方合併,Git會自動建立合併提交。

衝突解決:當兩個不一樣的分支對同一個文件的同一個地方作了不一樣的修改,合併的時候就會出現衝突。此時須要使用【git status】查看衝突並手動去解決,而後再提交。

  • 分支管理
$ git branch #查看全部分支,僅提示分支名字。當前分支的最前面會有「*」號標記。
$ git branch -v #查看全部分支最近一次提交
$ git branch --merge #查看已經合併到當前分支的全部分支
$ git branch --no-merge #查看尚未合併到當前分支的全部分支

2.2 項目開發分支工做流

項目開發中經常使用分支策略:長期分支、特性分支、遠程分支。

  • 長期分支
    保留主分支做爲項目穩定版本,使用開發分支進行開發和維護。

  • 特性分支
    主分支是穩定版本,能夠根據須要建立特性分支,完成特定的工做內容後能夠隨時刪除。

  • 遠程分支
    遠程服務器上的分支。
$ git fetch origin #拉取遠程服務器上origin倉庫的數據到本地,而且更新本地數據庫,使本地倉庫與遠程倉庫一致
$ git merge origin/分支 #將從遠程倉庫拉取下來的內容,合併到當前分支

從一個遠程跟蹤分支檢出一個本地分支,Git會自動建立一個叫作 「跟蹤分支」。跟蹤分支是本地分支,與遠程分支有直接關係。若是在一個跟蹤分支上輸入git pull,Git 能自動地識別去哪一個服務器上抓取、合併到哪一個分支。

3 重寫Git歷史 REWRITING GIT HISTORY

建議:不要涉及任何已經推送到中央服務器的內容。

  • 修改最後一次提交
    要從新修改最後一次提交的狀況,好比要新建一個文件(新建後添加到暫存區),或要修改前一次提交的註解內容,或者須要增長提交幾個文件,就能夠執行下面命令:
$ git add/rm 文件  #先進行修改
$ git commit --amend #而後「撤銷」前一次提交,從新完成提交操做,新提交操做會覆蓋前一次提交

執行上述操做須要注意,若是已經把提交的內容推送到遠程服務器上面,就不要修正它(從新在前一次提交後的基礎上再提交)。

  • 修改多個提交信息
    經過交互式的變基工具,指定要重寫多久遠的歷史,完成操做。
$ git rebase -i HEAD~n #最後的n是數字,表示要修改最後的n次提交,「-i」爲交互式操做。

注意上面的命令是變基操做,若是提交已經推送到服務器就不要執行,要保證全部內容都是在本地且還沒有推送,不要涉及任何已經推送到中央服務器的提交(會出現一次變動的兩個版本)。
執行上面命令後,根據提示輸入相應的命令來完成修改。

  • 修改提交順序
    命令和前一小節同樣。
$ git rebase -i HEAD~n #最後的n是數字,表示要修改最後的n次提交,「-i」爲交互式操做。

在打開的修改文件中,直接修改相應的提交順序便可,還能夠直接刪除某個提交,當你完成操做保存文件的時候,所作的修改就會生效。
執行上面命令後,根據提示輸入相應的命令來完成修改。

  • 壓縮合並提交
    命令和前一小節同樣。
$ git rebase -i HEAD~n #最後的n是數字,表示要修改最後的n次提交,「-i」爲交互式操做。

第一行的命令關鍵字使用「pick」,其餘行使用「squash」替代「pick」能夠將全部的提交壓縮到第一個提交來完成。
執行上面命令後,根據提示輸入相應的命令來完成修改。

  • 拆分提交
    把一次提交拆分得更細,分幾回來提交完成。
$ git rebase -i HEAD~n #最後的n是數字,表示要修改最後的n次提交,「-i」爲交互式操做。

執行上面命令後,進入提交文件進行修改,要拆分的那個提交的「pick」命令改爲「edit」,而後進行修改及add/commit操做,完成時運行「git rebase --continue」繼續。

  • 修改因此提交歷史 「git filter-branch 」命令能夠經過腳本的方式修改歷史上大量的提交(危險操做!!慎重!)。能夠從歷史上全部提交中移除文件、讓子目錄做爲新的根目錄、全局修改郵箱地址等。
相關文章
相關標籤/搜索