[toc]
前言
基础入门,参考廖雪峰老师的git教程
一. git日常操作
git add fileName;
git commit -m ‘提交说明’;
git push -u;//提交到github
git status -s//查看文件状态
git提交文件到github示意图:
二. git提交tag
标签
可以针对某一时间点的版本做标记,常用于版本发布。 也可以是某个重要版本的标识,可标识里程碑版本,可回溯可参考亦可纪念,哈哈。
git tag -a v1.0 -m “Release version 1.0″
详解:
git tag 是命令
-a v1.0是增加 名为v1.0的标签
-m 后面跟着的是标签的注释
git tag
的操作发生在我们commit修改到本地仓库之后。
完整操作流程
- 提交
git add .
git commit -m ‘add tags’
git tag -a v1.0 -m ‘Release version 1.0’
- 推送标签到远程服务器上
默认情况下,git push
并不会把标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库。其命令格式如同推送分支,运行 git push origin [tagname]
即可:
git push origin master
git push origin v1.0
如果要一次推送所有本地新增的标签上去,可以使用 –tags 选项:git push origin --tags
后期追加标签
你甚至可以在后期对早先的某次提交加注标签。比如在下面展示的提交历史中:
$ git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
我们忘了在提交 “updated rakefile” 后为此项目打上版本号 v1.2,没关系,现在也能做。只要在打标签的时候跟上对应提交对象的校验和(或前几位字符)即可:
$ git tag -a v1.2 a6b4c97
切换已有tag
git tag –list // 查看已有tag列表
git checkout [tag/branch/commit] // 切换到指定tag/branch/commit都是此命令
删除tag
git tag -d v1.0
删除远端服务器的标签
git push origin :refs/tags/v1.0
三. git分支
分支
意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。git可以在工作流程中频繁的使用分支与合并。
关于分支
的更多概念理解,参考git api, 这里我只关注常用操作。
创建分支
那么,Git 又是如何创建一个新的分支的呢?答案很简单,创建一个新的分支指针。比如新建一个 testing 分支,可以使用 git branch 命令:
git branch testing
切换分支
要切换到其他分支,可以执行 git checkout 命令。我们现在转换到新建的 testing 分支:
git checkout testing
当然,我们也可以新建并切换到该分支,运行 git checkout
并加上 -b
参数:
$ git checkout -b iss53
Switched to a new branch ‘iss53’
分支的合并
在问题 #53 相关的工作完成之后,可以合并回 master
分支。实际操作同前面合并 hotfix
分支差不多,只需回到 master
分支,运行 git merge
命令指定要合并进来的分支:
$ git checkout master
$ git merge iss53
Auto-merging README
Merge made by the 'recursive' strategy.
README | 1 +
1 file changed, 1 insertion(+)
查看分支合并情况:
git log --graph --pretty=oneline --abbrev-commit
分支删除
既然之前的工作成果已经合并到 master
了,那么 iss53
也就没用了。你可以就此删除它,并在问题追踪系统里关闭该问题。
$ git branch -d iss53
遇到冲突时的分支合并
有时候合并操作并不会如此顺利。如果在不同的分支中都修改了同一个文件的同一部分,Git 就无法干净地把两者合到一起(译注:逻辑上说,这种问题只能由人来裁决。)。如果你在解决问题 #53 的过程中修改了 hotfix
中修改的部分,将得到类似下面的结果:
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
Git 作了合并,但没有提交,它会停下来等你解决冲突。要看看哪些文件在合并时发生冲突,可以用 git status
查阅:
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")\
Unmerged paths:
(use "git add ..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
任何包含未解决冲突的文件都会以未合并(unmerged)的状态列出。Git 会在有冲突的文件里加入标准的冲突解决标记,可以通过它们来手工定位并解决这些冲突。可以看到此文件包含类似下面这样的部分:
<<<<<<< HEAD
=======
>>>>>>> iss53
可以看到 =======
隔开的上半部分,是 HEAD
(即 master
分支,在运行 merge
命令时所切换到的分支)中的内容,下半部分是在 iss53
分支中的内容。解决冲突的办法无非是二者选其一或者由你亲自整合到一起。比如你可以通过把这段内容替换为下面这样来解决:
<div id="footer">
please contact us at email.support@github.com
</div>
这个解决方案各采纳了两个分支中的一部分内容,而且我还删除了 <<<<<<<
,=======
和 >>>>>>>
这些行。在解决了所有文件里的所有冲突后,运行 git add
将把它们标记为已解决状态(译注:实际上就是来一次快照保存到暂存区域。)。因为一旦暂存,就表示冲突已经解决。
利用分支进行开发的工作流程
参考: git api
远程分支
查看远程分支:
git branch -a
**查看本地分支关联(跟踪)的远程分支之间的对应关系:
git branch -vv
git关联本地与远程分支:
git branch –set-upstream-to origin/devtest devtest
注意:git pull
和git merge
区别?git pull
= git fetch
+ git merge
,fetch
和push
命令可以分别对远程分支进行fetch
和push
操作,而pull
不是直接跟远程分支对话的。fetch
同pull
的区别在于:git fetch
:是从远程获取最新版本到本地,不会自动merge
,而git pull
是从远程获取最新版本并merge
到本地仓库。
从安全角度出发,git fetch
比git pull
更安全,因为我们可以先比较本地与远程的区别后,选择性的合并。git push
默认推送到master
,如果有多个分支,则多个分支一起推送到远程。
更多远程操作,查看文章
四. git开发一般流程
上面说的是git的基本操作,那实际项目开发应用实例,我们的做法大致如下(转载,继续完善):
情况一: 远程仓库有master和dev分支
1.克隆代码
> git clone https://github.com/master-dev.git
# 这个git路径是无效的,示例而已
2.查看所有分支
> git branch --all
# 默认有了dev和master分支,所以会看到如下三个分支
# master[本地主分支] origin/master[远程主分支] origin/dev[远程开发分支]
# 新克隆下来的代码默认master和origin/master是关联的,也就是他们的代码保持同步
# 但是origin/dev分支在本地没有任何的关联,所以我们无法在那里开发
3.创建本地关联origin/dev的分支
> git checkout dev origin/dev
# 创建本地分支dev,并且和远程origin/dev分支关联,本地dev分支的初始代码和远程的dev分支代码一样
4.切换到dev分支进行开发
> git checkout dev # 这个是切换到dev分支,然后就是常规的开发
情况二: 假设远程仓库只有mater分支
1.克隆代码
> git clone https://github.com/master-dev.git
# 这个git路径是无效的,示例而已
2.查看所有分支
> git branch --all
# 默认只有master分支,所以会看到如下两个分支
# master[本地主分支] origin/master[远程主分支]
# 新克隆下来的代码默认master和origin/master是关联的,也就是他们的代码保持同步
3.创建本地新的dev分支
> git branch dev # 创建本地分支
> git branch # 查看分支
# 这是会看到master和dev,而且master上会有一个星号
# 这个时候dev是一个本地分支,远程仓库不知道它的存在
# 本地分支可以不同步到远程仓库,我们可以在dev开发,然后merge到master,使用master同步代码,当然也可以同步
4.发布dev分支发布dev分支指的是同步dev分支的代码到远程服务器
> git push origin dev:dev # 这样远程仓库也有一个dev分支了
5.在dev分支开发代码
> git checkout dev # 切换到dev分支进行开发
# 开发代码之后,我们有两个选择
# 第一个:如果功能开发完成了,可以合并主分支
git checkout master # 切换到主分支
git merge dev # 把dev分支的更改和master合并
git push # 提交主分支代码远程
git checkout dev # 切换到dev远程分支
git push # 提交dev分支到远程
# 第二个:如果功能没有完成,可以直接推送
git push # 提交到dev远程分支
# 注意:在分支切换之前最好先commit全部的改变,除非你真的知道自己在做什么
6.删除分支
> git push origin :dev # 删除远程dev分支,危险命令哦
# 下面两条是删除本地分支
git checkout master # 切换到master分支
git branch -d dev # 删除本地dev分支