2013年2月20日 星期三

控制某排的checkbox全選與不選

<script language="JavaScript"><!--
function check_all(obj,cName) {
var checkboxs;
try
{
checkboxs=document.getElementsByClassName(cName);
}
catch(e)
{
checkboxs=document.getElementsByName(cName);
}
for(var i=0;i<checkboxs.length;i++){
checkboxs[i].checked = obj.checked;
}
}
--></script>

<TABLE WIDTH="100%" CELLSPACING=2 CELLPADDING=3 BORDER=0>
<FORM method="post">
<TR>
<TD align="center"><B>02</B><input type="checkbox" name="all" onClick="check_all(this,'20110802');" title="全選/非全選"></TD>
<TD align="center"><B>星期二</B></TD>
<td><input type="checkbox" class="20110802" name="fm_data[roomset][]" value="20110802-2-1">未使用</td>
<td><input type="checkbox" class="20110802" name="fm_data[roomset][]" value="20110802-2-2">未使用</td>
<td><input type="checkbox" class="20110802" name="fm_data[roomset][]" value="20110802-2-3">未使用</td>
<td><input type="checkbox" class="20110802" name="fm_data[roomset][]" value="20110802-2-4">未使用</td>
<td><input type="checkbox" class="20110802" name="fm_data[roomset][]" value="20110802-2-5">未使用</td>
<td><input type="checkbox" class="20110802" name="fm_data[roomset][]" value="20110802-2-6">未使用</td>
<td><input type="checkbox" class="20110802" name="fm_data[roomset][]" value="20110802-2-7">未使用</td>
<td><input type="checkbox" class="20110802" name="fm_data[roomset][]" value="20110802-2-8">未使用</td>
<td><input type="checkbox" class="20110802" name="fm_data[roomset][]" value="20110802-2-9">未使用</td>
</TR><TR>
<TD align="center"><B>03</B><input type="checkbox" name="all" onClick="check_all(this,'20110803');" title="全選/非全選"></TD>
<TD align="center"><B>星期三</B></TD>
<td><input type="checkbox" class="20110803" name="fm_data[roomset][]" value="20110803-3-1">未使用</td>
<td><input type="checkbox" class="20110803" name="fm_data[roomset][]" value="20110803-3-2">未使用</td>
<td><input type="checkbox" class="20110803" name="fm_data[roomset][]" value="20110803-3-3">未使用</td>
<td><input type="checkbox" class="20110803" name="fm_data[roomset][]" value="20110803-3-4">未使用</td>
<td><input type="checkbox" class="20110803" name="fm_data[roomset][]" value="20110803-3-5">未使用</td>
<td><input type="checkbox" class="20110803" name="fm_data[roomset][]" value="20110803-3-6">未使用</td>
<td><input type="checkbox" class="20110803" name="fm_data[roomset][]" value="20110803-3-7">未使用</td>
<td><input type="checkbox" class="20110803" name="fm_data[roomset][]" value="20110803-3-8">未使用</td>
<td><input type="checkbox" class="20110803" name="fm_data[roomset][]" value="20110803-3-9">未使用</td>
</TR></TABLE>
</FORM>
以上文章摘自http://twpug.net/modules/newbb/viewtopic.php?topic_id=6195

2013年2月19日 星期二

SVN:Branch By Abstraction


lesser-known source-control best practice I’ve been pushing for a number of years is “Branch by Abstraction”. It is not my invention, and has been best practice for many years, but how about it is given a name. The suggestion is that you can convene large sets of developers in a single trunk (Trunk Based Development) and avoid “short lived feature branches” that you have to merge back. The problem being with feature branches is that the current state of any one of them might be unable to be deployed for a number of weeks while the team gets it right. Those branches just end up running and running ….

Provisos

There are some general provisos for the single as opposed to composite trunk design, that coincide with hard-core Agile development:
  • You’ve broken your application into multiple components.
  • Each component into a directory inside the trunk (possibly hierarchical).
  • Each directory its own source self-contained and its own build (possibly hierarchical).
  • You have a good set of unit tests and consider them important enough to illustrate snippets of example usage.
  • Continuous Integration drives things, even for hundreds of components, that drops items into a Maven-like repository. CruiseControl has a nice directive that with the directive that allows you to set up the killer CI installation that is branch-ready meaning you can run without a dedicated CI administrator.
  • Your management are good at release planning.
  • Developers are in the habit of never breaking the build :-)
Your trunk may look like:
  
    trunk/
      foo-components/
        foo-api/
        foo-beans/
        foo-impl/
          build.xml
          src/
            java/
            test/
          cruisecontrol-config-snippet.xml
        remote-foo/
      bar-services/
        bar/
          build.xml
          src/
            java/
            test/
          cruisecontrol-config-snippet.xml
        bar-web-service/

So back to the problem..

What to do when (if) your team says they want need to shift from Hibernate to iBatis (hypothetical case). There could be thousands of classes that depend on Hibernate. The architects might suggest that the build will be broken for weeks so a separate branch is the best place for this change. Instead, lets try Branch by Abstraction (BBA) instead of the traditional “Branch by Source Control” ( Stacy Curl coined the name by the way – I’m trying to shame him into writing a better blog article than this one).

The steps to living Branch By Abstraction

With your most responsible developers -
  1. Introduce an abstraction over the core bits of the big thing you’re going to change and commit
  2. Update all the bits of code that were formerly using the thing directly to use it via the new abstraction and commit
  3. Make a second implementation of the abstraction, with unit tests that specifically test its core functionality and commit
  4. Update all the code from (2) to use the new implementation (still via the abstraction)* and commit
  5. Deprecate the first implementation (or skip to 6 if you don’t want a respectful grace period).
  6. Delete the first implementation (its proven there is no need for you to go back).
  7. Remove the abstraction (if it is inelegant).

Benefits

  • Only a small team is even bothered by the change.
  • You can go live at any stage – because the larger application works at all times.
  • Management can be adaptive about scheduling.
  • Avoids merge hell.
  • Introducing Abstraction helps increase understanding/modeling of piece – which is useful in itself.
