工具准备
操作系统中已安装Git,个人比较喜欢命令行操作,所以即使Windows下也习惯使用Git Bash。
项目准备
选择服务器
需要有一个存放在Git服务器中的项目,不限于Github和CSDN中的CODE。
举例:
git@github.com:username/project.git
或者:
https://github.com/username/project.git
以上是同一个Github项目的SSH和HTTPS两种路径,不赘述。
如果搭建私服,可以使用git init --bare project.git
创建。
创建项目
本文以GitHub项目例:
git@github.com:username/project.git
然后在本地克隆项目代码:
git clone git@github.com:username/project.git
查看项目分支情况可以使用命令git branch
:
$ git branch
* master
可以看到当前项目坐在的分支是master(*号后边为当前所在分支名)。
而且项目目前也只有一个分支,就是master。
团队开发
但是我们在实际项目开发中,通常都是以团队开发为主,所以为了维护线上主干代码的稳定,我们也都会采取创建分支-开发-测试-合并-上线的形式进行实际操作的。所以接下来描述一下简单的团队开发Git项目。
本地分支
工程师Alice需要对原来的代码做改动,这是她需要创建一个分支,名字为develop:
$ git branch develop
$ git branch
develop
* master
这个时候我们看到本地工作区已经有两个分支:master和develop。但当前工作区还是在master上(注意*号位置),需要手动切换到develop上。只需使用git checkout
命令
$ git checkout develop
Switched to branch 'develop'
$ git branch
* develop
master
这样就将当前工作区切换到新的分支中,我们可以发现此时的develop分支中的内容是master的复制。
当然有人希望创建分支后直接切换到新的分支:
$ git checkout -b develop
Switched to a new branch 'develop'
远程分支
现在的develop分支只是存在于Alice的本地环境,当工程师Bob打算协同Alice进行相同业务的开发时,他也需要拿到develop分支的代码,那该怎么获取呢,此时需要Alice将本地分支编程远程分支,以供给其他工程师共同开发。
使用git branch -a
能够查询当前所有分支,包括本地分支和远程分支(下边remotes/origin开头)
$ git branch -a
* develop
master
remotes/origin/HEAD -> origin/master
remotes/origin/master
发现并没有远程分支里并没有新建的develop,这是需要执行git push origin develop
命令,将本地develop分支推送到Git服务器,生成远程分支。
$ git push origin develop
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:username/project.git
* [new branch] develop -> develop
这是再用git branch -a
查看分支。
$ git branch -a
* develop
master
remotes/origin/HEAD -> origin/master
remotes/origin/develop
remotes/origin/master
可以看到多了一个名为remotes/origin/develop
的分支,即为创建的远程分支。
好了,现在Bob和其他任何工程师都可以通过拉取远程分支获取Alice创建的develop分支代码。
Bob先做一次分支查询
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/develop
remotes/origin/master
发现存在remotes/origin/develop
远程分支。
此时只需执行git fetch origin develop:develop
将远程分支代码拉取到本地.。
$ git fetch origin develop:develop
From github.com:username/project
* [new branch] develop -> develop
$ git branch -a
develop
* master
remotes/origin/HEAD -> origin/master
remotes/origin/develop
remotes/origin/master
再通过查询可以看到本地多了一个develop本地分支。
git fetch origin develop:develop
这个命令的意思是将远程develop分支代码拉取到本地develop分支中。这是一个快捷的方式,如果Bob本地没有develop分支,该命令会创建一个名为develop的分支,如果Bob本地有自己的分支,如Bob_dev,则可以执行git fetch origin develop:Bob_dev
或者先切到Bob_dev分支内,执行git fetch origin develop
即可。
多人开发
此时Alice和Bob就可以切到本地develop分支进行开发了(git checkout develop
)。
1. 开发过程中每个工程师在推送代码之前要先执行拉取操作,因为远程仓库有更新的话,不先拉取(pull/fetch)是无法推送(push)的,尽量少使用git pull
进行拉取,而是先用git fetch
拉取在进行git merge
。
2. 在每个开发阶段都及时地提交代码(git commit
)并推送(git push
)至远程仓库,可以使用git status
检查工作区是否还有未处理的代码和文件。在提交代码的时候写好优秀的注释(git commit file -m 'Alice fix bug in filename'
)。
3. 在项目代码将要合并到主干master的时候,要由一名工程师做最后的合并处理,如创建分支的Alice。由于在合并代码时极易产生冲突,所以一定要先与主干代码版本做对比(git diff
),合并时可以使用git merge
,当然如果develop可以废除的话,也可以使用git rebase
做最后的合并。
4. 最后在分支代码合并到主干或者代码上线后,develop分支完成了自己的任务,可以删除本地分支和远程分支。
删除本地分支:
$ git branch -d develop
Deleted branch develop (was 1fe1352).
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/develop
remotes/origin/master
删除远程分支:
$ git push origin --delete develop
To git@github.com:username/project.git
- [deleted] develop
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
解决冲突
在代码的合并阶段(git pull
或者git merge
命令),通常会产生代码冲突。如果是其他工程师造成的冲突,需要转给相关工程师处理,也造成大量的沟通成本。为了减少冲突,建议每个工程师各自单独负责模块,业务互相不冲突。
在解决冲突时,需要使用git log
和git diff
来检查历史版本的修改信息
$ git log README.md
commit 265886db0d6868cc669e0ef253e6e9ac1e39319c
Author: Alice <alice@mail.com>
Date: Sat Apr 30 23:38:27 2016 +0800
chenge readme
commit 1fe13525fa14a4234accd9c345c2a85fd1b30b09
Author: Bob <bob@mail.com>
Date: Sat Apr 30 17:06:12 2016 +0800
Create README.md
git log
可以列出该文件的历史提交版本,能看到提交的版本号和提交的注释信息。
然后使用git diff
来对比该文件两个版本的不同。
$ git diff 265886db0d6868cc669e0ef253e6e9ac1e39319c 1fe13525fa14a4234accd9c345c2a85fd1b30b09 README.md
diff --git a/README.md b/README.md
index a760469..d879d21 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,2 @@
# testRepository
-project Repository
+Test Repository
需要回退到某一版本,可以使用git reset
命令
$ git reset --hard 265886db0d6868cc669e0ef253e6e9ac1e39319c
HEAD is now at 265886d chenge readme
如果文件尚未提交,也可以用git checkout filename
恢复到提交前。
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
$ git checkout README.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
开发规范
git config --global user.name "<用户名>"
。
git config --global user.email "<电子邮件>" 。
- 团队开发禁止在主干直接修改代码,一定要开分支,而且是远程分支进行开发。
- 创建分支可以打标签,
git tag
。 - 拉取代码时最好先
git fetch
再git merge
而不是直接git pull
。 - 提交代码和推送代码以及代码上线之前,一定要先和原来版本对比
git diff
。 - 提交代码加注释
git commit -m 'Bob developed'
。