1. 程式人生 > >版本管理之gitlab實踐教程:進階篇(1)

版本管理之gitlab實踐教程:進階篇(1)

實踐gitflow

結合git flow,使用gitlab作為遠端倉庫管理,在實際的專案中是一種可行的方式,而且這種方式對與複雜大型的專案有較好的適應方式。

git flow

git flow源於Vincent Driessen在2010年提出的一個分支模型:
這裡寫圖片描述

主要特點

兩個長期分支

git flow中有兩個長期的分支,一直不會被刪除,這兩個分支是develop和master。

分支 生命期 作用說明
master 長期 用於保持和生產環境一致或者半步先於生產環境,主要目的用於保證生產環境的實時可用狀態
develop 長期 開發的整合分支,主要目的用於顯示最新的開發狀況

實踐原則1:

master 分支時常保持著軟體可以正常執行的狀態,一般不允許開發者直接對master 分支的程式碼進行修改和提交。結合gitlab的具體方式,可以將改分支設定為protect方式。

實踐原則2:

master分支專人管理,結合gitlab的許可權管理,設定團隊負責釋出的人具有owner或者master的許可權,其餘人禁止直接對此分支進行操作。

master分支的使用場景

master分支主要在以下場景中會用到:

生產環境bug再現與調查

當代碼規模和團隊規模到了一定程度之後,如果缺乏有效的管理,加之多團隊的開發,尚未釋出的功能,臨時對應的bug,甚至還會有一些手動修改暫時未歸入版本管理的檔案,這些混雜在一起會變得非常的複雜。所以在問題發生時,想清楚的知道bug發生的生產化境所對應的原始碼基線都是一件困難的事情,此分支與上線功能息息相關,必須嚴格管理。

新的功能釋出

特性分支開發完畢,完成測試,確認此分支內容可以進行釋出之後,便可與master分支合併,釋出時一般會附加版本編號。

緊急bug修正釋出

緊急bug修正之後,需要立即體現在master分支上,不然下次釋出依然會有很多問題

實踐原則3

建議在專案中新增自動化測試環節,使用gitlab的webhook設定,在merge時根據專案需要自動執行自動化測試驗收,如果不通過及時報警,此自動化測試即使是很少的覆蓋率,也能防範大部分人為因素導致的問題,比如不小心將一個編譯都沒有通過的版本推到了master上,即使專人負責,但是專人並不一定對所有的技術和專案功能以及實時狀態都有全面的掌控,另外所有的問題都需要人去檢查和確認,一張會無限增長的checklist從此產生,最終會形成一個幾千行甚至更多的一個雖都不會去看的敷衍了事的檢查環節,此環節在很多專案實踐中已經得到證實:只在事後檢討的時候有用,檢討之後這張checklist會變得更長。

develop分支的使用場景

特性開發合併

根據專案的模組進行拆分,不同的模組不同的團隊負責,或者根據特性進行開發,不同的特性不同的團隊負責,這些分支開發完畢時需要合併到develop分支上,以保證develop分支具有最新的功能。

緊急bug修正釋出

緊急bug修正之後,需要立即體現在master分支上,但是同時需要在develop分支上進行反應,為何不直接在develop分支上進行管理,有很多因素需要考慮,比如新的功能雖然開發完畢了,但是由於其他制約的因素,釋出的時期尚未確定,不能將這些已經完成開發和測試的內容釋出到master分支上,簡單來說此模型的出發點在於master分支用於和生產環境直接關聯,之所以多一條分支就是為了管理各種複雜的難以掌控的專案實際需求的。緊急bug修正之後,master和develop分支都需要進行更新,前者保證下次釋出不會將此緊急修正的內容覆蓋,後者保證通過下次通過測試的內容合併到master上時不會覆蓋此內容或者儘可能的減少merge操作。

實踐原則4

develop分支是開發過程中程式碼中心分支,與master 分支一樣,這個分支也是非常重要的分支,這個分支的合併操作可能每個人都會參與,如果做專人管理的話,基本上所有的開發者都需要參與。所以,合併之前需要建立基礎的原則,比如java的專案最好做到如下內容才合併到本分支
本地編譯通過
本地本次修改內容沒有新的sonarqube高級別的defect對應
本地單體測試通過
手工或者自動化驗收的測試通過

實踐原則5

develop分支進行傳統的每日構建甚至實時構建,結合不斷完善的自動化測試,以可以接受的成本和代價保證開發的流水線不會斷開。

實踐原則6