Of course, BBA is not a panacea . It is just a practice that developers/architects can often do it when architects with less nerve are suggesting yet another long running feature branch. Architects should strive to do BBA instead of new feature branches – Architects should not hope to reach a situation where they can declare at the outset that a new branch is the “only way” to achieve something.

Oh by the way, ClearCase sucks

A buddy last week was telling me of 21 significant branches who’s merge order was uncertain in his nameless client. Sucks. He smiled wryly when I guessed ClearCase as their SCM choice. ClearCase whether in dynamic, static or UCM modes has no place in Agile development efforts. It is a self fulfilling prophesy that requires dozens of administrators a few black-belt merge-meisters and multiple branches and causes long development cycles, waterfall thinking and high staff turnover. The only thing worse than it is PVCS (who owns it now?). Anyone wanting a good SCM tool for Agile development should be looking at Perforce (a favorite because cos Intellij works very well with it) or Subversion. Subversion will overtake Perforce one year soon I guess [note: Early 2007 comment].

When do you branch then?

Ideally for release only.
  
    trunk/
    releases/
      rel-1.0/
      rel-1.1/
      rel-1.2.x/
You may branch some days before release, then “production harden” the branch on a staging box. You’re not going to give permissions to all developers to that branch, just a couple who are ensuring its ready and handling later merges (one’s or two’s only if at all). You branch the release from trunk of course – given that CI proved that trunk was at all times pretty solid.
As well as Stacy Curl, I’m hoping Martin writes an article on this important practice. He is better with words than me.
Written April 26, 2007

Update (May 2nd, 2009)

So the state of the art has shifted some from Subversion to Mercurial, GIT and (some burn a candle to it) Bazaar. Prior to this update, the blog article concerns trunk best practice, and is preaching to a multi-branch development team that “trunk based development” can work for you with discipline. That discipline is “Branch by Abstraction” and “little and often” commits. Of course, the team is trying to push towards Agile ad an increase in the frequency of deployments to production, with fewer defects each time. ClearCase is often where they are coming from. So I had a FX trading client in 2005 that I persuaded to move from multi-branch development to trunk-based. There was a lot of choreography to move from the entangled source tree represented in fifty branches to a trunk metaphor broken out into buildable components as outlined. It took months of course be left them with a clearer understanding of their workflow and asset control.
Later in 2005, Roy Singham (ThoughtWorks owner), made me fly in the middle of the OSCONconference (!) to CollabNet’s offices to present on Subversion and the importance of trunk based development as a way for their sales engineers to pitch in corporations who are otherwise invested in ClearCase, StarTeam, PVCS etc. The theory being that Subversion is a sellable piece in its own right, and that the larger Collab stack was not the only product/service of theirs worth talking about to clients.

Multi branch versus trunk diagrams

Here is a diagram of an often encountered development team branching choice : Multi branch. Merges are happening in multiple direction all the time. Some branches are long lived, some short. Some branches concern functional enhancements (business value) and others are for non-functional technical reasons (like a shift from RDMBS to a distributed database). Its chaos – the department pushes to production from any of the branches that allege that they need to go live and have all of the integrations needed. Here are the bad things associated with multi branch :
  1. For weeks at a time, an individual branch can be in an undeployable state
  2. the development team will report that merging is a major part of their day, and fraught with complexity given (1)
  3. Often there are regressions, as a merges are missed, and the business yells at the IT dept.
  4. Labeling and handling labels makes you consider another career
Contrast to the trunk model:
So here we see concentrated development on the trunk (actually we imply that, see the diagram below). We also see releases exclusively from release branches. We see only bug fixes on the release branches, and merges back to trunk (though we might hope that all bugs are fixed on the trunk, and merged to the release branch). We see something that is not only buildable at all times, but is also deployable from anywhere with a day’s notice. Of course you are not going to deploy from just anywhere, but imagine that as a requirement from the business – “be ready to go live within a day’s notice, and have a high level of confidence”.
A day in the life of two trunk developers..
  1. Checkout : 2 minutes (100BaseT network)
  2. Checkout : 2 minutes
  3. Update/Sync (speculative) : 3 seconds
  4. Update/Sync (speculative) : 3 seconds
  5. Update/Sync (speculative) : 3 seconds
  6. Commit : 10 seconds (10 java files)
  7. Update/Sync (speculative) : 6 seconds (10 java files)
  8. Commit : 10 seconds (6 java files)
  9. Update/Sync (speculative) : 3 seconds
  10. Update/Sync (speculative) : 3 seconds
  11. Commit : 10 seconds (5 java files)
This is just showing regular life in the trunk, and not branch by abstraction commit by commit per se.
Moving to trunk based development on a nimble SCM
Flipping from ClearCase to a Subversion or Perforce. Some clients take a phased approach, some do a big bang. One automotive client did the latter in a lunch break. Wherever it happens, you will hear reports of increased personal productivity from 20% to 33%.
Be aware though that ClearCase requires admins. As much as one admin to twenty developers. They’ll want to put up a case for not switching SCM tools. I’m sure that Perforce and Subversion require admins. As Google apparently use Perforce , I wonder how many of twenty thousand staff use ‘p4 admin’ on a daily basis. Not many I hope.

On Distributed?

Agile teams report productivity improvements over Perforce or Subversion. There’s no doubt that’s true at least today, but the Subversion team is pushing towards the features of their distributed competitors. At least, one feature at a time. I wonder though, if a team should not be adept with trunk-based development (BBA and “little&often”) before they move to distributed. That is a longer discussion.
[ article published: Apr 26th, 2007 ]

Update: Dec 7th, 2010

Update: May 13th, 2011

Jez Humble linked back to me on his experience report for BBA (thanks Jez). Ironically, he’s performing the change from iBatis to Hibernate which is the opposite of the hypothetical case that I’d made some years ago.
After reading his article and seen some field usage of BBA, I wanted to say some more.

Avoid big bang

