四、提交与历史
了解了文件的状态,我们对文件进行了必要的修改后,就要把我们所做的修改放入版本库了,这样以后我们就可以在需要的时候恢复到现在的版本,而要恢复到某一版,一般需要查看版本的历史。
提交
提交很简单,直接执行"git commit"。执行git commit后会调用默认的或我们设置的编译器要我们填写提示说明,但是提交说明最好按GIT要求填写:第一行填简单说明,隔一行填写详细说明。因为第一行在一些情况下会被提取使用,比如查看简短提交历史或向别人提交补丁,所以字符数不应太多,40为好。下面看一下查看提交历史。
查看提交历史
查看提交历史使用如下图的命令
如图所示,显示了作者,作者邮箱,提交说明与提交时间,"git log"可以使用放多参数,比如:
仅显示最新的1个log,用"-n"表示。
显示简单的SHA-1值与简单提交说明,oneline仅显示提交说明的第一行,所以第一行说明最好简单点方便在一行显示。
"git log --graph"以图形化的方式显示提交历史的关系,这就可以方便地查看提交历史的分支信息,当然是控制台用字符画出来的图形。
"git log"的更多参数可以查看命令帮助。
不经过暂存的提交
如果我们想跳过暂存区直接提交修改的文件,可以使用"-a"参数,但要慎重,别一不小心提交了不想提交的文件
git commit -a
如果需要快捷地填写提交说明可使用"-m"参数
git commit -m ‘commit message‘
修订提交
如果我们提交过后发现有个文件改错了,或者只是想修改提交说明,这时可以对相应文件做出修改,将修改过的文件通过"git add"添加到暂存区,然后执行以下命令:
git commit --amend
然后修改提交说明覆盖上次提交,但只能重写最后一次提交。
重排提交
通过衍合(rebase)可以修改多个提交的说明,并可以重排提交历史,拆分、合并提交,关于rebase在讲到分支时再说,这里先看一下重排提交。
假设我们的提交历史是这样的:
如果我们想重排最后两个提交的提交历史,可以借助交互式rebase命令:
git rebase -i HEAD~2 或 git rebase -i 3366e1123010e7d67620ff86040a061ae76de0c8
HEAD~2表示倒数第三个提交,这条命令要指定要重排的最旧的提交的父提交,此处要重排Second commit与Third commit,所以要指定Initial commit的Commit ID。如图所示:
注释部分详细说明了每个选项的作用,如果我们想交互这两个提交,只需把开头的这两行交换下位置就OK了,交换位置后保存,然后看下提交历史:
可以看到提交历史已经变了,而且最新的两个提交的Commit ID变了,如果这些提交已经push到了远程服务器,就不要用这个命令了。
删除提交与修改提交说明
如果要删除某个提交,只需要删除相应的行就可以了,而要修改某个提交的提交说明的话,只需要把相应行的pick改为reward。
合并提交-squashing
合并提交也很简单,从注释中的说明看,只需要把相应的行的pick改为squash就可以把这个提交全并到它上一行的提交中。
拆分提交
至于拆分提交,由于Git不可能知道你要做哪里把某一提交拆分开,把以我们就需要让Git在需要拆分的提交处停下来,由我们手动修改提交,这时要把pick改为edit,这样Git在处理到这个提交时会停下来,此时我们就可以进行相应的修改并多次提交来拆分提交。
撤销提交
前面说了删除提交的方法,但是如果是多人合作的话,如果某个提交已经Push到远程仓库,是不可以用那种方法删除提交的,这时就要撤销提交
git revert <commit-id>
这条命令会把指定的提交的所有修改回滚,并同时生成一个新的提交。
Reset
git reset会修改HEAD到指定的状态,用法为
git reset [options] <commit>
这条命令会使HEAD提向指定的Commit,一般会用到3个参数,这3个参数会影响到工作区与暂存区中的修改:
--soft: 只改变HEAD的State,不更改工作区与暂存区的内容
--mixed(默认): 撤销暂存区的修改,暂存区的修改会转移到工作区
--hard: 撤销工作区与暂存区的修改
cherry-pick
当与别人和作开发时,会向别人贡献代码或者接收别人贡献的代码,有时候可能不想完全Merge别人贡献的代码,只想要其中的某一个提交,这时就可以使用cherry-pick了。就一个命令
git cherry-pick <commit-id>
filter-branch
这条命令可以修改整个历史,如从所有历史中删除某个文件相关的信息,全局性地更换电子邮件地址。