Wie füge ich einen leeren Ordner in ein Mercurial-Projekt ein?


44

In meinem Projekt verwende ich Mercurial und einen Ordner, in den der Benutzer Dateien hochladen kann. Da der Benutzer jedoch Dateien hochlädt, ist der Ordner leer.

Ich weiß nicht, wie ich diesen Ordner zu meinem Projekt hinzufügen kann, ohne eine Datei darin abzulegen.

Weißt du wie ich das kann?

Antworten:


46

Mercurial verfolgt nur Dateien , keine Verzeichnisse .

Eine Lösung besteht darin, Ihrem Repository eine leere Datei hinzuzufügen:

$ touch uploads/.empty
$ hg add uploads/.empty

1
Ja, das ist in der Tat die richtige Lösung: Mercurial verfolgt nur Dateien , keine Verzeichnisse. Eine andere Lösung besteht darin, die leeren Verzeichnisse zu erstellen, wenn Sie Ihre Software bereitstellen.
Martin Geisler

2
Ich denke, die Benennung .hgemptykönnte einen besseren Hinweis darauf geben, wofür es ist
User

8
Ja oder.hgkeep
Natim

2
Könnte auch für verbose gehen: .hgkeepifempty :)
Daniel Sokolowski

4

Ich habe ein Python-Skript erstellt, das das Erstellen / Löschen dieser Dateien automatisiert.

Hier ist die Quelle des Skripts: http://pastebin.com/inbYmMut

#!/usr/bin/python

# Copyright (c) 2011 Ernesto Mendez (der-design.com)
# Dual licensed under the MIT and GPL licenses:
# http://www.opensource.org/licenses/mit-license.php
# http://www.gnu.org/licenses/gpl.html

# Version 1.0.0
# - Initial Release

from __future__ import generators
import sys
from optparse import OptionParser
import os

def main():
    # Process arguments

    if len(args) > 1:
        parser.error('Too many arguments')
        sys.exit()

    elif len(args) == 0:
        parser.error('Missing filename')
        sys.exit()

    if not os.path.exists(options.directory):
        parser.error("%s: No such directory" % options.directory)
        sys.exit()

    filename = args[0]

    # Create generator

    filetree = dirwalk(os.path.abspath(options.directory))

    # Walk directory tree, create files

    if options.remove == True:

        removed = ['Removing the following files: \n']
        cmd = "rm"

        for file in filetree:
            if (os.path.basename(file) == filename):
                removed.append(file)
                cmd += " %s" % fixpath(file)

        if cmd != "rm":
            for f in removed: print f
            os.system(cmd)
        else:
            print "No files named '%s' found" % filename
            sys.exit()

    # Walk directory tree, delete files

    else:

        created = ["Creating the following files:\n"]
        cmd = "touch"

        for file in filetree:
            if (os.path.isdir(file)):
                created.append("%s%s" % (file, filename))
                cmd += " " + fixpath("%s%s" % (file, filename))

        if cmd != "touch":
            for f in created: print f
            os.system(cmd)
        else:
            print "No empty directories found"
            sys.exit()


def dirwalk(dir, giveDirs=1):
    # http://code.activestate.com/recipes/105873-walk-a-directory-tree-using-a-generator/
    for f in os.listdir(dir):
        fullpath = os.path.join(dir, f)
        if os.path.isdir(fullpath) and not os.path.islink(fullpath):
            if not len(os.listdir(fullpath)):
                yield fullpath + os.sep
            else:
                for x in dirwalk(fullpath):  # recurse into subdir
                    if os.path.isdir(x):
                        if giveDirs:
                            yield x
                    else:
                        yield x
        else:
            yield fullpath


def wrap(text, width):
    return reduce(lambda line, word, width=width: '%s%s%s' % (line, ' \n'[(len(line)-line.rfind('\n')-1 + len(word.split('\n', 1)[0] ) >= width)], word), text.split(' ') )


def fixpath(p):
    return shellquote(os.path.normpath(p))


def shellquote(s):
    return "'" + s.replace("'", "'\\''") + "'"


def init_options():
    global parser, options, args
    parser = OptionParser(usage="usage: %prog [options] filename", description="Add or Remove placeholder files for SCM (Source Control Management) tools that do not support empty directories.")
    parser.add_option("-p", "--path", dest="directory", help="search within PATH", metavar="PATH")
    parser.add_option("-r", "--remove", dest="remove", action="store_true", help="remove FILE from PATH, if it's the only file on PATH")

    (options, args) = parser.parse_args()

if __name__ == '__main__':
    print
    init_options()
    main()
    print

Der Link ist tot.
Natim,


2
Host es auf Bitbucket (oder) Github, alten Pastebin ist alt
Phyo Arkar Lwin

-1, dieses Skript veranschaulicht Nti-Muster und schlechte Praktiken.
Nikratio

1

Sie machen einfach folgendes:

mkdir images && touch images/.hgkeep
hg add images/.hgkeep
hg commit -m"Add the images folder as an empty folder"

Beachten Sie dabei Folgendes:

In Ihrem Fall laden Sie möglicherweise Bilder in Ihre Entwicklungsumgebung hoch. Daher würde ich auch empfehlen, Folgendes zu Ihrer .hgignoreDatei hinzuzufügen, damit Sie nicht versehentlich Bilder festschreiben, die Sie nicht festschreiben wollten:

^(images)\/(?!\.hgkeep)

Die Regel ignoriert alles images/**außer der .hgkeepDatei, die Sie benötigen, um der Versionskontrolle einen "leeren" Ordner hinzuzufügen. Der Grund, warum diese Regel wichtig ist, ist, dass alle Dateien in diesem Ordner (dh images/test-image.pngwie eine neue nicht versionierte Datei in Ihrem Ordner aussehen, hg statuswenn Sie dieses Muster nicht ignorieren).


2
Bitte lesen Sie die Frage noch einmal sorgfältig durch. Ihre Antwort beantwortet nicht die ursprüngliche Frage: "Wie füge ich einen leeren Ordner hinzu
?

1
Du hast recht. Ich habe meine Antwort aktualisiert, um die Frage tatsächlich zu beantworten. Ich habe meinen Rat geändert und ihn verlassen, weil es wichtig ist, zu 99% der Zeit ein gewünschtes Verhalten zu kennen.
Paul Redmond

@PaulRedmond Was ist, wenn imagessich ein Verzeichnis tief im Pfad befindet? So etwas wie ./lectures/chapter_10/images? Was ist dann die richtige Syntax?
Aaron

@aaragon Zugegeben, es ist schon eine Weile her, dass ich Mercurial verwendet habe, aber Sie müssten die Regex anpassen, um sie an die von Ihnen beabsichtigten Muster anzupassen. Passen Sie den regulären Ausdruck nach Bedarf an, wenn Sie Pfade bemerken, von denen Sie erwarten, dass sie ignoriert werden.
Paul Redmond
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.