专门的工作流的不易展开药模式

转载:http://www.cnblogs.com/woshimrf/p/git-workflow.html

目录

1.1.制造客栈
1.2.
效仿客商A

1.3.
仿照顾客B

1.4.
效仿客商A

1.5.
模拟客商C

1.6.
模仿客商B

1.7.
模拟客商C

2.1
模拟客商C

2.2
模拟客户D

2.3
C继续支付

2.4
D继续支付

2.5 C
提交

2.6 C
提PR

2.7
C修改再push

2.8
C开采提交次数过多,历史太乱,合併一些历史

2.9
C再次push

2.10 新的merge方式:
rebase

2.11 那时候D也产生了
2.12 提交前rebase
最后结果

葡京手机 1

前言

直接在使用git做版本调整,也直接工作很顺畅,直到和别人产生冲突的时候。那才注意到git
职业流并非那么轻巧。举个例子,在此之前遇到的理清历史。百度到的素材比很多,重复性也相当多,但实施性操作相当少,我很难间接精通其所发挥的意思。直接以点带面日常获得错误的定论,只好用时间去印证真理了,否则见到的结果都以似懂非懂,最后如故一团糟。

学习git工作流

1. 最简便易行的利用,不推荐

1.1.创办酒馆

$ pwd
/home/ryan/workspace/l4git-workflow
$ touch readme.md
$ ls
readme.md
$ touch .gitignore
$ git init
初始化空的 Git 仓库于 /home/ryan/workspace/l4git-workflow/.git/
$ touch test.txt
$ git add .
$ git commit -m "init"
[master (根提交) dae77d6] init
 3 files changed, 12 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 readme.md
 create mode 100644 test.txt
$ git remote add origin git@github.com:Ryan-Miao/l4git-workflow.git
$ git push -u origin master
对象计数中: 5, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (3/3), 完成.
写入对象中: 100% (5/5), 388 bytes | 0 bytes/s, 完成.
Total 5 (delta 0), reused 0 (delta 0)
To git@github.com:Ryan-Miao/l4git-workflow.git
 * [new branch]      master -> master
分支 master 设置为跟踪来自 origin 的远程分支 master。

葡京手机 2

1.2. 模拟客户A

git clone git@github.com:Ryan-Miao/l4git-workflow.git
git checkout a
touch a.txt
//write one
//....
$ git add .
$ git commit -m "one"
[a 53ff45e] one
 2 files changed, 34 insertions(+), 2 deletions(-)
 create mode 100644 a.txt

那儿,a还没有提交到origin。 git log 如下:

葡京手机 3

1.3. 模拟客商B

git clone git@github.com:Ryan-Miao/l4git-workflow.git
git checkout b

$ touch b.txt

//write something
葡京手机,//…

$ git add .
$ git commit -m "b write one"
[b 847078e] b write one
 1 file changed, 1 insertion(+)
 create mode 100644 b.txt

//write something
//….
$ git add . $ git commit -m "b write two" [b 3f30f41] b write two 1 file changed, 2 insertions(+), 1 deletion(-)

此时,git log如下
葡京手机 4

1.4. 模仿客商A

A和B分别是在地点开拓,所以这种顺序是不解的,恐怕A比B先commit一遍,大概B先commit一回。这里的程序是指commit的光阴戳。但皆以在本地提交的代码。
write something

git add .
git commit -m "a write two"

wirte something

git add .
git commit -m "write three"

A push to server branch a

$ git push origin a:a
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:Ryan-Miao/l4git-workflow.git
 * [new branch]      a -> a

A created a Pull Request

葡京手机 5
葡京手机 6

1.5. 模拟客户C

C review the PR and then merged it.

葡京手机 7
这时候,github的历史如下:
葡京手机 8
能够观望,merge的时候多了三次commit,message默以为 Merge pull request #1 from Ryan-Miao/a...
当今看起来,独有a一人的历史记录,还算清楚,a做了3次提交。

1.6. 效仿客户B

客商B提交前先pull master,更新最新的代码到本地,幸免冲突。

 git fetch
 git merge origin/master