If you can help it, you should not do the cutover from A to B in a big bang. Imagine you had a set of components that you needed to change in some way, that was going to take some time. Perhaps a longer time than you’re production release interval. Say that was three months, and your team was in the habit of pushing production releases monthly like clockwork.
Strategy A (big bang).
1) You take your starting set of components like so
2) work over three months to get them all in the finished state. Commit to trunk of course, but provide a feature toggle that is ‘old implementation’ for everyone on trunk, and the two production release branches that were made from it, with only yourself and a CI build pipeline as seeing the ‘new implementation’. Like so:
3) When finished, and everyone agrees, then flip the switch (toggle) for everyone (including the next live release). Then, when that has been in production for a while, remove the switch and the old implementation (and perhaps the abstraction if it was not useful for unit testing):
Strategy B: Iterative instead of Big Bang
Instead, how about an iterative approach where components are turned on as they are completed. You would be forcing all developers to take the changed implementation, and production releases that go out. You would not need to hold on to the old implementation as long, and the switch/toggle is somewhat less magnificent. This feels safer to me.
The less than magnificent switch/toggle is still there of course, but it only concerns the single component that you’re currently working on. At any moment in time, as viewed by everyone else on trunk, or the folks concerned with releases, some components have the old implementation, and some have the new ones. Over the three months the transition is completed, and everyone gets to use the new implementation as it is progressively rolled out.
Of course, you still need to introduce the abstraction throughout the codebase before you start to change the first implementation.
The benefits of this approach?
You are able to defuse these allegations:
“you’ll never finish”
“devs in other teams are still making old implementations, therefore you new version is at risk”
“there is too much at risk for the big bang, as it has never been tested properly”

Agile teams and BBA

There’s some responsibility needed using BBA in Agile teams. Practitioners of XP (and alike) are bound to love refactoring. There’s going to be pain from merging to working-copy as much as there is to any branch (all SCM tools to variable degrees irrespective of workflow). Therefore responsibility is needed. If someone wants to rename every and package to fit with some new understanding of the application, then you have to be 100% sure the thing is going to merge to whatever developers don’t have committed. Git (and alike) hit the new high-bar of SCM, merge through rename , quite well so could cope, but lesser SCM tools might not. If you understand that refactoring is not refactoring+make some other changes, then it might be polite to notify developers that you’re about to to a big rename/move thing and they might want to a) checkin stuff they are doing if timely, and b) go to lunch.

Ball of Mud vs Hairball

Jez cites Brain Foote’s ball of mud article. I’ve met Brian a couple of times, and he’s engagingand entertaining , but I’m not sure that ball of mud is the right metaphor for the entanglement we see in enterprise application development. I think ‘hairball’ is. Imagine the thing a cat coughs up, with implicit horrific entanglement.

以上文章摘自http://paulhammant.com/blog/branch_by_abstraction.html/

SVN: 常用管理分支(Branching)方式


三月 31, 2011
好久沒 PO 文了, 自從開始工作之後越來越少時間能做一些有的沒的事, 包含分享一些東西, 以前看不懂英文, 總覺得為什麼中文的資源總是這麼的少, 現在看的懂英文卻懶的將這些文章一一的翻譯成中文, 看的速度遠比打字的速度還要快, 我這條小鯨魚有時也只能量力而為。
或許很多人都對 SVN 不陌生, 也了解 Version Control 的意涵, 但在實際的開發上, 不僅僅只是要會用這些工具, 而是要能將這些東西合理順暢的在團隊的運作中使用. 並且讓所有人了解, 在我第一次將 SVN 導入開發團隊的工作中也吃了不少苦頭, 絕大多數沒有 Version Control 概念的使用者, 沒有辦法理解這樣的制度, “為什麼要 commit, 要 update 這麼麻煩", “我的程式碼一 update 後就壞了怎麼辦", 更有人是放出大絕招, 把檔案直接砍了用自己原本的蓋回去, …也就是跟別人 conflict 的東西全消失了…只剩他的, 換言之別人的心血也全沒了…。
SVNBook 其實很詳盡, 但內容太多, 所以我只能就有需要的部份翻譯, 讓大家了解概念, however, 剛好今天抽了點時間把 SVNBook 中  Common Branching Patterns 的內容做了一點翻譯, 裡面說明實務上管理 branch 常用的方式.
————————————————————————————————————————-

SVN-常用的分支方式

SVN 中分支與合併有很多不同的用法,這個小節只說明常用的幾種方式。
版本控制經常被用在軟體的開發上,這裡介紹兩個程式設計師所最常使用的方式。如果您目前並非使用 Subversion 做為軟體開發的工具,您可以跳過此節。如果您是個第一次使用版本控管系統的軟體開發者,那就需要認真了解,因此這幾個方式是被有經驗的使用者認為最適合做 為範例案例。以下談到的流程並不僅限用於 Subversion,也可以應用在其他的版本控管系統。

發佈用分支(Release Branches)

大部份的軟體常見的生命週期為: 開發(Code), 測試(Test), 發佈(Release), 循環(Repeat)。在這樣的流程式當中會有兩個問題:
第一, 開發團隊需要開發新的功能的同時, 品管團隊需要持續的測試來維持軟體的穩定性, 新的開發工作並沒有辦法等待軟體測試而中斷。
第二, 開發團隊通常需要去維護舊有已發佈的版本,若在這些舊有的版本中發現問題,客戶會想要立即修正目前的問題,而不想等待其他新的主要功能開發完畢才發佈的版本。
這就是版本控管所能解決的問題,常見的處理流程如下:
  1. 開發團隊會持續送交(Commit)所有新的開發內容到主幹(Trunk)。
    開發團隊每天都會不停持續的修改並且將修改的內容送交到 /trunk: 不論是新功能、問題修正、等等。
  2. 將主幹複製成為 “發佈用" 分支。
    當開發團隊認為軟體已經可以準備發佈 (例如: 1.0 release), 則會從 /trunk 複製一份分支到 /branches/1.0。
  3. 開發團隊與品管團隊同時進行工作。
    品管團隊對要準備發佈的分支進行測試,而開發團隊則繼續開發 (例如: 2.0) 於 /trunk,如果發現有錯誤同時存在兩個分支,則會將問題的修正移植(Ported)到分支,並且繼續開發。在任何時間都可以做這件事,即使開發的流程 已經中止。當最終的測試完成時會將分支凍結(Frozen)停止修改並等待發佈。
  4. 將分支標記(Tagged)並且正式發佈。
    當測試結束,/branches/1.0 會被複製到 /tags/1.0.0 做為備份,並且將已標記的版本打包(Packaged)並正式發佈給客戶。
  5. 當分支維護一段時間後。
    當 2.0 的開發工作一直持續在 /trunk 進行,錯誤的修正也會持續從 /trunk 移植到 /branches/1.0。當累積足夠的錯誤修正,管理者可能會決定發佈 1.0.1 release: 再將 /branches/1.0 複到 /tags/1.0.1,並將 /tags/1.0.1 打包並發佈。
