Git-命令2

git cat-file

git cat-file (-t|-s|-p)  object 顯示 object 的大小,類型,以及內容.git

  • -t 顯示 object 的類型.commit,tag,tree,blob.shell

  • -s 顯示 object 的大小,字節爲單位.編輯器

  • -p 顯示 object 的內容.工具

git branch

git branch [-r] 默認狀況下,僅顯示當前本地擁有的分支.fetch

  • -r 僅顯示本地保存的遠程版本庫的分支列表.優化

git branch <branchName> [<commit>] [--track] 新建一個分支.ui

  • commit 指定了新建分支 branchName 引用的 commit object,默認爲 HEAD.url

  • --track 若 commit 經過一個分支指定,則將 branchName 與 commit 創建追蹤(分支追蹤,見下).spa

git branch (-d|-D) [-r] <branchName> 刪除分支3d

  • -d 若 branchName 已經與其餘分支合併,則刪除該分支.不然不執行刪除操做.

  • -D 老是刪除分支 branchName.

  • -r 代表 branchName 爲遠程版本庫分支,此時將從本地移除遠程版本庫分支 branchName.

$ git branch -r
  origin/Branch
  origin/Branch1
  origin/HEAD -> origin/master
  origin/master
$ git branch -d -r origin/master
已刪除遠程分支 origin/master (曾爲 53bcdd3).

git branch (-m|-M) <oldBranchName> <newBranchName> 將分支 oldBranchName 重命名爲 newBranchName.

  • -m 若 newBranchName 已經存在,則拒絕執行重命名操做.

  • -M 強制重命名,總會執行重命名操做.

分支追蹤

# 將本地分支 master 與遠程版本庫 origin 的 heads/master 分支創建追蹤.    
[branch "master"] 
        remote = origin # 遠程版本庫名.
        merge = refs/heads/master # 遠程版本庫分支.
# 將本地分支 test 與本地分支 master 創建追蹤.
[branch "test"] 
        remote = . # 代表本地版本庫
        merge = refs/heads/master
# 參見 git push/git pull 對以上配置項的使用

git tag

git tag -nN 顯示當前擁有的標籤列表.

  • -nN 對於每個標籤,顯示最多 N 行的標籤註釋.若標籤爲輕量級標籤,則顯示標籤指向 commit object 的註釋.

git tag (-a|-m <message>) [-f]  <tagName> [<commit>] 建立一個重量級標籤 tagName.

  • -a 此時打開默認的編輯器來輸入標籤 tagName 的註釋.

  • -m <message> 此時將標籤 tagName 的註釋指定爲 message.

  • -f 當 <tagName> 已經存在時,仍強制建立標籤.此時效果至關於更新原有的 <tagName> 標籤

  • commit 指定了標籤關聯的 commit object,默認爲 HEAD.

git tag  [-f] <tagName> [<commit>] 建立一個輕量級標籤 tagName.

  • -f 當 <tagName> 已經存在時,仍強制建立標籤.此時效果至關於更新原有的 <tagName> 標籤

git tag -d <tagName> 移除標籤 tagName,標籤在 .git/logs/ 下並無對應的日誌文件,因此一旦刪除,不易恢復.

$ git tag -d Qing
已刪除 tag 'Qing' (曾爲 91d5974)  
# Qing 爲輕量級標籤,因此此時輸出的是標籤對應的 commit object 的 SHA1 值.
$ git tag -d Zhong
已刪除 tag 'Zhong' (曾爲 8898195)
# Zhong 爲重量級標籤,因此此時輸出的是 tag object 自身的 SHA1 哈希值.
# 刪除標籤後,惟一的恢復方法: 就是利用 git tag -d 的輸出從新建立標籤.

git add 

git add [options] 將工做區中新建或者修改後的文件添加到暫存區中.options 可取值:

  • -u 對已經加入到暫存區而且修改的文件調用 git add,對已經加入到暫存後但被刪除的文件調用 git rm .

  • -A 等同於 -u,只不過 -A 會對未加入到暫存區的文件也調用 git add 操做.

  • -v 詳細的輸出.

  • -f 強制添加被忽略的文件.

注意:

  • 當調用 git add 向暫存區添加新的文件,而後調用 git rm 從暫存區刪除文件(或者先調用 git rm,而後再調用 git add),此時暫存區就會比較被刪除文件的內容與新增文件的內容,而後根據差別結果來判斷這到底是一個重命名操做,仍是添加,刪除操做.如:

$ cp README ReadMe
$ git status -s
?? ReadMe        # ReadMe 未被追蹤.
$ git rm README
rm 'README'      # 從暫存區/工做區中移除 README
$ git status -s
D  README
?? ReadMe       
$ git add ReadMe # 將 ReadMe 添加到暫存區中.  
$ git status -s  # 能夠檢測到這是一個重命名操做.
R  README -> ReadMe

