簡體   English   中英

如何編寫簡單的版本控制系統?

[英]How to code a simple versioning system?

我想做一個簡單的版本控制系統,但我沒有關於如何構建我的數據和我的代碼的想法。

這是一個簡短的例子:

  1. 用戶登錄
  2. 上傳文件時,用戶有兩個選項:
    • 提交一個新文件
    • 提交文件的新版本

用戶應該能夠看到樹。 (不同版本)樹最多只能達到2個級別:

|
|--File_A_0
 \--File_A_1
 \--File_A_2
 \--File_A_3
 \--File_A_4

還有兩種類型的文件,一個final(最新批准的版本)和一個草稿版本(最新上傳的文件)該文件將物理存儲在服務器上。 每個文件都由用戶(或更多)擁有,只有一個組。

編輯:組代表一組文檔,文檔只能由一個組一次擁有。 用戶不依賴於組。

開始編輯:

這就是我所做的,但效率並不高!

id_article | relative_group_id | id_group | title | submited | date | abstract | reference | draft_version | count | status

id_draft | id_file | version | date

但是很難管理,擴展。 我認為這是因為小組參議員......

結束編輯

所以問題是:

  • 我如何模式化我的數據庫?
  • 什么樣的信息應該對這項工作的版本有用?
  • 文件夾,文件是什么類型的結構?
  • 有什么樣的提示,提示你做這種工作嗎?

(該應用程序是用PHP和Zend Framework開發的,數據庫應該是mysql或postgresql)

看在上帝的份上, 不要 你真的不想走這條路。

暫時停下來考慮一下大局。 你想保留早期版本的文檔,這意味着在某些時候,有人會想要看到一些早期版本,對吧? 然后他們會問, “版本3和版本7有什么區別”? 然后他們會說, “我想回到版本3,但保留我在第5版中所做的一些更改,嗯,好嗎?”

版本控制非常重要,並且不需要重新發明輪子 - 那里有許多可行的版本控制系統,其中一些是免費的,甚至是免費的。

從長遠來看,學習其中一個系統的API會更加容易,並且會為您的用戶編寫一個Web前端,為您的用戶提供他們正在尋找的功能子集(現在)。

您不會為您的用戶編寫文本編輯器,是嗎?

你可以從那里獲得靈感。


關於你的評論:

至於數據庫結構,你可以嘗試這種結構(MySQL sql):

CREATE TABLE `Users` (
       `UserID` INT NOT NULL AUTO_INCREMENT
     , `UserName` CHAR(50) NOT NULL
     , `UserLogin` CHAR(20) NOT NULL
     , PRIMARY KEY (`UserID`)
);

CREATE TABLE `Groups` (
       `GroupID` INT NOT NULL AUTO_INCREMENT
     , `GroupName` CHAR(20) NOT NULL
     , PRIMARY KEY (`GroupID`)
);

CREATE TABLE `Documents` (
       `DocID` INT NOT NULL AUTO_INCREMENT
     , `GroupID` INT NOT NULL
     , `DocName` CHAR(50) NOT NULL
     , `DocDateCreated` DATETIME NOT NULL
     , PRIMARY KEY (`DocID`)
     , INDEX (`GroupID`)
     , CONSTRAINT `FK_Documents_1` FOREIGN KEY (`GroupID`)
                  REFERENCES `Groups` (`GroupID`)
);

CREATE TABLE `Revisions` (
       `RevID` INT NOT NULL AUTO_INCREMENT
     , `DocID` INT
     , `RevUserFileName` CHAR(30) NOT NULL
     , `RevServerFilePath` CHAR(255) NOT NULL
     , `RevDateUpload` DATETIME NOT NULL
     , `RevAccepted` BOOLEAN NOT NULL
     , PRIMARY KEY (`RevID`)
     , INDEX (`DocID`)
     , CONSTRAINT `FK_Revisions_1` FOREIGN KEY (`DocID`)
                  REFERENCES `Documents` (`DocID`)
);

CREATE TABLE `M2M_UserRev` (
       `UserID` INT NOT NULL
     , `RevID` INT NOT NULL
     , INDEX (`UserID`)
     , CONSTRAINT `FK_M2M_UserRev_1` FOREIGN KEY (`UserID`)
                  REFERENCES `Users` (`UserID`)
     , INDEX (`RevID`)
     , CONSTRAINT `FK_M2M_UserRev_2` FOREIGN KEY (`RevID`)
                  REFERENCES `Revisions` (`RevID`)
);

Documents是一個邏輯容器,Revisions包含指向文件的實際鏈接。 每當一個人更新一個新文件時,在每個表中創建一個條目,Revisions中的條目包含一個插入到Documents中的鏈接的鏈接。

表M2M_UserRev允許將多個用戶與文檔的每個修訂相關聯。

更新文檔時,僅在“修訂”中插入,並附加到相應的“文檔”。 要知道要鏈接到哪個文檔,您可以使用命名約定,或要求用戶選擇正確的文檔。

