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 的远程版本库.

相关文章
相关标签/搜索