整個流程不停的重複循環,當 2.0 開發工作完成,則會建立新的 2.0 發佈用分支,經過測試、標記直到最後的正式發佈。
幾年過後,儲存庫(Repository)上會有數個以 “維護中(Maintenance)" 的狀態存在的分支(Branch),並且有數最終已發佈的版本的標記(Tag)。

開發用分支(Feature Branches)

特色分支(Feature Branches),這邊稱做開發用分支,它是一個暫時的分支,用在複雜的開發工作,可以避免影響 /trunk 的穩定性。與發佈用分支不同的是 (可能需要永久維護),開發用分支最終會合併(Merge)回到主幹,然後永久移除。
開發用分支的使用時機會隨著專案的管理政策有廣泛影響。
有些專案不使用開發用分支: 這些專案將所有的修改都送交到 /trunk,這樣的好處是管理方式非常的簡單–沒有人需要學習分支(Branching)與合併(Merging)的管理。缺點是主幹的程式碼時常處 於不穩定(Unstable)或不可用(Unusable)的狀態。
也有一些專案會極端的使用分支: 沒有任何的修改會直接送交到主幹,即使修改內容非常微小、使用的分支的時間非常短暫,也會一一經過嚴密的審查(Review)過後才合併到主幹,然後分支才會被移除,這樣的管理方式使主幹擁有異常的穩定性及可用性,但會耗費巨大的開銷。
大多數的專案會採用中傭之道,這些專案堅持使用 /trunk 開發並且測試。但需要大量的修改會使送交的內容不穩定的時候,就會使用開發用分支。良好的經驗法則是先考慮以下的問題:如果開發人員獨立開發數天並一次送 交大量的修改內容 (為了維持 /trunk 在穩定的狀態),這樣的修改幅度是否會導致管理人員審查? 如果您的答案是 “是",那麼這些修改應該在開發用分支中進行。因為這樣開發人員能將修改內容逐一送交到分支,而不是一次送交大量的修改內容,如此一來管理人員就能較輕易 的去審查這些修改內容。
最後, 還有一個問題是如何保持開發用分支與主幹的內容保持同步(Sync)。如先前所提到的,讓一個分支獨立開發數週或數月有很大的風險,主幹依然會持續開發,在這樣的情況之下若主幹與分支的開發內容差異過大,那合併分支回主幹的工作將會成為一場惡夢。
這個問題最好的解決方法是定時的合併主幹的修改內容到分支。訂定一個方針: 每週一次, 將最新一週主幹的開發內容合併到分支。
直到一直都有在進行同步的開發用分支要準備合併回主幹。要將分支合併回主幹,需先將最新版本的主幹內容合併至分支,這個動作是確認除了您在分支所修改的內容以外,其餘的部分會與主幹完全相同,最後使用 –reintegrate 參數將分支合併回主幹。
————————————————————————————————————————-
原文的參考文件其實很多, 我隨便挑了一個, 可以參考以下網址的圖片會更容易了解

SVN 檔案庫備份及同步


2007/06/14 16:51
以下是有關SVN備份及同步的工作記事 有關SVN的架設及使用請看這一篇


SVN Server端檔案庫備份


svnadmin hotcopy 原始檔案庫路徑 要備份目標路徑

例如

svnadmin hotcopy D:\SVNRoot\Proj1 E:\SVNBack\Proj1

另外 備份目標必須為空目錄
所以備份前需要先刪除舊有資料 或是建立新資料夾
可以使用windows所提供的批此檔及排程來自動備份
批次檔內容例如下方

@echo off

set SVN_BackUp=E:\SVNBackup
set SVN_ROOT=D:\SVNRoot
set SVN_BackUp_Dir=%SVN_BackUp%\%date:~0,4%%date:~5,2%%date:~8,2%

if not exist %SVN_BackUp% mkdir %SVN_BackUp%
if exist %SVN_BackUp_Dir% goto ALREADY_EXIST_DATE
mkdir %SVN_BackUp_Dir%
for /r %SVN_ROOT% %%D in (.) do @if exist "%%D\conf\svnserve.conf" svnadmin hotcopy %%~fD %SVN_BackUp_Dir%\%%~nD
goto END

:ALREADY_EXIST_DATE
echo 目錄%SVN_BackUp_Dir%已存在

:END

將上方內容存檔到D:\SVNRoot\BackUp.bat
並利用Windows排程 每天晚上10點備份

at 22:00 /every:s,m,t,w,th,f,sa "D:\SVNRoot\BackUp.bat"


不過這一個功能僅能本機端使用
可以注意到svnadmin後面的參數給的都是本機端的路徑
所以處理檔案也都不需要經過SVNService


SNV 檔案庫同步

在新版的SVN提供了SVNSYNC的程式 可以達成兩個檔案庫之間的同步
和上方備份不同的是 他可以經由遠端來運作 因此可以備份到不同電腦上
另外在備份之前不需要刪除舊有資料 因為他是同步
Subversion的官網上雖然有文章介紹如何使用
不過是針對Linux的環境下的說明...
那在Windows雖然很類似 不過要作一些修改

首先 要建立同步目標的檔案庫

svnadmin create DestRepository

