Laden...

Rekursives verschieben von .svn Ordnern

Erstellt von 1mannlan vor 13 Jahren Letzter Beitrag vor 13 Jahren 6.494 Views
1
1mannlan Themenstarter:in
88 Beiträge seit 2009
vor 13 Jahren
Rekursives verschieben von .svn Ordnern

Hallo,

da ich für mein Projekt SVN nutze habe ich wie auch jeder das allbekannte Problem das der Client .svn Ordner erstellt. Nun dachte ich mir ich möchte die Ordner nicht einfach löschen was ja nicht das Problem wäre, sondern ich wollte ein Programm schreiben was sie Exportiert und die Struktur erhält. Ich habe also folgendes gebastelt:

    public partial class Form1 : Form
    {
        string Hauptpfad = "C:\\PlayX";
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            OrdnerSuchen(Hauptpfad);
        }

        private void OrdnerSuchen(string Pfad)
        {
            foreach (string svn in Directory.GetDirectories(Pfad))
            {
                if (svn.Contains(".svn"))
                {
                    if (svn.Length == (Pfad.Length + 5))
                    {
                        Directory.Move(svn, "C:\\Backup\\" + (svn.Substring(Hauptpfad.Length)));
                        MessageBox.Show(svn, "C:\\Backup\\" + (svn.Substring(Hauptpfad.Length)));
                    }
                }
                else
                {
                    OrdnerSuchen(svn);
                }
            }
        }

(if (svn.Length == (Pfad.Length + 5)) bewirkt das Ordner wie C:\PlayX.svn\Ordner übersprungen werden.)

Mein Problem ist jetzt, das er zwar alle Ordner inklusive Pfad auflistet nehme ich den Teil mit dem verschieben raus, bleibt er jedoch drin scheint es als nimmt er nur den ersten Ordner verschiebt diesen und bricht ab.
Ich stehe da jetzt wirklich auf dem Schlauch eine Idee woran es liegen kann?

5.742 Beiträge seit 2007
vor 13 Jahren

da ich für mein Projekt SVN nutze habe ich wie auch jeder das allbekannte Problem das der Client .svn Ordner erstellt. Nun dachte ich mir ich möchte die Ordner nicht einfach löschen was ja nicht das Problem wäre, sondern ich wollte ein Programm schreiben was sie Exportiert und die Struktur erhält.

Hmm? Das Problem verstehe ich nicht ganz - SVN funktioniert ohne diese Ordner gar nicht.
Sie zu entfernen wäre folglich kontraproduktiv.

1
1mannlan Themenstarter:in
88 Beiträge seit 2009
vor 13 Jahren

Die Sache ist die das man sie aus Performancegründen löschen muss/sollte.
Das will ich ja auch nicht tun, sondern sie verschieben um sie später wiederherstellen zu können. Der Nutzen ist quasi nur für die Verständlich, die damit arbeiten.

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo 1mannlan,

eine Ordnerstruktur zu verändern, während man sie durchläuft, kann in der Tat Probleme machen. Merk dir stattdessen die zu verschiebenden Ordner in einer List<> und verschiebe erst, nachdem das rekursive Durchlaufen beendet ist.

herbivore

S
417 Beiträge seit 2008
vor 13 Jahren

Öhm, wieso nimmst Du nicht anstelle eines SVN-Checkout Commands, einfach einen SVN-Export Command?
Dann bekommst Du die .svn Ordner garnicht erst.

1
1mannlan Themenstarter:in
88 Beiträge seit 2009
vor 13 Jahren

Sowas hatte ich auch schon versucht, mit einer Arraylist, nur bringt das leider das gleiche Ergebnis.
Den Export nehme ich nicht, weil ich nicht die Gedownloadeten Dateien doppelt auf der Platte haben will, es geht eher ums wie und nicht warum 😄.

Hinweis von herbivore vor 13 Jahren

ArrayList gehört in die Mottenkiste und sollte wie alle untypisierten Collections aus System.Collections nicht mehr benutzt werden. Verwende stattdessen List<T> und alle anderen typisierten Collections aus System.Collections.Generic.

656 Beiträge seit 2008
vor 13 Jahren

Nur mal so nebenbei, was spricht gegen Directory.GetDirectories mit einem Pattern von ".svn" (oder "?svn", um auch die "_svn"-Sandboxes zu erwischen) und SearchOption.AllDirectories?

S
753 Beiträge seit 2006
vor 13 Jahren

Bau dir im ersten Durchlauf eine Liste der Verzeichnisse, die du moven willst und reproduziere dabei die Ordner-Struktur.

Der zweite Schritt moved dann die Ordner

Edit: BhaaL: Weil er dann eine Methode braucht, die mehrere Verzeichnisse eines Pfads erstellen muss.

Life is a short

1
1mannlan Themenstarter:in
88 Beiträge seit 2009
vor 13 Jahren

Problem ist das ich obwohl ich eine Arraylist mit den Korrekten Pfaden habe, das ganze einfach nur die erste Datei kopiert. Ich werde morgen mal das Beispiel hochladen inklusive der Testdaten. Seltsam ist ja das es keinerlei Fehler ausspuckt.
Liegt es vielleicht daran das die Zielverzeichnisse nicht existieren? Aber normal werden die doch erstellt oder es gibt ggf. eine Meldung aus.

Hinweis von herbivore vor 13 Jahren

ArrayList gehört in die Mottenkiste und sollte wie alle untypisierten Collections aus System.Collections nicht mehr benutzt werden. Verwende stattdessen List<T> und alle anderen typisierten Collections aus System.Collections.Generic.

S
753 Beiträge seit 2006
vor 13 Jahren

Pack dir als einfacher test einfach bevor du etwas von a nach b kopierst ein
Debug.Assert(Directory.Exists("von"));
Debug.Assert(Directory.Exists("nach"));

rein, dann wirst du merken, ob das Problem daher kommt

Life is a short

U
1.688 Beiträge seit 2007
vor 13 Jahren

Die Sache ist die das man sie aus Performancegründen löschen muss/sollte.

Wieso das denn? Welche Performance?

1
1mannlan Themenstarter:in
88 Beiträge seit 2009
vor 13 Jahren

Ich habe das ganze mal umgeschrieben komme aber trotzdem nicht zum gewünschten Ergebnis.
Habe mal das Projekt und den Ordner welcher auf C:\ liegen muss in den Anhang gelegt.
Ordner C:\Backup müsste erstellt werden.
Performancegründe liegt daran das das Programm welches dann drauf zugreift deutlich mehr Daten hat = deutlich erhöhte Ladezeit

1
1mannlan Themenstarter:in
88 Beiträge seit 2009
vor 13 Jahren

#Anhang 2 (PlayX Ordner)

2.891 Beiträge seit 2004
vor 13 Jahren

Weil er dann eine Methode braucht, die mehrere Verzeichnisse eines Pfads erstellen muss.

Die Directory.CreateDirectory-Methode (System.IO) erstellt doch sämtliche Ordner des übergebenen Pfades. Wenn es kein Verzeichnis "D:/A" gibt, erstellt ein einfaches Directory.CreateDirectory("D:/A/B/C/D/E/D/G/H/I"); die komplette Hierarchie.

S
753 Beiträge seit 2006
vor 13 Jahren

Weil er dann eine Methode braucht, die mehrere Verzeichnisse eines Pfads erstellen muss.
Die
>
erstellt doch sämtliche Ordner des übergebenen Pfades. Wenn es kein Verzeichnis "D:/A" gibt, erstellt ein einfaches Directory.CreateDirectory("D:/A/B/C/D/E/D/G/H/I"); die komplette Hierarchie.

Oh, hatte ich nicht aufm Schirm, wieder was gelernt.

@1mannlan: du hast noch nichts zu der Performance gesagt

Life is a short

1
1mannlan Themenstarter:in
88 Beiträge seit 2009
vor 13 Jahren

Das Problem ist ja das ich nicht einfach die Ordner verschieben möchte sondern die Ordnerstruktur beibehalten möchte.
Wenn also im Original "C:\PlayX\lua.svn" galt soll der neue Pfad "C:\Backup\lua.svn" sein. Zur Performance habe ich bereits im letzten Post was gesagt, das Programm was den Ordner verwendet bzw. das Addon durchsucht aufgrund der vielen .svn Ordner ausgebremst wird.

S
753 Beiträge seit 2006
vor 13 Jahren

Benötigst du auch leere Verzeichnisse, in denen kein .svn drin ist? Wenn nein, dann wäre http://msdn.microsoft.com/de-de/library/system.io.directory.createdirectory.aspx ja ideal, weil es die Hierarchie erstellt.
Du erzeugst einfach alle Verzeichnisse und movest die .svn dann.

Das Addon ist bei dir aber nicht TortoiseSVN, oder? 😃

Life is a short

U
1.688 Beiträge seit 2007
vor 13 Jahren

das Addon durchsucht aufgrund der vielen .svn Ordner ausgebremst wird.

Welches "Addon" durchsucht den Projektordner?

1
1mannlan Themenstarter:in
88 Beiträge seit 2009
vor 13 Jahren

Also, ich brauche auch wirklich nur die Ordner die .svn Ordner enthalten, was aber eigentlich eh wurst ist, weil jeder einen .svn Ordner enthält.
Zum Thema Tortoise-SVN. Nein ich setze auf einen Command Line SVN Clienten. Das Programm ist dieses hier:
(Ist ein Programm was Addons für Garrysmod Installiert, welches durch die .svn Ordner ausgebremst wird.)
http://gmod.de/threads/28425-Garrysmod-Manager
Ich möchte eine Funktion bauen sämtliche .svn Ordner auszuschneiden das ganze Später auch Rückwärts.
Nur finde ich es jetzt ein bisschen umständlich wenn ich es richtig verstehe erstmal alle Ordner einzulesen, dann zu erstellen und anschliessen die Dateien zu verschieben und die Ordner wieder zu löschen.
Das einfache verschieben wie es ja eigentlich gehen sollte ist deutlich effizienter.
Es gibt ja auch noch andere Dateien die nicht kopiert werden sollen.

Den Code habe ich nochmal angepasst selber Zweck, selbes Problem:

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        string Hauptpfad = "C:\\PlayX";
        string Backuppfad = "C:\\Backup";
        List<string> Liste = new List<string>(); 
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            OrdnerSuchen(Hauptpfad);

            foreach (string item in Liste)
            {
                MessageBox.Show(item.Replace(Hauptpfad, Backuppfad));
                Debug.Assert(Directory.Exists(item.Replace(Hauptpfad, Backuppfad)));
                Directory.Move(item, item.Replace(Hauptpfad, Backuppfad));
            }
        }

        private void OrdnerSuchen(string Pfad)
        {
            foreach (string svn in Directory.GetDirectories(Pfad))
            {

                if (svn.Contains(".svn"))
                {
                    if (svn.Length == (Pfad.Length + 5))
                    {
                        Liste.Add(svn);
                    }
                }
                else
                {
                    OrdnerSuchen(svn);
                }

            }
        }


    }
}

*edit
Selbst wenn ich das Liste.Add(svn); durch Directory.Delete(svn); ersetze passiert nichts, ich versteh nun garnichtsmehr.

S
753 Beiträge seit 2006
vor 13 Jahren

Klingt jetzt blöd, aber einfach mal im Debugger durch steppen und gucken was passiert.

Life is a short

1
1mannlan Themenstarter:in
88 Beiträge seit 2009
vor 13 Jahren

*Edit

Es liegt mit höchster Wahrscheinlichkeit am Schreibschutz, warum bringt mir der Compiler keine Meldung?
Habe jetzt folgendes versucht:

        private void SetzeAttribute(string Hauptpfad)
        {
            foreach (string svn in Directory.GetDirectories(Hauptpfad))
            {
                if (svn.Contains(".svn"))
                {
                    if (svn.Length == (Hauptpfad.Length + 5))
                    {
                        File.SetAttributes(svn, FileAttributes.Normal);
                        foreach (string files in Directory.GetFiles(svn))
                        {
                            File.SetAttributes(files, FileAttributes.Normal);
                        }
                    }
                }
                SetzeAttribute(svn);
            }
        }}

Bekomme aber den Schreibschutz nicht richtig weg, ausserdem sollen die Ordner unsichtbar bleiben.

2.891 Beiträge seit 2004
vor 13 Jahren

Das Programm ist dieses hier: (Ist ein Programm was Addons für Garrysmod Installiert, welches durch die .svn Ordner ausgebremst wird.)

>

Du bist doch der Autor vom AddOn, oder? Kannst du da nicht einfach drauf verzichten, versteckte Ordner zu durchsuchen (TSVN versteckt die .svn-Ordner jedenfalls)?

1
1mannlan Themenstarter:in
88 Beiträge seit 2009
vor 13 Jahren

Nein die Addons stammen nicht von mir, mein Programm lädt diese nur herunter und die .svn Ordner werden leider versteckt und mit Schreibschutz (Inhalt auch) erstellt.
(Macht der SVN-Command-line-client und auch jedes andere SVN Programm so.)

F
10.010 Beiträge seit 2004
vor 13 Jahren

Bei deinem "Program" sieht man schön, wie man sich durch vermeintlich professionellere Schreibweise das Debuggen und damit das finden der Fehler erschweren kann.


foreach (string item in Liste)
{
    Directory.Move(item, "C:\\Backup\\" + (item.Substring(Hauptpfad.Length)));
}

Das ist der Hauptcode. Kannst du mir sagen was da von wo nach wo verschoben wird?
Wie willst du das debuggen?


foreach (string item in Liste)
{
    string subPath = item.Substring(Hauptpfad.Length+1);
    string backupPath = Path.Combine("b:\\Backup", subPath);
    string backupDirectoty = Path.GetDirectoryName(backupPath);

    Directory.CreateDirectory(backupDirectoty);
    Directory.Move(item, backupPath);
}

Das hier funktioniert hingegen, und es ist debugbar.
Und die evtl auftretenden 2 microsecunden die das länger dauert........

1
1mannlan Themenstarter:in
88 Beiträge seit 2009
vor 13 Jahren

Jetzt geht es, ich danke dir.
Ich denke es lag daran das ich den Ordner nicht vorher erstellt habe, nehme ich das bei deinem raus macht er das gleiche wie mein Code auch.
Mit der Ergänzung funktioniert meins auch.
z.B. "C:\PlayX.svn", wird mit Substring gekürtzt auf ".svn" und anschliessen als neuen Pfad ausgegeben:
C:\Backup.svn

 Directory.CreateDirectory(Path.GetDirectoryName("C:\\Backup\\" + (item.Substring(Hauptpfad.Length))));
                Directory.Move(item, "C:\\Backup\\" + (item.Substring(Hauptpfad.Length)));

...Liefert demnach das gleiche Ergebnis, es lag also am Ordner erstellen, dafür besten dank.

Das ganze sieht nun so aus und funktioniert:

        private void Form1_Load(object sender, EventArgs e)
        {
            OrdnerSuchen(Hauptpfad);
        }

        private void OrdnerSuchen(string Pfad)
        {
            foreach (string svn in Directory.GetDirectories(Pfad))
            {
                if (svn.Contains(".svn"))
                {
                    if (svn.Length == (Pfad.Length + 5))
                    {
                        string backupPath = Path.Combine("C:\\Backup\\" + (svn.Substring(Hauptpfad.Length)));
                        Directory.CreateDirectory(Path.GetDirectoryName(backupPath));
                        Directory.Move(svn, backupPath);
                    }
                }
                else
                {
                    OrdnerSuchen(svn);
                }

            }
        }
F
10.010 Beiträge seit 2004
vor 13 Jahren

string backupPath = Path.Combine("C:\\Backup\\" + (svn.Substring(Hauptpfad.Length)));

Und das lässt sich compilieren?

F
240 Beiträge seit 2006
vor 13 Jahren

Ja, da Path.Combine nen params string[] overload hat.

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo zusammen,

auch wenn es sich compilieren lässt macht Path.Combine (string1 **+** string2) wenig Sinn sind, denn dann wird das Zusammenfügen der Teile doch durch das Plus (+) vorgenommen und nicht durch das Path.Combine, wie es sein soll. Die Anweisung sollte sinnvollerweise Path.Combine (string1**,** string2) lauten.

herbivore