Git 命令使用说明--note

@常见字段说明

1.origin和master

远程仓库名字 “origin” 与分支名字 “master” 一样,在 Git 中并没有任何特别的含义一
样。 同时 “master” 是当你运行 git init 时默认的起始分支名字,原因仅仅是它的广泛
使用, “origin” 是当你运行 git clone 时默认的远程仓库名字

2.如何理解git快照

git中的快照,就是一个备份。每次提交 commit 时 git 会生成 快照 来记录这次commit 时整个项目所有文件的信息。

1.git会把出现变更的文件直接拷贝,形成新的blob,而非与上一个版本的diff。
2.并非每个当前版本都需要做备份,如果没有改变,那么快照其实是链接上一个版本
3.git会在隐藏目录.git里存在object里,定期会优化,保证快照空间,和读取时间的平衡。

如果项目久了后产生的 blob 对象文件越来越多,而每个 blob 对象文件是当前文件的一次全拷贝记录,并非是基于原始文件的差异性记录。git 权衡时间和空间利用率会进行优化存储,保存当前最新版本的整个文件,时间久远或者不经常使用的版本只保存diff,这样就达到了存储空间和读取加载速度的平衡。

1. Git 命令说明

目录结构说明

Git 和其它版本控制系统(包括 Subversion 和近似工具)的主要差别在于 Git 对待数据的方式
Git 更像是把数据看作是对小型文件系统的一系列快照。 在 Git中,每当你提交更新或保存项目状态时,它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引。
为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个 快照流。

在这里插入图片描述

当在一个新目录或已有目录执行 git init 时,Git 会创建一个 .git 目录。 这个目录包含了几乎所有 Git 存储
和操作的东西。 如若想备份或复制一个版本库,只需把这个目录拷贝至另一处即可。 新初始化的 .git 目录的典型结构如下:

config
description
HEAD
hooks/
info/
objects/
refs/

description 文件仅供 GitWeb 程序使用,

config 文件包含项目特有的配置选项。

info 目录包含一个全局性排除(global exclude)文件, 用以放置那些不希望被记录在 .gitignore
文件中的忽略模式(ignored patterns)。

hooks 目录包含客户端或服务端的钩子脚本(hook scripts),

objects 目录存储所有数据内容

refs 目录存储指向数据(分支、远程仓库和标签等)的提交对象的指针;

HEAD 文件指向目前被检出的分支;

index 文件保存暂存区信息。

Git对象

Git 是一个内容寻址文件系统,听起来很酷。但这是什么意思呢? 这意味着,Git 的核心部分是一个简单的键值
对数据库(key-value data store)。 你可以向 Git 仓库中插入任意类型的内容,它会返回一个唯一的键,通过
该键可以在任意时刻再次取回该内容。

可以通过底层命令 git hash-object 来演示上述效果——该命令可将任意数据保存于 .git/objects 目录
(即 对象数据库),并返回指向该数据对象的唯一的键。

$ echo 'test content' | git hash-object -w --stdin
d670460b4b4aece5915caf5c68d12f560a9fe3e4

新建数据 并存入git数据库中

git hash-object 会接受你传给它的东西,而它只会返回可以存储在 Git 仓库中的唯一键

-w 选项会指示该命令不要只返回键,还要将该对象写入数据库中。

–stdin 选项则指示该命令从标准输入读取内容;若不指定此选项,则须在命令尾部给出待存储文件的路径。

此命令输出一个长度为 40 个字符的校验和。 这是一个 SHA-1 哈希值(一个将待存储的数据外加一个头部信息
(header)一起做 SHA-1 校验运算而得的校验和)

$ find .git/objects -type f
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4

查看 objects 目录,那么可以在其中找到一个与新内容对应的文件。 这就是开始时 Git
存储内容的方式——一个文件对应一条内容, 以该内容加上特定头部信息一起的 SHA-1 校验和为文件命名。 校验和的前两个字符用于命名子目录(d6),余下的 38 个字符则用作文件名(70460b4b4aece5915caf5c68d12f560a9fe3e4)。

$ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
test content

使用git cat-file -p 来获取数据

使用git cat-file -t 来查询数据的类型(tree blob commit)

git 把每次提交的内容作为一个快照存入到git对象里。

树对象tree

树对象(tree object),它能解决文件名保存的问题

$ git cat-file -p master^{tree}
100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README
100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile
040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib

master^{tree} 语法表示 master 分支上最新的提交所指向的树对象。 请注意,lib 子目录(所对应的那条
树对象记录)并不是一个数据对象,而是一个指针,其指向的是另一个树对象:

$ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0
100644 blob 47c6340d6459e05787f644c2447d2595f5d3a54b simplegit.rb

操作文件的流程图