然後設定DestRepository的Conf檔跟建立一個新的帳號 (例如"SvnSync")
並在來源檔案庫新增一筆一樣的帳號密碼
並且在hooks的目錄下建立一個新的檔案叫
"pre-revprop-change.bat"
檔案內容使用空白即可運作
不過這一個目標檔案庫有一個限制 他不應該被一般使用者Commit資料上去
也就是說應該只有svnsync可以對他作寫入的動作
應此建議將檔案內容修改為下列所述

@echo off

set repos=%1
set rev=%2
set user=%3
set propname=%4
set action=%5

if not '%user%'=='SvnSync' goto ERROR_USERNAME
exit 0
:ERROR_USERNAME
echo Only allow user SvnSync. >&2
exit 1 

此動作是檢查使用者帳號是否為SvnSync (大小寫有分)
如果要不分大小寫 請將此行改為

if /I not '%user%'=='SvnSync' goto ERROR_USERNAME


接下來要對此檔案庫做初始化的動作 讓他知道要跟哪個來源作同步

svnsync init --username SvnSync --password XXX 目標檔案庫位址 來源檔案庫位址

這一個命令的目標跟來來源都是使用位址 因此可以使用本地端或是遠端路徑
例如

svnsync init --username SvnSync --password XXX file:///E:/SVNBackup/DestRepository svn://SVNServer/SourceRepository

注意 本地端位置中斜線的方向跟數量

最後就是同步的動作

svnsync sync --username SvnSync --password XXX 目標檔案庫位址

同樣的 我們可以寫一些批次檔來達成自動化的目的
方式是在來源檔案庫的hooks的目錄下 建立一個新檔案叫做
"post-commit.bat"
他會在來源檔案庫接受每一次的Commit之後啟動 內容為下

@echo off
svnsync sync --non-interactive --username SvnSync --password XXX svn://SVNServer2/DestRepository

這邊是備份到跟來源檔案庫不同的Server上
可以依據每個人不同的需求作更動...

結論是 新的1.4版中的svnsync實在很好用
上半段文章看看就好 使用hotcopy的方式實在是太浪費磁碟空間了
不過前提示 要先把伺服器換成1.4版或以後的版本
並且 目標檔案庫必須是使用1.4版以後的svnadmin所建立的

另外可以發現 寫一些批次檔放進hooks目錄中
可以達成蠻多功能的 有興趣可以網路上搜尋一下文章看看

希望此文章對有使用SVN並架設在Windows上的人有一些幫助

update
如有遇到同步失敗, 或是不同Thread同時要進行同步造成鎖定而錯誤
可使用下列指令解決鎖定

svn propdel svn:sync-lock --revprop -r 0 目標檔案庫位址

Subversion之路--实现精细的目录访问权限控制(v1.0 更新于2006.12.05)



(终于提交正稿了,从开始动笔到现在提交正稿,由于私人原因,整整经过了半年时间方才结束,惭愧!对于那些因为本文的错误而走了弯路的网友们,本人深表歉意。
非常感谢各位读者的关注,在这半年时间里面,正是各位的支持,才让我鼓起勇气,持续着将文章写完。
本人其实就是个业余爱好者,不是专业人士,因此文章里面的错误在所难免,希望各位斧正,以免让我混淆视听。)


================
Subversion之路
================
----------------------------
实现精细的目录访问权限控制
----------------------------
:作者: 郑新星
:联系: zhengxinxing gmail com
:状态: 正稿
:版本: 1.0
:修订: $Id: The.Road.to.Subversion_authz.rst 1749 2006-12-05 08:05:59Z zhengxinxing $
:版权:  作者保留对本文的一切修改、发布等权力。任何人想要转载本文部分或全部内容时,必须保留包括作者、联系、状态、版本、修订、版权,共六项信息,并给出出处。对本文的参考引用,则不受限制。
:关键词: Subversion 目录访问 权限
:献辞:
    仅以本文,献给中国广大的自由软件爱好者们
:摘要:
    本文从一个实际的例子入手,介绍了如何利用 Subversion 自带的目录管理功能,来实现对项目目录的精细访问权限的控制。同时描述了在配置的过程中,需要注意的一些地方,如对中文的处理等。
.. section-numbering::
.. contents:: 目 录
   :backlinks: top

前言
====

Subversion 权限简介
-------------------

在 Subversion 的使用当中,存在“认证”、“授权”两个概念。认证,即 authentication,是指用户名与密码的认证。授权,即 authorization ,是指某用户对某个目录是否具备读、写权限的一种审核。这两者配合作用,就组成了 Subversion 的整个帐户管理体系。

在实际的工作当中,我们有时候会遇见需要控制项目目录的访问权限的情况,比如说对项目的一些关键模块进行限制,仅允许少数授权人士才可以修改等。由于项目的目录本身就是作为版本库的一个部分被 Subversion 所收管,所以我们无法利用操作系统的帐户权限体系,来实现授权控制。因此,这个问题就只有让svn自己来解决了。

Subversion 提供了面向目录的帐户权限管理功能,通过它,我们就可以很精确地实现项目目录的访问控制。不过在 1.2 及其以前的版本,我们只能利用 mod_authz_svn.so 模块,结合 Apache服务器来实现目录访问控制,这对于对 Apache 的配置与使用不是很熟悉的人来说,就不是很方便了。而Subversion终于在 1.3 版本上,在 svnserve.exe 服务器里面添加了这一功能,方便了很多人。


其他信息
--------

本文面向那些 Subversion 的管理员,或者任何对 Subversoin 有兴趣的人们。本文假定读者对Subversion有一定的了解,因此不打算对所有涉及到的安装、使用,做一个细节性的描述。若对于文章中描述的其他细节方面有所疑问,请访问“参考文献”一节里面的参考资料。如果你对本文任何地方有什么意见,或者发现本文有着大大小小的错误,请联系 zhengxinxing gmail com 。


