- 基础命令
- 合并提交
- 变基合并
基础命令
首先,列一下git的基础命令,相信大家对这些基础命令已经特别熟悉了,这里不做详细的介绍。
分支管理
- 查看分支:
git branch
- 创建分支:
git branch <branch name>
- 删除分支:
git branch -d <branch name>
- 切换分支:
git switch <branch name>
- 创建并切换分支:
git switch -c <branch name>
- 合并某分支到当前分支:
git merge <branch name>
- 重命名分支:
git branch -m <old name> <new name>
提交
- 将项目文件添加到暂存区:
git add .
- 提交:
git commit -m <commit message>
推送
推送到远程仓库:git push <remote name> <branch name>
例如:git push origin master
加上-f
参数为强制推送,会直接覆盖掉远程仓库中的代码。
合并提交
合并当前提交
将当前提交合并到上一次提交:git commit --amend -m "commit message"
- 使用场景:在工作中,我们提交一次代码去测试环境测试之后,发现漏了一行代码,或者有个地方没改。
- 普通做法:修改代码,重新提交,推送到内网仓库(公司一般用
Gitlab
),然后再到测试环境测试。 - 存在的问题:明明只是修改了一处地方,却不得不产生一次提交信息。实际上,可以将这次的小修改合并到上一次的提交当中。
- 正确做法:使用`git commit --amend -m "commit message",将本次提交合并到上一次的提交当中。
- 强制推送:由于没有产生新的提交信息,所以在像远程仓库推送的时候,会出错,因此需要加上
-f
参数来强制推送:git push -f origin <branch-name>
合并多次提交
使用场景:多次修改,多次提交,这些提交可以合并成一次提交的情况下使用。
使用交互式的rebase
命令来完成:git rebase -i HEAD~n
输入完命令之后,跳到rebase
的操作信息页面,可以看到当前rebase
操作pick
了几次提交。我们将要与上一次提交合并的提交信息前面的pick
改为s
即可。s是squash的缩写。
举例:
我们合并一个仓库的最后三次提交。
通过git log --oneline
看到,该仓库有四次提交:
1b8a4c0 (HEAD -> master) d
76b3726 c
2d0035f b
6eb0818 a
通过git rebase -i HEAD~3
打开rebase操作信息编辑页面(忽略注释):
pick 2d0035f b
pick 76b3726 c
pick 1b8a4c0 d
提交信息从早到晚按顺序列出,我们将要与上一次合并的提交前面的pick
改为s
,修改结果如下:
pick 2d0035f b
s 76b3726 c
s 1b8a4c0 d
保存退出后,会要求我们修改三次提交的信息。
修改完成再次保存退出后,便完成了合并最后三次提交的操作,通过git log --oneline
查看提交信息:
3b9f7a5 (HEAD -> master) bcd
6eb0818 a
可以看到,我们已经将三次提交合成了一次。
扩展:
在rebase操作信息界面,通过注释,我们能看到rebase还能完成其他的功能:
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
命令列表:
- p,选择提交
- r,重命名某次的提交信息
- e,rebase流程会停在这一次提交,等待纠错,通过
git commit --amend
完成纠错或git rebase --continue
继续rebase - s,将提交合并到上一次提交
- f,与s类型,但是丢弃提交信息
- x,使用shell执行本行后面的命令
- b,在这一行停止rebase,可以通过
git rebase --continue
来继续rebase - d,丢弃提交
- l,给当前HEAD指向的提交打一个标签
- t,将HEAD指针指向一个标签标明的提交
- m,合并几次提交
这些命令可以被重新排序,它们将会按照从上至下的顺序执行。
如果删掉了其中一行,那么那一次的提交将会丢失。
但是,如果清空了全部信息,rebase操作将会被终止。
变基合并
merge 是合并的意思,rebase是复位基底的意思。 现在我们有这样的两个分支,test和master,提交如下:
D---E test
/
A---B---C---F master
在master执行git merge test
然后会得到如下结果:
D--------E
/ \
A---B---C---F---G test , master
在master执行git rebase test
,然后得到如下结果:
A---C---D---E---C `---F` test , master
可以看到merge操作会生成一个新的节点,之前提交分开显示。而rebase操作不会生成新的节点,是将两个分支融合成一个线性的操作。