git cherry-pick

git cherry-pick <commit> 應用提交 commit.此時 git cherry-pick 的行爲:

  1. 生成 commit->commit object->tree object 相對於 commit^->commit object->tree object 的差別文件.即生成 commit 目錄樹相對於其父提交目錄樹的差別文件.關於

  2. 在當前工做區引用該差別文件.

  3. 更新暫存區,

  4. 建立一個新的提交.

當發生衝突時,停留在第 2 步,此時要作的就是:

  1. 打開引發衝突的文件,並修正衝突(詳見 git merge)

  2. 手動完成第 3,4 步.

git revert

git revert commit 反轉提交 commit.此時 git revert 的行爲:

  1. 生成 commit^->commit object->tree object 相對於 commit->commit object->tree object 的差別文件,即生成 commit 父提交目錄樹相對於 commit 目錄樹的差別文件.

  2. 同 git cherry-pick 的第 2,3,4 步.

當發生衝突時,停留在第 2 步,此時要作的就是:

  1. 打開引發衝突的文件,並修正衝突(詳見 git merge)

  2. 手動完成第 3,4 步.

git rebase

git rebase --onto <newBase> <since> <till> 變基,此時行爲:

  1. git checkout till ;切換到 till,因此 git rebase 後可能會處於分離頭指針狀態.

  2. 將 (since,till] 所包含的提交範圍寫入一個臨時文件中,

  3. git reset --hard newBase;

  4. git cherry-pick 應用 (since,till] 所包含的提交.

當變基遇到衝突後(即 git cherry-pick 遇到衝突時),則在修正衝突後,能夠:

  • git rebase --continue ,繼續變基.

  • git rebase --skip ,跳過此提交.

  • git rebase --abort,就此終止變基操做並切換到變基前的分支.

git commit-tree

git commit-tree [(-p <parent>)...] [(-m <message>)...] [(-F <file>)...] <tree> 基於 tree 指定的 tree object 建立一個 commit object.

  • -p 指定該 commit object 的父提交對象,能夠指定多個,若不指定 -p,則新建的 commit object 沒有父提交,能夠看成根提交.

  • -m <message> 指定提交說明,能夠爲多個.此時每個 <message> 佔據一個段落.

  • -F <file> 從 <file> 中讀取提交說明.若 <file> 爲'-',則代表從標準輸入中讀取提交說明.

$ echo "你好 "|git commit-tree -m "Hello" -m "World" -F - HEAD^{tree}
f02feca314fe4570293ed1ab0e257b3f5898889b # 新建 commit object 的 SHA1 值
$ git cat-file -p f02feca
tree 0ee5a125454857f41e45a586cb87621844cfa725
author WangXiaoWei <1258941862@qq.com> 1401697344 +0800
committer WangXiaoWei <1258941862@qq.com> 1401697344 +0800

Hello     # 一個 -m 佔據一個段落

World

你好      # -F 能夠與 -m 一同指定

git clone

git clone [--bare|--mirror] <repository> <directory>  將版本庫 repository 克隆到目錄 directory 中.

  • --bare 將版本庫<repository>克隆到一個裸版本庫中,此時<directory>的名稱通常之後綴 .git 結尾.

  • --mirror 與 --bare 的不一樣就是見下,如:

$ git clone Git/ Git_bare.git --bare
$ git clone Git/ Git_mirror.git --mirror
$ git diff  Git_bare.git/ Git_mirror.git/
diff --git a/Git_bare.git/config b/Git_mirror.git/config
index 96b01bf..86dc706 100644
--- a/Git_bare.git/config
+++ b/Git_mirror.git/config
@@ -4,3 +4,5 @@
        bare = true
 [remote "origin"]
        url = /root/CCProject/Git/
