分支的本质是什么?
分支的本质是一个指向某个commit的指针。所以未commit的修改是没有分支的概念的,只有commit才有分支的概念。
下面的命令中我们使用git checkout
来切换分支,新版本的git推荐使用git switch
来切换分支。但是git checkout
命令还有其他功能,比如检出某个版本,所以git switch
命令并不能完全替代git checkout
命令。
Git 命令对比表(checkout
vs switch
/restore
)
操作场景 | git checkout (旧命令) |
git switch (新命令) |
git restore (新命令) |
---|---|---|---|
切换分支 | git checkout <branch> |
git switch <branch> |
- |
创建并切换分支 | git checkout -b <new-branch> |
git switch -c <new-branch> |
- |
切换到上一个分支 | git checkout - |
git switch - |
- |
恢复文件到最新版本 | git checkout -- <file> |
- | git restore <file> |
恢复文件到某提交 | git checkout <commit> -- <file> |
- | git restore --source=<commit> <file> |
丢弃所有未提交修改 | git checkout -- . |
- | git restore . |
检出历史提交 | git checkout <commit> |
- | - |
关键区别
功能分离:
git switch
:仅处理分支切换(更安全)git restore
:仅处理文件恢复(更精准)git checkout
:混合功能(易误操作)
默认行为:
git switch
会阻止有未提交修改时的切换(需加-m
或-f
)git checkout
可能静默覆盖未提交修改
定期同步主分支
我们的项目主分支是main
,我的feature分支由主分支创建而来,以下命令用来从main分支创建feature分支。
1 | git checkout main |
这个feature分支对应的功能比较复杂,需要数周的时间才能完成,所以每天早上来到公司,我都要将main分支上的最新代码同步到feature分支上,以下命令用来将main分支的最新代码同步到feature分支。
这又可以分为两种情况:
情况一:feature分支代码已经commit
如果你在feature分支上做了一些修改,并且已经提交了代码,这时候你想要将main分支的最新代码同步到feature分支上,你可以使用以下命令。
1 | git checkout feature-branch # 确保在feature分支上 |
这时可能会产生冲突,如果你的feature分支和main分支修改了同一个文件的同一个地方,git会提示你冲突,提示信息如下:
1 | CONFLICT (content): Merge conflict in <文件名> |
用VSCode打开冲突的文件,会看到类似下面的提示:
1 | <<<<<<< HEAD |
解决完冲突后,你需要将修改的文件添加到暂存区,然后提交代码。
1 | git add . |
情况二:feature分支代码没有commit
如果你在feature分支上做了一些修改,但是还没有提交代码,这时候你想要将main分支的最新代码同步到feature分支上,你可以使用以下命令。
1 | git stash # 保存当前修改 |
stash pop之后,也可能会产生冲突,和情况一一样,先解决冲突,然后提交修改后的文件即可。
1 | git add . |
注意:这种情况下最好先stash,在pull。如果不尽兴stash操作就直接pull,在有冲突的时候就会失败,提示信息如下:
1 | error: Your local changes to the following files would be overwritten by merge: |
这时候,你要么先commit,然后按照情况一的方式操作,要么先stash,然后按照情况二的方式操作。
操作了错误的分支
这也是一个常见的问题,有时候我们一顿操作猛如虎,然后发现竟然选错了分支,比如你在main分支上做了一大堆修改,想要提交时发现选错了分支,这时候我们需要将main分支的修改挪动到其他分支,然后再恢复main分支。
这也分两种情况:
情况一:修改已经commit
如果你在main分支上的修改已经commit了,这时候你可以使用以下命令将main分支的修改挪动到其他分支。
1 | # 创建feature分支并将修改挪动到feature分支 |
然后就可以提交Pull Request将feature分支的修改合并到main分支了。
情况二:修改没有commit
这种情况比较好办,因为没有commit,所以main分支没有被污染,我们可以直接将修改带到新创建的分支上,这样main分支就恢复了。
1 | # 创建feature分支并将修改挪动到feature分支 |
然后就可以提交Pull Request将feature分支的修改合并到main分支了。
查看配置
- 查看全局配置:
git config --global --list
统一换行符
如果你在使用git的过程中遇到了如下提示:
1 | warning: in the working copy of 'tags/prototype/index.html', LF will be replaced by CRLF the next time Git touches it |
这个问题的根本原因是各个系统上换行符不一致导致的:
- Windows系统使用CRLF换行符。
- Unix/Linux系统使用LF换行符。
- Mac系统早期使用CR换行符,目前使用LF换行符。
可以按照如下方法来解决:
- 禁止git自动转换换行符
1 | git config --global core.autocrlf false |
- 统一使用LF换行符
新建一个文件.gitattributes
,内容如下:
1 | * text=auto eol=lf |
提交此文件,以后所有的文件都会使用LF换行符。这种方式适合团队协作,所有人都使用相同的换行符。
Git学习资源
以下是网上搜集到的用来学习git的资源,闲暇时间可以勤加练习,一定能够熟练掌握git。
- Git Hello world - 新手教程。
- GitHug - 边玩游戏,边学习git。
- Learn Git Branching - 通过图形化的方式学习git分支。
- Git Cheat Sheet - git命令速查表。
- Pro Git Book - git官方文档,内容非常详细。
- GitHub Learning Lab - GitHub官方的学习平台,提供了很多实用的课程。
- GitHub Flow - GitHub的工作流,适合小团队使用。
- Git fight rules - 强推这个!这里总结了实践中遇的高频git问题和解决方案,适合遇到问题时来查阅。