本文是基于 Subversion 1.3.2、MS Windows 2003 Server Edition 平台来编写的,且 Subversion 服务器是利用 svnserve.exe 来架设的。不过,本文讲述到的绝大多数内容,都是不仅与操作系统平台无关,而且与是采用 svnserve(.exe) 还是使用 Apache 来作为 Subversion 服务器也基本无关。因此为免罗嗦,本文就以 svnserve(.exe) 为例进行描述,而略过 Apache 服务器相关的内容,有兴趣的读者可以参考其他文章来在 Apache 服务器下实现类似的功能。

本文是利用 reST 格式来编写的,如果你对它感兴趣,请访问http://docutils.sourceforge.net/rst.html 。如果想要看到更好的html格式,你可以通篇复制本文到一个文本文件里,然后利用 docutils 的 rst2html.py 脚本编译它,当然,首先你必须安装 python。

本文的获得方式:

  - 原始发布点: http://iusesvn.com/bbs/thread-6-1-1.html
  - 完整源文件,请利用 svn 命令来获取,命令为  ``svn co svn://cvs.woodpecker.org.cn/woodpecker/zqlib/tangle/michael.zheng/road2svn``
  - HTML版式文件,请访问 http://zhengxinxing.googlepages. ... bversion_authz.html(推荐) 或 http://swjr.blog.com.cn/archives ... version1authz.shtml 



致谢
====
非常感谢 iusesvn.com 站的站长 PCplayer ,他在本文编写过程中,给我提出了很多宝贵的意见与建议。
感谢 woodpecker.org.cn 提供的 Subversion 空间,让更多的人可以通过 svn 获得本文件。
感谢 google 公司提供的免费主页空间,让我可以放置完全定制的 HTML 文件。

实战
====
本章先直接给出需求及其最终的结果,如果你觉得对配置有什么疑问,或者看不懂,请不要着急,我会在后面的章节详细描述的。


背景假设
--------
厦门央瞬公司是一家电子元器件设备供应商,其中有个ARM部门,专门负责ARM芯片的方案设计、销售,并在北京、上海各设立了一个办事处。对于工作日志,原先采用邮件方式发给经理,但是这种方式有个缺点,那就是不具备连续性,要看以前的日志必须一封一封邮件去查看,很麻烦。于是就想到利用 Subversion, 让员工在自己电脑上编辑日志,然后利用svn传送回来,既方便员工自己编写日志,又方便对日志的归档处理,而且提交日志的时候只需要执行一下 svn commit即可,比发送邮件还要简单的多。

- svn服务器相关信息


  - 服务器地址: 192.168.0.1
  - 服务器OS: MS Windows 2000 Server Edition 中文版
  - 用于存放日志的代码库本地目录: ``D:\svn\arm``

- arm部门文档的目录结构如下::

    arm                 部门名称
    ├─diary           工作日志目录
    │  ├─headquarters    总部工作日志目录
    │  ├─beijing         北京办日志目录
    │  └─shanghai        上海办日志目录
    ├─ref             公司公共文件参考目录
    └─temp            临时文件目录

- 人员情况

  - morson,公司总经理,不习惯使用电脑,更喜欢传统的纸与笔,以及面对面的交流
  - michael,arm事业部的部门经理,没事的时候喜欢弄点儿新技术,用svn来管理日志,就是他想出来的主意
  - scofield,北京办人员,老员工,为人油滑难管
  - lincon,上海办人员,老员工,大老实人一个
  - linda,总部协调员、秘书,文笔不错,长得也不错
  - rory,单片机技术员,技术支持

- 访问权限需求分析

  - 允许总经理、部门经理读取所有文件。顺便给他们开放写权限,以便体现对他们职位的尊重,虽然对于某些文件来说,他们若拥有“写”权限其实也没什么用处
  - 除部门经理外,所有其他人员,均只能看到本办事处人员工作日志
  - 不允许匿名访问
  - ref目录只允许经理和秘书读写,对其他人只读
  - temp目录人人都可以随意读写


使用 svnserve.exe 作为 Subversion 服务器
----------------------------------------
本节描述如何利用 svnserve.exe 来作为代码库服务器端,实现上述功能。至于另外一种代码库服务器端,即利用 Apache 结合 mod_dav_svn.so 来实现的代码库服务器端,由于其对于本文叙述的内容“实现精细的目录访问权限控制”而言,与前者没有太大的区别,故而略过不提。它们二者只是在初次安装、配置方面存在一些不同,有兴趣的读者,可以参考其他文档,重新实验下述步骤。


启动 Subversion 服务
````````````````````
在服务器端,打开一个命令行窗口,用CD命令进入 Subversion 安装目录下的 bin 目录,运行如下指令::

    svnserve -d -r d:\svn

其中的 -d 参数表示 svnserve.exe 将会作为一个服务程序运行在后台,而 -r 参数表示将 ``D:\svn`` 目录指定为代码库的根目录。这样,当客户端使用类似 svn://192.168.0.1/foo 这样内容的 URL 来访问服务器时候,其所访问到的真实代码库,其实就是 ``D:\svn\foo``

用上述命令行方式启动的 svn 服务有个小缺点,就是在本试验过程中,服务器端必须要一直开着那个运行了上述命令的DOS窗口,不能关闭它。如果不想看到这个窗口,可以将 svnserve 安装成windows 的一个 services,安装方式请参考其他文章。


建立代码库
``````````
在服务器端的 ``D:\svn`` 目录下,建立一个名为 arm 的代码库,命令如下::

    D:\svn>svnadmin create arm

使用上述命令之后,如果不出问题的话,在 ``D:\svn`` 目录下就会多出一个叫做 ``arm`` 的目录,其下具备 conf、dav、hooks、locks、db 等子目录或文件,此即 **一个名为arm的代码库** 。从此,通过 ``svn://192.168.0.1/arm`` 这样的 URL,我们就可以对这个代码库进行访问了。接下来就要进入本文的正题了,也就是权限配置部分了。

其实进入 ``arm\conf`` 目录你就会发现,它下面已经存在三个写了一些帮助信息和示例的配置文件,以帮助用户尽早掌握其配置方法。这三个默认的配置文件分别是 svnserve.conf、passwd、authz 。其中后两者没有后缀,对于 windows 系统的用户来说,看起来总是有些怪异,所以在接下来的章节里面,我将它们两个都给添加了个 conf 后缀,以便管理。


