Category Archives: Git

Git 使用规范流程

团队开发中,遵循一个合理、清晰的Git使用流程,是非常重要的。

否则,每个人都提交一堆杂乱无章的commit,项目很快就会变得难以协调和维护。

下面是ThoughtBot 的Git使用规范流程。我从中学到了很多,推荐你也这样使用Git。

第一步:新建分支

首先,每次开发新功能,都应该新建一个单独的分支(这方面可以参考《Git分支管理策略》)。

第二步:提交分支commit

分支修改后,就可以提交commit了。

git add 命令的all参数,表示保存所有变化(包括新建、修改和删除)。从Git 2.0开始,all是 git add 的默认参数,所以也可以用 git add . 代替。

git status 命令,用来查看发生变动的文件。

git commit 命令的verbose参数,会列出 diff 的结果。

第三步:撰写提交信息

提交commit时,必须给出完整扼要的提交信息,下面是一个范本。

第一行是不超过50个字的提要,然后空一行,罗列出改动原因、主要变动、以及需要注意的问题。最后,提供对应的网址(比如Bug ticket)。

第四步:与主干同步

分支的开发过程中,要经常与主干保持同步。

第五步:合并commit

分支开发完成后,很可能有一堆commit,但是合并到主干的时候,往往希望只有一个(或最多两三个)commit,这样不仅清晰,也容易管理。

那么,怎样才能将多个commit合并呢?这就要用到 git rebase 命令。

git rebase命令的i参数表示互动(interactive),这时git会打开一个互动界面,进行下一步操作。

下面采用Tute Costa的例子,来解释怎么合并commit。

上面的互动界面,先列出当前分支最新的4个commit(越下面越新)。每个commit前面有一个操作命令,默认是pick,表示该行commit被选中,要进行rebase操作。