在这里插入图片描述
untacked未跟踪的文件
unmodifed 未修改的
Modifed 修改过的文件
Staged 暂存区的文件

修改最后一个提交amend

git commit --amend

修改最后一个提交,修改上次提交。
如果你刚提交后,发现有些错误,或者需要再次提交,可以使用amend,再次提交,它会上次提交合为为一个快照。可以理解为完全用一个 新的提交 替换旧的提交。

$ git commit -m 'initial commit'
//此时发现还有其他错误,继续下面的命令
$ git add forgotten_file
$ git commit --amend

添加远程仓库remote add

git remote add <originname> <url>

添加远程仓库

拉取远程仓库fetch

git fetch <originname>

拉取远程仓库。这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支 的引用,可以随时合并或查看。

将 master 分支推送到 origin 服务器时

git push origin master

git cherry-pick 插入某次提交到另外分支

请添加图片描述
将提交 e43a6 拉取到 master 分支

$ git cherry-pick e43a6
Finished one cherry-pick.
[master]: created a0a41a9: "More friendly message when locking the index
fails."
3 files changed, 17 insertions(+), 3 deletions(-)

在这里插入图片描述
这样会拉取和 e43a6 相同的更改,但是因为应用的日期不同,你会得到一个新的提交 SHA-1 值

git reflog 引用日志

当你在工作时, Git 会在后台保存一个引用日志(reflog), 引用日志记录了最近几个月你的 HEAD 和分支引用
所指向的历史。

git stash

git stash list

//应用哪次的贮藏
git stash apply stash@{0}

//应用储存且删除
git stash pop
//删除单次贮藏
git stash drop stash@{0}

//不仅要贮藏所有已暂存的内容,同时还要将它们保留在索引中(暂存区??)
git stash --keep-index   

git clean 从工作目录中移除未被追踪的文件
git stash --all 来移除每一样东西并存放在栈中

使用 git clean -f -d 命令来移除工作目录中所有未追踪的文件以及空的子目录。

​ -f 意味着“强制(force)”或“确定要移除”,使用它需要 Git 配置变量 clean.requireForce 没有显式设置为 false

如果只是想要看看它会做什么,可以使用 --dry-run 或 -n 选项来运行命令, 这意味着“做一次演习然后告诉你 将要 移除什么”。相当于预览效果

搜索 grep

Git 提供了一个 grep 命令,你可以很方便地从提交历史、工作目录、甚至索引中查找一个字符串或者正则表达式

//匹配的行号(n=--line-number)
git grep -n gmtime_r
//多少个匹配
git grep --count gmtime_r

git grep --break --heading

日志搜索

git log -S ZLIB_BUF_MAX --oneline
//想找到 ZLIB_BUF_MAX 常量是什么时候引入的(什么时候提交的)

修改多个提交信息

为了修改在提交历史中较远的提交,必须使用更复杂的工具。 Git 没有一个改变历史工具,但是可以使用变基工
具来变基一系列提交,基于它们原来的 HEAD 而不是将其移动到另一个新的上面。 通过交互式变基工具,可以
在任何想要修改的提交后停止,然后修改信息、添加文件或做任何想做的事情。 可以通过给 git rebase 增加
-i 选项来交互式地运行变基。 必须指定想要重写多久远的历史,这可以通过告诉命令将要变基到的提交来做
到。
例如,如果想要修改最近三次提交信息,或者那组提交中的任意一个提交信息, 将想要修改的最近一次提交的
243
父提交作为参数传递给 git rebase -i 命令,即 HEAD~2^ 或 HEAD~3。 记住 ~3
可能比较容易,因为你正尝试修改最后三次提交;但是注意实际上指定了以前的四次提交,即想要修改提交的父
提交:

git rebase -i HEAD~3

git log --pretty=format:"%h %s" HEAD~3…HEAD

Tag

git tag //列出所有tag
git tag -l "v1.2.*" //过滤tag

git tag -a v1.4 -m "msg"//创建tag

git show v1.4 //查看tag对应的提交

git log --pretty=oneline//显示log

git tag -a v1.2 9fceb02 //后期给某次提交打标签

默认情况下,tag不会给推送给服务器
git push orgin v1.5 主动推送
git tag -d v1.4 //不会删除远程仓库的tag

git push <remote>:refs/tags/<tagname> 更新远程仓库tag

检出标签
git checkout 2.0

2.分支

Git 保存的不是文件的变化或者差异,而是一系列不同时刻的快照 。在进行提交操作时,Git 会保存一个提交对象(commit object)。 知道了 Git 保存数据的方式,我们可以很自
然的想到——该提交对象会包含一个指向暂存内容快照的指。首次提交产生的提交对象没有父对象,普通提交操
作产生的提交对象有一个父对象, 而由多个分支合并产生的提交对象有多个父对象

