Git 的正确使用姿势与最佳实践:团队协作和版本控制的最佳实践 | 青训营

91 阅读5分钟

Git 的正确使用姿势与最佳实践:团队协作和版本控制的最佳实践

版本控制

2023-05-31-22-46-27.png 增量存储

  • SVN是集中式的,本地不存储版本代码;Git是分布式的,每个库都有完整的提交,支持本地提交
  • Git分支管理方便,方便多人协同
  • Git复杂概念多,SVN简单易上手
  • Git对大文件支持不好(git-lfs)

Git基本概念

git本地有三个工作域:工作区(working directory), 暂存区(stage/index), 资源库(repository)。如果再算上远程服务器上的git仓库(remote directory)就可以分为四个工作域。其关系如下:

2023-08-26-23-54-24.png

  • Workspace: 工作区,就是你平时存放项目代码的地方
  • Index / Stage: 暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
  • Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数 据。其中HEAD指向最新放入仓库的版本
  • Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换

文件的四种状态:

  • Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.
  • Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文 件有两种去处, 如果它被修改, 而变为Modified. 如果使用git rm移出版本库, 则成为Untracked文件
  • Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可 进入暂存staged状态, 使用git checkout 则丢弃修改过,返回到unmodify状态, 这个git checkout即 从库中取出文件, 覆盖当前修改
  • Staged: 暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存,文件状态为Modified

Git基本操作

git init :在当前目录下创建一个新的Git仓库。
git clone :从远程服务器上克隆一个Git仓库到本地。
git add filename :将文件添加到Git仓库的暂存区。
git commit :将暂存区中的文件提交到Git仓库。
git status : 查看仓库状态
git log :查看提交的历史记录
git reflog :查看对仓库的操作日志
git diff HEAD :比较当前内容与最后一次提交的版本的差异。
git checkout filename :放弃对工作区代码的修改。

分支相关:

git branch :列出当前所有的分支。
git checkout :切换到指定的分支。
git merge :将指定分支的代码合并到当前分支中。
git rebase :将当前分支的代码变到指定分支上。

远程相关

git remote
git push :将本地Git仓库中的代码推送到远程服务器上。
git pull :从远程服务器上拉取最新的代码。
git fetch :从远程服务器上拉取最新的代码。
git merge :将远程分支的代码合并到本地分支中

常用命令的细节

这里个人常用到的命令主要是:

设置用户名和邮箱:

git config --global user.name "Your Name"
git config --global user.email "email@example.com"

换行设置:

Windows使用回车和换行两个字符来结束一行,而Mac和Linux只使用换行一个字符

Git可以在你提交时自动地把行结束符CRLF转换成LF,而在签出代码时把LF转换成CRLF。用core.autocrlf来打开此项功能, 如果是在Windows系统上,把它设置成true,这样当签出代码时,LF会被转换成CRLF (如果是仅运行在Windows上的项目,可以设置false取消此功能,把回车符记录在库中)

git config --global core.autocrlf true

Linux或Mac系统使用LF作为行结束符,因此你不想Git在签出文件时进行自动的转换;当一个以CRLF为行结束符的文件不小心被引入时你肯定想进行修正, 把core.autocrlf设置成input来告诉Git在提交时把CRLF转换成LF,签出时不转换:

git config --global core.autocrlf input

与远端仓库连接:

git remote add [shortname] [url]
git remote add origin git@github.com:xxxxx.git  
#SSH
git remote add origin https://github.com/xxx/repo.git
#HTTP

需要注意,使用 SSH 需要配置秘钥,具体操作可以参考

2023-08-27-00-14-16.png

使用 HTTPS 则需要登录,需要输入用户名和密码。Github现在登录不再允许使用密码,这里显示输入密码,实际是输入personal access tokens,输入密码会提示无权限。Token 的创建可以参考, 这里我个人图方便把所有的令牌的权限都勾上了,并且设置过期时间为永久。

2023-08-27-00-16-34.png 2023-08-27-00-25-45.png

克隆远端仓库默认建立连接 同样可以使用 SSH 和 HTTPS

git clone [url]

保存更改,提交 commit, 并推送

git add .                       # 添加全部改动到缓存区
git commit -m "xxx"             # 提交并备注信息
git push -u origin master       # origin 是远端别名 master是本地分支

拉取远端更改并合并:

git pull 相当于 git fetch + git merge

git pull <远程主机名> <远程分支名>:<本地分支名>

git pull origin master 

推送不成功

一般是远端有别的改动推送 强制推送,覆盖远端:

git push -f origin master

或者考虑放弃本地修改,先与远端同步,再重新提交commit

拉取合并不成功:

一般是远端文件与本地冲突,可以考虑放弃本地修改,或者撤销远端提交

放弃本地修改

git checkout -- filepathname (eg: git checkout -- test.md) 
# 放弃掉所有还没有加入到缓存区的修改
git checkout . 

git reset HEAD filepathname (eg: git reset HEAD readme.md)
# 放弃掉所有加入到缓存区但还没commit的修改 然后还需上一步
git reset HEAD . 

放弃本地修改,强制回退到特定commit:

git log
git reset --hard  commitid

2023-08-27-12-17-24.png

撤销远端提交

本地回退 commit,强制提交到远端

git log
git reset --soft commitid
git push origin master --force