0%

git最佳实践及常用技巧

分支的本质是什么?

分支的本质是一个指向某个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> - -

关键区别

  1. 功能分离

    • git switch仅处理分支切换(更安全)
    • git restore仅处理文件恢复(更精准)
    • git checkout:混合功能(易误操作)
  2. 默认行为

    • git switch 会阻止有未提交修改时的切换(需加 -m-f
    • git checkout 可能静默覆盖未提交修改

定期同步主分支

我们的项目主分支是main,我的feature分支由主分支创建而来,以下命令用来从main分支创建feature分支。

1
2
3
git checkout main
git pull
git checkout feature-branch

这个feature分支对应的功能比较复杂,需要数周的时间才能完成,所以每天早上来到公司,我都要将main分支上的最新代码同步到feature分支上,以下命令用来将main分支的最新代码同步到feature分支。

这又可以分为两种情况:

情况一:feature分支代码已经commit

如果你在feature分支上做了一些修改,并且已经提交了代码,这时候你想要将main分支的最新代码同步到feature分支上,你可以使用以下命令。

1
2
git checkout feature-branch # 确保在feature分支上
git pull origin main # 同步main分支的最新代码

这时可能会产生冲突,如果你的feature分支和main分支修改了同一个文件的同一个地方,git会提示你冲突,提示信息如下:

1
2
CONFLICT (content): Merge conflict in <文件名>
Automatic merge failed; fix conflicts and then commit the result.

用VSCode打开冲突的文件,会看到类似下面的提示:

1
2
3
4
5
<<<<<<< HEAD
feature 分支的代码
=======
main 分支的代码
>>>>>>> origin/main

解决完冲突后,你需要将修改的文件添加到暂存区,然后提交代码。

1
2
3
git add .
git commit -m "fix: merge main branch to feature branch"
git push origin feature-branch

情况二:feature分支代码没有commit

如果你在feature分支上做了一些修改,但是还没有提交代码,这时候你想要将main分支的最新代码同步到feature分支上,你可以使用以下命令。

1
2
3
git stash # 保存当前修改
git pull origin main # 拉取最新代码
git stash pop # 恢复当前修改

stash pop之后,也可能会产生冲突,和情况一一样,先解决冲突,然后提交修改后的文件即可。

1
2
3
git add .
git commit -m "fix: merge main branch to feature branch"
git push origin feature-branch

注意:这种情况下最好先stash,在pull。如果不尽兴stash操作就直接pull,在有冲突的时候就会失败,提示信息如下:

1
2
3
error: Your local changes to the following files would be overwritten by merge:
Please commit your changes or stash them before you merge.
Aborting

这时候,你要么先commit,然后按照情况一的方式操作,要么先stash,然后按照情况二的方式操作。

操作了错误的分支

这也是一个常见的问题,有时候我们一顿操作猛如虎,然后发现竟然选错了分支,比如你在main分支上做了一大堆修改,想要提交时发现选错了分支,这时候我们需要将main分支的修改挪动到其他分支,然后再恢复main分支。

这也分两种情况:

情况一:修改已经commit

如果你在main分支上的修改已经commit了,这时候你可以使用以下命令将main分支的修改挪动到其他分支。

1
2
3
4
5
6
7
8
9
10
11
12
# 创建feature分支并将修改挪动到feature分支
git checkout -b feature

# 切回 main 分支并清理工作区
git checkout main
# 丢弃所有未提交的修改(确保 main 分支恢复干净状态)
git reset --hard

# 切回 feature 分支
git checkout feature
# 提交修改
git push origin feature

然后就可以提交Pull Request将feature分支的修改合并到main分支了。

情况二:修改没有commit

这种情况比较好办,因为没有commit,所以main分支没有被污染,我们可以直接将修改带到新创建的分支上,这样main分支就恢复了。

1
2
3
4
5
6
7
# 创建feature分支并将修改挪动到feature分支
git checkout -b feature

# 提交修改
git add .
git commit -m "fix: move changes to feature branch"
git push origin feature

然后就可以提交Pull Request将feature分支的修改合并到main分支了。

查看配置

  1. 查看全局配置: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换行符。

可以按照如下方法来解决:

  1. 禁止git自动转换换行符
1
git config --global core.autocrlf false
  1. 统一使用LF换行符
    新建一个文件.gitattributes,内容如下:
1
* text=auto eol=lf

提交此文件,以后所有的文件都会使用LF换行符。这种方式适合团队协作,所有人都使用相同的换行符。

Git学习资源

以下是网上搜集到的用来学习git的资源,闲暇时间可以勤加练习,一定能够熟练掌握git。