設立時限原則:develop分支一旦發生構建或者關聯的自動化測試出現問題,結合工具第一時間定位到對應的負責人進行回滾或者緊急修正,根據專案整合情況進行設立時限,比如平均每日由各個臨時分支提交的功能為4次,則可設立時限最長不超過2小時,如果超過2小時無法對應,則意味著下次會有人在這個錯誤的版本上進行再一次的提交,錯上加錯是最需要避免的,發現問題在第一時間解決,超過時限,立即止損回滾。

三種臨時分支

相比於長期存在的分支,git flow的模型中還有三種臨時性的分支

分支型別 說明 是否可為多條
Feature分支 特性分支 可為多條
Hotfix分支 bug對應分支 可為多條
Release分支 release實施分支 可為多條

特性分支

特性分支有時也被稱為Topic分支,一般是用來開發新的特性,而其關聯的釋出可能近在眼前,也有可能需要很長一段時間,特性分支最終會被合併到develop分支或者最終會被丟棄。
丟棄特性分支開發的內容在敏捷開發中並不罕見,尤其是當專案需要不斷地試驗的階段。

根據DevOps的調查顯示,Trunc-based開發方式是主流推動的開發方式,但是由於專案的複雜性和實際推行時候各種制約因素的存在,
多條分支長時間的並行還是很難避免的,特性分支開發的時候在git flow模型中一般遵循如下步驟:

步驟 內容 git 命令
Step 1 以develop分支為基礎建立特性分支 git checkout -b 特性分支名稱 develop
Step 2 進行特性內容開發直至可以提交
Step 3 特性分支開發完成後切換至develop分支 git checkout develop
Step 4 合併特性分支開發內容到develop分支 git merge –no-ff 特性分支名稱
Step 5 刪除特性分支 git branch -d 特性分支名稱
Step 6 push修改內容到遠端倉庫儲存 git push origin develop

特性分支的使用注意事項如下:

注意事項 詳細說明
源分支 特性分支需要以develop分支為源分支
目標分支 特性分支的合併目標分支為develop分支,此模型中只能合併回develop分支
分支命名 除去master/develop/hotfix-/release-命名的所有分支

實踐原則6

特性分支合併或者其他的分支合併,儘可能不使用fast forward的方式,以方便回滾和狀態確認。

實踐原則7

特性分支在git flow中仍然是臨時性分支,使用之後請刪除此分支,同時刪除遠端倉庫上的該分支。另外,分支的增多以為著可能的溝通/合併/衝突等的增加,而這些正是精益開發中
所要規避的“waste”,不用即刪,因為在實踐中我們已經利用了git的非fast forward的方式,所以特性分支開發的資訊已經完整地在develop分支儲存,刪除不會引起問題追蹤上的問題。

Release分支

Release分支基於develop分支為基礎進行建立,主要用於版本的釋出,主要用於保證最後一步的安全和順暢,為釋出所需要的各種準備以及手工操作,甚至小規模的bug對應都可以在此分支上完成。而當Release分支上的一切做完之後,標誌著最新develop分支的功能已經發布到了master,同時為下一次釋出的功能特性的接收已經開始。

實踐原則8

特性分支或者其他分支合併到develop開發主分支的策略需要專案根據情況自行建立,最主要的原則之一在於儘量避免由於釋出時期的不同導致頻繁的分支合併/版本挑選等手工作業的發生。
比如釋出計劃明明是最後,但是在專案已開始的時候就合併進了主分支,這樣會導致後續每次釋出的時候都需要將此內容挑選出去,雖然使用gitlab的rebase+cherry pick等功能可以實現這種要求,
但是單純在提交的規範上進行要求則可以避免這種無用的浪費的發生。

實踐原則9

Release分支主要目的是用於大型專案中各個特性分支開發完畢之後,定義了一個準備就緒到工作完成的中間階段,一般會和專案的管理工作結合進行,比如進行釋出的申請和批准,結果確認和稽核,
由於不同的開發流程不僅需要考慮到技術本身,還要考慮到各個公司實際的流程規範/audit等等,以保證release能夠正常進行。雖然可以在此分支上進行小量的修改,但是大規模的功能修改請儘可能地規避。

Release分支在使用時候一般遵循如下步驟:

