Come aggiungere una cartella vuota in un progetto Mercurial?


44

Nel mio progetto, sto usando Mercurial e una cartella in cui l'utente può caricare il file. Ma poiché l'utente caricherà i file, la cartella è vuota.

Non so come posso aggiungere questa cartella al mio progetto senza inserire alcun file.

Sai come posso fare?

Risposte:


46

Mercurial tiene traccia solo dei file , non delle directory .

Una soluzione è aggiungere un file .empty al repository:

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

1
Sì, questa è davvero la soluzione corretta: Mercurial sta solo tenendo traccia dei file , non delle directory. Un'altra soluzione è quella di creare le directory vuote quando si distribuisce il software.
Martin Geisler,

2
Sto pensando di nominarlo .hgemptypotrebbe dare un indizio migliore su cosa serve
Utente

8
Sì o.hgkeep
Natim,

2
Potrebbe anche andare per verbose: .hgkeepifempty :)
Daniel Sokolowski

4

Ho creato uno script Python che automatizza il processo di creazione / eliminazione di tali file.

Ecco la fonte dello script: 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

Il link è morto.
Natim,

Link vero, aggiornato ...
mendezcode

2
ospitalo su bitbucket (o) github, il vecchio pastebin è vecchio
Phyo Arkar Lwin,

-1, quella sceneggiatura esemplifica nti-pattern e cattive pratiche.
Nikratio,

1

Fai semplicemente quanto segue:

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

Tenere presente quanto segue quando si esegue questa operazione:

Nel tuo caso potresti caricare immagini nel tuo ambiente di sviluppo, quindi ti consiglio anche di aggiungere quanto segue al tuo .hgignorefile in modo da non commettere accidentalmente immagini che non intendevi impegnare:

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

La regola ignorerà tutto su images/**tranne il .hgkeepfile necessario per aggiungere una cartella "vuota" al controllo versione. Il motivo per cui questa regola è importante è che tutti i file in quella cartella (ad es. images/test-image.pngAppariranno come un nuovo file senza versione nel tuo hg statusse non ignori quel modello.


2
Si prega di leggere di nuovo attentamente la domanda. La tua risposta non risponde alla domanda originale, che chiedeva "come aggiungere una cartella vuota" e non "Come ignorare una cartella"
DavidPostill

1
Hai ragione. Ho aggiornato la mia risposta per rispondere effettivamente alla domanda. Ho modificato il mio consiglio e l'ho lasciato perché è importante conoscere e il 99% delle volte un comportamento desiderato.
Paul Redmond,

@PaulRedmond e se imagesuna directory fosse nel percorso? Qualcosa del genere ./lectures/chapter_10/images? Qual è quindi la sintassi giusta?
Aaragon,

@aaragon è vero che è da un po 'che non uso Mercurial, ma dovresti adattare la regex per adattarla ai pattern che intendi. Quando noti percorsi che ti aspetti di essere ignorato, modifica la regex secondo necessità.
Paul Redmond,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.