มีใครทราบวิธีลบไฟล์ทั้งหมดซ้ำ ๆ ในสำเนาที่ใช้งานได้ซึ่งไม่ได้อยู่ภายใต้การควบคุมเวอร์ชัน (ฉันต้องการสิ่งนี้เพื่อให้ได้ผลลัพธ์ที่น่าเชื่อถือมากขึ้นในการสร้าง VMware อัตโนมัติของฉัน)
hg purge --all
ใน Mercurial.
มีใครทราบวิธีลบไฟล์ทั้งหมดซ้ำ ๆ ในสำเนาที่ใช้งานได้ซึ่งไม่ได้อยู่ภายใต้การควบคุมเวอร์ชัน (ฉันต้องการสิ่งนี้เพื่อให้ได้ผลลัพธ์ที่น่าเชื่อถือมากขึ้นในการสร้าง VMware อัตโนมัติของฉัน)
hg purge --all
ใน Mercurial.
คำตอบ:
แก้ไข:
การโค่นล้ม 1.9.0 แนะนำตัวเลือกในการทำสิ่งนี้:
svn cleanup --remove-unversioned
ก่อนหน้านั้นฉันใช้สคริปต์ python นี้เพื่อทำสิ่งนั้น:
import os
import re
def removeall(path):
if not os.path.isdir(path):
os.remove(path)
return
files=os.listdir(path)
for x in files:
fullpath=os.path.join(path, x)
if os.path.isfile(fullpath):
os.remove(fullpath)
elif os.path.isdir(fullpath):
removeall(fullpath)
os.rmdir(path)
unversionedRex = re.compile('^ ?[\?ID] *[1-9 ]*[a-zA-Z]* +(.*)')
for l in os.popen('svn status --no-ignore -v').readlines():
match = unversionedRex.match(l)
if match: removeall(match.group(1))
ดูเหมือนว่าจะทำงานได้ดี
svn cleanup --remove-unversioned
ดีกว่า และมีไว้สำหรับ Subversion 1.9.0 (เวอร์ชันนี้มาจากปี 2015) มีความเสถียรและเป็นมาตรฐาน
สิ่งนี้ใช้ได้กับฉันในการทุบตี:
svn status | egrep '^\?' | cut -c8- | xargs rm
Seth Renoดีกว่า:
svn status | grep ^\? | cut -c9- | xargs -d \\n rm -r
จัดการโฟลเดอร์และช่องว่างที่ไม่ได้แปลงในชื่อไฟล์
ตามความคิดเห็นด้านล่างนี้ใช้ได้เฉพาะกับไฟล์ที่การโค่นล้มไม่ทราบ (status =?) อะไรก็ตามที่การโค่นล้มทำทราบเกี่ยวกับ (รวมถึงไฟล์ละเว้น / โฟลเดอร์) จะไม่ถูกลบ
หากคุณกำลังใช้การโค่นล้ม 1.9 หรือสูงกว่าคุณสามารถใช้คำสั่งsvn cleanupด้วยตัวเลือก --remove-unversioned และ --remove-ignored
svn status | grep "^?" | awk '{print $2}' | xargs -d \\n rm -r
ฉันวิ่งผ่านหน้านี้ในขณะที่ต้องการทำสิ่งเดียวกันแม้ว่าจะไม่ใช่สำหรับบิลด์อัตโนมัติ
หลังจากค้นหาอีกเล็กน้อยฉันก็ค้นพบ ' Extended Context Menu ' ใน TortoiseSVN กดปุ่ม shift ค้างไว้แล้วคลิกขวาที่สำเนาที่ใช้งานได้ ขณะนี้มีตัวเลือกเพิ่มเติมภายใต้เมนู TortoiseSVN ซึ่งรวมถึง ' ลบรายการที่ไม่ได้เวอร์ชัน ... '
แม้ว่าอาจจะใช้ไม่ได้กับคำถามเฉพาะนี้ (เช่นในบริบทของโครงสร้างอัตโนมัติ) แต่ฉันคิดว่ามันอาจเป็นประโยชน์สำหรับคนอื่น ๆ ที่ต้องการทำสิ่งเดียวกัน
ดู: svn-clean
หากคุณใช้บรรทัดคำสั่งของ windows
for /f "tokens=2*" %i in ('svn status ^| find "?"') do del %i
เวอร์ชันปรับปรุง:
for /f "usebackq tokens=2*" %i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%i %j"
หากคุณใช้สิ่งนี้ในไฟล์แบตช์คุณต้องเพิ่มเป็นสองเท่า%
:
for /f "usebackq tokens=2*" %%i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%%i %%j"
ฉันเพิ่มสิ่งนี้ในโปรไฟล์ windows powershell ของฉัน
function svnclean {
svn status | foreach { if($_.StartsWith("?")) { Remove-Item $_.substring(8) -Verbose } }
}
--no-ignore
ไปsvn status
และ-Recurse
ไปRemove-Item
บรรทัดคำสั่ง Linux:
svn status --no-ignore | egrep '^[?I]' | cut -c9- | xargs -d \\n rm -r
หรือหากไฟล์บางไฟล์ของคุณเป็นของ root:
svn status --no-ignore | egrep '^[?I]' | cut -c9- | sudo xargs -d \\n rm -r
นี่เป็นไปตามคำตอบของเคน (คำตอบของเคนข้ามไฟล์ที่ไม่สนใจคำตอบของฉันลบออก)
เพียงแค่ทำบน unix-shell ด้วย:
rm -rf `svn st . | grep "^?" | cut -f2-9 -d' '`
หากคุณมีTortoiseSVNบนเส้นทางของคุณและคุณอยู่ในไดเรกทอรีที่ถูกต้อง:
TortoiseProc.exe /command:cleanup /path:"%CD%" /delunversioned /delignored /nodlg /noui
ตัวเลือกต่างๆได้อธิบายไว้ในวิธีใช้ TortoiseSVN สำหรับ/command:cleanup
:
ใช้ / noui เพื่อป้องกันไม่ให้กล่องโต้ตอบผลลัพธ์โผล่ขึ้นมาทั้งที่บอกเกี่ยวกับการล้างข้อมูลเสร็จสิ้นหรือแสดงข้อความแสดงข้อผิดพลาด) / noprogressui ปิดใช้งานกล่องโต้ตอบความคืบหน้าด้วย / nodlg ปิดใช้งานการแสดงกล่องโต้ตอบการล้างข้อมูลซึ่งผู้ใช้สามารถเลือกสิ่งที่ควรทำในการล้างข้อมูล การดำเนินการที่มีสามารถระบุได้ด้วยอ็อพชัน / การล้างข้อมูลสำหรับการล้างสถานะ, / ย้อนกลับ, / delunversioned, / delignored, / refreshshell และ / externals
หากคุณใช้เต่า svn มีคำสั่งที่ซ่อนอยู่เพื่อทำสิ่งนี้ กด shift ค้างไว้ขณะคลิกขวาที่โฟลเดอร์เพื่อเปิดเมนูบริบทใน windows explorer คุณจะได้รับคำสั่ง "Delete Unversioned Items"
ดูรายละเอียดที่ด้านล่างของหน้านี้หรือภาพหน้าจอด้านล่างซึ่งไฮไลต์คุณสมบัติเพิ่มเติมที่มีดาวสีเขียวและรูปสี่เหลี่ยมสีเหลืองที่น่าสนใจ ...
การโค่นล้ม 1.9.0 แนะนำตัวเลือกในการลบรายการที่ไม่ได้เวอร์ชัน [1]
svn cleanup --remove-unversioned
[1] https://subversion.apache.org/docs/release-notes/1.9.html#svn-cleanup-options
การแปลง C # ของฉันของสคริปต์ Thomas Watnedals Python:
Console.WriteLine("SVN cleaning directory {0}", directory);
Directory.SetCurrentDirectory(directory);
var psi = new ProcessStartInfo("svn.exe", "status --non-interactive");
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.WorkingDirectory = directory;
using (var process = Process.Start(psi))
{
string line = process.StandardOutput.ReadLine();
while (line != null)
{
if (line.Length > 7)
{
if (line[0] == '?')
{
string relativePath = line.Substring(7);
Console.WriteLine(relativePath);
string path = Path.Combine(directory, relativePath);
if (Directory.Exists(path))
{
Directory.Delete(path, true);
}
else if (File.Exists(path))
{
File.Delete(path);
}
}
}
line = process.StandardOutput.ReadLine();
}
}
svn st --no-ignore | grep '^[?I]' | sed 's/^[?I] *//' | xargs -r -d '\n' rm -r
นี่คือคำสั่ง unix shell เพื่อลบไฟล์ทั้งหมดที่ไม่อยู่ภายใต้การควบคุมการโค่นล้ม
หมายเหตุ:
st
ในsvn st
เป็นสร้างในนามแฝงสำหรับstatus
เช่นคำสั่งเทียบเท่ากับsvn status
--no-ignore
ยังรวมถึงไฟล์ที่ไม่ใช่ที่เก็บในเอาต์พุตสถานะมิฉะนั้นจะละเว้นผ่านกลไกเช่น.cvsignore
อื่น ๆ - เนื่องจากเป้าหมายคือการมีจุดเริ่มต้นที่สะอาดสำหรับการสร้างสวิตช์นี้จึงเป็นสิ่งที่จำเป็นgrep
ฟิลเตอร์ที่ส่งออกดังกล่าวว่ามีเพียงไฟล์ที่ไม่รู้จักที่จะโค่นล้มที่เหลือ - เส้นเริ่มต้นด้วย?
ไฟล์รายการที่ไม่รู้จักที่จะโค่นล้มที่จะถูกละเลยโดยไม่มี--no-ignore
ตัวเลือกsed
xargs
คำสั่งมีคำสั่งผ่านทาง-r
ที่จะได้ดำเนินการrm
เมื่อรายการอาร์กิวเมนต์จะเป็นที่ว่างเปล่า-d '\n'
ตัวเลือกที่จะบอกxargs
จะใช้ขึ้นบรรทัดใหม่เป็นตัวคั่นคำสั่งดังกล่าวยังทำงานสำหรับชื่อไฟล์ที่มีช่องว่างrm -r
ใช้ในกรณีที่ไดเร็กทอรีที่สมบูรณ์ (ซึ่งไม่ใช่ส่วนหนึ่งของที่เก็บ) จำเป็นต้องลบออกฉันไม่สามารถทำงานใด ๆ ข้างต้นได้หากไม่มีการอ้างอิงเพิ่มเติมฉันไม่ต้องการเพิ่มลงในระบบบิลด์อัตโนมัติของฉันบน win32 ดังนั้นฉันจึงรวบรวมคำสั่ง Ant ต่อไปนี้ - โปรดทราบว่าสิ่งเหล่านี้ต้องการ Ant-Contrib JAR เพื่อติดตั้ง (ฉันใช้เวอร์ชัน 1.0b3 ซึ่งเป็นเวอร์ชันล่าสุดกับ Ant 1.7.0)
หมายเหตุสิ่งนี้จะลบไฟล์ที่ไม่ได้เวอร์ชันทั้งหมดโดยไม่มีคำเตือน
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
<taskdef name="for" classname="net.sf.antcontrib.logic.ForTask" />
<macrodef name="svnExecToProperty">
<attribute name="params" />
<attribute name="outputProperty" />
<sequential>
<echo message="Executing Subversion command:" />
<echo message=" svn @{params}" />
<exec executable="cmd.exe" failonerror="true"
outputproperty="@{outputProperty}">
<arg line="/c svn @{params}" />
</exec>
</sequential>
</macrodef>
<!-- Deletes all unversioned files without warning from the
basedir and all subfolders -->
<target name="!deleteAllUnversionedFiles">
<svnExecToProperty params="status "${basedir}""
outputProperty="status" />
<echo message="Deleting any unversioned files:" />
<for list="${status}" param="p" delimiter="
" trim="true">
<sequential>
<if>
<matches pattern="\?\s+.*" string="@{p}" />
<then>
<propertyregex property="f" override="true" input="@{p}"
regexp="\?\s+(.*)" select="\1" />
<delete file="${f}" failonerror="true" />
</then>
</if>
</sequential>
</for>
<echo message="Done." />
</target>
สำหรับโฟลเดอร์อื่นให้เปลี่ยนการ${basedir}
อ้างอิง
svn status --no-ignore | awk '/^[I\?]/ {system("echo rm -r " $2)}'
ลบเสียงสะท้อนหากแน่ใจว่าคุณต้องการทำอะไร
/bin/sh
n และ n ที่rm
แยกออกจากกัน
เพราะใคร ๆ ก็ทำกัน ...
svn status | grep ^? | awk '{print $2}' | sed 's/^/.\//g' | xargs rm -R
อาจมีส่วนช่วยอีกทางเลือกหนึ่งเช่นกัน
svn status | awk '{if($2 !~ /(config|\.ini)/ && !system("test -e \"" $2 "\"")) {print $2; system("rm -Rf \"" $2 "\"");}}'
/(config|.ini)/ มีไว้เพื่อวัตถุประสงค์ของฉันเอง
และอาจเป็นความคิดที่ดีที่จะเพิ่ม --no-ignored ในคำสั่ง svn
ฉันสะดุดกับ svn-clean ในเครื่อง RH5 ของฉัน ตั้งอยู่ที่ / usr / bin / svn-clean
http://svn.apache.org/repos/asf/subversion/trunk/contrib/client-side/svn-clean
โซลูชัน cmd / bat ของ windows บริสุทธิ์:
@echo off
svn cleanup .
svn revert -R .
For /f "tokens=1,2" %%A in ('svn status --no-ignore') Do (
If [%%A]==[?] ( Call :UniDelete %%B
) Else If [%%A]==[I] Call :UniDelete %%B
)
svn update .
goto :eof
:UniDelete delete file/dir
if "%1"=="%~nx0" goto :eof
IF EXIST "%1\*" (
RD /S /Q "%1"
) Else (
If EXIST "%1" DEL /S /F /Q "%1"
)
goto :eof
ฉันได้ลองใช้เวอร์ชันของ Seth Renoจากคำตอบนี้แต่ไม่ได้ผลสำหรับฉัน ฉันมีอักขระ 8 ตัวก่อนหน้าชื่อไฟล์ไม่ใช่ 9 ตัวที่ใช้ในcut -c9-
.
นี่คือเวอร์ชันของฉันsed
แทนที่จะเป็นcut
:
svn status | grep ^\? | sed -e 's/\?\s*//g' | xargs -d \\n rm -r
หากคุณเจ๋งกับ powershell:
svn status --no-ignore | ?{$_.SubString(0,1).Equals("?")} | foreach { remove-item -Path (join-Path .\ $_.Replace("?","").Trim()) -WhatIf }
นำแฟล็ก -WhatIf ออกเพื่อให้คำสั่งดำเนินการลบจริง มิฉะนั้นมันจะส่งออกสิ่งที่จะทำหากรันโดยไม่มี -WhatIf
ฉันจะเพิ่มสิ่งนี้เป็นความคิดเห็นในคำตอบของ Thomas Watnedalแต่ยังทำไม่ได้
ปัญหาเล็กน้อยกับมัน (ซึ่งจะไม่มีผลกับ Windows) คือมันจะตรวจสอบเฉพาะไฟล์หรือไดเร็กทอรีเท่านั้น สำหรับระบบ Unix like ที่อาจมีลิงก์สัญลักษณ์จำเป็นต้องเปลี่ยนบรรทัด:
if os.path.isfile(fullpath):
ถึง
if os.path.isfile(fullpath) or os.path.islink(fullpath):
เพื่อลบลิงก์
สำหรับฉันการเปลี่ยนบรรทัดสุดท้ายif match: removeall(match.group(1))
เป็น
if match:
print "Removing " + match.group(1)
removeall(match.group(1))
เพื่อให้แสดงสิ่งที่กำลังลบก็มีประโยชน์เช่นกัน
ทั้งนี้ขึ้นอยู่กับกรณีการใช้งานที่?[\?ID]
เป็นส่วนหนึ่งของการแสดงออกปกติอาจจะดีกว่าที่เป็น?[\?I]
เป็นD
ไฟล์ยังลบลบซึ่งอยู่ภายใต้การควบคุมเวอร์ชัน ฉันต้องการใช้สิ่งนี้เพื่อสร้างในโฟลเดอร์ที่สะอาดและตรวจสอบในโฟลเดอร์ดังนั้นจึงไม่ควรมีไฟล์อยู่ในD
สถานะ
@zhoufei ฉันทดสอบคำตอบของคุณและนี่คือเวอร์ชันอัปเดต:
FOR /F "tokens=1* delims= " %%G IN ('svn st %~1 ^| findstr "^?"') DO del /s /f /q "%%H"
FOR /F "tokens=1* delims= " %%G IN ('svn st %~1 ^| findstr "^?"') DO rd /s /q "%%H"
%
เครื่องหมายสองตัวหน้า G และ H%~1
ใช้ชื่อไดเร็กทอรีใดก็ได้ฉันใช้สิ่งนี้เป็นฟังก์ชันในไฟล์ bat ดังนั้น%~1
พารามิเตอร์อินพุตแรกจึงเป็นสำหรับคนที่ชอบทำสิ่งนี้ด้วย perl แทนที่จะเป็น python, Unix shell, java และอื่น ๆ นี่คือสคริปต์ perl ขนาดเล็กที่ทำ jib เช่นกัน
หมายเหตุ: นอกจากนี้ยังลบไดเรกทอรีที่ไม่ได้เวอร์ชันทั้งหมด
#!perl
use strict;
sub main()
{
my @unversioned_list = `svn status`;
foreach my $line (@unversioned_list)
{
chomp($line);
#print "STAT: $line\n";
if ($line =~/^\?\s*(.*)$/)
{
#print "Must remove $1\n";
unlink($1);
rmdir($1);
}
}
}
main();
การใช้ TortoiseSVN: * คลิกขวาที่โฟลเดอร์สำเนาที่ใช้งานได้ในขณะที่กดปุ่ม shift ค้างไว้ * เลือก "ลบรายการที่ไม่ได้เวอร์ชัน"
ฉันจะลบไฟล์ / โฟลเดอร์ที่ไม่ได้เวอร์ชัน / ละเว้นทั้งหมดในสำเนาที่ใช้งานได้อย่างไร
วิธีที่สะอาดใน PERL คือ:
#!/usr/bin/perl
use IO::CaptureOutput 'capture_exec'
my $command = sprintf ("svn status --no-ignore | grep '^?' | sed -n 's/^\?//p'");
my ( $stdout, $stderr, $success, $exit_code ) = capture_exec ( $command );
my @listOfFiles = split ( ' ', $stdout );
foreach my $file ( @listOfFiles )
{ # foreach ()
$command = sprintf ("rm -rf %s", $file);
( $stdout, $stderr, $success, $exit_code ) = capture_exec ( $command );
} # foreach ()
ฉันใช้เวลาประมาณ 3 ชั่วโมงในการสร้างสิ่งนี้ จะใช้เวลา 5 นาทีในการทำใน Unix ปัญหาหลักคือช่องว่างในชื่อสำหรับโฟลเดอร์ Win ไม่สามารถแก้ไข %% i และปัญหาในการกำหนด vars ใน Win cmd loop
setlocal enabledelayedexpansion
for /f "skip=1 tokens=2* delims==" %%i in ('svn status --no-ignore --xml ^| findstr /r "path"') do (
@set j=%%i
@rd /s /q !j:~0,-1!
)
รหัส C # ด้านบนใช้ไม่ได้สำหรับฉัน - ฉันมีไคลเอนต์เต่า svn และรูปแบบบรรทัดต่างกันเล็กน้อย นี่คือรหัส snipet เดียวกับด้านบนเขียนใหม่เฉพาะเพื่อใช้งานและใช้ regex
/// <summary>
/// Cleans up svn folder by removing non committed files and folders.
/// </summary>
void CleanSvnFolder( string folder )
{
Directory.SetCurrentDirectory(folder);
var psi = new ProcessStartInfo("svn.exe", "status --non-interactive");
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.WorkingDirectory = folder;
psi.CreateNoWindow = true;
using (var process = Process.Start(psi))
{
string line = process.StandardOutput.ReadLine();
while (line != null)
{
var m = Regex.Match(line, "\\? +(.*)");
if( m.Groups.Count >= 2 )
{
string relativePath = m.Groups[1].ToString();
string path = Path.Combine(folder, relativePath);
if (Directory.Exists(path))
{
Directory.Delete(path, true);
}
else if (File.Exists(path))
{
File.Delete(path);
}
}
line = process.StandardOutput.ReadLine();
}
}
} //CleanSvnFolder