git cat-file (-t|-s|-p) object 显示 object 的大小,类型,以及内容.git
-t 显示 object 的类型.commit,tag,tree,blob.shell
-s 显示 object 的大小,字节为单位.编辑器
-p 显示 object 的内容.工具
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 -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 [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 <commit> 应用提交 commit.此时 git cherry-pick 的行为:
生成 commit->commit object->tree object 相对于 commit^->commit object->tree object 的差别文件.即生成 commit 目录树相对于其父提交目录树的差别文件.关于
在当前工做区引用该差别文件.
更新暂存区,
建立一个新的提交.
当发生冲突时,停留在第 2 步,此时要作的就是:
打开引发冲突的文件,并修正冲突(详见 git merge)
手动完成第 3,4 步.
git revert commit 反转提交 commit.此时 git revert 的行为:
生成 commit^->commit object->tree object 相对于 commit->commit object->tree object 的差别文件,即生成 commit 父提交目录树相对于 commit 目录树的差别文件.
同 git cherry-pick 的第 2,3,4 步.
当发生冲突时,停留在第 2 步,此时要作的就是:
打开引发冲突的文件,并修正冲突(详见 git merge)
手动完成第 3,4 步.
git rebase --onto <newBase> <since> <till> 变基,此时行为:
git checkout till ;切换到 till,因此 git rebase 后可能会处于分离头指针状态.
将 (since,till] 所包含的提交范围写入一个临时文件中,
git reset --hard newBase;
git cherry-pick 应用 (since,till] 所包含的提交.
当变基遇到冲突后(即 git cherry-pick 遇到冲突时),则在修正冲突后,能够:
git rebase --continue ,继续变基.
git rebase --skip ,跳过此提交.
git rebase --abort,就此终止变基操做并切换到变基前的分支.
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 [--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 [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 [远程版本库] [引用表达式] [--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 [--no-tags] [remoteRepository] [+][<引用表达式>] 将远程版本库 remoteRepository 的引用下载下来.
--no-tags 不下载 tag object,以及 remoteRepository 中 .git/refs/tags 下全部标签引用.
引用表达式,同 git push
git merge [--no-commit] <commit> 将<commit>指向的目录树与 HEAD 指向的目录树合并.此时行为:
生成 commit->tree object 相对于 HEAD->tree object 的差别文件
在工做区应用该差别文件,此时会新建/移除某些文件,而且可能修改某些文件
更新暂存区
建立一个新的提交
--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 init [--bare] [dir] 在目录 dir 下初始化一个空的版本库.即建立 .git 目录.dir 的默认值为当前目录.
--bare 初始化一个裸版本库.
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 [--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/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 的远程版本库.