+       fetch = +refs/*:refs/*
+       mirror = true
# --mirror 對 repository 進行了註冊.
diff --git a/Git_bare.git/packed-refs b/Git_mirror.git/packed-refs
index 72f6723..3125a54 100644
--- a/Git_bare.git/packed-refs
+++ b/Git_mirror.git/packed-refs
@@ -1,5 +1,11 @@
 pack-refs with: peeled fully-peeled 
 e156455ea49124c140a67623f22a393db62d5d98 refs/heads/master
+e156455ea49124c140a67623f22a393db62d5d98 refs/remotes/origin/HEAD
+eea591373e139fc8aab89a78ccb0b1512a2bf0de refs/remotes/origin/maint
+e156455ea49124c140a67623f22a393db62d5d98 refs/remotes/origin/master
+5318336450357c9ecf6ffed2ca846e4c22dbfb7c refs/remotes/origin/next
+2c23f4020ee1398f929c3781c88e9446e28482a4 refs/remotes/origin/pu
+aa5f59252760682ebd536e08b83b70792890ee5a refs/remotes/origin/todo
 d5aef6e4d58cfe1549adef5b436f3ace984e8c86 refs/tags/gitgui-0.10.0
 ^3d654be48f65545c4d3e35f5d3bbed5489820930
 33682a5e98adfd8ba4ce0e21363c443bd273eb77 refs/tags/gitgui-0.10.1
 # --mirror 同時將遠程分支也克隆下來..
 # 好吧,... --bare 與 --mirror 具體差別我不是很清除.

git push

git push [remote-repository] <引用表達式> 將本地引用上傳到遠程版本庫,此時行爲:

string remoteName,remoteUrl,refexp;
if(branch.currentBranch.remote 存在 && 不爲空) /* 肯定遠程版本庫名. */
    remoteName=branch.currentBranch.remote;
else
    remoteName=origin;
    
if(remote.remoteName.pushurl 存在 && 不爲空) /* 肯定遠程版本庫的 url */
    remoteurl=remote.remoteName.pushurl;
else
    remoteurl=remote.remoteName.url;
    
if(remote.remoteName.push 存在 && 不爲空)    /* 肯定引用表達式 */
    refexp=remote.remoteName.push
else 
    refexp=":"; /* 同名分支推送. */

  • 引用表達式: local-ref:remote-ref.共有如下幾種狀況:

    • local-ref:remote-ref 將本地引發 local-ref 上傳爲遠程版本庫引用 remote-ref.

    • :remote-ref 將一個空值推送到遠程版本庫對應的引用.至關於刪除遠程版本庫對應的引用.

    • : 同名分支推送,即對全部在遠程版本庫中有同名分支的本地分支執行推送.

  • -f 強制執行非快進式提交

# 遠程版本庫有分支: b1,b2,b3,b4,master
# 本地版本庫有分支: b1,b2,b3_3,b4_4,master
本地版本庫$ git push origin :
To ../git1/
   f166127..d68d8ef  b2 -> b2
   421c365..e61d632  b1 -> b1
   e21a307..57a8ab4  master -> master
# 即僅上傳了 b1,b2,master 分支.由於他們在遠程版本庫中存在同名分支.
本地版本庫$ git push origin :b3
To ../git1/
 - [deleted]         b3
# 遠程版本庫中 b3 分支被移除了.
遠程版本庫$ git branch
  b1
  b2
  b4
* master

git pull

git pull [遠程版本庫] [引用表達式] [--rebase] 等同於 git fetch 與 git merge/git rebase,即首先將遠程版本庫 remote-repository 上的 local-ref 引用下載下來,而後在當前分支執行變基或者合併操做.行爲:

/* 當調用 git pull,而且沒有指定任何參數時的行爲: */
string remoteName,remoteUrl,refexp;
remoteName=branch.currentBranch.remote 存在 && 不爲空 ? 
    branch.currentBranch.remote : 
    origin;    /* 肯定遠程版本庫名. */
    
remoteUrl=remote.remoteName.url;/* 肯定遠程版本 url */
refexp=remote.remoteName.fetch; /* 肯定引用表達式 */
git fetch remoteName refexp;    /* 調用 git fetch 取得遠程版本庫引用 */
if(branch.currentBranch.merge 存在 && 不爲空)
    if(branch.currentBranch.rebase==true ||
       指定了 --rebase 選項)
        git rebase;/* TODO(此時不是很清除) */
    else
        git merge branch.currentBranch.merge;
else 出錯.

git fetch

git fetch [--no-tags]  [remoteRepository] [+][<引用表達式>] 將遠程版本庫 remoteRepository 的引用下載下來.

  • --no-tags 不下載 tag object,以及 remoteRepository 中 .git/refs/tags 下全部標籤引用.

  • 引用表達式,同 git push

git merge

git merge [--no-commit] <commit> 將<commit>指向的目錄樹與 HEAD 指向的目錄樹合併.此時行爲:

  1. 生成 commit->tree object 相對於 HEAD->tree object 的差別文件

  2. 在工做區應用該差別文件,此時會新建/移除某些文件,而且可能修改某些文件

  3. 更新暫存區

  4. 建立一個新的提交

  • --on-commit 則不執行最後一步,即不建立新的提交.

若在合併過程當中發生衝突,則:

  • 修改引發衝突的文件,而後調用 git add,再 git commit.