4个commit的下面是一大堆注释,列出可以使用的命令。

  • pick:正常选中
  • reword:选中,并且修改提交信息;
  • edit:选中,rebase时会暂停,允许你修改这个commit(参考这里
  • squash:选中,会将当前commit与上一个commit合并
  • fixup:与squash相同,但不会保存当前commit的提交信息
  • exec:执行其他shell命令

上面这6个命令当中,squash和fixup可以用来合并commit。先把需要合并的commit前面的动词,改成squash(或者s)。

这样一改,执行后,当前分支只会剩下两个commit。第二行和第三行的commit,都会合并到第一行的commit。提交信息会同时包含,这三个commit的提交信息。

如果将第三行的squash命令改成fixup命令。

运行结果相同,还是会生成两个commit,第二行和第三行的commit,都合并到第一行的commit。但是,新的提交信息里面,第三行commit的提交信息,会被注释掉。

squash和fixup命令,还可以当作命令行参数使用,自动合并commit。

这个用法请参考这篇文章,这里就不解释了。

第六步:推送到远程仓库

合并commit后,就可以推送当前分支到远程仓库了。

git push命令要加上force参数,因为rebase以后,分支历史改变了,跟远程分支不一定兼容,有可能要强行推送(参见这里)。

第七步:发出Pull Request

提交到远程仓库以后,就可以发出 Pull Request 到master分支,然后请求别人进行代码review,确认可以合并到master。

from:http://www.ruanyifeng.com/blog/2015/08/git-use-process.html

Git版本控制与工作流

这篇文章是针对git版本控制和工作流的总结,如果有些朋友之前还没使用过git,对git的基本概念和命令不是很熟悉,可以从以下基本教程入手:

  • 专为设计师而写的GitHub快速入门教程
  • git – 简明指南
  • 学习Git的在线互动教程

基本概念

Git是什么?

Git是分布式版本控制系统,与SVN类似的集中化版本控制系统相比,集中化版本控制系统虽然能够令多个团队成员一起协作开发,但有时如果中央服务器宕机的话,谁也无法在宕机期间提交更新和协同开发。甚至有时,中央服务器磁盘故障,恰巧又没有做备份或备份没及时,那就可能有丢失数据的风险。

但Git是分布式的版本控制系统,客户端不只是提取最新版本的快照,而且将整个代码仓库镜像复制下来。如果任何协同工作用的服务器发生故障了,也可以用任何一个代码仓库来恢复。而且在协作服务器宕机期间,你也可以提交代码到本地仓库,当协作服务器正常工作后,你再将本地仓库同步到远程仓库。

为什么要使用Git

  • 能够对文件版本控制多人协作开发
  • 拥有强大的分支特性,所以能够灵活地以不同的工作流协同开发
  • 分布式版本控制系统,即使协作服务器宕机,也能继续提交代码或文件到本地仓库,当协作服务器恢复正常工作时,再将本地仓库同步到远程仓库。
  • 当团队中某个成员完成某个功能时,通过pull request操作来通知其他团队成员,其他团队成员能够review code后再合并代码。

Git有哪些特性

  • 文件三种状态(modified, staged, committed)
  • 直接记录快照,而非差异比较
  • 多数操作仅添加操作
  • 近乎所有操作都是本地执行
  • 时刻保持数据完整性

有关以上特性的详细解释,请查看Pro git的git基础章节

Git基本工作流程

  1. 在git版本控制的目录下修改某个文件
  2. 使用git add命令对修改后的文件快照,保存到暂存区域
  3. 使用git commit命令提交更新,将保存在暂存区域的文件快照永久转储到 Git 目录中

Git基本技巧

  • 自动补全
  • Git 命令别名

关于具体如何使用自动补全和命名别名技巧,请查看Pro git的技巧和窍门

Git版本控制

创建仓库

  • git init
  • git clone
  • git config

保存修改

  • git add
  • git commit

查看仓库

  • git status
  • git log –oneline

撤销修改

查看之前的commit
  • git checkout <commit> <file>
  • git checkout <commit>
  • git checkout <branch>
撤销公共修改
  • git revert <commit>
撤销本地修改
  • git reset
  • git clean

重写Git历史记录

  • git commit –amend
  • git rebase
  • git reflog

Git协作开发

分支

  • git branch
  • git checkout
  • git merge

仓库同步

  • git remote
  • git fetch
  • git pull
  • git push

Git工作流

由于git拥有强大的分支特性,它的工作流比较灵活而缺乏约束,于是参考Atlassian Git Tutorial的Comparing Workflows章节提供四种Git工作流

  • Centralized Workflow
  • Feature Branch Workflow
  • Gitflow Workflow
  • Forking Workflow

以上工作流只是参考指南,而不是具体规则。你可以根据自己实际情况来选择适合自己的工作流或微调来满足自己的需要。

Centralized Workflow

过渡到分布式版本控制系统看起来像一个艰巨的任务,但如果你充分利用好git的话,你不必改变你既有的工作流,你的团队可以采用与之前使用SVN一样的方式来开发项目。

如何工作

6941baebjw1esuqsmka98j20tm0yagmx

Centralized Workflow

  1. 从远程仓库(central repository)克隆工程到本地仓库(local repository) — git clone
  2. 在本地仓库编辑文件和提交更新 — git addgit commit
  3. fetch远程仓库已更新的commit到本地仓库和rebase到已更新的commit的上面 —git fetchgit rebase 或 git pull --rebase
  4. push本地主分支(master branch)到远程仓库 — git push

管理冲突

6941baebjw1esuqsli4y0j20ro0ho758

File Conflicts

  • 何时发生冲突:在开发者发布它们功能之前,他们需要fetch远程仓库已更新的commit到本地仓库和rebase到已更新的commit的上面。有时,本地提交与远程提交会发生冲突,git会暂停rebase过程来让你手动解决冲突。
  • 如何解决冲突:你可以使用git statusgit add来手动解决合并时冲突。

Feature Branch Workflow

Feature Branch Workflow的主要思想就是在开发每个功能时都应该创建一个独立的分支而不只是使用主分支。由于每个分支是独立且互不影响,这就意味着主分支不会包含broken code,对持续集成环境是很有帮助的。

如何工作

6941baebjw1esuqskspf8j20yg0byq3h

Feature Branch Workflow

  1. 仍然使用远程仓库(central repository)和主分支(master branch)仍记录官方工程的历史
  2. 开发者每次开发新功能时都创建一个新分支 — git checkout -b
  3. Feature branches应该推送到远程仓库(central repository) — git push
  4. 发送pull request来请求管理员能否合并到主分支(master branch)
  5. 发布新功能到远程仓库(central repository)

Pull Request

Pull request是一种当开发者完成一个新功能后向其他团队成员发送通知的机制。它的使用过程如下:

  • 开发者可以通过Github或Bitbucket发送pull request

6941baebjw1esuqsk1e8nj20yg0c0tbk

Pull request on Github

  • 其他的团队成员审查、讨论和修改代码
  • 项目维护者合并新增功能分支到主分支(master branch),然后关闭pull request

Gitflow Workflow

Feature Branch Workflow是一种非常灵活的开发方式。对于一些规模比较大的团队,最好就是给特定的分支赋予不同的角色。除了功能分支(feature branch),Gitflow Workflow还使用独立的分支来准备发布(preparing)维护(maintaining), 和记录版本(recording releases)。下面我会逐个介绍这个几个分支:Historical Branches、Feature Branches、Release Branches和Maintenance Branches。

Historical Branches

6941baebjw1esuqsji8e2j20x80dyab0

Historical Branches

  • master分支保存官方发布历史
  • develop分支衍生出各个feature分支

Feature Branches

6941baebjw1esuqshwkhnj20xy0jwmyx

Feature Branches

  • feature分支使用develop分支作为它们的父类分支
  • 当其中一个feature分支完成后,它会合并会develop分支
  • feature分支应该从不与master分支直接交互

Release Branches

6941baebjw1esuqsfj7tgj20xs0mwmzg

Release Branches

  • release分支主要用来清理释放、测试和更新文档
  • 一旦develop分支获得足够的功能来发布时,你可以从develop衍生出一个release分支
  • 一旦准备好上架,release合并到master分支并且标记一个版本号
  • 另外,还需要合并回develop分支

Maintenance Branches

6941baebjw1esuqsejflhj20y20p6wh5

Maintenance Branches.png

  • maintenance分支用来快速给已发布产品修复bug或微调功能
  • 它从master分支直接衍生出来
  • 一旦完成修复bug,它应该合并回master分支和develop分支
  • master应该被标记一个新的版本号

标记Tags

使用两个命令来给master分支标记版本号:

  • git tag -a 0.1 -m "Initial public release" master
  • git push origin master --tags

Forking Workflow

Forking Workflow与以上讨论的工作流很不同,一个很重要的区别就是它不只是多个开发共享一个远程仓库(central repository),而是每个开发者都拥有一个独立的服务端仓库。也就是说每个contributor都有两个仓库:本地私有的仓库和远程共享的仓库。

6941baebjw1esuqsdhl51j20ui0j8ace

Forking Workflow

Forking Workflow这种工作流主要好处就是每个开发者都拥有自己的远程仓库,可以将提交的commits推送到自己的远程仓库,但只有工程维护者才有权限push提交的commits到官方的仓库,其他开发者在没有授权的情况下不能push。Github很多开源项目都是采用Forking Workflow工作流。

如何工作

  1. 在服务器上有一个官方公共的仓库
  2. 开发者fork官方仓库来创建它的拷贝,然后存放在服务器上6941baebjw1esuqs7u6n5j20wy0eswfvFork official repository.png
  3. 当开发者准备好发布本地的commit时,他们push commit到他们自己的公共仓库
  4. 在自己的公共仓库发送一个pull request到官方仓库
  5. 维护者pull贡献者的commit到他自己的本地仓库
  6. 审查代码确保它不会破坏工程,合并它到本地仓库的master分支
  7. push master分支到服务器上的官方仓库
  8. 其他开发者应该同步官方仓库。

from:http://www.techug.com/git-2

Git快速入门

版本控制系统可以分为集中式(CVCS, Centralized Version Control System, 例如CVS、Subversion)和分布式(DVCS, Distributed Version Control System,例如Git)版本控制系统。

传统的集中式版本控制系统,本地只保存代码库的一个版本拷贝。 所有历史版本都保存在服务器。GIT 与之最大的不同是,本地不仅保存一个快照,而且保存着整个代码库(repository)。因此它可以“离线”工作。

GIT 使用 SHA-1 哈希码(40个字符)来标识提交,同时保证本次提交后整体(一个快照)的完整性。

文件状态分为:未跟踪 (untracked) 和已跟踪 (tracked),已跟踪又分为三种状态: 已暂存(staged),已修改(modified),已提交(committed)

一般过程如下:

1) 新建文件,该文件状态为“未跟踪”,位于工作区;

