1.同一台电脑存在多个Git账号假设我们在同一台电脑上有多个Git账号,比如公司内部使用Gitlab,个人使用Github或者Gitee。那么你会遇到这样一种情况,你在工作中想要提交代码给你的个人开源项目,但是Git却绑定了公司账号。这种情况下,我们可以让Git绑定多个不同的sshkey,每个sshkey对应不同的Git服务器。生成第一个ssh密钥:ssh-keygen-trsa-C"xxx@xxx.xx"生成第二个ssh密钥:ssh-keygen-trsa-fpath/to/file-C"xxx@xxx.xx"参数-f表示指定生成的文件名,path/to/file为文件名路径,例如~/.ssh/id_rsa_github。执行以上两条命令后,你会得到两对sshkeys。这个时候你还需要在这个目录下创建一个config文件。写入如下内容:Hostgithub.comHostNamegithub.comUsergitIdentityFile~/.ssh/id_rsa_github#私钥文件路径Hostgitlab.comHostNamegitlab.comUsergitIdentityFile~/.ssh/id_rsaHostgitee.comHostNamegitee.comUsergitIdentityFile~/.ssh/的id_rsa_github配置文件的作用是指定私钥文件的位置。然后我们就可以把第一个key配置到公司的Gitlab服务器上,全局设置对应的Git账号和邮箱。gitconfig--globaluser.name"xxx"gitconfig--globaluser.email"xxx@xxx.xx"然后再配置一对sshkey到Github,在计算机名和Github项目中分别配置Git用户电子邮件。gitconfiguser.name"xxx"gitconfiguser.email"xxx@xxx.xx"到目前为止,我们已经完成了。现在可以同时在不同的Gitlab和Github项目上提交代码。2、修改gitcommit中记录的用户名和邮箱地址。假设电脑上同时存在Gitlab和Github项目,并且全局配置了Gitlab用户信息。现在已经拉取了一个新的Github项目,提交了commit并推送到远程仓库。这时发现项目没有配置Github的用户信息,默认使用全局账号Gitlab的用户信息。我们可以使用如下命令修改上次提交的用户信息:gitcommit--amend--author="username"--no-editusername为用户名,<>符号旁边用户邮箱无法删除。修改后执行gitpush-f推送到远程仓库。如果要修改多次commit的用户信息怎么办?可以通过如下代码修改:gitfilter-branch--commit-filter'if["$GIT_AUTHOR_EMAIL"="tanguangzhi@shiqiao.com"];然后GIT_AUTHOR_NAME="woai3c";GIT_AUTHOR_EMAIL="411020382@qq.com";git提交树“$@”;否则gitcommit-tree"$@";fi'HEAD将上面代码中的用户名和email修改后,保存为.sh格式的文件,如edit.sh。然后在项目根目录下执行shedit.sh(右键->GitBashHere->windows下的shedit.sh),然后执行gitpush-f强制推送。3、修改某条历史记录的message假设当前分支有4条commit记录abcd:abcd如果要修改c中记录的message。可以用gitrebase把c记录放到最前面,然后用gitcommit--amend修改它的message。具体操作步骤执行如下命令编辑d记录前面的三个commit:gitrebase-id进入vim编辑界面后,将光标移动到c记录,按dd剪切记录,然后将光标移动到第一行,按p粘贴,然后输入:wq保存。切换顺序后执行gitcommit--amend修改c记录。进入vim编辑界面后,按i修改,再按ESC,再输入:wq保存。最后使用前面提到的gitrebase操作,将c记录恢复到原来的位置。这个过程的执行结果和上图一样。这是修改后当前分支和远程分支的对比。箭头所指的记录消息就是修改后的消息。如果要将修改后的记录同步到远程仓库,此时执行gitpush-f即可。第二种方式是使用gitcheckout-bc从指定的记录中切出一个分支,使用gitcommit--amend修改新分支中的提交信息,使用gitcherry-pick追加b一条记录到新分支(注意这里的bacommit记录是指在原分支上的commit,即原分支上的ba记录被选中添加到新分支,这样新分支上的记录就变成了abc,并且c记录的commitmessage已经在第二步修改过了Exactly)使用gitchecout切换回原来的分支,然后执行gitrebase合并新的分支,最后强制push到远程分支4.选择指定的commit进行合并假设你剪了一个bugFix分支来修复线上的bug,经过一段时间的努力,这个bug终于被修复了。但是为了调试(加了很多调试代码)或者其他原因,bugFix上有很多无用的日志信息。commit3:Fixloginbugcommit2:adddebugstatementcommit1:addconsolestatement例如上面的三个记录,前两个记录添加了很多调试代码,最后一个记录终于修复了bug并删除了调试代码。这时候如果直接合并bugFix分支到master分支,调试记录也会合并。这时候可以使用gitcherry-pick只合并最后一条记录到master分支。或者使用gitrebase将bugFix分支的另外两条记录丢弃,然后合并。5、^和~的区别运算符^和~运算符一样,后面也可以跟数字。~表示最多返回几代记录。但是这个运算符后面的数字和~后面的数字是不一样的。它不是用来指定向上返回多少代,而是用来指定合并提交记录的父记录的数量。默认情况下,Git选择合并提交的“第一个”父级,运算符^后跟一个数字可以覆盖此默认行为。光看文字可能不太容易理解,我们来看几个例子。执行命令gitcheckoutmain^返回到第一条父记录(原来HEAD指向c3,现在指向c1)。执行命令gitcheckoutmain^2返回到第二条父记录(原来HEAD指向c3,现在指向c2)。最后,一个更复杂的例子:GHIJ\/\/DEF\|/\\|/||/|BC\/\/AA==A^0B=A^=A^1=A~1C=A^2=A^2D=A^^=A^1^1=A~2E=B^2=A^^2F=B^3=A^^3G=A^^^=A^1^1^1=A~3H=D^2=B^^2=A^^^2=A~2^2I=F^=B^3^=A^^3^J=F^2=B^3^2=A^^3^2通过这些例子我们也可以发现~n等于n个连续的^。6、gitrevert和gitreset的区别gitreset可以回滚Git的历史。比如当前分支有3条记录,HEAD指向c记录:c<-HEADba如果我们想回滚到b记录,只需要执行gitresetb:b<-HEADa然后用gitpush-f即可rollback版本后的分支强制推送到远程仓库,使本地分支和远程分支同步。gitpush-fgitrevert也可以撤销记录,但是撤销的记录不会消失,这一点和gitreset不同。gitreset撤销的记录就像消失了一样。现在我们用gitrevert重新演示一下之前的操作:cba如果我们执行gitrevertb,会在当前分支上生成一条新的commit记录,变成abcb',这个b'的状态和记录b的是相同。也就是说执行gitresetb后,当前分支记录会变成ab。执行gitrevertb后,当前分支记录会变成abcb'。如果你想让别人知道你已经撤消了,就用gitrevert,因为它会留下撤消的记录,否则就用gitreset。参考资料一台电脑绑定两个git账号(GitHub和GitLab)Git-tools-rewritehistorylearngitbranching