步驟 內容 git 命令
Step 1 以develop分支為基礎建立release分支 git checkout -b release-版本號 develop
Step 2 做Release準備或者小的bug對應,然後進行提交 git commit -a -m “release相關資訊”
Step 3 切換至master分支 git checkout master
Step 4 合併Release分支內容到master分支 git merge –no-ff release-版本號
Step 5 設定tag git tag -a 版本號 -m “release的tag資訊”
Step 6 切換至develop分支 git checkout develop
Step 7 合併Release分支內容到develop分支 git merge –no-ff release-版本號
Step 8 刪除release分支 git branch -d release-版本號
Step 9 推送develop分支到遠端倉庫 git push origin develop
Step 10 切換至master分支並推送master分支到遠端倉庫 git checkout master; git push origin master
Step 11 推送tag資訊到遠端分支 git push origin 版本號

Release分支的使用注意事項如下:

注意事項 詳細說明
源分支 release分支需要以develop分支為源分支
目標分支 特性分支的合併目標分支為develop分支和master,在此分支上的諸如小的bug修正必須同時反映到develop分支和master分支,不然就會給下次釋出留下隱患
分支命名 release-*

實踐原則10

為了避擴音交或者tag資訊被惡意修改,可以在使用簽名技術實現這一保障。簽名使得操作具有了不可抵賴性和無法篡改性兩種保證。而在git中只是需要加入-u或者-s選項即可簡單實現。

hotfix分支

hotfix分支與release分支非常相像,都牽扯到向生產環境ready的master進行版本的更新。但是不同的是hotfix往往是因為生產環境上出現了非常緊急的問題對應,需要立即對應,而專案的特性開發等又不想受到影響而中斷,這時就可以依據master生成一個新的hotfix的分支,在此分支上進行bug的對應,既不影響develop主開發分支,又能保證到生產環境緊急問題的及時對應,而對應完畢之後同時向develop主開發分支進行同步跟新即可。

實踐原則11

諸如hotfix和release上的對應需要向git flow的兩條主線同時進行更新,如果一旦忘記其中一條,勢必會引起不必要的後續問題,在流程規範或者工具的自動化裡面建立增加對此操作執行的確認。

Hotfix分支在使用時候一般遵循如下步驟:

步驟 內容 git 命令
Step 1 以master分支為基礎建立hotfix分支 git checkout -b hotfix-版本號 master
Step 2 進行bug對應,然後進行提交 git commit -a -m “hotfix相關資訊”
Step 3 切換至master分支 git checkout master
Step 4 合併hotfix分支內容到master分支 git merge –no-ff hotfix-版本號
Step 5 設定tag git tag -a 版本號 -m “hotfix的tag資訊”
Step 6 切換至develop分支 git checkout develop
Step 7 合併hotfix分支內容到develop分支 git merge –no-ff hotfix-版本號
Step 8 刪除hotfix分支 git branch -d hotfix-版本號
Step 9 推送develop分支到遠端倉庫 git push origin develop
Step 10 切換至master分支並推送master分支到遠端倉庫 git checkout master; git push origin master
Step 11 推送tag資訊到遠端分支 git push origin 版本號

hotfix分支的使用注意事項如下:

注意事項 詳細說明
源分支 hotfix分支需要以master分支為源分支
目標分支 特性分支的合併目標分支為develop分支和master,修正必須同時反映到develop分支和master分支,不然就會給下次釋出留下隱患
分支命名 hotfix-*

實際使用

接下來我們使用gitlab10.4.2以及git1.8.3.1來模擬一下git flow開發的流程。

建立一個專案

首先我們使用gitlab的restapi建立一個專案,當然也可以直接在gitlab上進行圖形介面操作,具體命令如下,請根據自己的gitlab的URL和token進行修改, 另外jq命令如果沒有可以不使用,對結果不產生影響,僅僅對結果的顯示格式進行整形而已

執行命令

curl –request POST –header “PRIVATE-TOKEN: sqiSUhn3tHYXe8nSGRDi” –data “name=gitflowmodel” “http://127.0.0.1:32001/api/v4/projects” |jq .

執行log