2) 用 git add a.txt  加入该文件,状态变为已跟踪的“已暂存”,位于暂存区;

3) 用 git commit a.txt -m “ha”  提交该文件,状态变为“已提交”,位于代码库(repository )。

当文件处于已跟踪的状态下,

4)编辑该文件并保存,状态变为“已修改”,位于工作区;

5) 重复步骤2、3,可提交代码至代码库。

我们创建一个测试项目来感受下如何通过命令行,使用Git对文件进行版本控制。

创建版本库

在多数版本控制系统,例如Subversion,工作目录与版本库是分开存放的。而在Git中,版本库(.git目录)是与工作目录树(Working Trees)并排放在同一个目录中的。

在Git中创建版本库,首先要决定把项目源代码存放在哪里。本例中,要创建一个简单的HTML页面,所以给这个项目取名为test。首先创建一个同名目录“test”,并进入到这个目录,然后输入命令git init。整个过程如下:

D:\test>git init

Initialized empty Git repository in D:/test/.git/

创建完成。从现在开始,这个Git版本库就可以用来记录和跟踪该项目的代码了。

添加初始文件

前面的操作已经创建了一个空版本库,现在该往里添加文件了。现在我们创建一个名为index.html的文件,并添加标题文本“Hello world”。详细内容如下:

<html>

<body>

<h1>Hello World!</h1>

</body>

</html>

创建了一个简单的HTML文件后,就可以开始跟踪版本了。我们会向这个文件不断添加更多的内容。要想让Git跟踪这个文件,须先让它知道这个文件要分两步走:首先使用git add命令把该文件添加到版本库的索引(index);然后使用git commit命令提交。

