git常用操作
推荐一个学习git的网站:Learn Git Branching。
本文记录学习git时总结的一些常用操作,如有错误欢迎在评论区指正。下文图中的c0,c1,…cn实际使用中为提交记录的hash值。
分支操作
新建分支:branch和checkout
新建分支 |
此外,自2.23
版本开始,git
添加了switch
命令,用于切换分支:
切换分支 |
合并分支:merge和rebase
将bname分支的内容合并到当前分支 |
下面简要说明下两者间的区别。假设我们当前的开发情况如下,在c1
结点创建了一个dev
分支进行开发。在开发过程中,在main
分支有人提交了代码。此时的提交记录如下图所示:
那么,当我们开发完成后想将代码提交到main
分支时,可以有如下两种方式:
-
merge:
- 切换到
main
分支:git checkout main
- 执行合并:
git merge dev
此时
main
分支就包含了dev
分支上的所有内容。 - 切换到
-
rebase:
在
dev
分支上可以直接使用git rebase main
,将代码提交到main
分支上。可以看到,
dev
本来是以c1提交为基础开发的,而进行rebase
后,git会把dev
分支的代码,以main
分支的最新代码作为起始点,重新生成新的提交。从结果上看,使用rebase
比merge
有更加简单清晰的提交记录。
撤销变更:reset和revert
在讲撤销变更之前,首先说明一下HEAD
和相对引用。
HEAD
一般情况下指向当前分支的最新提交(使用git checkout <hash>
可以将HEAD指向特定提交)。
^
和~
符号是相对引用,其中^
表示上一级提交,有n个^
则表示上n个提交;~
后面更上数字,~n
表示上n个提交。
-
git reset
撤销本地的提交,默认仅回退提交记录,不会删除本地的修改;加上--hard
参数会将本地修改全部删除,要谨慎使用。回退到上个版本
git reset HEAD^
回退到上上上个版本
git reset HEAD~3 -
git revert
是用一个新的提交来声明之前的提交要被撤销。回退到上个版本,注意与reset不同,没有^
git revert HEAD
回退到上上版本
git revert HEAD^
修改提交树:cherry-pick和rebase -i
-
cherry-pick是将一个或几个记录应用到当前分支
将指定记录转移到当前分支
git cherry-pick <hash1> <hash2> ...
指定分支的最新提交转移到当前分支
git cherry-pick <bname> -
rebase加上
-i
参数会打开交互式的提交界面,通过它可以调整提交记录、删除不要的提交、和并提交等。修改最近的两次提交
git rebase -i HEAD~2一般是使用的vim编辑器,通过调整各个记录的顺序可以修改提交顺序,按照下方给出的提示,可以删除、编辑之前的提交记录。
常用操作
暂存修改:stash
如果已经有了修改,又需要切换到其他分支,可以使用stash
暂存已经做出的修改,之后再进行恢复。
暂存修改 |
标签:tag
给指定commit打标签,不指定则默认为当前commit |
想要查询距离某个提交最近的tag,可以使用describe
命令。默认情况下仅会查询带有注释的标签,如果想有查询所有标签则可以加上--tags
参数。
查找距离指定提交最近的标签 |
如果指定的commit处正好有标签,则直接输出标签名,否则输出如下格式的字符串:
# tag-最近的标签名;num-距离该标签的提交数;hash-本次查询的commit的hash |
远程操作
当使用clone
命令从远端克隆一个仓库后,本地会有远程分支origin/master
(具体名字由远程主机和分支名决定),它反映了远程仓库的状态。
拉取:pull
在讲pull
之前,有必要先说明一下fetch
命令,它会从远程仓库下载本地确实的记录,更新本地的远程分支(如origin/master
),它不会更改本地的分支和文件。
默认情况下,git pull
命令是fetch
+merge
的组合,也就可以将本地与远程的文件同步。如果添加--rebase
参数,则使用rebase
来代替默认的merge
操作。
推送:push
基本格式为 remotename source:dest |
-u
为--set-upstream
的缩写,当推送新的分支到远程仓库时,需要该参数建立与远程仓库的关联。
remote_branch
不填,则默认与local_branch
相同。
local_branch
为空时,可以删除远程分支,如git push origin :dev
则会删除远程仓库的dev
分支,但本地的dev
分支不会删除。
同理,使用git fetch origin :dev
会在本地新建dev
分支。
不建议使用以上两种删除和新建分支的方式,因为这会导致本地与远程的分支联系错乱,需要自己重新指定。
其他操作
合并多个提交为一个提交
当在开发过程中,针对同一问题进行了多次提交,如果不想保留历史提交记录而想将之前的多次提交合并为一次提交,则可以使用rebase -i
方便地修改之前的提交记录。
假设之前进行了3次提交,如下所示:
使用git rebase -i HEAD~2
合并第2、3两次提交(rebase
是将指定提交后面的提交进行修改,因此无法合并第1次的提交)。会进入如下界面:
想将3号提交合并到2上,则将3号提交前面的pick
修改为squash
,最终结果为:
pick 7973919 2 |
将修改的文件保存后进入下一步的编辑提交信息的操作。
由于我安装git
时指定了编辑器是vscode,所以这些编辑操作会在vscode中进行,此时修改完成后关闭标签页即可进入到下一步。如果是默认的vim
编辑器,则需要使用wq
进行保存后进入下一步。
编辑提交信息界面如下所示:
可以使用#
将之前的提交信息注释掉,然后添加本次的提交信息,保存即可完成此次合并提交。