Dosya değiştirildikten sonra otomatik sürüm oluşturma (değiştir / oluştur / sil)


16

Bir dizindeki herhangi bir değişikliği (yinelemeli olarak) otomatik ve şeffaf bir şekilde sürümlendiren bir mekanizmanın (Linux'ta) bir uygulamasını arıyorum. Bu, standart sürümlere (SVN, git, ...) bir ekleme (muhtemelen tüm istenen özellikler varsa değiştirme) olarak tasarlanmıştır.

MS Windows üzerinde bunu yapan bir ürün AutoVer'dir (gereksinimler hakkında daha iyi bir fikre sahip olmak için). Böyle bir şeye sahip olmak isterdim ama grafik olmayan bir ortamda Linux'u hedefliyorum.

Linux'ta bu işlevselliğe sahip olmak için bazı girişimler olduğunu gördüm, en yakın bulduğum şey Subversion'da otomatik sürümdür, ancak mevcut ortamlarda (örneğin, yapılandırma dosyalarının yerel olduğu sunucular) uygulanması açık değildir.

Belki birlikte çalışan bir şey inotify?

Herhangi bir işaretçi için şimdiden teşekkür ederiz! woj


ile ilgili: flashbake
Dan D.


Hangi yazılımı kullandığınız konusunda özel bir gereklilik var mı? Çünkü yalnızca manuel olarak yaptığınız değişiklikleri (dosyaları düzenleyerek) izlemek istiyorsanız, Eclipse bu özelliğe sahiptir, buna "yerel geçmiş" denir.
Stefan Seidel

@StefanSeidel Konu başlatıcı değilim, ancak IDE olmayan çözümü tercih ederim.
Michael Pankov

Yanıtlar:


6

1. Çarşı ve inotify kullanarak genel amaçlı yöntem

Bu benim tarafımdan test edilmedi, ancak (çarşı) ' yı kullanan ve bir dizini ve sürümü izlemek için içindeki dosyaları kontrol eden bu yazıyı buldum .bzrinotifywait

Bu komut dosyası dizindeki değişiklikleri izlemek için tüm işleri yapar:

#!/bin/bash

# go to checkout repository folder you want to watch
cd path/to/www/parent/www
# start watching the directory for changes recusively, ignoring .bzr dir
# comment is made out of dir/filename
# no output is shown from this, but wrinting a filename instead of /dev/null 
# would allow logging
inotifywait –exclude \.bzr -r -q -m -e CLOSE_WRITE \
    –format=”bzr commit -m ‘autocommit for %w/%f’” ./ | \
    sh  2>/dev/null 1>&2 &
# disown the pid, so the inotify thread will get free from parent process
# and will not be terminated with it
PID=`ps aux | grep inotify | grep CLOSE_WRITE | grep -v grep | awk ‘{print $2}’`
disown $PID

# this is for new files, not modifications, optional
inotifywait –exclude \.bzr -r -q -m -e CREATE \
    –format=”bzr add *; bzr commit -m ‘new file added %w/%f’” ./ | \
    sh  2>/dev/null 1>&2 &
PID=`ps aux | grep inotify | grep CREATE | grep -v grep | awk ‘{print $2}’`
disown $PID

exit 0;

2. Yönetme / vb

Sisteminizin /etcdizinini yönetme özel durumu için, uygulama etckeeper'ı kullanabilirsiniz .

etckeeper, git, mercurial, darcs veya bzr deposunda saklanmasına izin veren bir araç koleksiyonudur. Paket yükseltmeleri sırasında / etc üzerinde yapılan değişiklikleri otomatik olarak yürütmek için apt (ve yum ve pacman-g2 dahil diğer paket yöneticileri) içine girer. Revizyon kontrol sistemlerinin normalde desteklemediği dosya meta verilerini izler, ancak / etc için / etc / shadow izinleri gibi önemlidir. Oldukça modüler ve yapılandırılabilir, revizyon kontrolü ile çalışmanın temellerini anlarsanız kullanımı da basittir.

İşte size başlamak için iyi bir öğretici .

3. git ve incron kullanma

Bu teknik yararlanır gitve incron. Bu yöntem için aşağıdakileri yapmanız gerekir:

A. Bir repo yap

% mkdir $HOME/git
% cd $HOME/git
% git init

B.$HOME/bin/git-autocommit Komut dosyası oluşturma

#!/bin/bash

REP_DIR="$HOME/git"       # repository directory
NOTIFY_DIR="$HOME/srv"    # directory to version

cd $REP_DIR
GIT_WORK_TREE=$NOTIFY_DIR /usr/bin/git add .
GIT_WORK_TREE=$NOTIFY_DIR /usr/bin/git commit -a -m "auto"

C. incrontab'a bir giriş ekleyin

% sudo incrontab -e $HOME/srv IN_MODIFY,IN_CREATE,IN_MOVED_FROM,IN_MOVED_TO $HOME/bin/git-autocommit

4. Flashbake kullanma

Başka bir seçenek Flashbake gibi bir araç kullanmaktır . Flashbake, Cory Doctorow'un (BoingBoing şöhretinden) kitaplarını yazmak için kullandığı sürüm kontrol sistemidir.

Flashbake, değişiklikleri izlemek için kaputun altında git'i kullanıyor ancak otomatik yedeklemeler yapmak ve düz bir sürüm kontrol sistemi kullanmak arasında bir yer.

Cory, versiyonun otomatik bir taahhüt gerçekleştiği sırada nerede olduğunu ve ne düşündüğünü istemlerini, anlık görüntülerini taşımasını istedi. Hızlı bir şekilde istediği bağlamsal bilgileri çekmek için bir Python betiği çizdim ve bir cron işi kabuk sarmalayıcıyı çağırdığında taahhüt yorumu için Python betiğinin çıktısını kullanarak git sürücü için bir kabuk betiğini hacklemeye başladım.

kaynaklar


3
inotifywait + "git local" = gitwatch.sh, şuraya bakın: github.com/nevik/gitwatch/blob/master/gitwatch.sh
diyizm


3

Bence doğru yoldasınız inotify. Bu makale , sizinkine benzer bir durumda temel kullanımını ayrıntılı olarak açıklamaktadır. Bunu doğrudan kullanmanızı veya fschange gibi bir çekirdek düzeyinde yardımcı programı derlemenizi öneririm . Bu bir güçlüktür, ancak daha sonra bir git commitveya benzeri değişikliklerin algılanmasını bağlayabilirsiniz .

Bu çözümlerin her ikisi de, bir şekilde kusurlu üçüncü taraf çözümlerine dayanma sorununa sahiptir. Ellerinizi kirletmenin bir sakıncası yoksa, NodeJS bu amaç için mükemmel bir platformlar arası tesis ( fs.watch ) sağlar. NodeJS'deki değişiklikler için dosyaları izlemeye ilişkin temel bir öğreticiyi burada bulabilirsiniz . Birkaç düzine satırda, dosyalar için bir dizini izleyen ve daha sonra kabukları ( child_process ile ) ve bir git commitya da benzerlerini çalıştıran (ya da hatta bir sürüm dosyası dizinini manuel olarak artıran bir şey yazabilirsiniz ) kendi yaklaşımı).

fs.watchinotifylinux tarafından desteklenmektedir , ancak kullanımı çok daha sezgiseldir. Bu dosya izleme işlevini, bu ya da bu gibi çeşitli kolaylık düzeylerinde saran başka NodeJS projeleri var .


Hala hazır bir çözüm değil, ve muhtemelen Python'larla giderdim inotify. Ama teşekkürler.
Michael Pankov

3

Linux üzerindeki inotify (2) büyük bir ağacı izleyemez, ancak dosya sistemi isteklerini svn veya git çağrılarına çevirerek veya doğrudan svn / git meta verilerini değiştirerek sigorta dosya sistemi (ayrı bir yere monte edilir) muhtemelen işleyebilir.

Bu çok ilginç bir fikir, ancak mevcut uygulamaları duymamıştım.


Diyelim ki sadece birkaç dosyam var.
Michael Pankov

0

Böyle bir senaryo yazmak zor değildir.

En sevdiğim sürüm kontrolü git.

Aşağıdaki komut dosyası bunu yapmalıdır:

#!/bin/sh
git add .
git commit -am "my automatic commit"

ya dizininizi düzenli olarak kontrol ettirin - ya da kaydettikten sonra düzenleyiciniz yazılabilir çağrı ise

Ancak bunu böyle yaparsanız büyük dosyaları ve belki de bazı "yararsız" otomatik kaydetmeleri hariç tutmak mantıklı olabilir.


Evet, kron tabanlı bir çözümün uygulanmasının basit olduğunu biliyorum. Ancak, kaydetme mekanizması ne olursa olsun, kaydetme sürümü olacak bir şey arıyorum. Bu yüzden svn'de autoversionninf'den bahsettim ve sorumu inotify ettim.
WoJ

0

SparkleShare ( http://sparkleshare.org ) git üzerine kuruludur ve sürüm kontrolü ile Dropbox-benzeri bir işlevsellik uygular, ancak bir ssh-sunucu (localhost olabilir) kurmanız gerekir.


Bu şey beceriksiz ve çok fazla kurulum gerektiriyor. Ayrıca, Dropbox işlevselliği gerekmez.
Michael Pankov


0

Bunu sadece rsync ve cron işi kullanarak yapmanın "fakir bir erkeğin" yolu da vardır. Temel olarak rsync'in yedekleme özelliğine güveniyorsunuz ve dosyalarınızı takip etmek için iki ayrı yol artı bir önek / sonek kullanıyorsunuz.

Daha azı şuna benzer: / usr / bin / rsync -a -A -X --backup --suffix = date +".%Y-%m-%d_%H-%M-%S"$ source_path $ backup_path

Sonuç: İlk yürütme işleminden sonra kaynak yolda test_rsync adlı bir dosyanın değiştirilmesi, yedekleme yolunda test_rsync.2017-02-09_11-00-01 adlı bir dosyanın oluşturulmasına neden olur.

Bu konuda bir sürü sorun var (sadece yeterli miktarda dosya varsa çalışır ve rsync'in iki ardışık çalışması arasında gerçekleşen değişiklikler için başarısız olur (benim durumumda 1 dakika)), ancak ihtiyaçlarınız için yeterli olabilir.

Burada samba hisseleri hakkında konuşuyorsak, bir hariç tutma listesi sırayla olabilir, buna henüz ulaşmadım, korkuyorum.

Bunu geliştirirsen bana haber ver.


0

Burada kaydedildiğinde orijinal dosya adına eklenmiş bir zaman damgası kullanarak VMS'yi otomatik dosya sürümlendirme gibi yapan bir Python3 betiği bulunmaktadır.

Senaryoya bir demet yorum koymak ve aynı anda birden çok dizin versiyonlamak böylece sadece dizinler betiğin her farklı sürümünde farklı olan ubuntu makinede yarım düzine böyle betikler çalıştırın. Makinelerin performansına gerçek bir ceza verilmez.

! / usr / bin / env python3

print ("PROJE DOSYALARI SÜRÜMÜ BAŞLADI") print ("version_creation.py") # bu kodun tamamını bu adın komut dosyasına yerleştirin print ("komut satırından" python3 version_creation.py 'olarak çalıştırın)) print ("ctrl' c 'durdurmak için ") print (" ") print (" Programı komut satırına aşağıdaki arka plan türünde çalıştırmak ve sonra pencereyi kapatmak için. ") print (" nohup python3 version_creation.py ") print (" .... işlemi durdur menü / yönetim / sistem monitörü ... ve python3'ü öldür ") print (" ") print (" Dosyaları daima 'ProjectFiles' dizinine ve sürüm dosyalarına kaydet ") print (" bu dizinde de oluşturulacaktır) . ") yazdır (" ") yazdır (" ") yazdır (" ") yazdır (" ")

ithalat kapat ithalat os ithalat süresi

--- aşağıdaki yeni dosyaları kontrol etmek için zaman aralığını ayarlayın (saniye cinsinden)

- bu aralık yeni dosyaların göründüğü aralıktan küçük olmalıdır!

t = 10

--- kaynak dizini (dr1) ve hedef dizini (dr2) ayarlayın

dr1 = "/ path / to / source_directory"

dr2 = "/ path / to / target_directory"

ithalat glob ithalat os

dr1 = "/ home / michael / ProjectFiles" # hem orijinal hem de sürümler bu dizine kaydedilecek

dr2 = "/ home / michael / ProjectFileVersions"

True iken:

if os.listdir(dr1) == []:

yazdır ("Boş")

    n = 100
else:
    list_of_files = glob.glob(dr1+'/*')   # * means all if need specific format then *.csv
    latest_file_path = max(list_of_files, key=os.path.getctime)

yazdır ("1 Latest_file_path =", son_dosya_yolu)

    originalname = latest_file_path.split('/')[-1]

yazdır ("2 orijinal ad =", orijinal ad)

    filecreation = (os.path.getmtime(latest_file_path))

print ("filecreation =", filecreation)

    now = time.time()
    fivesec_ago = now - 5 # Number of seconds

yazdır ("fivesec_ago =", fivesec_ago)

    timedif = fivesec_ago - filecreation #time between file creation

yazdır ("timedif =", timedif)

    if timedif <= 5: #if file created less than 5 seconds ago

        nameroot = originalname.split(".")[-0]
        print ("3 nameroot= ", nameroot)

        extension = os.path.splitext(originalname)[1][1:]
        print ("4 extension = ", extension)

        curdatetime = time.strftime('%Y%m%d-%H%M%S')
        print ("5 curdatetime = ", curdatetime)

        newassembledname = (nameroot + "_" + curdatetime + "." + extension)
        print ("6 newassembledname = ", newassembledname)



        source = dr1+"/"+originalname
        print ("7 source = ", source)

        target = dr1+"/"+newassembledname
        print ("8 target = ", target)

        shutil.copy(source, target)


    time.sleep(t)

Paylaş

aşağıda daha önce koyuldu ve çalışıyor ama yukarıdaki python komut dosyası çok daha iyi gibi ...... (yaklaşık 3 saat boyunca python kullanarak)

#!/usr/bin/env python3

print ("PROJECT FILES VERSIONING STARTED")
print ("projectfileversioning.py")
print ("run as..  'python3 projectfileversioning.py'       from command line")
print ("ctrl 'c'      to stop")
print (" ")
print ("To run program in background type below to command line and then close the window. ")
print ("nohup python3 projectfileversioning.py")
print ("....to stop process go menu/administration/system monitor... and kill python")
print (" ")
print ("Always save files to the 'ProjectFiles' directory and the file ")
print ("   will be redirected to the ProjectFileVersions where")
print ("   time stamped versions will also be created.")
print (" ")
print ("If you like you may then copy/move the versioned and original file from 'ProjectFileVersions' to ")
print ("any other directory you like.")

import shutil
import os
import time

#--- set the time interval to check for new files (in seconds) below 
#-   this interval should be smaller than the interval new files appear!
t = 10

#--- set the source directory (dr1) and target directory (dr2)
#dr1 = "/path/to/source_directory"
#dr2 = "/path/to/target_directory"

import glob
import os

dr1 = "/home/michael/ProjectFiles"
dr2 = "/home/michael/ProjectFileVersions"


while True:

    if os.listdir(dr1) == []:
        n = 100
    else:
        list_of_files = glob.glob(dr1+'/*')   # * means all if need specific format then *.csv
        latest_file_path = max(list_of_files, key=os.path.getctime)
        print ("1 Latest_file_path = ", latest_file_path)

        originalname = latest_file_path.split('/')[-1]
        print ("2 originalname = ", originalname)

        nameroot = originalname.split(".")[-0]
        print ("3 nameroot= ", nameroot)

        extension = os.path.splitext(originalname)[1][1:]
        print ("4 extension = ", extension)

        curdatetime = time.strftime('%Y%m%d-%H%M%S')
        print ("5 curdatetime = ", curdatetime)

        newassembledname = (nameroot + "_" + curdatetime + "." + extension)
        print ("6 newassembledname = ", newassembledname)




        source = dr1+"/"+originalname
        print ("7 source = ", source)

        target = dr2+"/"+originalname
        print ("8 target = ", target)

        shutil.copy(source, target)



        source = dr1+"/"+originalname
        print ("9 source = ", source)

        target = dr2+"/"+newassembledname
        print ("10 target = ", target)

        shutil.move(source, target)
        time.sleep(t)


#share
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.