D:\test>git add index.html

D:\test>git commit -m “inital version”

[master (root-commit) 96707ef] inital version

1 file changed, 5 insertions(+)

create mode 100644 index.html

文件或文件列表可以作为git add命令的参数。

git commit命令创建一个提交记录。提交记录是存储在版本中的历史记录,每提交一次创建一个记录,并标记出代码的演进。Git把提交者的姓名和邮件地址,以及提交留言,都添加到提交记录中。

前面命令中参数-m的作用是,告诉Git本次提交的注释为initial version。对于任何版本控制系统,适当书写的提交留言都是极其重要的。它可以说明提交的原因:新添加的文件是做什么用的?修改那行代码的原因是什么?

现在我们已经提交了一个文件到版本库中。运行命令git log可以看到这个提交相关的信息:

D:\test>git log

commit 96707ef87920925b664ea3cafc5c4926bee20de8

Author: jag <jag@gmail.com>

Date:   Fri Sep 19 09:23:47 2014 +0800

inital version

命令git log运行后输出的第一行显示提交名称,该名称是Git自动产生的SHA-1码。Git通过它来跟踪提交。Git使用该哈希码可以保证每个提交的名称都是独一无二的。这在分布式的环境中非常重要。第二行是提交者的信息。第三行是提交日期。第四行是提交的注释。

用命令git commit显示的七位字符来表示一个提交,通常已经足够了,没有必要使用完整的40位哈希码。但是命令git log将显示完整的40位哈希码。

修改文件

下面开始学习怎样处理文件修改。

刚才的HTML文件里还没有<head>和<title>元素。下面为该文件添加这些元素:

<html>

<head>

<title>Hello World in Git</title>

</head>

<body>

<h1>Hello World!</h1>

</body>

</html>

修改完毕,Git可以检测到文件被修改。命令git status会显示工作目录树的状态,即当前的视图状态。Git中的工作目录树与Subversion和CVS中的工作拷贝差不多是一个概念。

D:\test>git status

On branch 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:   index.html

no changes added to commit (use “git add” and/or “git commit -a”)

上面的输出结果表明Git检测到了修改,但还不知道如何处理它们。修改过的文件在Changed but not updated下列出来,如果要提交,须要暂存(stage)修改。

暂存修改,以准备把修改提交到版本库。Git中有三个地方可以存放代码。第一个地方是工作目录树,编辑文件时可以直接在这里操作。第二个是索引(index),也就是暂存区(staging area)。暂存区是工作目录树和版本库之间的缓冲区。第三个是版本库。暂存区中存放的是准备提交到版本库中的修改。

回头看命令git add,它可以暂存对index.html刚刚做的修改。它跟前面添加一个新文件时使用的是同一个命令,只不过,这次它告诉Git要跟踪的是一个新的修改而非新的文件。

D:\test>git add index.html

D:\test>git status

On branch master

Changes to be committed:

(use “git reset HEAD <file>…” to unstage)

modified:   index.html

暂存修改过的index.html后,执行命令git status可以看到,输出信息中的标题从Changed but not updated变成了Changes to be committed。如果打开颜色开关,index.html这一行会由红色变为绿色。

使用命令git commit时,不要忘记使用带-m的参数,并在参数后面加上提交注释,以解释修改的原因。如下所示:

D:\test>git commit -m “add <head> and <title> to index”

[master 12e743e] add <head> and <title> to index

1 file changed, 3 insertions(+)

命令git log可以快速浏览提交的注释。

D:\test>git log

commit 12e743e19386b25ed22d8dc8ac49771233774e26

Author: jag <jag@gmail.com>

Date:   Fri Sep 19 09:57:54 2014 +0800

add <head> and <title> to index

commit 96707ef87920925b664ea3cafc5c4926bee20de8

Author: jag <jag@gmail.com>

Date:   Fri Sep 19 09:23:47 2014 +0800

inital version

获取历史文件

如果要获取某个老版本的文件,则可以使用git checkout命令,并指定文件名,如下所示:

D:\test>git checkout ed941ed97975757490256fb2b956c27d900e1059 index.html

一旦熟悉了以上命令后,我们使用GUI进行可视化操作时也将信手拈来,如下图所示:

在eclipse中也有相应的插件,如下图所示:

到目前为止,我们已经感受了如何使用Git,包括添加新文件、修改文件、查看版本库的历史记录等。

http://blog.sina.com.cn/s/blog_66e177dd0100j4rk.html
http://wangcong.org/blog/archives/283
git/github初级运用自如
git – 简明指南
图解Git
怎样使用 GitHub?
pro git  book

from:http://jag522.iteye.com/blog/2118196?utm_source=tuicool