git install
git需要安装2.7或更高的版本, git --version 查看版本号, 如果版本较低,需要升级至高的版本(否则后面克隆仓库会有ssh权限问题)
ssh 权限
在非root用户下操作
在自己的服务器上生成公钥
ssh-keygen, 一路回车,最终在/home/xxx/.ssh/下生成id_rsa.pub
将id_rsa.pub的内容拷贝到git用户的SSH密钥中
clone
现在让我们来看一个简单的分支与合并的例子,来说明日常工作流程。在此之前,你需要克隆(clone)自己的远程仓库。自己的远程仓库,是从公司远程仓库fork出来的,也就是派生出来的。永远不要克隆(clone)公司远程仓库。
克隆自己的远程仓库到本地:
git clone [email protected]:weiyabo/encoder.git
此时,你的工作目录看起来是这样的:
$ git branch -va
* master caeea77 Remove the makefile unused log
现在开始我们的例子:
- 开发某个功能。
- 为实现某个新的需求,创建一个分支。
- 在这个分支上开展工作。 ```
首先创建一个分支。
请时刻理解这段话:从
master
(或
develop
,下同)新建分支,所有的工作都是在新建的分支上隔离完成的 。这样,可以保持master中的代码稳定性,并且可以随时切回到master分支:
$ git checkout -b const_sdi_timestamp
Switched to a new branch 'const_sdi_timestamp'
此时,你的工作目录看起来是这样的:
$ git branch -va
* const_sdi_timestamp caeea77 Remove the makefile unused log
master caeea77 Remove the makefile unused log
开发这个功能
此时,分支*const_sdi_timestamp*和*master*分支处于同一起跑线。你可在新分支 *const_sdi_timestamp*上开发新功能,不必担心master分支被改坏,更不用担心公司仓库被改坏。 经过多次文件修改和提交后,const_sdi_timestamp 分支已经领先于*master*分支。
$ edit some.file
$ git add some.file
$ git commit -m "update some.file"
紧急BUG修复
眼看*const_sdi_timestamp*分支的功能就快要完了,一个噩耗传来,有个刻不容缓的bug 需要被修复。有了git,我们就不需要为这个尴尬的局面而苦恼。此时你只需要回到master 分支,再次从*master*分支为该bug创建一个分支:
$ git checkout master
Switched to branch 'master'
$ git checkout -b bug_9527
Switched to a new branch 'bug_9527'
经过多次文件修改和提交后,bug 9527终于修复完成了:
$ edit bug_9527.file
$ git add bug_9527.file
$ git commit -m "fix bug 9527"
$ git push
代码合并
自己确认bug修复无误后,可以向你的主管提交代码合并。
- 在浏览器上打开你的代码仓库,并切换到公司代码仓库
- 提交合并请求。确认切换到公司代码仓库后,在*合并请求*标签页点击*创建合并请求*按钮。
- 在新弹出的页面,我们在*对比分支*选择*bug_9527*。
- 会在页面上显示分支*bug_9527*的改动内容。确认改动无误,就去填写本次提交的title,点击*创建合并请求*按钮。
- 会跳转到pull页面。将地址栏复制,发给你的主管。
- 主管合并请求后,bug_9527的改动就合并到了公司仓库的*master*分支。
继续你的工作
*bug_9527*已经完成了它的任务,你可以删掉它了。在删除之前,我们还有一些同步工作要做
同步公司代码到你的仓库 *bug_9527*分支已经提交到了公司仓库。而你自己的仓库是从公司仓库fork过来的,并未 包含*bug_9527*分支的改动。此时你需要同步公司代码到你的本地仓库和远程仓库。否则,删除 分支时会报错,提示本地*master*分支merge不完全:
$ git branch -d bug_9527
error: The branch 'bug_9527' is not fully merged.
If you are sure you want to delete it, run 'git branch -D bug_9527'.
添加公司仓库为远程仓库。
检查远程仓库状态
$ git remote -v
origin http://192.168.1.230:3000/weiyabo/encoder.git (fetch)
origin http://192.168.1.230:3000/weiyabo/encoder.git (push)
上述结果表明,当前只有一个远程仓库,即自己从公司fork出来的仓库,并没有添加公司仓库作为远程仓库。
注:git clone或者添加远程分支时,可以用远程分支的ssh链接进行clone或者添加,避免每次都要输入密码。
添加远程仓库:
$ git remote add bravo http://192.168.1.230:3000/bravo_dev/encoder.git
$ git remote -v
bravo http://192.168.1.230:3000/bravo_dev/encoder.git (fetch)
bravo http://192.168.1.230:3000/bravo_dev/encoder.git (push)
origin http://192.168.1.230:3000/weiyabo/encoder.git (fetch)
origin http://192.168.1.230:3000/weiyabo/encoder.git (push)
上述表明,公司远程仓库已添加到本地,名字为bravo
注:git clone或者添加远程分支时,可以用远程分支的ssh链接进行clone或者添加,避免每次都要输入密码。
获取公司仓库的更新:
$ git fetch bravo
remote: Counting objects: 1, done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (1/1), done.
From http://192.168.1.230:3000/bravo_dev/encoder
* [new branch] master -> bravo/master
上述表明,公司仓库确实有一些更新。现在它们已经被download到本地的.git文件夹下了,但是还没有合并到本地的代码中。
合并到本地分支 切换到本地*master*分支:
$ git checkout master
Switched to branch 'master'
将download到本地的公司远程仓库的改动,merge到本地*master*分支:
$ git merge bravo/master
Updating caeea77..b161343
Fast-forward
src/video/live-engine/ingesters/ingester_sdi_decklink_duo.cpp | 1 +
1 file changed, 1 insertion(+)
更新到自己的远程仓库 将本地*master*分支push到自己的远程仓库:
$ git push
Counting objects: 1, done.
Writing objects: 100% (1/1), 259 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To http://192.168.1.230:3000/weiyabo/encoder.git
caeea77..b161343 master -> master
删除你远程仓库中的*bug_9527*分支:
$ git push origin --delete bug_9527
To http://192.168.1.230:3000/weiyabo/encoder.git
- [deleted] bug_9527
使用 git branch 的 -d 选项删除本地*bug_9527*分支:
$ git branch -d bug_9527
Deleted branch bug_9527 (was 3a0874c).
现在你可以回到*const_sdi_timestamp*分支的继续完成被bug_9527打断的工作:
$ git checkout const_sdi_timestamp
Switched to branch 'const_sdi_timestamp'
$ edit some.file
$ git add some.file
$ git commit -m "update some.file"
*const_sdi_timestamp*分支的功能完成之后,便可以像先前提交bug_9527的代码合并一样,提交本次的代码修改。
Rebase操作
在更新您本地的
master
分支时,并在push和pull之前,先进行rebase操作。Rebasing将 合并到你正在操作的分支
master
中,并将您本地进行的提交应用于所有历史提交的最顶 端,而不会去创建额外的merge提交(假设没有冲突的话)。这样可以保持一个漂亮而干 净的历史提交记录。
解决冲突
请确保在pull rebase的时候解决完潜在的冲突。
需求分支删除
merge后删除本地和远程需求分支。如果不删除需求分支,会导致大量僵尸分支存在,会 很混乱。请确保一次性合并到
master
。只有当这个feature需求分支还处于开发中时才 应该存在。
Pull前基本要求
在进行Pull请求之前,请确保您的需求分支已经建立,并已经通过了所有的测试(包括代 码规则检查)。您即将将代码提交到这个稳定的分支。而如果您的需求分支功能测试都失 败了,那您的目标分支构建很可能也会失败。此外,确保在进行pull请求之前应用代码规 则检查。因为它有助于我们代码的可读性,并减少格式化的代码与实际业务代码更改混合 在一起导致的混乱问题。
参考链接
Git-分支的新建与合并
更新fork的repository