[[email protected] ~]# curl --request POST --header "PRIVATE-TOKEN: sqiSUhn3tHYXe8nSGRDi" --data "name=gitflowmodel" "http://127.0.0.1:32001/api/v4/projects" |jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1907  100  1890  100    17   1711     15  0:00:01  0:00:01 --:--:--  1711
{
  "id": 2,
  "description": null,
  "name": "gitflowmodel",
  "name_with_namespace": "Administrator / gitflowmodel",
  "path": "gitflowmodel",
  "path_with_namespace": "root/gitflowmodel",
  "created_at": "2018-02-04T14:11:10.055Z",
  "default_branch": null,
  "tag_list": [],
  "ssh_url_to_repo": "[email protected]:root/gitflowmodel.git",
  "http_url_to_repo": "http://3ff5a6afdc80/root/gitflowmodel.git",
  "web_url": "http://3ff5a6afdc80/root/gitflowmodel",
  "avatar_url": null,
  "star_count": 0,
  "forks_count": 0,
  "last_activity_at": "2018-02-04T14:11:10.055Z",
  "_links": {
    "self": "http://3ff5a6afdc80/api/v4/projects/2",
    "issues": "http://3ff5a6afdc80/api/v4/projects/2/issues",
    "merge_requests": "http://3ff5a6afdc80/api/v4/projects/2/merge_requests",
    "repo_branches": "http://3ff5a6afdc80/api/v4/projects/2/repository/branches",
    "labels": "http://3ff5a6afdc80/api/v4/projects/2/labels",
    "events": "http://3ff5a6afdc80/api/v4/projects/2/events",
    "members": "http://3ff5a6afdc80/api/v4/projects/2/members"
  },
  "archived": false,
  "visibility": "private",
  "owner": {
    "id": 1,
    "name": "Administrator",
    "username": "root",
    "state": "active",
    "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
    "web_url": "http://3ff5a6afdc80/root"
  },
  "resolve_outdated_diff_discussions": false,
  "container_registry_enabled": true,
  "issues_enabled": true,
  "merge_requests_enabled": true,
  "wiki_enabled": true,
  "jobs_enabled": true,
  "snippets_enabled": true,
  "shared_runners_enabled": true,
  "lfs_enabled": true,
  "creator_id": 1,
  "namespace": {
    "id": 1,
    "name": "root",
    "path": "root",
    "kind": "user",
    "full_path": "root",
    "parent_id": null
  },
  "import_status": "none",
  "import_error": null,
  "open_issues_count": 0,
  "runners_token": "iCwH41nomRPp-nwF4xoP",
  "public_jobs": true,
  "ci_config_path": null,
  "shared_with_groups": [],
  "only_allow_merge_if_pipeline_succeeds": false,
  "request_access_enabled": false,
  "only_allow_merge_if_all_discussions_are_resolved": false,
  "printing_merge_request_link_enabled": true
}
[[email protected] ~]# 

這樣我們就建立了一個名為gitflowmodel的gitlab專案了。

初期化專案

初期化master分支

git clone遠端倉庫內容,進行結果確認

[[email protected] ~]# git clone http://192.168.163.154:32001/root/gitflowmodel.git
Cloning into 'gitflowmodel'...
Username for 'http://192.168.163.154:32001': root
Password for 'http://[email protected]:32001': 
warning: You appear to have cloned an empty repository.
[[email protected] ~]# cd gitflowmodel/
[[email protected] gitflowmodel]# git branch
[[email protected] gitflowmodel]# git remote -v
origin  http://192.168.163.154:32001/root/gitflowmodel.git (fetch)
origin  http://192.168.163.154:32001/root/gitflowmodel.git (push)
[[email protected] gitflowmodel]# 

對專案進行初期化,建立master分支,在master分支上新增一個檔案C1,並將此檔案推送到遠端倉庫。

[root@devops gitflowmodel]# touch C1
[root@devops gitflowmodel]# git add C1; git commit -m"add C1"
[master (root-commit) 858d807] add C1
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C1
[root@devops gitflowmodel]# git push origin master
Username for 'http://192.168.163.154:32001': root
Password for 'http://[email protected]:32001': 
Counting objects: 3, done.
Writing objects: 100% (3/3), 199 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://192.168.163.154:32001/root/gitflowmodel.git
 * [new branch]      master -> master
[root@devops gitflowmodel]# 

初期化develop分支

在目前master的狀態下建立develop分支,新增一個檔案C2,並將此檔案推送到遠端倉庫。

[root@devops gitflowmodel]# git checkout -b develop master
Switched to a new branch 'develop'
[root@devops gitflowmodel]# ls
C1
[root@devops gitflowmodel]# touch C2; git add C2; git commit -m "add C2";
[develop e9aff8a] add C2
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C2
[root@devops gitflowmodel]# git push origin develop
Username for 'http://192.168.163.154:32001': root
Password for 'http://[email protected]:32001': 
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 225 bytes | 0 bytes/s, done.
Total 2 (delta 0), reused 0 (delta 0)
remote: 
remote: To create a merge request for develop, visit:
remote:   http://3ff5a6afdc80/root/gitflowmodel/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote: 
To http://192.168.163.154:32001/root/gitflowmodel.git
 * [new branch]      develop -> develop
[root@devops gitflowmodel]#