對於文件的文件系統架構,它確實沒關系。 我只是在將文件存儲在服務器上之前將其重命名為獨特的文件,並將用戶文件名保存在數據庫中。 只需將重命名的文件存儲在任何位置的文件夾中,並在數據庫中保留它的路徑。 這樣,您就知道如何在用戶請求時重命名它。 如果你確定它是唯一的,你也可以保留用戶給出的原始名稱,但我不會太依賴它。 您可能很快就會看到兩個不同的版本具有相同的名稱,另一個會覆蓋您文件系統上的另一個版本。

數據庫架構


為了保持極其簡單,我會選擇以下數據庫設計。 我將“ 文件 ”(與文件系統文件相同)概念與“ 文檔 ”( 文檔的gerarchic組)概念分開。

用戶實體:

  • 用戶身份
  • 用戶名

集團實體:

  • 的groupId
  • 組名

文件實體:

  • fileId(序列)
  • fileName(用戶為文件指定的名稱)
  • filesystemFullPath
  • uploadTime
  • uploaderId(上傳者用戶的ID)
  • ownerGroupId

文件實體:

  • documentId
  • parentDocumentId
  • FILEID
  • VERSIONNUMBER
  • 創建時間
  • 被批准

每次上傳新文件時,都會創建“文件”記錄,還會創建新的“文檔”。 如果是第一次上傳該文件,則該文檔的parentDocumentId將為NULL。 否則,新文檔記錄將指向第一個版本。

“isApproved”字段(布爾值)將處理作為草稿或批准修訂的文檔。
您可以獲得文檔的最新草稿,只需按版本號或上傳時間排序即可。

提示


從描述問題的方式來看,在遷移到數據庫模式設計之前,應該更好地分析這些方面:

  • 哪個是“團體”實體的角色?
  • 組/用戶/文件如何相關?
  • 如果不同組的兩個用戶嘗試上傳同一文檔怎么辦?
  • 你需要文件夾嗎? (可能你會;我的解決方案仍然有效,給“文檔”實體提供一個類型,“文件夾”或“文檔”)

希望這可以幫助。

現有的版本控制解決方案可能比滾動自己更好嗎? 顛覆可以做你想做的大部分,而且就在那里。

在傳統的關系數據庫(如MySQL)中創建豐富的數據結構通常很困難,並且有更好的方法來實現它。 使用具有層次結構的基於路徑的數據結構時,我喜歡創建基於平面文件的系統,該系統使用數據序列化格式(如JSON)來存儲有關特定文件,目錄或整個存儲庫的信息。

這樣,您可以使用當前可用的工具輕松地導航和操作結構,並且您可以輕松地閱讀,編輯和理解結構。 XML也適用於此 - 它比JSON稍微冗長,但易於閱讀,也適用於消息傳遞和其他基於XML的系統。

一個簡單的例子。 如果我們有一個包含目錄和三個文件的存儲庫。 在它前面看它會看起來像這樣:

/repo
  /folder
    code.php
  file.txt
  image.jpg

我們可以有一個元數據文件夾,其中包含我們在操作系統中隱藏的JSON文件,這些文件位於每個目錄的根目錄下,用於描述該目錄的內容。 這是傳統版本控制系統的工作方式,除了它們使用自定義語言而不是JSON。

/repo
  */.folderdata*
  /code
    */.folderdata*
    code.php
  file.txt
  image.jpg

每個.folderdata文件夾都可以包含它自己的結構,我們可以使用它來正確組織文件夾的數據。 然后可以壓縮每個.folderdata文件夾以節省磁盤空間。 如果我們查看/ code目錄中的.folderdata文件夾:

*/.folderdata*
  /revisions
    code.php.r1
    code.php.r2
    code.php.r3
  folderstructure.json
  filerevisions.json

文件夾結構定義了我們文件夾的結構,文件和文件夾彼此相關等。這可能看起來像這樣:

{
  '.':        'code',
  '..':       'repo',
  'code.php': {
    'author_id': 11543,
    'author_name': 'Jamie Rumbelow',
    'file_hash': 'a26hb3vpq22'
    'access': 'public'
  }
}

這允許我們關聯該文件的元數據,檢查真實性和完整性,保留持久數據,指定文件屬性以及執行更多操作。 然后,我們可以在filerevisions.json文件中保留有關特定修訂的信息:

{
  'code.php': [
    1: {
      'commit': 'ah32mncnj654oidfd',
      'commit_author_id': 11543,
      'commit_author_name': 'Jamie Rumbelow',
      'commit_message': 'Made some changes to code.php',
      'additions': 2,
      'subtractions': 4
    },
    2: {
      'commit': 'ljk4klj34khn5nkk5',
      'commit_author_id': 18676,
      'commit_author_name': 'Jo Johnson',
      'commit_message': 'Fixed Jamie\'s bad code!',
      'additions': 2,
      'subtractions': 0
    },
    3: {
      'commit': '77sdnjhhh4ife943r',
      'commit_author_id': 11543,
      'commit_author_name': 'Jamie Rumbelow',
      'commit_message': 'Whoah, showstopper found and fixed',
      'additions': 8,
      'subtractions': 5
    },
  ]
}

