Git 的正确使用姿势与最佳实践:团队协作和版本控制的最佳实践
版本控制
增量存储
- SVN是集中式的,本地不存储版本代码;Git是分布式的,每个库都有完整的提交,支持本地提交
- Git分支管理方便,方便多人协同
- Git复杂概念多,SVN简单易上手
- Git对大文件支持不好(git-lfs)
Git基本概念
git本地有三个工作域:工作区(working directory), 暂存区(stage/index), 资源库(repository)。如果再算上远程服务器上的git仓库(remote directory)就可以分为四个工作域。其关系如下:
- 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 需要配置秘钥,具体操作可以参考。
使用 HTTPS 则需要登录,需要输入用户名和密码。Github现在登录不再允许使用密码,这里显示输入密码,实际是输入personal access tokens,输入密码会提示无权限。Token 的创建可以参考, 这里我个人图方便把所有的令牌的权限都勾上了,并且设置过期时间为永久。
克隆远端仓库默认建立连接 同样可以使用 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
撤销远端提交:
本地回退 commit,强制提交到远端
git log
git reset --soft commitid
git push origin master --force