這樣兩條長期分支master和develop已經就緒,接下來我們開始模擬實際上的分支開發/bug對應/release等臨時分支操作。

特性分支使用過程

步驟 內容 git 命令
Step 1 以develop分支為基礎建立特性分支 git checkout -b 特性分支名稱 develop
[root@devops gitflowmodel]# git branch
* develop
  master
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git checkout -b feature_F1001 develop
Switched to a new branch 'feature_F1001'
[root@devops gitflowmodel]# 
步驟 內容 git 命令
Step 2 進行特性內容開發直至可以提交
[[email protected] gitflowmodel]# touch C3; git add C3; git commit -m "add C3";
[feature_F1001 fa40dce] add C3
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C3
[[email protected] gitflowmodel]# 
步驟 內容 git 命令
Step 3 特性分支開發完成後切換至develop分支 git checkout develop
[root@devops gitflowmodel]# git checkout develop
Switched to branch 'develop'
[root@devops gitflowmodel]# ls
C1  C2
[root@devops gitflowmodel]# 
步驟 內容 git 命令
Step 4 合併特性分支開發內容到develop分支 git merge –no-ff 特性分支名稱
[[email protected] gitflowmodel]# git merge --no-ff feature_F1001
Merge made by the 'recursive' strategy.
 C3 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C3
[[email protected] gitflowmodel]# 
步驟 內容 git 命令
Step 5 刪除特性分支 git branch -d 特性分支名稱
[root@devops gitflowmodel]# git branch
* develop
  feature_F1001
  master
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git branch -d feature_F1001
Deleted branch feature_F1001 (was fa40dce).
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git branch
* develop
  master
[root@devops gitflowmodel]# 
步驟 內容 git 命令
Step 6 push修改內容到遠端倉庫儲存 git push origin develop
[root@devops gitflowmodel]# git branch
* develop
  master
[root@devops gitflowmodel]# ls
C1  C2  C3
[root@devops gitflowmodel]# git push origin develop
Username for 'http://192.168.163.154:32001': root
Password for 'http://[email protected]:32001': 
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 331 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: 
remote: To create a merge request for develop, visit:
remote:   http://3ff5a6afdc80/root/gitflowmodel/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote: 
To http://192.168.163.154:32001/root/gitflowmodel.git
   e9aff8a..eb06c4a  develop -> develop
[root@devops gitflowmodel]#

此時git倉庫的狀態

[[email protected] gitflowmodel]# git log --graph --pretty=oneline
*   eb06c4ad2a9bd1f70d1ec3135f7b8bdc8703f41f Merge branch 'feature_F1001' into develop
|\  
| * fa40dce00a8878824641c281bd91e10749e8cc86 add C3
|/  
* e9aff8adf4b6344c5d7f59155134ef2e579f1e32 add C2
* 858d8070c8176c42e35f453a3394e4ff1bdc7e94 add C1
[[email protected] gitflowmodel]#

Release分支的使用過程

步驟 內容 git 命令
Step 1 以develop分支為基礎建立release分支 git checkout -b release-版本號 develop
root@devops gitflowmodel]# git branch
* develop
  master
[root@devops gitflowmodel]# ls
C1  C2  C3
[root@devops gitflowmodel]# git checkout -b release-0.1 develop
Switched to a new branch 'release-0.1'
[root@devops gitflowmodel]#
步驟 內容 git 命令
Step 2 做Release準備或者小的bug對應,然後進行提交 git commit -a -m “release相關資訊”
[[email protected] gitflowmodel]# touch C4; git add C4; git commit -m "add C4";
[release-0.1 fcca679] add C4
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C4
[[email protected] gitflowmodel]# 
步驟 內容 git 命令
Step 3 切換至master分支 git checkout master
[root@devops gitflowmodel]# git checkout master
Switched to branch 'master'
[root@devops gitflowmodel]#
步驟 內容 git 命令
Step 4 合併Release分支內容到master分支 git merge –no-ff release-版本號
[[email protected] gitflowmodel]# git merge --no-ff release-0.1
Merge made by the 'recursive' strategy.
 C2 | 0
 C3 | 0
 C4 | 0
 3 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C2
 create mode 100644 C3
 create mode 100644 C4
[[email protected] gitflowmodel]# ls
C1  C2  C3  C4
[[email protected] gitflowmodel]# 
步驟 內容 git 命令
Step 5 設定tag git tag -a 版本號 -m “release的tag資訊”
[root@devops gitflowmodel]# git tag -a 0.1
[root@devops gitflowmodel]# 
步驟 內容 git 命令
Step 6 切換至develop分支 git checkout develop
[root@devops gitflowmodel]# git checkout develop
Switched to branch 'develop'
[root@devops gitflowmodel]# 
步驟 內容 git 命令
Step 7 合併Release分支內容到develop分支 git merge –no-ff release-版本號
[[email protected] gitflowmodel]# git merge --no-ff release-0.1
Merge made by the 'recursive' strategy.
 C4 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C4
[[email protected] gitflowmodel]# 
步驟 內容 git 命令
Step 8 刪除release分支 git branch -d release-版本號
[root@devops gitflowmodel]# git branch -d release-0.1
Deleted branch release-0.1 (was fcca679).
[root@devops gitflowmodel]#
步驟 內容 git 命令
Step 9 推送develop分支到遠端倉庫 git push origin develop
[root@devops gitflowmodel]# git branch
* develop
  master
[root@devops gitflowmodel]# git push origin develop
Username for 'http://192.168.163.154:32001': root
Password for 'http://[email protected]:32001': 
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 339 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: 
remote: To create a merge request for develop, visit:
remote:   http://3ff5a6afdc80/root/gitflowmodel/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote: 
To http://192.168.163.154:32001/root/gitflowmodel.git
   eb06c4a..ff52200  develop -> develop
[root@devops gitflowmodel]# 
步驟 內容 git 命令
Step 10 切換至master分支並推送master分支到遠端倉庫 git checkout master; git push origin master
[root@devops gitflowmodel]# git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 5 commits.
  (use "git push" to publish your local commits)
[root@devops gitflowmodel]# git push origin master
Username for 'http://192.168.163.154:32001': root
Password for 'http://[email protected]:32001': 
fatal: Authentication failed for 'http://192.168.163.154:32001/root/gitflowmodel.git/'
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git push origin master
Username for 'http://192.168.163.154:32001': root
Password for 'http://[email protected]:32001': 
Counting objects: 1, done.
Writing objects: 100% (1/1), 223 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To http://192.168.163.154:32001/root/gitflowmodel.git
   858d807..1ad3d55  master -> master
[root@devops gitflowmodel]# 
步驟 內容 git 命令
Step 11 推送tag資訊到遠端分支 git push origin 版本號
[root@devops gitflowmodel]# git push origin 0.1
Username for 'http://192.168.163.154:32001': root
Password for 'http://[email protected]:32001': 
Counting objects: 1, done.
Writing objects: 100% (1/1), 152 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To http://192.168.163.154:32001/root/gitflowmodel.git
 * [new tag]         0.1 -> 0.1
[root@devops gitflowmodel]#

確認分支狀態

[[email protected] gitflowmodel]# git log --graph --pretty=oneline
*   1ad3d55b2b35220d30f00be7da0c82d385aeb48d Merge branch 'release-0.1'
|\  
| * fcca679ee89ad9e2ed90e7b319ba78d10cd22dac add C4
| *   eb06c4ad2a9bd1f70d1ec3135f7b8bdc8703f41f Merge branch 'feature_F1001' into develop
| |\  
| | * fa40dce00a8878824641c281bd91e10749e8cc86 add C3
| |/  
| * e9aff8adf4b6344c5d7f59155134ef2e579f1e32 add C2
|/  
* 858d8070c8176c42e35f453a3394e4ff1bdc7e94 add C1
[[email protected] gitflowmodel]# 
[[email protected] gitflowmodel]# git branch
  develop
* master
[[email protected] gitflowmodel]# 
[[email protected] gitflowmodel]# git checkout develop
Switched to branch 'develop'
[[email protected] gitflowmodel]# git log --graph --pretty=oneline
*   ff52200742dc3515c85d41e206b4b7c5208881c2 Merge branch 'release-0.1' into develop
|\  
| * fcca679ee89ad9e2ed90e7b319ba78d10cd22dac add C4
|/  
*   eb06c4ad2a9bd1f70d1ec3135f7b8bdc8703f41f Merge branch 'feature_F1001' into develop
|\  
| * fa40dce00a8878824641c281bd91e10749e8cc86 add C3
|/  
* e9aff8adf4b6344c5d7f59155134ef2e579f1e32 add C2
* 858d8070c8176c42e35f453a3394e4ff1bdc7e94 add C1
[[email protected] gitflowmodel]# 

hotfix分支的使用過程

步驟 內容 git 命令
Step 1 以master分支為基礎建立hotfix分支 git checkout -b hotfix-版本號 master
[root@devops gitflowmodel]# git checkout -b hotfix-0.1.1 master
Switched to a new branch 'hotfix-0.1.1'
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git branch
  develop