那会儿log看起来有一点点乱。如下:
葡京手机 9
令人倍感混乱的是b原本的野史只有本身的交由,更新了master到地头之后,历史记录被插入了master中的历史。于是,开采原先自个儿到底的历史被中间插入数次commit。乃至四次merge
master的日记显得又长又碍眼。但不管怎么说,B依然要交给的。

于是,B提交到长途分支b:
葡京手机 10

1.7. 模仿顾客C

此时,A达成了feature a,然后提了P本田UR-V,然后找别人C
merge了。而后,B也成功了feature b,提了PHighlander,须求review and merge。 C
review之后,approved, 然后D review, D merge。

此时,项目为主走上专门的学业。feature二个三个增加进去,重复以前的劳作流程:
fetch -》 work -》 commit -》 push -》 P揽胜极光 -》 merged。
然后,项目历史就成为了那样:

葡京手机 11

一眼大概看起来好在,每一趟都能看出提交历史,只要不是message写的特意少,大约能够知晓这段时间亲交欢由的内容。但是,留神一看,顺序好像不对。方今共计三个feature,但历史却远远超过2个。不要紧,保险细粒度更便于反映开辟进程。但是,这一个历史并非遵守feature的昭示顺序,那么,当自个儿想要找到feature
a的时候就很难串联起来。如果commit充分多,时间跨度足够大,乃至一贯看不出来feature
a到底做了怎么样修改。

那时想要使用图形化git 历史工具来扶持领悟历史:
葡京手机 12

那边,幸亏,还勉强能见到走向。但当拾一个广大个人同期支付来讲,线简直无法看了,时间跨度丰硕大的话,线也数不胜数。

故而,这种形式,就是大家团结眼下使用的方式。差评。那还不算完,后边越来越大的狼狈来了。最早发布的feature
a出了难题,必需回滚。怎么达成。关于回滚,正是另叁个话题了。
但大家应当理解使用revert而不是reset.
但revert只好回滚钦命的commit,只怕接二连三的commit,并且revert不能够revert
merge操作。那样,想回滚feature a,
我们将在找到a的两遍提交的本子号,然后由于不是接连的,分别revert。那会变成复杂到不想管理了。幸而github给了造福的事物,PTiggo提供了revert的机缘。找到从前的PEvoque。

葡京手机 13

可是,那相对不是个好操作!


2. 引入的做事流程

导致上述现象的缘故是因为个别异步编制程序决定的。因为每一种人都足以任何时候间提交,最终合併起来的时候以提交时间戳来作为体系的依据,就能形成那样。由此,当要求交给的长途服务器的时候,如果能重写下commit的年索爱当前时间,然后push到服务端,历史就能系列到终极了。

2.1 模拟客户C

C顾客新下载代码。

$ git clone git@github.com:Ryan-Miao/l4git-workflow.git c正克隆到 'c'...
remote: Counting objects: 28, done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 28 (delta 8), reused 22 (delta 4), pack-reused 0
接收对象中: 100% (28/28), 5.90 KiB | 0 bytes/s, 完成.
处理 delta 中: 100% (8/8), 完成.
检查连接... 完成。

然后编辑,提交

$ cd c
$ git config user.name "C"
$ ls
a.txt  b.txt  readme.md  test.txt
$ vim c.txt
$ git add .
$ git commit -m "C write one"
[master cf3f757] C write one
 1 file changed, 2 insertions(+)
 create mode 100644 c.txt

2.2 模拟顾客D

并且,D也须要开荒新feature

$ git clone git@github.com:Ryan-Miao/l4git-workflow.git d正克隆到 'd'...
remote: Counting objects: 28, done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 28 (delta 8), reused 22 (delta 4), pack-reused 0
接收对象中: 100% (28/28), 5.90 KiB | 0 bytes/s, 完成.
处理 delta 中: 100% (8/8), 完成.
检查连接... 完成。
$ cd d
/d$ git config user.name "D"
/d$ vim d.txt
/d$ git add .
/d$ git commit -m "d write one"
[master db7a6e9] d write one
 1 file changed, 1 insertion(+)
 create mode 100644 d.txt

2.3 C继续支付

$ vim c.txt
$ git add .
$ git commit -m "c write two"
[master 01b1210] c write two
 1 file changed, 1 insertion(+)

2.4 D继续支付

/d$ vim d.txt
/d$ git add .
/d$ git commit -m "d write two"
[master a1371e4] d write two
 1 file changed, 1 insertion(+)

2.5 C 提交

$ vim c.txt 
$ git add .
$ git commit -m "c write three"
[master 13b7dde] c write three
 1 file changed, 1 insertion(+)

C开垦结束,提交到长途

$ git status
位于分支 master
您的分支领先 'origin/master' 共 3 个提交。
  (使用 "git push" 来发布您的本地提交)
无文件要提交,干净的工作区
$ git push origin master:C
对象计数中: 9, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (6/6), 完成.
写入对象中: 100% (9/9), 750 bytes | 0 bytes/s, 完成.
Total 9 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 1 local object.
To git@github.com:Ryan-Miao/l4git-workflow.git
 * [new branch]      master -> C

2.6 C 提PR

然后,create a Pull Request.
葡京手机 14

2.7 C修改再push

然后,发掘还会有个bug要修复,再度修改提交到远程C

$ vim c.txt 
$ git add .
$ git commit -m "C finish something else"
[master 2c5ff94] C finish something else
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git push origin master:C
对象计数中: 3, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (3/3), 完成.
写入对象中: 100% (3/3), 301 bytes | 0 bytes/s, 完成.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To git@github.com:Ryan-Miao/l4git-workflow.git
   13b7dde..2c5ff94  master -> C

2.8 C开掘提交次数过多,历史太乱,合併一些历史

那时,开掘一个主题素材,由于C在付出进度中付出了累累,而那三遍提交的message其实未有多大野趣,只是因为C可能为了保留代码,也可能是暂存。总来说之,C的前3次提交的message的含义其实是一致的,都以成立C文件,都以一个宗旨,那么为了保障历史的到底。最佳把那3条消息统百分之十六条C create file c.txt

参考git
合并历史
,大家供给将3次历史合併成突显为叁遍。

查看git历史,找到必要联合的初阶区间

$ git log --oneline
2c5ff94 C finish something else
13b7dde c write three
01b1210 c write two
cf3f757 C write one
7151f4c 记录操作。
0bfe562 Merge pull request #2 from Ryan-Miao/b_remote
d81ce20 Merge remote-tracking branch 'origin/master' into b
2d74cfb Merge pull request #1 from Ryan-Miao/a
b90a3dd write three
4b1629e a write two
3f30f41 b write two
847078e b write one
53ff45e one
dae77d6 init

明明,是要联合cf3f75713b7dde。那么找到前一个的版本号为7151f4c

git rebase - i 7151f4c

下一场进入相互分界面,因为我们想要把第3次和第2次以致第1次提交新闻统一。将第3次的连串修改为squash,
意思是和第2次联合。然后将第2次的门类修改为squash,
同样是指合併的前四个commit。
葡京手机 15
不相同git的相互略有分裂,从前在windows上的git
bash是截然根据vim的指令修改的。此次测试基于Ubuntu,发掘存档命令为ctel + X。确认后步入下八个分界面,合併3次提交后要求多少个message

葡京手机 16

删除恐怕anyway you like, 改造message。存档。完成。

$ git rebase -i 7151f4c
[分离头指针 e3764c5] c create  file c.txt
 Date: Fri Oct 20 22:06:24 2017 +0800
 1 file changed, 4 insertions(+)
 create mode 100644 c.txt
Successfully rebased and updated refs/heads/master.

Tips
当在rebase进程中出现了失误,能够行使git rebase --abort归来起初状态。如若开采冲突,则能够化解矛盾,然后git rebase --continue .

就好像已有 rebase-merge 目录,小编匪夷所思你正处在其他三个变基操作
经过中。 若是是那般,请实行
git rebase (–continue | –abort | –skip)
若是或不是这么,请实行
rm -fr “/home/ryan/temp/c/.git/rebase-merge”
接下来再重复实行变基操作。 为幸免错失首要数据,小编曾经结束当前操作。

此刻,查看log, 鲜明,C的那贰回提交已经统一了。

$ git log --oneline
50b9fe9 C finish something else
e3764c5 c create  file c.txt
7151f4c 记录操作。
0bfe562 Merge pull request #2 from Ryan-Miao/b_remote
d81ce20 Merge remote-tracking branch 'origin/master' into b
2d74cfb Merge pull request #1 from Ryan-Miao/a
b90a3dd write three
4b1629e a write two
3f30f41 b write two
847078e b write one
53ff45e one
dae77d6 init

2.9 C再次push

此前的push已经无法用了。须求开新支行推送过去。因为 rebase
只好在地面分支做。不要涂改公共分支
 。

$ git push origin master:C
To git@github.com:Ryan-Miao/l4git-workflow.git
 ! [rejected]        master -> C (non-fast-forward)
error: 无法推送一些引用到 'git@github.com:Ryan-Miao/l4git-workflow.git'
提示:更新被拒绝,因为推送的一个分支的最新提交落后于其对应的远程分支。
提示:检出该分支并整合远程变更(如 'git pull ...'),然后再推送。详见
提示:'git push --help' 中的 'Note about fast-forwards' 小节。

选取推送的新分支C2

$ git push origin master:C2
对象计数中: 6, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (5/5), 完成.
写入对象中: 100% (6/6), 569 bytes | 0 bytes/s, 完成.
Total 6 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To git@github.com:Ryan-Miao/l4git-workflow.git
 * [new branch]      master -> C2

创办新的PRubicon
葡京手机 17

2.10 新的merge方式: rebase

透太早先的日常流程发掘,每一回merge的时候,都会多出一条新的交给信息,那让历史看起来很古怪。那么,能够采用rebase到master,变基,正是重新以master为基本,把这两天的提交直接移动到master的前边。不会因为提交时间的离散导致多次commit的message被拆卸。
选择 rebase and merge
葡京手机 18

葡京手机 19

那时候,能够看看C提交的四回信息都以风靡的,未有发出交叉。並且也并未有生出多余的merge音讯。
葡京手机 20

有人会问,那么岂不是看不到P奥迪Q7的地址了。点开C的历史。能够看看message下方是有PLAND的号子的:
葡京手机 21

对了,刚带头的P奥德赛要记得close
葡京手机 22

2.11 那时候D也成就了

/d$ git push origin master:D
对象计数中: 10, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (7/7), 完成.
写入对象中: 100% (10/10), 4.49 KiB | 0 bytes/s, 完成.
Total 10 (delta 2), reused 4 (delta 1)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To git@github.com:Ryan-Miao/l4git-workflow.git
 * [new branch]      master -> D

提P途达, 那时候,假如运用merge:
葡京手机 23

葡京手机 24

结果必然发掘,1)
d提交message被依据时间分散插入历史了(被插入到c的历史在此之前),
2)多了二遍 Merge pull request #5 from Ryan-Miao/D..的交给音信。同先河所述同样,历史先河变得乌烟瘴气了。那么,这种难点如何做呢?

2.12 提交前rebase

就像C
rebase后merge到master一样。大家一致能够在本地做到那样的业务。在该地rebase,让大家此番feature的提交全体插到master节点从此,有序,何况便于revert。
本次,以新的E和F交叉commit为例子,最后将获取各自分离的历史

E:

$ git clone git@github.com:Ryan-Miao/l4git-workflow.git e
正克隆到 'e'...
remote: Counting objects: 52, done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 52 (delta 18), reused 36 (delta 7), pack-reused 0
接收对象中: 100% (52/52), 7.91 KiB | 0 bytes/s, 完成.
处理 delta 中: 100% (18/18), 完成.
检查连接... 完成。

$ cd e
/e$ vim e.txt
/e$ git add .
/e$ git config user.name "E"
/e$ git commit -m "e commit one"
[master 77ecd73] e commit one
 1 file changed, 1 insertion(+)
 create mode 100644 e.txt

F:

$ git clone git@github.com:Ryan-Miao/l4git-workflow.git f
正克隆到 'f'...
remote: Counting objects: 52, done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 52 (delta 18), reused 36 (delta 7), pack-reused 0
接收对象中: 100% (52/52), 7.91 KiB | 0 bytes/s, 完成.
处理 delta 中: 100% (18/18), 完成.
检查连接... 完成。

$ cd f
$ vim f.txt
$ git config user.name "F"
$ git add .
$ git commit -m "d write one"
[master b41f8c5] d write one
 1 file changed, 2 insertions(+)
 create mode 100644 f.txt

E:

/e$ vim e.txt
/e$ git add .
/e$ git commit -m "e write two"
[master 2b8c9fb] e write two
 1 file changed, 1 insertion(+)

F:

$ vim f.txt
$ git add .
$ git commit -m "f write two"
[master de9051b] f write two
 1 file changed, 1 insertion(+)

E:

/e$ vim e.txt 
/e$ git add .
/e$ git commit -m "e write three"
[master b1b9f6e] e write three
 1 file changed, 2 insertions(+)

那时,e实现了,供给交给。提交前先rebase:

/e$ git fetch
/e$ git rebase origin/master
当前分支 master 是最新的。

然后,再提交

/e$ git push origin master:E
对象计数中: 9, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (6/6), 完成.
写入对象中: 100% (9/9), 753 bytes | 0 bytes/s, 完成.
Total 9 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 1 local object.
To git@github.com:Ryan-Miao/l4git-workflow.git
 * [new branch]      master -> E

然后, PR, merge.

同样F:

$ git status
位于分支 master
您的分支领先 'origin/master' 共 2 个提交。
  (使用 "git push" 来发布您的本地提交)
无文件要提交,干净的工作区
$ git fetch 
remote: Counting objects: 12, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 12 (delta 6), reused 6 (delta 3), pack-reused 0
展开对象中: 100% (12/12), 完成.
来自 github.com:Ryan-Miao/l4git-workflow
   24c6818..f36907c  master     -> origin/master
 * [新分支]          E          -> origin/E
$ git rebase origin/master
首先,回退分支以便在上面重放您的工作...
应用:d write one
应用:f write two

$ git push origin master:F
对象计数中: 6, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (4/4), 完成.
写入对象中: 100% (6/6), 515 bytes | 0 bytes/s, 完成.
Total 6 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To git@github.com:Ryan-Miao/l4git-workflow.git
 * [new branch]      master -> F

PCRUISER, rebase and merge。 这时候看history:

葡京手机 25

依据前四遍的做法,E和F交叉在地头提交,每一趟commit的年月戳也是交叉,最后合併到master的时候,历史并不曾被拆除与搬迁。而是像大家目的在于的一致,顺序下来。那才是我们想要的。通过看图形化分界面也能收看差异:

紫藤色的线是master
葡京手机 26

那么,操作就是fetch-》rebase。事实上,能够二合一为:

git pull --rebase origin master

葡京手机 27

终极结出

在都没交给到server的时候,
历史是分散在相继开荒者的本土,但commit时间有程序。
葡京手机 28

按照rebase的用法,提交前rebase二次,就可以使得多少个feature的交给串联到三头
葡京手机 29

最终在github的commit看起来也正是胜利的多
葡京手机 30

表率

  1. 想保持树的清爽,方法正是:在git push在此之前,先git fetch,再git
    rebase。

git fetch origin master
git rebase origin/master
git push

或者

git pull --rebase origin master

比如您把变基命令当做是在推送前清理提交使之整洁的工具,而且只在并未有推送至共用酒店的付出上实行变基命令,就不会有事。
借使在那个早就被推送至共用饭馆的提交上实践变基命令,并由此放任了有些外人的支出所依附的交给,这您就有大麻烦了,你的同事也会就此漠视你。

假定你或你的同事在某个情状下决定要那样做,请应当要布告各种人实行 git
pull –rebase 命令,那样就算不能够防止伤痛,但能抱有缓和。

  1. 相对不用在公私(远程分支)上rebase,也等于说,若无要求就绝不在github
    merge的时候选择rebase,而是用上述的方式,在该地自身的分段推送前rebase
  2. 相对无法在公私分支上reset,也毫无用–force
  3. 独立功效的往往付出要学会联合提交,保持提交的洗练。
  4. 交付message尽量能总结修改内容。

参照来源