這是文件版本控制系統的基本大綱計划 - 我喜歡這個想法以及它是如何工作的,並且我過去使用過JSON來實現這樣豐富的數據結構。 這種數據不適合像MySQL這樣的關系型數據庫 - 隨着您獲得更多修訂和更多文件,數據庫將變得越來越大,這樣您就可以錯開多個文件的修訂,保留所有內容的備份,制作確保你有跨接口和平台等的持久數據。

希望這給了你一些見解,希望它也能為社區提供一些思考的食物!

我最近為一些靜態數據實體構建了一個簡單的版本控制系統。 要求是具有“活動”版本和0或1個“待定”版本。

最后,我的版本化實體具有與版本控制相關的以下屬性。

VersionNumber(int / long)ActiveVersionFlag(boolean)

哪里:-

  • 只有1個實體可以是ActiveVersionFlag ='Y'
  • 只有1個實體可以是版本號>“活動”版本(即“待定”版本)

我允許的那種操作是

克隆當前版本。

  • 如果已經存在版本>“活動”版本的版本號,則會失敗
  • 將所有數據復制到新版本
  • 將版本號遞增1

激活待定版本

  • 如果指定的版本不是“活動”版本+ 1,則失敗
  • 找到'Active'版本並將其ActiveVersionFlag設置為'N'
  • 將“待定”版本的ActiveVersionFlag設置為“Y”

刪除待定版本

  • 刪除待處理實體

這是相當成功的,我的用戶現在克隆和激活所有的時間:)

邁克爾

對於數據庫模式,您可能需要兩組信息,文件和文件版本。 存儲新文件時,也會創建初始版本。 必須明確存儲最新批准的版本,而最新版本可以從版本表中選擇(通過查找與文件相關的最高版本,或者如果在創建時存儲,則為最新日期)

files(id,name,approved_version)
file_versions(id,fileId)

然后可以使用它們的ID(例如,'/ fileId / versionId'或'/ fileId / versionId_fileName')在服務器上存儲文件版本,其原始名稱存儲在數據庫中。

從現有的內容管理系統開始 ,如果符合您的要求,請使用PHP和MySQL,例如eZ PublishKnowledgetree 為了快速測試這些應用程序, Bitnami還提供了快速安裝的“ 堆棧 ”(類固醇上的WAMP堆棧)。

然后,您可以根據組織需求定制這些應用程序,並隨時了解上游的變化。

作為我上一篇文章的替代方案,如果您認為層次結構最好,您可能希望使用平面文件存儲,並通過Web服務公開API。

服務器將具有其數據根目錄,您可以將文件組(文件)存儲在文件夾中,每個文件夾中都有一個根元數據條目。 (也許是XML?)

然后,您可以使用包含在API中的現有修訂控制工具,或者自己滾動,將文件的修訂保留在文件夾中項目下方的修訂文件夾中。 檢查修訂,並使用文件I / O命令執行文件I / O. 將API公開給Web應用程序或其他客戶端應用程序,讓服務器通過XML文件確定文件權限和用戶映射。

遷移服務器? 郵編和副本。 跨平台? 郵編和副本。 備份? 郵編和副本。

例如,這是我喜歡Mercurial DVCS的平面文件后端。

當然,在這個小例子中,.rev文件可能有revisions.xml文件中定義的日期,時間,壓縮等。 如果要訪問其中一個修訂版,則公開AccessFile()方法,服務器應用程序將查看revisions.xml,並確定如何打開該文件,是否授予訪問權限等。

所以你有了

DATA
| + ROOT
| | . metadata.xml
| | |
| | + REVISIONS
| | | . revisionsdata.xml
| | | . documenta.doc.00.rev
| | | . documenta.doc.01.rev
| | | . documentb.ppt.00.rev
| | | . documentb.ppt.03.rev
| | |___
| | |
| | . documenta.doc
| | . documentb.ppt
| | |
| | + GROUP_A
| | | . metadata.xml
| | | |
| | | + REVISIONS
| | | | . revisionsdata.xml
| | | | . documentc.doc.00.rev
| | | | . documentc.doc.01.rev
| | | | . documentd.ppt.00.rev
| | | | . documentd.ppt.03.rev
| | | |___
| | |
| | | . documentc.doc
| | | . documentd.ppt
| | |___
| | |
| | + GROUP_B
| | | . metadata.xml
| | |___
| |
| |___
|
|___

它並不像看起來那么簡單。 閱讀Eric Sink 撰寫的關於存儲這些文件的存儲意義的文章

或許更好的問題是加載什么類型的文件,它們是否適合版本控制(如文本文件)

我認為這描述了完美的版本控制系統

http://tom.preston-werner.com/2009/05/19/the-git-parable.html

查看ProjectPier (最初是ActiveCollab )。 它有一個與此類似的系統,您可以查看它們的來源。

上傳文件是1990-ty =)看看Google Wave! 您可以圍繞其“版本控制”框架構建整個應用程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM