参考文档:
https://en.wikipedia.org/wiki/Git
Git官网: https://git-scm.com
登录Git官网: https://git-scm.com/ 下载Git for Windows,安装后有3个程序:
推荐使用Git Bash,Git CMD和Git GUI可以忽略。
在Linux/Unix和Mac上使用Git和在Windows上使用Git Bash一样,不再赘述。
现在主流的IDE(比如Intellij Idea和Eclipse) 都对Git有非常好的支持。
推荐通过IDE + Git Bash 方法来使用Git。
如何选择?
- 土豪自己搭建GitHub Enterprise
- Atlassian铁粉用BitBucket
- 中产用GitLab Enterprise
- 屌丝自己搭建GitLab CE (我是屌丝我自豪)
- 最屌丝用国内的代码托管网站…
下图列出了一个简明的Git工作流:
分支的目的为了支持多人、多版本开发。
Git支持多分支开发,并鼓励使用本地多分支,这些分支之间是彼此完全独立的。
参考文档:
这里以GitHub Flow为例 来演示常见的分支操作。
打开GitHub Flow ,点击动画上的不同区域来理解常见的分支操作:
创建分支
提交改动
填写有意义的commit message: what & why
推荐的commit message格式为
,比如:
512: 增加了对NFS的支持
发起合并请求
代码评审和讨论
部署
合并回master分支
GitHub Flow是一种非常好的Git分支策略,但不是唯一的Git分支策略。
在后面的分支策略中会对Git分支策略作深入探讨。
除了查看网上的参考文档之外,还可以在Git Bash中执行git --help
或 git
来查看Git帮助文档。
下面列出常用的Git使用场景。
如果不想让公众都能看到你的代码,需要将repository设置为private,并将相应权限授给团队成员。
强烈推荐为每个repository创建README.md和.gitignore文件。
强烈推荐对repository的public branch进行保护,只有通过merge request才能合并代码进public branch。
GitLab支持SSH和HTTP(S)两种方式。
设置git config的user.name
和 user.email
:
# 查看git config
git config --list
# 设置Global的user.name和user.email
git config --global user.name
git config --global user.email
# 查看git config确认
git config --list
从GitLab上clone一个repository到本地:
# SSH 方式
git clone
# HTTP 方式
git clone
克隆后的缺省分支是GitLab repository上的缺省分支,一般是master分支。
Git创建分支时,缺省从当前分支(base branch)来创建,如果当前分支不是想要的base branch,需要先切换分支。
# 切换当前分支(base branch)
git checkout
# 创建一个新分支,并切换到该分支
git checkout -b
# 更新working directory
git pull
# 改动代码...此处省略2048个字
# 查看working tree状态
git status
# 比较改动前后,查看改动了什么 (用IDE来比较更加直观)
git diff
# 添加新建的文件到Git Stage中
git add
# 或添加全部新建的文件到Git Stage中
git add .
# 提交改动到local repository
git commit -m ""
# 推送到remote repository,创建remote new branch,并设置upstream reference
git push -u origin
如果第一次push时不通过-u
来push新的branch,在git pull
时会提示要先设置upstream reference。
# 设置upstream reference
git branch --set-upstream-to=origin/
之后的push可以不需要再加-u
参数:
git push origin
此时B在git push
时会遇到错误,错误信息为:
error: failed to push some refs to …
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., ‘git pull …’) before pushing again.
hint: See the ‘Note about fast-forwards’ in ‘git push –help’ for details.
B执行git pull
试图自动合并A先前提交的改动,自动合并失败的情况下需要手工合并:
Auto-merging …
CONFLICT (content): Merge conflict in …
Automatic merge failed; fix conflicts and then commit the result.
B打开并编辑发生冲突的文件,手工修改后,保存文件。
参照场景4,重新提交完成合并冲突(合并冲突也是一种改动)的文件到GitLab。
git add
前回退撤销本地改动:
git checkout --
推荐使用IDE的revert功能,更加简单直观。
Intellij Idea: Version Control -> Local Changes -> Right click the file -> Revert
git push
前回退用远程repository强制替换本地文件:
git fetch origin
git reset --hard origin/
推荐使用IDE的Reset功能,更加简单直观。
Intellij Idea: Version Control -> Log -> Right click the last commit marked with remote branch (origin/) -> Reset current branch to here -> Select “Hard”
git push
后回退方法一:
手工回退后,重新提交改动去覆盖remote branch。
方法二:
使用IDE的revert功能。
Intellij Idea: Version Control -> Log -> Right click the commit -> Revert, and then commit and push a “revert commit” to override both remote and local branches.
方法三:
# 查看git commit log,复制要回退的版本commit id
git log --graph --oneline --decorate --all
# 将本地回退到指定版本
git reset --hard
# 查看working tree状态,此时本地落后于远程1个commit
git status
# 强制用本地覆盖远程(危险操作!!)
git push -f origin
# 再次查看working tree状态,此时本地和远程应该同步
git status
推荐使用方法二
方法三比较危险,不推荐使用;强烈建议通过protect branch来防止强制用本地覆盖远程分支。
# 按树形结构显示
git log --graph --oneline --decorate --all [file]
# 按列表显示
git log --pretty=oneline [file]
# 简单粗暴显示
git log [file]
推荐使用IDE的查看历史功能。
Intellij Idea:
用Admin或Owner或Master账号登录,打开指定project -> Settings -> Repository -> Protected Branches
选择要protect的branch (支持wildcard):
参考文档:
https://docs.gitlab.com/ee/user/project/protected_branches.html
在我使用的GitLab CE 10.6.4 貌似有一个bug,当选择”Allowed to
push”为”Masters“时,Developer角色的用户仍然可以push。
这个问题的原因可能是在向gitlab作git push
时,读取的是在Windows上Manage WindowsCredentials中的另一个较高权限的username,所以gitlab才允许作git push
。
参照场景4,创建一个新的本地分支,改动后push到远程的该分支。
然后在GitLab上发起merge request:
GitLab CE貌似不能做到防止自己来merge自己的merge request,这一点和GitHub Enterprise还是有差距的。
所以只能流程上要求大家不要merge自己的merge request。
如果发起merge request后,在该merge request关闭之前,继续往source branch分支push代码,这些commit也会被自动包含在该merge request里。
打开项目,点击左边的Merge Request,选择Open查看Open状态的merge request
点击Commit查看详细信息
点击Changes查看具体的改动
写comment,并和代码提交者讨论。
审查通过后,点击”Merge”按钮
如果审查不通过,写清楚comment,并在和代码提交者讨论后,要求其进行修改。
在GitLab上创建一个同名的空project (不包含任何文件),设置好用户权限。
用Owner/Master角色账号将本地项目push到GitLab:
# 设置Global的user.name和user.email (如果需要)
git config --global user.name
git config --global user.email
# 将本地项目转成Git项目
git init
# 检查对应的remote repository
git remote -v
# 添加远程的remote repository
git remote add origin
# 确认remote repository
git remote -v
# 推送到remote branch
git status
git add .
git commit -m "Inital commit"
git push -u origin
在我使用的GitLab CE 10.6.4 有一个bug,当创建好一个空的项目后,用Owner账号将本地项目作
git push
,会遇到”You are not allowed to push code to this project“的错。这个问题的原因是在向gitlab作
git push
时,读取的是在Windows上Manage Windows Credentials中的另一个错误的username,所以被gitlab拒绝了。解决的方法是,在Manage Windows Credentials中删除原来的credentials,作
git push
时会提示输入用户名和密码,输入owner的用户名和密码后,就可以git push
成功了。这应该是GitLab的一个设计缺陷,也就是GitLab假设在一个GitLab上,你总是只用一个账号来登陆。
参考文档:https://gitlab.com/gitlab-com/support-forum/issues/207
打开GitHub Explore 来查看GitHub上最流行的项目,也可以通过搜索来查看比如最流行的Java项目、最流行的JavaScript项目等等。
国内有一些走歪道的程序员上淘宝买GitHub加star服务(鄙视),所以看到一些流行的中文项目时,要持保留态度。
大部分开源软件都把代码托管在GitHub上,可以通过GitHub来clone开源软件的代码到本地作源代码研读,是提升编程的内功的有效方法。如果想加快clone速度可以在git clone
后加上--depth=1
的参数来只clone最新版本。
你也可以把你的点子变成一个项目放到GitHub上,分享给开源社区。
分支策略就是在哪个分支上开发、在哪个分支上部署、分支同步和分支合并的原则。
项目团队应该遵循统一的分支策略。
现代主流的分支策略包括:
注意:这里讲的分支不包括个人的private branch,不管哪种分支策略都要求先在private branch开发测试后再发起merge request/pull request, 通过代码评审后才能合并进入public branch。
下表对上面的三种现代主流的分支策略进行了比较:
Trunk based development官网将Trunk based development和一些现代主流的分支策略进行了比较:
https://trunkbaseddevelopment.com/alternative-branching-models/
下面这篇文章也详细地论述了比较了不同的分支策略:
https://www.continuousdeliveryconsulting.com/blog/version-control-strategies/
分支策略没有好坏,适合自己的才最重要。
通常的建议是,项目团队选择一种比较符合自己团队的主流分支策略,在实际工作中加以调整,最终发展成符合团队开发节奏的分支策略。
分支越多,复杂度越大,分支同步与分支合并的成本越大,团队内部的沟通成本也越大。
选择分支策略的原则:
前面章节也已经描述了如何作代码评审,这里再对代码评审的一些原则作小结:
不要既当运动员,又当裁判员
审查代码是否满足功能、规范、测试结果、测试覆盖等等
你应该把几乎一切文件都作版本控制,除了:
IDE自动生成的配置文件
空文件夹(如果一定要加入Git,在该目录下添加一个.gitkeep 文件)
使用.gitignore来让Git忽略上述的文件和文件夹。
参考文档: