Subversion unversion dosyalarını otomatik olarak kaldırın


111

Çalışan bir kopyadaki sürüm kontrolü altında olmayan tüm dosyaları yinelemeli olarak kaldırmanın bir yolunu bilen var mı? (Otomatik derleme VMware'imde daha güvenilir sonuçlar almak için buna ihtiyacım var.)


7
Ben bir SVN kullanıcısıyım ve sonunda geçiş yapmak isteyip istemediğimi görmek için Git ile SVN'yi karşılaştırıyorum. Bu, Git'in "git clean" komutuyla parladığı başka bir örnek gibi görünüyor.
jpierson

3
Veya hg purge --allMercurial'de.
Brendan Long

Kopyası stackoverflow.com/questions/2803823/... çok daha yararlı etkinlik olduğu yerde.
Heath Raftery

Yanıtlar:


26

Düzenle:

Subversion 1.9.0, bunu yapmak için bir seçenek sundu:

svn cleanup --remove-unversioned

Bundan önce, bunu yapmak için bu python betiğini kullanıyorum:

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))

İşi oldukça iyi yapıyor gibi görünüyor.


1
Python 2.7.2 ile benim için hala çalışıyor. Warren P: Daha fazla ayrıntı verebilir misiniz?
Thomas Watnedal

Python 2.6 ile ilgili bir problem olduğunu düşünüyorum. 2.7'de benim için tekrar çalışıyor.
Warren P

1
Olumsuz oy: Aşağıdaki diğer çözüm svn cleanup --remove-unversioneddaha iyidir. Ve Subversion 1.9.0 içindir (bu sürüm 2015'ten itibaren). Kararlı ve standarttır.
tres. 14159

138

bu benim için bash'da çalışıyor:

 svn status | egrep '^\?' | cut -c8- | xargs rm

Seth Reno ' nunki daha iyidir:

svn status | grep ^\? | cut -c9- | xargs -d \\n rm -r 

Dosya adlarındaki değiştirilmemiş klasörleri ve boşlukları yönetir

Aşağıdaki yorumlara göre, bu yalnızca subversion'ın bilmediği dosyalarda çalışır (status =?). Yıkılma o şey yok silinmez (Yok Sayılan dosya / klasörleri dahil) biliyorum.

Subversion 1.9 veya daha üstünü kullanıyorsanız svn cleanup komutunu --remove-unversioned ve --remove-ignored seçenekleriyle kullanabilirsiniz.


6
Cygwin'de Windows'ta da kullanılabilir.
Honza

9
Boşluklu dosya adları için xargs'e -d seçeneğini ve eklenen dizinler için rm'ye -r seçeneğini eklemeyi düşünebilirsiniz: svn durumu | grep ^ \? | kesim -c9- | xargs -d \\ n rm -r
Seth Reno

4
OS X üzerinde çalışan -d seçeneğiyle de problemler yaşadım, alternatifim aşağıdaki gibi satır kesmelerini boş karakterlere çeviriyor ve dosya adlarındaki boşlukları işlemek için xargs üzerinde -0 seçeneğini kullanıyor: svn durumu | grep ^ \? | kesim -c9- | tr '\ n' '\ 0' | xargs -0 rm
Brian Webster

3
Başka bir komutun çıktısındaki tam karakter sayısına dayanan komutlara kaşlarını svn status | grep "^?" | awk '{print $2}' | xargs -d \\n rm -r
çatarsanız

3
@Pavel xargs - no-run-if-empty seçeneğine bir göz atın
Ken

71

Otomatik bir derleme için olmasa da aynı şeyi yapmaya çalışırken bu sayfaya rastladım.

Biraz daha baktıktan sonra TortoiseSVN'de ' Genişletilmiş Bağlam Menüsü'nü keşfettim . Shift tuşunu basılı tutun ve çalışan kopyaya sağ tıklayın. TortoiseSVN menüsü altında artık ' Sürülmemiş öğeleri sil ... ' dahil ek seçenekler var .

Bu belirli soru için belki uygulanabilir olmasa da (yani, otomatikleştirilmiş bir yapı bağlamında), aynı şeyi yapmak isteyen başkaları için yararlı olabileceğini düşündüm.


Harika! XP'de, ağaç görünümünde (sol taraf) değil, yalnızca liste görünümünde (gezginin sağ tarafında) çalışır.
Christopher Oezbek

Harika, sadece geri dönüşüm kutusuna gönderin, doğrudan silmek güzel olurdu. Tam ihtiyacım olan şey.
Dean Thomas

Bunu TortoiseSVN's TortoiseProc.exe ile komut satırında da otomatikleştirebilirsiniz: detaylar aşağıdaki cevabımda.
stevek_mcc


9

Windows komut satırındaysanız,

for /f "tokens=2*" %i in ('svn status ^| find "?"') do del %i

Gelişmiş versiyon:

for /f "usebackq tokens=2*" %i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%i %j"

Bunu bir toplu iş dosyasında kullanırsanız, aşağıdakileri ikiye katlamanız gerekir %:

for /f "usebackq tokens=2*" %%i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%%i %%j"

1
Bu benim için çalıştı. Yine de bazı dönüştürülmemiş klasörlerde boğuluyor gibiydi.
jpierson

7

Bunu Windows powershell profilime ekledim

function svnclean {
    svn status | foreach { if($_.StartsWith("?")) { Remove-Item $_.substring(8) -Verbose } }
}

2
@FelipeAlvarez Evet. Evet yaparız. Dilimlenmiş ekmekten sonraki en iyi şey değil, ama toplu işten daha iyi. NET derlemelerini çekebildiğiniz için en azından bash kadar kullanışlı olduğunu söyleyebilirim, muhtemelen biraz daha fazla.
jpmc26

Microsoft'un ayrıntıya yönelik iğrenç eğiliminden muzdariptir (yalnızca komut adı uzunluğunda değil, internetten dev parçacıkları kopyalamadan bir şey yapmanın genel olarak imkansızlığı), ancak şaşırtıcı derecede yararlı ve oldukça iyi düşünülmüş.
Warren P

1
Sen eklemek isteyebilirsiniz --no-ignoreiçin svn statusve -RecurseiçinRemove-Item
Kevin Smyth

5

Linux komut satırı:

svn status --no-ignore | egrep '^[?I]' | cut -c9- | xargs -d \\n rm -r

Veya dosyalarınızdan bazılarının sahibi kökse:

svn status --no-ignore | egrep '^[?I]' | cut -c9- | sudo xargs -d \\n rm -r

Bu Ken'in cevabına dayanmaktadır. (Ken'in cevabı göz ardı edilen dosyaları atlar; cevabım onları siler).


5

Bunu unix-shell'de şununla yapın:

rm -rf `svn st . | grep "^?" | cut -f2-9 -d' '`

Bu, silinecek dosyaların sayısı komut satırı argümanlarının maksimum sayısını aşarsa çalışmaz. Ayrıca xargs tabanlı cevaplara bakınız.
maxschlepzig

4

Sadece yeni bir yere ihracat yapıp oradan inşa edemez misiniz?


1
Otomatikleştirilmiş bir yapı için temiz bir dışa aktarım isterim.
g.

1
İdeal olarak, bunu yaparsınız, ancak ödeme çok büyükse bu sorunludur. OP'nin sormasının nedeni muhtemelen buydu: yapıyı kısaltmak.
jpmc26

4

Yolunuzda TortoiseSVN varsa ve doğru dizindeyseniz:

TortoiseProc.exe /command:cleanup /path:"%CD%" /delunversioned /delignored /nodlg /noui

Seçenekler, TortoiseSVN yardımında şu konularda açıklanmıştır /command:cleanup:

Sonuç iletişim kutusunun açılarak temizlemenin bittiğini bildirmesini veya bir hata mesajı göstermesini önlemek için / noui kullanın. / noprogressui ayrıca ilerleme iletişim kutusunu devre dışı bırakır. / nodlg, kullanıcının temizlemede tam olarak ne yapılması gerektiğini seçebileceği temizleme iletişim kutusunu göstermeyi devre dışı bırakır. Mevcut eylemler, durum temizleme için / cleanup, / revert, / delunversioned, / delignored, / refreshshell ve / externals seçenekleriyle belirtilebilir.


4

Kaplumbağa svn kullanıyorsanız, bunu yapmak için gizli bir komut vardır. Windows gezgininde bağlam menüsünü başlatmak için bir klasöre sağ tıklarken vardiyayı basılı tutun. Bir "Sürüm Edilmemiş Öğeleri Sil" komutu alacaksınız.

Ayrıntılar için bu sayfanın altına veya genişletilmiş özellikleri yeşil yıldızlarla ve ilgi çekici olanı sarı dikdörtgenle vurgulayan aşağıdaki ekran görüntüsüne bakın ...

SVN Genişletilmiş içerik menüsü ve standart menü



3

Thomas Watnedals Python komut dosyasının C # dönüşümüm:

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();
    }
}

Daha sonra bir yere ihtiyaç duymanız durumunda, dönüştürülmemiş dosyaları taşımayı tercih ederim.
leppie

Elbette bir geliştirme makinesinde - ancak VMware derlemesinde bu hiç kimsenin oturum açmamasına ve dosya oluşturmamasına neden olmaz.
Stefan Schultze

Teşekkürler, bunu derlemelerden önce kaynak
dizinimi


3
svn st --no-ignore  | grep '^[?I]' | sed 's/^[?I]  *//' | xargs -r -d '\n' rm -r

Bu, subversion kontrolü altında olmayan tüm dosyaları silmek için bir unix kabuk komutudur.

Notlar:

  • stiçinde svn stbir yap-için verilen adlar olduğu status, yani komut eşdeğerdirsvn status
  • --no-ignoreayrıca durum çıktısında depo dışı dosyaları da içerir, aksi takdirde .cvsignorevb. mekanizmalar yoluyla yok sayar - amaç derlemeler için temiz bir başlangıç ​​noktasına sahip olmak olduğundan bu anahtar bir zorunluluktur
  • greptahrip etmek böyle çıktı sadece bilinmeyen dosyaları filtreler bırakılır - çizgiler ile başlayan ?olmadan göz ardı olacağını tahrip etmek listesi dosyaları bilinmeyen --no-ignoreseçeneği
  • dosya adına kadar olan önek şu yolla kaldırılır: sed
  • xargsKomut yoluyla talimatı -ryürütmek değil rmargüman listesi boş olurdu zaman,
  • -d '\n'seçenek söyler xargsböyle komut da boşluklu dosya adları için çalışır sınırlayıcı olarak bir yeni satır kullanmak
  • rm -r tam dizinlerin (havuzun parçası olmayan) kaldırılması gerektiğinde kullanılır

2

Yukarıdakilerin hiçbirinin ek bağımlılıklar olmadan çalışmasını sağlayamadım, win32'deki otomatik derleme sistemime eklemek zorunda kalmak istemedim. Bu yüzden aşağıdaki Ant komutlarını bir araya getirdim - bunların Ant-Contributor JAR'ın yüklenmesini gerektirdiğini unutmayın (En son sürüm 1.0b3'ü Ant 1.7.0 ile kullanıyordum).

Bunun sürümsüz tüm dosyaları uyarı vermeden sildiğini unutmayın.

  <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 &quot;${basedir}&quot;" 
                       outputProperty="status" />
    <echo message="Deleting any unversioned files:" />
    <for list="${status}" param="p" delimiter="&#x0a;" 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>

Farklı bir klasör için ${basedir}referansı değiştirin .


1
Not: yalnızca sürümü olmayan dosyaları siler; boş, değiştirilmemiş klasörleri kaldırmaz.

2
svn status --no-ignore | awk '/^[I\?]/ {system("echo rm -r " $2)}'

Yapmak istediğinizden eminseniz yankıyı kaldırın.


1
Bu, xargs tabanlı yanıtlardan daha düşüktür çünkü silinecek n dosyalar için çatallanmış n /bin/shve n rmsüreç vardır.
maxschlepzig

Kabul. Xargs bilgisi için teşekkürler.
Aria

2

Herkes yaptığı için ...

svn status | grep ^? | awk '{print $2}' | sed 's/^/.\//g' | xargs rm -R

1

Başka bir seçeneğe de katkıda bulunabilir

svn status | awk '{if($2 !~ /(config|\.ini)/ && !system("test -e \"" $2 "\"")) {print $2; system("rm -Rf \"" $2 "\"");}}'

/(Config|.ini)/ kendi amaçlarım içindir.

Ve svn komutuna --no-ignore eklemek iyi bir fikir olabilir



1

Saf Windows cmd / bat çözümü:

@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

Aslında bu komut dosyası dosyalarımı silmedi. Belki içindeki boşluklardan dolayı. @ SukeshNambiar'ın tek satırlık cevabı işe yaradı.
Christiaan Westerbeek

1

Seth Reno'nun versiyonunu bu cevaptan denedim ama benim için işe yaramadı. Dosya adından önce 8 karakterim vardı, 9 karakterinde kullanılmadı cut -c9-.

Yani bu benim sürümüdür sedyerine cut:

svn status | grep ^\? | sed -e 's/\?\s*//g' | xargs -d \\n rm -r

1

Powershell konusunda iyiyseniz:

svn status --no-ignore | ?{$_.SubString(0,1).Equals("?")} | foreach { remove-item -Path (join-Path .\ $_.Replace("?","").Trim()) -WhatIf }

Komutun silme işlemlerini gerçekten gerçekleştirmesini sağlamak için -WhatIf bayrağını çıkarın. Aksi takdirde sadece çıkış o ne olacağını -whatIf olmadan çalıştırırsanız yapmak.


1

Bunu Thomas Watnedal'ın cevabına bir yorum olarak ekleyecektim ama henüz yapamam.

Bununla ilgili küçük bir sorun (Windows'u etkilemeyecek), yalnızca dosyaları veya dizinleri kontrol etmesidir. Sembolik bağlantıların mevcut olabileceği Unix benzeri sistemler için satırı değiştirmek gerekir:

if os.path.isfile(fullpath):

için

if os.path.isfile(fullpath) or os.path.islink(fullpath):

bağlantıları da kaldırmak için.

Benim için son satırı değiştirerek if match: removeall(match.group(1))içine

    if match:
        print "Removing " + match.group(1)
        removeall(match.group(1))

böylece neyin kaldırıldığını da gösterir.

Kullanım durumuna bağlı ?[\?ID]olarak ?[\?I], Dsürüm kontrolü altında olan silinmiş dosyaları da kaldırdığı için normal ifadenin parçası daha iyi olabilir . Bunu temiz, kontrol edilmiş bir klasör oluşturmak için kullanmak istiyorum, bu nedenle bir Ddurumda dosya olmamalı .


1

@zhoufei Cevabınızı test ettim ve güncellenmiş versiyon:

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 ve H'nin önünde iki işaret kullanmalısınız
  • Sırayı değiştirin: önce tüm dosyaları kaldırın, ardından tüm dizinleri kaldırın
  • (isteğe bağlı :) %~1Herhangi bir dizin adı kullanılabilir yerine, bunu bir bat dosyasında bir işlev olarak kullandım, bu yüzden %~1ilk giriş parametresi

0

Herhangi bir kod yazmak istemiyorsanız, svn2svn'den svn2.exe bunu yapar, ayrıca nasıl uygulandığına dair bir makale de vardır . Silinen klasörler ve dosyalar geri dönüşüm kutusuna konur.

"Svn2.exe sync [yol]" komutunu çalıştırın.


0

Bunu python, Unix shell, java, vb. Yerine perl ile yapmaktan hoşlananlar için. Burada jib de yapan küçük bir perl betiği.

Not: Bu aynı zamanda tüm değiştirilmemiş dizinleri de kaldırır.

#!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();


0

Bunu PERL'de yapmanın temiz bir yolu şudur:

#!/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 ()

0

Bunu oluşturmak için ~ 3 saat kullandım. Bunu Unix'te yapmak 5 dakika sürer. Ana hat sorunu şöyleydi: Win klasörleri için adlarda boşluklar, %% i'yi düzenlemenin imkansızlığı ve Win cmd döngüsünde değişkenleri tanımlamayla ilgili sorun.

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!
)

0

Yukarıdaki C # kod parçacığı benim için işe yaramadı - kaplumbağa svn istemcim var ve satırlar biraz farklı biçimlendirilmiş. Burada yukarıdakiyle aynı kod parçacığı var, yalnızca işlev görecek ve normal ifade kullanılarak yeniden yazılmış.

        /// <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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.