* hotfix-0.1.1
  master
[root@devops gitflowmodel]#
步驟 內容 git 命令
Step 2 進行bug對應,然後進行提交 git commit -a -m “hotfix相關資訊”
[[email protected] gitflowmodel]# touch C5; git add C5; git commit -m "add C5";
[hotfix-0.1.1 7190442] add C5
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C5
[[email protected] gitflowmodel]# 
步驟 內容 git 命令
Step 3 切換至master分支 git checkout master
[root@devops gitflowmodel]# git checkout master
Switched to branch 'master'
[root@devops gitflowmodel]# 
步驟 內容 git 命令
Step 4 合併hotfix分支內容到master分支 git merge –no-ff hotfix-版本號
[[email protected] gitflowmodel]# git merge --no-ff hotfix-0.1.1
Merge made by the 'recursive' strategy.
 C5 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C5
[[email protected] gitflowmodel]# 
步驟 內容 git 命令
Step 5 設定tag git tag -a 版本號 -m “hotfix的tag資訊”
[root@devops gitflowmodel]# git tag -a 0.1.1 -m "hotfix for 0.1.1"
[root@devops gitflowmodel]# 
步驟 內容 git 命令
Step 6 切換至develop分支 git checkout develop
root@devops gitflowmodel]# git checkout develop
Switched to branch 'develop'
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git branch
* develop
  hotfix-0.1.1
  master
[root@devops gitflowmodel]#
步驟 內容 git 命令
Step 7 合併hotfix分支內容到develop分支 git merge –no-ff hotfix-版本號
[[email protected] gitflowmodel]# git merge --no-ff hotfix-0.1.1
Merge made by the 'recursive' strategy.
 C5 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C5
[[email protected] gitflowmodel]# 
步驟 內容 git 命令
Step 8 刪除hotfix分支 git branch -d hotfix-版本號
            
           

相關推薦

版本管理gitlab實踐教程(1)

實踐gitflow 結合git flow,使用gitlab作為遠端倉庫管理,在實際的專案中是一種可行的方式,而且這種方式對與複雜大型的專案有較好的適應方式。 git flow git flow源於Vincent Driessen在2010年提出的一個分

版本管理gitlab實踐教程基礎(1)

這幾篇文章主要面向對git和gitlab稍有基礎,但是又不太會用的使用者,通過這幾文章你可以學到如下gitlab的使用方法: sshkey的設定 建立專案 分支操作 使用者/許可權/組的操作 配置專案可見性 Merge Request Issues操作

版本管理gitlab實踐教程基礎(16)

這篇文章介紹一下如何修改初始管理賬號root的密碼。 命令列方式 確認gitlab-rails 使用gitlab-rails進行設定 which gitlab-rails /opt/gitlab/bin/gitlab-rails # #

版本管理gitlab實踐教程基礎(14)

這篇文章整理一下對gitlab/github進行clone或者push操作時,不需要每次提交都輸入使用者名稱/密碼的幾種方式。 場景 何時需要輸入使用者名稱/密碼 gitlab可以建立private/protected/public的倉庫,priv

版本管理gitlab實踐教程 1

實踐gitflow 結合git flow,使用gitlab作為遠端倉庫管理,在實際的專案中是一種可行的方式,而且這種方式對與複雜大型的專案有較好的適應方式。 git flow git flow源於Vincent Driessen在2010年提出的一個分支模型: 主要特點 兩個長期

版本管理gitlab實踐教程 基礎 1

這幾篇文章主要面向對git和gitlab稍有基礎,但是又不太會用的使用者,通過這幾文章你可以學到如下gitlab的使用方法: sshkey的設定 建立專案 分支操作 使用者/許可權/組的操作 配置專案可見性 Merge Re

版本管理gitlab實踐教程 基礎 3

symbol 為什麽 reg details pro == 什麽 操作 requests comment是版本管理中非常重要的內容,尤其是在經年累月的大型項目中,鐵打的項目,流水的SE,哪怕只言片語的留下,對後來者問題的對應很多時候都能起到重要作用,這篇文章用來講解

版本管理SVN實踐教程基礎(6)tag的查詢/建立/刪除/設定

這篇文章介紹一下在svn中tag操作的查詢/建立/刪除與設定。 查詢tag 因為因為tags目錄是apache建議的方式,其本質也就是一個目錄,所以查詢的方式可以結合svn list命令確認改目錄下的檔案資訊,以及svn log確認提交資訊來進行。