编辑代码库基础配置文件
``````````````````````
在服务器端,编辑代码库的 ``arm\conf\svnserve.conf`` 文件,如下::

    [general]
    password-db = passwd.conf
    anon-access = none
    auth-access = write
    authz-db = authz.conf


管理用户帐号
````````````
在服务器端,新建 ``arm\conf\passwd.conf`` 文件,如下::

    [users]
    morson = ShowMeTheMoney
    michael = mysecretpassword
    scofield = hellolittilekiller
    lincon = asyouknows111
    rory = 8809117
    linda = IlikeWorldCup2006


建立目录访问权限控制文件
````````````````````````
在服务器端,新建 ``arm\conf\authz.conf`` 文件,内容如下::

    [groups]
    g_vip = morson
    g_manager = michael
    g_beijing = scofield
    g_shanghai = lincon
    g_headquarters = rory, linda
    g_docs = linda

    [arm:/]
    @g_manager = rw
    * = r

    [arm:/diary/headquarters]
    @g_manager = rw
    @g_headquarters = rw
    @g_vip = r
    * =

    [arm:/diary/beijing]
    @g_manager = rw
    @g_beijing = rw
    @g_vip = r
    * =

    [arm:/diary/shanghai]
    @g_manager = rw
    @g_shanghai = rw
    @g_vip = r
    * =

    [arm:/ref]
    @g_manager = rw
    @g_docs = rw
    * = r

    [arm:/temp]
    * = rw


导入代码
````````
在客户机 ``F:\temp`` 目录下,建立好前述“背景假设”一节中描述的目录结构,然后用命令 ``F:\temp>svn import arm svn://192.168.0.1/arm --username michael --password mysecretpassword`` 导入整个目录结构。

这条指令的精确意思是,将 arm 目录下面的所有东西,导入到那个名叫 arm 的代码库中去。如果你不指定源目录,则 svn 会默认将当前目录作为源目录。比如说,你处于 ``F:\temp`` 目录下的时候,直接执行 ``svn import svn://192.168.0.1/arm`` ,那么当你取出你的代码的时候,你会发现,居然多了一层名为 arm 的目录。结果,你就必须使用类似  ``svn://192.168.0.1/arm/arm`` 这样怪异的URL,才能够正确访问到你的代码们。

这一点粗看好像不是特别重要,不过联想到前述的目录授权规则,可都是按照标准的项目目录结构来设计的。突然之间,你项目的根目录之上,多出了一个名为 arm 的目录,那么我们的所有目录授权规则,基本上都要全部改过了,否则除了根目录,你永远会得到一个莫名其妙的“access denied”。由于 Subversion 在这一步骤上的界面不够人性化,因此这是初学者很容易弄混的地方之一。


测试
````
在服务器上,打开一个 DOS Prompt 窗口,输入如下指令::

    svn co svn://127.0.0.1/arm --no-auth-cache --username rory --password 8809117

我们应该得到如下目录结构::

    arm
    ├─diary
    │  └─headquarters
    ├─ref
    └─temp

然后修改ref目录下任意文件并提交,服务器将会报错“Access denied”,Bingo!


2013年2月6日 星期三

Redhat 下svn服务器搭建--CentOS 5.5下搭建部署独立SVN服务器全程详解


