2009-12-09 32 views
7

我有一個個人的Mercurial存儲庫,跟蹤我正在處理的一些更改。我想與合作者分享這些更改,但是他們沒有/無法獲取Mercurial,所以我需要發送整個文件集並且合作者將在他們的最後合併。我正在尋找一種方法來提取在兩個版本號之間修改的文件子集的「tip」版本。有沒有辦法在Mercurial中輕鬆做到這一點?Mercurial - 如何創建在兩個修訂之間更改的文件的.zip文件?

添加賞金 - 這對我們來說仍然很痛苦。我們經常與內部的「客戶」合作,他們將我們的源代碼發佈爲.zip,測試一個小的修補程序更容易以.zip覆蓋而不是修補程序的形式發佈(因爲我們通常不知道其文件的狀態)。

回答

13

最理想的情況是把這些人適當的壓力得到水銀,但除此之外,一個補丁可能比一個更好的壓縮文件集,因爲該補丁將跟蹤刪除和重命名。如果你仍然想一個zip文件,我寫了一個簡短的腳本,使一個zip文件:

import os, subprocess, sys 
from zipfile import ZipFile, ZIP_DEFLATED 

def main(revfrom, revto, destination, *args): 
    root, err = getoutput("hg root") 
    if "no Merurial repository" in err: 
     print "This script must be run from within an Hg repository" 
     return 
    root = root.strip() 

    filelist, _ = getoutput("hg status --rev %s:%s" % (revfrom, revto)) 
    paths = [] 

    for line in filelist.split('\n'): 
     try: 
      (status, path) = line.split(' ', 1) 
     except ValueError: 
      continue 
     if status != 'D': 
      paths.append(path) 

    if len(paths) < 1: 
     print "No changed files could be found." 
     return 

    z = ZipFile(destination, "w", ZIP_DEFLATED) 
    os.chdir(root) 
    for path in paths: 
     z.write(path) 
    z.close() 

    print "Done." 


def getoutput(cmd): 
    p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    return p.communicate() 


if __name__ == '__main__': 
    main(*sys.argv[1:]) 

的用法是nameofscript.py fromrevision torevision目的地。例如,nameofscript.py 45 51 c:\updates.zip

對不起,糟糕的命令行界面,但嘿腳本只花了25分鐘寫。

注意:這應該從存儲庫中的工作目錄運行。

1

據我所知,這沒有一個方便的工具(雖然一個mercurial插件可能是可行的)。你可以導出文件集的補丁,使用hg export from:to(來自和識別修訂版)。如果你確實需要在tip上看到的整個文件,你可以根據hg diff --stat -r from:to的輸出結果一起進行攻擊,輸出一個有多少行與批註文件的列表被改變,如:

... 
src/test/scala/RegressionTest.scala      | 25 +++++++++++++---------- 
src/test/scala/SLDTest.scala        | 2 +- 
15 files changed, 111 insertions(+), 143 deletions(-) 

如果沒有任何文件的名稱中包含空格或特殊字符,你可以使用類似:

hg diff -r156:159 --stat | head - --lines=-1 | sed 's!|.*$!!' | xargs zip ../diffed.zip 

我我們將把特殊字符作爲練習ise爲讀者;)

11

好吧。 hg export $base:tip > patch.diff將產生一個標準的補丁文件,可供大多數工具讀取。

特別是,GNU patch命令可以將整個補丁應用於以前的文件。這不夠嗎?我不明白你爲什麼需要這些文件:對我來說,應用補丁似乎比從zip壓縮文件中提取文件並將它們複製到正確的位置更簡單。 ,如果您的協作者有本地更改,您將覆蓋它們。您沒有使用版本控制工具直接強制其他人合併手動的更改,對吧?讓patch處理,誠實:)

+2

我同意發送區別是一個更好的主意。當一個人向另一個人提供更新(子)文件集時,變得非常容易。每當我看到整個.java文件通過電子郵件發送到我以前的工作中時,我都感到c c不安。 – 2009-12-09 09:36:39

1

這是一個小而醜陋的bash腳本,將完成這項工作,至少如果你在Linux環境下工作。這絕對沒有檢查什麼如此,並且很有可能會在您移動文件時中斷,但這只是一個開始。

命令:

zipChanges.sh REVISION REPOSITORY DESTINATION 
zipChanges.sh 3 /home/hg/repo /home/hg/files.tgz 

代碼:

#!/bin/sh 
REV=$1 
SRC_REPO=$2 
DST_ZIP=$3 

cd $SRC_REPO 
FILES=$(hg status --rev $1 $SRC_REPO | cut -c3-) 

IFS=$'\n' 
FILENAMES="" 
for line in ${FILES} 
do 
    FILENAMES=$FILENAMES" \""$SRC_REPO"/"$line"\"" 
done 

CMD="tar czf \"$DST_ZIP\" $FILENAMES" 

eval $CMD 
1

我知道你已經有這個問題的一些答案,但我的一個朋友有一個類似的問題,我在VB.Net中創建了一個簡單的程序來爲他做這個也許它可以幫助你,編和該來源的副本位於下面鏈接的文章的底部。

http://www.simianenterprises.co.uk/blog/mercurial-export-changed-files-80.html

雖然這並不讓你選擇結束脩訂的時刻,這將是很容易的添加,在使用源,但是你必須更新到目標修訂提取之前手動文件。 如果需要,你甚至可以修改它來創建zip而不是文件的文件夾(這也很好,很容易手動壓縮)

希望這可以幫助你或任何其他想要此功能的人。

2

我也貢獻了一個擴展,看到hgexportfiles extension on bitbucket更多信息。導出文件擴展名適用於給定的修訂版本或修訂版本範圍,並在指定的目錄中創建一組更改後的文件。將目錄作爲腳本的一部分進行壓縮很容易。

5

在UNIX這是可以做到的:

hg status --rev 1 --rev 2 -m -a -n | xargs zip changes.zip 
+1

'-a'添加文件丟失 – schlamar 2012-11-13 15:25:14

0

我就遇到了這個問題最近。我的解決方案:

hg update null 
hg debugsetparents (starting revision) 
hg update (ending revision) 

這將會刪除所有在這兩個修訂版之間沒有更改的跟蹤文件。不過,您必須自己刪除未跟蹤的文件。這樣做後,本地分支將處於不一致的狀態;您可以通過運行hg debugrebuildstate(或者簡單地刪除本地分支,如果不再需要它)來解決此問題。

+0

至於爲什麼我不能使用補丁:有問題的修訂版本大多是新創建的二進制文件,遍佈整個存儲庫。補丁是否可以正確重構二進制文件?我不知道,但這種方式比想象出來容易。 – Brilliand 2012-04-25 01:02:35

相關問題