git branch dev 创建分支

HEAD指针指向当前所在的本地分支

git checkout dev 切换分支

这样HEAD就指向dev了

git log --oneline --decorate --graph --all
//输出提交历史 各个分支的指向及分支的分叉情况

1.新建和合并

git checkout -b dev 新建并切换到dev

//在dev修改完信息,提交后
git checkout master//切换到主线
git merge dev //把刚才dev的更改合并到主线

//任务完成后,删除分支dev
git branch -d dev

2.冲突时的分支合并

如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们。

$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

可以使用git status 查看哪些文件冲突

$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")

任何因包含合并冲突而有待解决的文件,都会以未合并状态标识出来

<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html

HEAD 所指示的版本(也就是你的 master 分支所在的位置,因为你在运行 merge 命令的时候已经检出
到了这个分支)在这个区段的上半部分(======= 的上半部分),而 iss53 分支所指示的版本在 ======= 的
下半部分。你必须手动选择如何修改此文件,修改完毕后,执行git add .标识着冲突解决。

可以使用图形化工具git mergetool来解决冲突,直观。

3.分支管理

git branch

当前所有分支的一个列表

git branch --merged

git branch --no-merged 哪些分支没有合并到当前分支

如果要查看哪些分支已经合并到当前分支

4.推送

当你想要公开分享一个分支时,需要将其推送到有写入权限的远程仓库上。 本地的分支并不会自动与远程仓库
同步——你必须显式地推送想要分享的分支

git pusn <remote> <branch>
git push origin dev

5.拉取fetch

当 git fetch 命令从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容。 它只会获取数据然
后让你自己合并。 然而,有一个命令叫作 git pull 在大多数情况下它的含义是一个 git fetch 紧接着一个
git merge 命令。

3.变基base(衍合)

在 Git 中整合来自不同分支的修改主要有两种方法:merge 以及 rebase

在这里插入图片描述

整合分支最容易的方法是 merge 命令。 它会把两个分支的最新快照(C3 和 C4)以及二者最近的
共同祖先(C2)进行三方合并,合并的结果是生成一个新的快照(并提交)。

在这里插入图片描述

,还有一种方法:你可以提取在 C4 中引入的补丁和修改,然后在 C3 的基础上应用一次。 在 Git 中,这种
操作就叫做 变基(rebase)。 你可以使用 rebase 命令将提交到某一分支上的所有修改都移至另一分支上

$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command

它的原理是首先找到这两个分支(即当前分支 experiment、变基操作的目标基底分支 master) 的最近共同
祖先 C2,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件, 然后将当前分支指向
目标基底 C3, 最后以此将之前另存为临时文件的修改依序应用。

在这里插入图片描述

现在回到 master 分支,进行一次快进合并。

git checkout master
$ git merge experiment

在这里插入图片描述

此时,C4’ 指向的快照就和 the merge example 中 C5 指向的快照一模一样了。 这两种整合方法的最终结果没
有任何区别,但是变基使得提交历史更加整洁。 你在查看一个经过变基的分支的历史记录时会发现,尽管实际
的开发工作是并行的, 但它们看上去就像是串行的一样,提交历史是一条直线没有分叉。

base高级

在这里插入图片描述

假设你希望将 client 中的修改合并到主分支并发布,但暂时并不想合并 server 中的修改, 因为它们还需要
经过更全面的测试。这时,你就可以使用 git rebase 命令的 --onto 选项, 选中在 client 分支里但不在
server 分支里的修改(即 C8 和 C9),将它们在 master 分支上重放:

$ git rebase --onto master server client

以上命令的意思是:“取出 client 分支,找出它从 server 分支分歧之后的补丁, 然后把这些补丁在
master 分支上重放一遍,让 client 看起来像直接基于 master 修改一样”。这理解起来有一点复杂,不过效
果非常酷。

在这里插入图片描述

现在可以快进合并 master 分支了。(如图 快进合并 master 分支,使之包含来自 client 分支的修改):

$ git checkout master
$ git merge client

在这里插入图片描述

接下来你决定将 server 分支中的修改也整合进来。 使用 git rebase 命
令可以直接将主题分支 (即本例中的 server)变基到目标分支(即 master)上。 这样做能省去你先切换到
server 分支,再对其执行变基命令的多个步骤。

$ git rebase master server

变基的风险

如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。

变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。 如果你已经将提
交推送至某个仓库,而其他人也已经从该仓库拉取提交并进行了后续工作,此时,如果你用 git rebase 命令
重新整理了提交并再次推送,你的同伴因此将不得不再次将他们手头的工作与你的提交进行整合,如果接下来你
还要拉取并整合他们修改过的提交,事情就会变得一团糟。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值