这是程序锅对之前学习和使用 Git 做的一份整理,后头继续使用和学习 Git 的话,还会更新这份内容
使用如下命令就可以对最近一次 commit 的 message 进行变更了
git commit --amend
输入如下命令
git rebase -i hash_value # hash_value,是需要的 commit 的父亲 commit 的 hash_value
之后会发生一系列交互
比如你想修改的是 9885fd5 这个 commit 对应的message,那么将 pick 改为 reword 或者 r(看下面的注释信息),然后保存退出。之后就跳到了修改 message 的文档了,在这里输入改变之后的 message 保存退出即可。
★注意:这种方式修改之后会导致该 commit 及后面 commit 的 hash_value 都被改变掉,所以不适合团队集成开发中使用。 ”
输入如下命令,
git rebase -i hash_value # hash_value 是要合并的 commit 的父亲 commit
输入之后会发生一系列的交互,如下所示,
假如我想要把上面两个 commit 合并成一个,需要使用 squash
,版本历史中较早的 commit 在上面,较晚的 commit 在下面,进行合并的话,是把较早的保留,较晚的合并到较早中去,所以要将上述两个 commit 进行合并的话,修改为如下所示,并保存退出
之后会进入另一个交互,在下面填写更改之后的 message 信息,保存退出之后即可。
与上述类似,就是把间隔的 commit 移到一块即可。同样首先是输入如下命令,hash_value 是间隔多个 commit 中的最开始那个 commit 的父亲 commit 的 hash_value
git rebase -i hash_value
之后会进入交互界面,
比如想要合并 760df21 和 2234131 这两个 commit的话,那么修改为如下内容,保存退出即可
之后会进入修改 message 的页面,修改之后保存退出即可
上述都使用了 git rebase
的命令,rebase 的意思是说改变基底,把版本历史中的某些 commit 给修改了。
git rebase origin/master # 把当前分支基于 origin/master 做 rebase 操作,也就相当于把当前分支的东西加到 origin/master 中
git rerere # 记录冲突解决的方式,然后可以在 rebase 的时候反复应用,可以和 rebase 结合用
git rebase --continue
。git reset HEAD
git reset HEAD -- file_name1 file_name2 # 暂存区部分文件变得跟 HEAD 一样
比如一开始的话,HEAD 、暂存区和工作目录都是一样的,都是状态A,并且 readme*.md 文件都已经被跟踪起来了。下面我们修改 readme3.md 文件,之后把它 add 到暂存区。那么这样子工作目录和暂存区都是状态 B,而 HEAD 是状态 A。那么使用上述命令之后,会将暂存区恢复成状态 A。
git checkout -- file_name # 工作目录中指定文件恢复为和暂存区一样
git checkout -- *|. ## 工作目录全部文件恢复为和暂存区一样
git reset --hard hash_value # 把 HEAD、暂存区、工作目录都回滚到 hash_value 所代表的 commit 中。
git reset --hard # 把暂存区里面的修改去掉,也就是让暂存区、工作目录默认恢复到 HEAD 的位置
git checkout
,git reset
git rabase
这个应用在开发中临时加塞了紧急任务的情况,可以把处理了一半,还在工作目录、暂存区的更改状态保存下来。
git stash # 把相应的修改内容给存下来,之后 git status 查看的话又变为什么都没改变的了
git stash list # 查看存下来的内容
git stash apply # 存下来的内容又恢复了,但是存下来的内容还在 stash 中
git stash pop # 存下来的内容恢复了,但是存下来的内容也没了
将两个分支或者两个 commit 进行 merge,merge 之后也会产生一个 commit
git merge branch_name1 branch_name2
git merge hash_value1 hash_value2
git merge --squash # 以 squash 方式进行 merge
在 merge 的过程中有时候会产生冲突,比如两个分支修改或者两个 commit 修改的是同文件的同一区域,那么就会发生冲突,那么会在相应文件冲突的地方有提示,大致如下所示。
<<<<<<< HEAD
windows
=======
root
>>>>>>> origin/master
通过协商和决定之后,确定文件最终内容,同时把上述内容删除。之后 git add
、git commit
即可。
★
”
分离头指针的例子如下所示,上面提到切换到某个分支的用法是
$ git checkout branch_name
那么假如把 branch_name 变成了 hash_value,那么这个就相当于“分离头指针”(PS:个人的理解是相当于创建了一个匿名 branch,这个匿名的 branch 是从 hash_value 的地方分出来的)
$ git checkout hash_value
之后的 commit 都是基于这个分离头指针的位置开始的,这些 commit 都没有基于某个 branch,相当于都是“游离”状态的。那么当切回到某个分支之后,这些 commit 都会被当成垃圾一样清理掉。如果这些 commit 很重要,那么请把这些 commit 跟某个 branch 绑在一起。
另外分类头指针也是可以用的,比如我们先用分离头指针进行一波修改和测试,如果测试不错,那么就把这些修改的 commit 添加成 branch。
git 更多是管理代码的版本控制,而代码构建出来的东西可以不用管理,因为这些是可以复现的。那么 .gitignore 这个文件就是告诉 git 哪些文件不需要被纳入版本控制系统的,也就是相当于会被忽视。
doc # doc 文件和 doc 目录都不会被管理
doc/ # 只指定 doc 目录不会被管理,但是 doc 文件没被说明,假如 doc 在的话,还是会被管理起来的
上面内容的有效范围是在整个项目中,即包括子目录等
★.gitignore 可以借助 github 创建仓库时生成,常用的 .gitignore 如下所示,自己写的时候也值得参考一波:https://github.com/github/gitignore ; 另外想要 git 不管理某些文件,只能在 .gitignore 文件中指定; ”
如果你的 git 仓库是跟其他人一起维护的,那么请注意一下几点:
git push -f
不能使用
-f 是 force 的意思,强制性把本地的 push 上去,就相当于本地的内容强制变成了远端的东西A 在 temp 分支上做 rabase 操作,那么 temp 分支就会和 master 分开。如下图所示,
然而在另一个人,还是基于如下情况做的 commit 等,那么这样,就出现问题了
git 中的对象有三种:commit、tree、blob。下面对这三种对象进行阐述。
每次执行git commit
都会创建一个commit对象,一个 commit 对象只包含一个 tree 对象,这个 tree 对象是 .git
所在父目录的对象, 那么这样子的话,一次 commit 就相当于把当前目录的情况给记录下来了。
目录的对象,那么由于目录中可以包含目录,也可以包含文件,所以 tree 对象可以包含 tree 对象,也可以包含 blob 对象。
blob 是一个文件的具体对象,比如png图像,css文件,这些文件都会对应一个blob对象,可以说是 git 对象中最基本的。另外,blob 跟文件名一点关系都么有,只要文件内容相同,不管文件名叫什么,blob 只有一份。
★新建的Git 仓库中,有且仅有一个 commit,仅仅包含了 /doc/readme,请问内含多少个 tree,多个 blob? 含两个 tree,一个 blob。首先是 git 仓库所在目录是一个 tree (也就是 /doc/readme 的父目录),doc 是一个tree,而 readme 文件是唯一 blob。 ”
git cat-file -t|p|s hash_value # 显示版本库对象的内容,类型及大小信息
git cat-file -t hash_value # 查看版本库对象的类型
git cat-file -p hash_value # 查看版本库对象的内容
git cat-file -s hash_value # 查看版本库对象的大小
HEAD文件的内容显示了 HEAD 当前所指的分支信息,通过下面的内容可以佐证上面 HEAD 说到的一点:HEAD 指向的是某个分支,但通过查看分支文件内容可以发现里面其实是 commit 的 hash_value,也就是说 HEAD 实际指向的是某个commit。
git_head_temp
使用 git checkout
命令之后,查看 HEAD
文件的内容
git_head_chang_to_master
存放本地仓库(local)相关的配置信息,假如之前设置了 local 下的 user.name
,那么会在这个文件中存储相关的内容等信息。修改 config 文件中 user.name
配置项的内容,使用命令查看到的也是修改之后的。
目录中包含的是各分支信息,每一个文件的内容都是 hash value,这个是值是该分支最后一次 commit 的 hash_value 值
.../.git/refs/heads# ls
master temp temp2
.../.git/refs/heads# cat master
9ef147d58eb7e09987cf5ce92254b1600ac92cd9
里面显示的是标签的信息,Git 仓库可以有很多标签,项目开发到一定程度,是一个关键的成果了,比如开发到 v1.0,那可以打上一个标签了。
存放对象的目录。git 中的对象都是由 40 位字符组成,前两位字符用来当 object 目录中子目录名,后 38 位做文件名。