CentOS 5.5下搭建部署独立SVN服务器全程详解
SVN服务器有2种运行方式:
1、独立服务器(例如:svn://xxx.com/xxx);
2、借助apache   (例如:http://svn.xxx.com/xxx);
为了不依赖apache,我选择第一种方式:独立的svn服务器。
SVN存储版本数据也有2种方式:
1、bdb;
2、fsfs。
由于bdb方式在服务器中断时,有可能锁住数据,所以还是fsfs方式更安全一点,我也选择这种方式。
具体部署:
1.下载subversion安装包[root@server ~]# cd /usr/local/src
[root@server src]# ls
[root@server src]# wget http://subversion.tigris.org/downloads/subversion-1.6.6.tar.gz
[root@server src]# wget http://subversion.tigris.org/downloads/subversion-deps-1.6.6.tar.gz
[root@server src]# tar xfvz subversion-1.6.6.tar.gz
[root@server src]# tar xfvz subversion-deps-1.6.6.tar.gz
[root@server src]# cd subversion-1.6.6
[root@server subversion-1.6.6]#
 
2.编译SVN
首先检测系统有没有安装SSL:[root@server subversion-1.6.6]# find / -name opensslv.h
[root@server subversion-1.6.6]#
找不到,就执行如下命令进行安装:[root@server subversion-1.6.6]# yum install openssl
[root@server subversion-1.6.6]# yum install openssl-devel 
安装之后用find / -name opensslv.h命令找到opensslv.h所在的目录,即下列--with-openssl=后面的路径,编译:
[root@server subversion-1.6.6]# find / -name opensslv.h
/usr/include/openssl/opensslv.h
[root@server subversion-1.6.6]# ./configure --prefix=/usr/local/svn --with-openssl=/usr/include/openssl --without-berkeley-db
注:以svnserve方式运行,不加apache编译参数。以fsfs格式存储版本库,不编译berkeley-db。
此时编译报如下错误:
configure: WARNING: unrecognized options: --with-openssl
configure: Configuring Subversion 1.6.6
configure: creating config.nice
checking for gcc... no
checking for cc... no
checking for cl.exe... no
configure: error: in `/usr/local/src/subversion-1.6.6':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details.
说明没有安装gcc相关库,使用如下命令安装gcc后再编译:
[root@server subversion-1.6.6]# yum -y install gcc
[root@server subversion-1.6.6]# ./configure --prefix=/usr/local/svn --with-openssl=/usr/include/openssl --without-berkeley-db 
最后出现下面WARNING,直接忽略即可,因为不使用BDB存储。configure: WARNING: we have configured without BDB filesystem support
You don't seem to have Berkeley DB version 4.0.14 or newer
installed and linked to APR-UTIL. We have created Makefiles which
will build without the Berkeley DB back-end; your repositories will
use FSFS as the default back-end. You can find the latest version of
Berkeley DB here:
http://www.sleepycat.com/download/index.shtml 
3.安装SVN
为避免出现以下错误
error while loading shared libraries: libiconv.so.2: cannot open shared object file: No such file or directory
先执行以下操作:
1)、编辑/etc/ld.so.conf文件,添加下面一行:
/usr/local/lib
2)、保存后运行ldconfig:
/sbin/ldconfig
 
 
注:ld.so.conf和ldconfig用于维护系统动态链接库。
安装
[root@server subversion-1.6.6]# make && make install
 
 
安装完成,执行以下命令测试:
[root@server subversion-1.6.6]# /usr/local/svn/bin/svnserve --version
 
svnserve,版本1.6.6 (r40053)
   编译于Feb 15 2012,22:15:26
 
版权所有(C) 2000-2009 CollabNet。
Subversion 是开放源代码软件,请参阅http://subversion.tigris.org/ 站点。
此产品包含由CollabNet(http://www.Collab.Net/) 开发的软件。
 
下列版本库后端(FS) 模块可用:
 
* fs_fs : 模块与文本文件(FSFS)版本库一起工作。
 
 
 
为了方便下操作,下面将SVN的BIN添加到PATH,编辑/etc/profile,添加:
PATH=/usr/local/svn/bin:$PATH
保存后,使其立即生效:
source /etc/profile
4.配置SVN
建立版本库目录,可建多个:
[root@server ~]# mkdir -p /home/svndata/repos

#建立版本库
[root@server ~]# /usr/local/svn/bin/svnadmin create /home/svndata/repos

#修改版本库配置文件 
编辑/home/svndata/repos/conf/svnserve.conf,内容修改为:
[general]
anon-access = none
auth-access = write
password-db = /usr/local/svn/conf/passwd (亦可不寫完整路徑)
authz-db = /usr/local/svn/conf/authz (亦可不寫完整路徑)
realm = repos (這邊就是你程式庫名稱 svn://xxx.xxx.xxx/repos)
注意:对用户配置文件的修改立即生效,不必重启svn。
在/usr/local/svn/下面新建conf目录,并在/usr/local/svn/conf内新建passwd.conf和authz.conf文件:

(若沒有寫完整路徑,其設定檔會在/home/svndata/repos/conf/目錄下)
mkdir conf
cd conf/
touch passwd.conf
touch authz.conf
 
添加用户及密码:

[root@server ~]# useradd wll (系統必需建立帳號,否則SVN Client不能正確登入)
[root@server ~]# passwd wll (其實這密碼跟登入SVN Client沒有關係,所以不設也可以)
 
编辑/usr/local/svn/conf/passwd.conf,添加如下代码并保存:
[users]
wll = 123456
配置svn用户访问权限,编辑usr/local/svn/conf/authz.conf,添加如下代码并保存:
[groups]
admin = wll
[/]
@admin = rw
# [repos:/abc/aaa]
# king = rw
# [repos:/pass]
# king =svn
 
 
注意:
* 权限配置文件中出现的用户名必须已在用户配置文件中定义。
* 对权限配置文件的修改立即生效,不必重启svn。
用户组格式:
[groups]
= ,
其中,1个用户组可以包含1个或多个用户,用户间以逗号分隔。
版本库目录格式:
[<版本库>:/项目/目录]
@<用户组名> = <权限>
<用户名> = <权限>
其中,方框号内部分可以有多种写法:
[/],表示根目录及以下,根目录是svnserve启动时指定的,我们指定为/home/svndata,[/]就是表示对全部版本库设置权限。
[repos:/] 表示对版本库repos设置权限;
[repos:/abc] 表示对版本库repos中的abc项目设置权限;
[repos:/abc/aaa] 表示对版本库repos中的abc项目的aaa目录设置权限;
权限主体可以是用户组、用户或*,用户组在前面加@,*表示全部用户。
权限可以是w、r、wr和空,空表示没有任何权限。
 
建立启动svn的用户:   

[root@server ~]# useradd svn
[root@server ~]# passwd svn
允许用户svn访问版本库:

[root@server ~]# chown -R svn:svn /home/svndata 
启动svn:

[root@server ~]# su - svn -c "svnserve -d --listen-port 9999 -r /home/svndata"
 
其中:
su - svn :表示以用户svn的身份启动svn;
-d :表示以daemon方式(后台运行)运行;
--listen-port 9999 :表示使用9999端口,可以换成你需要的端口。但注意,使用1024以下的端口需要root权限;
-r /home/svndata :指定根目录是/home/svndata。
 
5.将svn加入到开机启动
编辑/etc/rc.d/rc.local文件,加入如下启动命令:/usr/local/svn/bin/svnserve -d --listen-port 9999 -r /home/svndata
如果想停止svn,则使用如下命令:
killall svnserve
如果想将svn作为服务,在/etc/rc.d/init.d/目录下新建名为svn的文件并设置权限为755,并添加如下代码:#!/bin/bash
# build this file in /etc/rc.d/init.d/svn
# chmod 755 /etc/rc.d/init.d/svn
# centos下可以用如下命令管理svn: service svn start(restart/stop)
SVN_HOME=/home/svndata
if [ ! -f "/usr/local/svn/bin/svnserve" ]
then
    echo "svnserver startup: cannot start"
    exit
fi
case "$1" in
    start)
        echo "Starting svnserve..."
        /usr/local/svn/bin/svnserve -d --listen-port 9999 -r $SVN_HOME
        echo "Finished!"
        ;;
    stop)
        echo "Stoping svnserve..."
        killall svnserve
        echo "Finished!"
        ;;
    restart)
        $0 stop
        $0 start
        ;;
    *)
        echo "Usage: svn { start | stop | restart } "
        exit 1
esac 
6.连接SVN
安装TortoiseSVN,重启系统。启动TortoiseSVN并在地址栏中输入svn://192.168.1.87:9999/repos
 
根据提示输入用户名与密码后就可以