持續整合jenkins實踐教程基礎(2): 整合gitlab

作為持續整合的利器Jenkins已經得到了廣泛地應用,僅僅作為一個工具,Jenkins已然有了自己的生態圈,支援其的plugin更是超過1300+。在實際中如何使用以及如何更好地使用jenkins,一直是大家在實踐並討論的。本系列文章將會從如何使用jenki

持續整合jenkins實踐教程基礎(7): 控制檯輸出的中文亂碼

jenkins是Java開發的應用程式,很多東西可以通過-D傳入選項來進行設定,這篇文章以中文亂碼的調整為例子,來說明一下常見修改的方式。 現象 使用jenkinsfile定義的流水線,如果stage名稱為中文的時候,圖形顯示沒有問題,但是在consol

持續整合jenkins實踐教程基礎(6): 在jenkins的容器中進行映象的構建

作為持續整合的利器Jenkins已經得到了廣泛地應用,僅僅作為一個工具,Jenkins已然有了自己的生態圈,支援其的plugin更是超過1300+。在實際中如何使用以及如何更好地使用jenkins,一直是大家在實踐並討論的。本系列文章將會從如何使用jenki

持續整合jenkins實踐教程基礎(1): 郵件設定

作為持續整合的利器Jenkins已經得到了廣泛地應用,僅僅作為一個工具,Jenkins已然有了自己的生態圈,支援其的plugin更是超過1300+。在實際中如何使用以及如何更好地使用jenkins,一直是大家在實踐並討論的。本系列文章將會從如何使用jenki

Linux Capabilities 入門教程實戰

> 原文連結:[https://fuckcloudnative.io/posts/linux-capabilities-in-practice-2/](https://fuckcloudnative.io/posts/linux-capabilities-in-practice-2/) 該系列文章總共分為三

【老驥伏櫪-原創】製作黑威聯通啟動盤

原文網址:http://www.nasyun.com/forum.php?mod=viewthread&tid=39748&fromuid=106494 (出處: NAS雲論壇)   前言   本文是【老驥伏櫪-狗年大禮包】的續篇進階篇。關於破解韌體,

如何分析虛擬機器(2) VMProtect 2.13.8

原文網址:https://www.52pojie.cn/forum.php?mod=viewthread&tid=723307&page=1   序言 系列第1篇對一個極弱的虛擬機器 VMProtect 1.81 Demo 版進行

用python寫爬蟲的一些技巧

以前寫過一篇使用python爬蟲抓站的一些技巧總結,總結了諸多爬蟲使用的方法;那篇東東現在看來還是挺有用的,但是當時很菜(現在也菜,但是比那時進步了不少),很多東西都不是很優,屬於”只是能用”這麼個層次。這篇進階篇打算把“能用”提升到“用得省事省心”這個層次

SNMP從入門到開發

管理資訊庫:MIB 我們要擴充套件mib首先必須清楚mib是如何定義的,用的什麼語言,有哪些約定,遵循哪些規則等等。這些基本東西掌握過後,我們就可以很輕鬆的來寫自己的mib檔案了。 所謂管理資訊庫,或者MIB,就是所有代理程序包含的、並且能夠被管理程序進行查詢和設定的資訊

Android開發貝塞爾曲線(仿直播送禮物,餓了麼購物車動畫)

又是一年畢業季,今年終於輪到我了,最近一邊忙著公司的專案,一邊趕著畢設和論文,還私下和朋友搞了些小外包,然後還要還抽出時間寫部落格,真是忙的不要不要的。 好了,言歸正傳,前幾天寫了一篇關於貝塞爾曲線的基礎篇,如果你對貝塞爾曲線還不是很瞭解,建議你先去閱讀下:Android開發之貝塞爾曲線初體驗 ,今天這篇文

hadoopmapreduce詳解(

上篇文章hadoop之mapreduce詳解(基礎篇)我們瞭解了mapreduce的執行過程和shuffle過程,本篇文章主要從mapreduce的元件和輸入輸出方面進行闡述。 一、mapreduce作業控制模組以及其他功能 mapreduce包括作業控制模組,程式設計模型,資料處理引擎。這裡我們重點闡述

Nmap使用教程

什麼是防火牆? 防火牆是用來控制網路訪問的軟體或硬體。分為以下兩類:1、基於主機的防火牆;2、基於網路的防火牆。 基於主機的防火牆 這是在單臺主機上執行的軟體,用來控制入站流量(從網路向主機)和出站流量(從主機向網路)。這些軟體安裝於作業系統之上,常見例子就是Linux上面的iptables和Windows上