樹衝突

  • 因爲文件名修改而致使的衝突.如在提交 A 上重命名: readme->README,在提交 B 上重命名: readme->ReadMe.則將 A 與 B 合併時就會遭遇樹衝突,此時執行 git merge 會提示信息:衝突(重命名/重命名): 在分支 "HEAD" 中重命名 "readme"->"ReadMe",在分支 "XXX" 中重命名 "readme"->"README".修改方式:

$ git status
位於分支 master
您有還沒有合併的路徑.未合併的路徑(酌情使用 "git add/rm <file>..." 標記解決方案):
      由他們添加:  README
      雙方刪除:     ReadMe
      由咱們添加:  readme
$ git rm README ReadMe # 即決定保留 readme.
README: needs merge
ReadMe: needs merge
rm 'README'
rm 'ReadMe'
$ git status 
位於分支 master
您有還沒有合併的路徑.未合併的路徑(使用 "git add <file>..." 標記解決方案):
      由咱們添加:  readme
$ git add readme
$ git status
位於分支 master
全部衝突已解決但您仍處於合併中。
  (使用 "git commit" 結束合併)

git mergetool

git mergetool 調用圖形化工具完成合並.

git init

git init [--bare] [dir] 在目錄 dir 下初始化一個空的版本庫.即建立 .git 目錄.dir 的默認值爲當前目錄.

  • --bare 初始化一個裸版本庫.

git fsck 

git fsck [--no-reflogs] 顯示未被任何引用文件引用的 git object,就像引用記數中,顯示引用記數爲0的 git object.

  • --no-reflogs 不考慮 .git/logs/ 中的引用文件.

$ git reset --hard HEAD^
$ git fsck    # 由於被重置的提交仍被 HEAD@{1} 引用.
Checking object directories: 100% (256/256), done.
$ git fsck --no-reflogs 
Checking object directories: 100% (256/256), done.
dangling commit 4967ff2f88d0f2ad9b8840b4921581be9328cf2e    
# 不考慮 .git/logs 下的引用,則該 commit object 未與任何引用關聯.

git gc

git gc [--aggressive] [--auto] [--no-prune] 執行打包,以及清除未被任何引用引用的 git object,以優化 .git 版本庫所佔內存以及存儲效率,此時 git gc 的行爲:

if(gc.packrefs == true)
    打包全部的引用 ;
git reflog expire --all; /* 清除已通過期的引用日誌,即已經存在 90 天的引用日誌 */
打包鬆散對象; /* 不會打包未被任何引用關聯的鬆散對象 */
清除已經存在 2 周的鬆散對象;
/* 由於此時若 git object 仍以鬆散對象形式存在,則說明該 object 未被任何引用引用. */

  • --aggressive 將致使 git gc 以更多的時間爲代價來優化存儲庫.而且優化的效果是持久的.

  • --auto 通常某些命令在執行完自身任務後會自動調用 git gc --auto.行爲以下:

if(git.auto!=0 && 鬆散對象的數量 > git.auto) 
    將鬆散對象打包進一個單一的包中.
if(git.autopacklimit!=0 && 包的數量 > git.autopacklimit)
    將全部的包(除了那些標有保留的包,those marked with a .keep file)打包進一個單一的包中.
退出.

  • --no-prune 不清除未被任何引用引用的 git object.

git remote

  • 遠程版本庫在本地的記錄,是記錄在 .git/config 配置文件中的,以下; git remote 命令實際上就是修改 .git/config 文件,如 git remote set-url remote url.至關於 git config remote.remote.url url.

[remote "hello-world"]  # 以'hello-world'爲名註冊一個遠程版本庫.
        url = /root/GitShared.git/ # 參見 git pull/git push.
        fetch = +refs/heads/*:refs/remotes/origin/* # 參見 git pull
        pushurl = /root/GitShared.git/  # 參見 git push.

git remote add  [--no-tags] remoteName remoteUrl 添加一個遠程版本庫 remoteName,其 url 爲 remoteUrl.

  • --no-tags 不會將該遠程版本庫的標籤引入到本地版本庫,即調用 git fetch 時,不會下載 tag object 以及 refs/tags/ 下全部引用文件.

git remote set-url [--push]  remoteName url 更改遠程版本庫 remoteName 的 url.即修改 remote.remoteName.url 的取值.

  • --push 此時修改的是 remote.remoteName.pushurl 的取值

git remote rename oldRemoteName newRemoteName 對遠程版本庫重命名: oldRemoteName->newRemoteName

git remote update 遍歷版本庫列表,對於 remote.<版本庫名>.skipDefaultUpdata 不爲真的版本庫調用 git fetch.

git remote rm remoteName 移除名爲 remoteName 的遠程版本庫.

相關文章
相關標籤/搜索