2012-02-01 40 views
3

包含.hg文件夾中的所有文件夾,我試圖寫在PowerShell中的腳本來備份我們的Mercurial庫的集合。如何遞歸發現在PowerShell中

我開始用這樣的:

$repos=Get-ChildItem C:\hgrepos|Where-Object { $_.PSIsContainer } 

這將讓文件夾下C第一層次:\ hgrepos,通常會好一些,因爲這是我們的倉庫的位置。但是,存在子庫。所以我需要遞歸。而最重要的是,包含子文件夾.hg只文件夾應列出

回答

7

可以使用-recurse標誌Get-ChildItem

這將是這樣的:

gci c:\hgrepos -recurse -include ".hg" | %{$_.Parent} 
+1

您可能要過濾的文件夾,以確保'.hg'是一個文件夾'GCI C:\ hgrepos -recurse -include 「.hg」 | ?{$ _。PSIsContainer} | %{$ _。Parent}' – 2012-02-01 08:54:57

+0

@jonZ - 實際上,我測試了它。它不會讓父母擁有一個名爲.hg的文件。 – manojlds 2012-02-01 17:26:20

+0

對,非常聰明:-)太糟糕了,我只能一勞永逸。 – 2012-02-01 18:48:20

1

我寫了這個PowerShell的功能來備份我們的Mercurial庫:

function BackupHg 
{ 
    param($repositoryRoot, $destination) 

    # The path to the Hg executable 
    $hg = """C:\Python26\hg.bat""" 

    # Get the list of repos 
    Get-ChildItem $repositoryRoot | 
     Where { $_.psIsContainer -eq $true } | 
     ForEach -Process { 
      $repo = $_.FullName 
      $folder = $_.Name 

      if (Test-Path "$repo\.hg") { 
       $cmdLine = "$hg clone -U $repo $destination\$folder" 
       cmd /c $cmdLine 
      } 
      else { 
       New-Item "$destination\$folder" -type directory 
       BackupHg "$repositoryRoot\$folder" "$destination\$folder" 
      } 
     }  
} 

你傳遞在根文件夾和備份目標中,它會查找所有文件夾,測試它是否是Mercurial repo(查找.hg目錄)和克隆回到備份目標。如果該文件夾不是Mercurial repo,那麼它自己執行遞歸。

它做過這樣的,因爲我們使用文件夾來組織我們的回購所以對於每一個客戶的所有代碼是在自己的文件夾從其他客戶分開。

的最後一點。 Mercurial子庫的存在並不意味着你需要遞歸。除非您有一個工作副本的存儲庫,否則您的子副本將不會存儲在存儲庫中,應該由存儲的任何系統進行備份。如果這與系統信息庫是同一個系統,那麼它將成爲您的系統信息庫文件夾中的另一個系統信息庫,並將由上述腳本進行備份。

例如,我們有一個Web應用程序庫與器WebControls子庫的客戶端和文件結構如下:

C:\Repositories\Hg\Client\WebApp 
C:\Repositories\Hg\Client\WebControls 

器WebControls沒有存儲在Web應用程序文件夾,即使它是一個子它的知識庫。

+0

您能否解釋$ backup_path和硬編碼路徑D:\ Repositories \ Mercurial的用途? – 2012-02-01 21:39:19

+0

糟糕......這些錯誤是我在將函數轉換爲函數時錯過了將全局變量/硬編碼路徑轉換爲參數的錯誤。我會修復它,測試它並儘快編輯我的答案。 – 2012-02-02 12:17:04

+1

我已經固定,現在的錯誤 - 它不會有備份多個文件夾深(我們剛剛加入到我們的結構的今天,巧合的是,這樣我們的備份會失敗今晚) – 2012-02-02 12:31:51

0

我結束了使用下面的腳本。感謝Steve Kaye和manojlds提供非常需要的反饋!

function BackupHg 
{ 
    param($repositoryRoot, $destination) 

    Remove-Item "$destination\*" -recurse 

    # The path to the Hg executable 
    $hg = """C:\Python27\Scripts\hg.bat""" 

    # Get the list of repos 
    Get-ChildItem $repositoryRoot -recurse | 
     Where { $_.psIsContainer -eq $true } | 
     ForEach -Process { 
      $repo = $_.FullName 
      $folder = $_.FullName.Replace($repositoryRoot, $destination) 


      if (Test-Path "$repo\.hg") { 
       if (!(Test-Path "$folder")) { 
        New-Item "$folder" -type directory 
       } 
       $cmdLine = "$hg clone -U $repo $folder" 
       write-host $cmdLine 
       cmd /c $cmdLine 
      } 
     }  
}