1

たとえば、ファイルをからに移動したとし/project/file.csます/project/subdir/file.cs。nautilusがこれを自動的にに変換するといいでしょうbzr mv /project/file.cs /project/subdir/file.cs。これを設定することは可能ですか?

バージョン管理されたファイルで昔ながらのことをしているときに警告されたらいいのですがmv、それは別の質問だと思います。

4

2 に答える 2

2

すでに自分自身を示したように、基本的に動きをリッスンするものが必要なので、これがどのように機能するかを示す何かをコード化すると思いました。

gio.FileMonitorを使用してみましたが、ファイルの名前変更/移動を検出するためのサポートが組み込まれているため、最終的にはプレーンな古いpyinotifyの使用に戻りました。

import pyinotify

import bzrlib
from bzrlib.workingtree import WorkingTree
from bzrlib.errors import NotBranchError, BzrRenameFailedError

directories_to_watch = [
    # Add the paths to your working copies / branches to watch here
]

wm = pyinotify.WatchManager()

# When you listen to both MOVED_FROM and MOVED_TO the event for MOVED_TO will include both 
# pathname (new path) and src_pathname (previous path).
mask = pyinotify.IN_MOVED_FROM | pyinotify.IN_MOVED_TO

class EventHandler(pyinotify.ProcessEvent):

    def process_IN_MOVED_TO(self, event):
        try:
            tree, path = WorkingTree.open_containing(event.src_pathname)
            root = event.src_pathname[:-len(path)] # Ugh, hackish

            if not path.startswith(".bzr"): # Also hackish (to exclude events for anything in the .bzr subdirectory)
                try:
                    tree.lock_tree_write()
                    source = event.src_pathname[len(root):] # Again hackish
                    target = event.pathname[len(root):] # Same
                    tree.rename_one(source, target)
                    print "Renamed %s to %s" % (source, target)
                except BzrRenameFailedError: # Same
                    pass
                finally:
                    tree.unlock()
        except NotBranchError:
            return

handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler)

for path in directories_to_watch:
    wdd = wm.add_watch(path, mask, rec=True, auto_add=True)
    print "Recursively watching %s" % path

notifier.loop()

仕組みは次のとおりです。

$ mv afile bfile
$ bzr status
renamed:
  afile => bfile

$ mv bfile foobar/
$ bzr status
renamed:
  afile => foobar/bfile

$ mv foobar/ zoobar
$ bzr status
renamed:
  afile => zoobar/bfile
  foobar/ => zoobar/

$ mv zoobar/ foobar
$ bzr status
renamed:
  afile => foobar/bfile

$ mv foobar/bfile afile

そして、私たちは始めたところに戻ってきました;-)

[編集]

監視するさまざまなディレクトリを手動で一覧表示したくない場合は、ナビゲート中に遭遇するさまざまな作業コピーを追跡するNautilus拡張機能を作成することをお勧めします。これがあなたが始めるための何かです(これは入ります~/.nautilus/python-extensions):

import os
import pickle

import nautilus 

import gio

from xdg import BaseDirectory as basedir

import bzrlib
from bzrlib.workingtree import WorkingTree
from bzrlib.errors import NotBranchError

class BzrMonitor(nautilus.InfoProvider, nautilus.MenuProvider):

    data_directory = basedir.save_data_path("bzrmonitor")
    data_filename = os.path.join(data_directory, "workingcopies.db")

    def __init__(self):
        print "Initializing BzrMonitor extension..."

        try:
            data_file = open(self.data_filename, "r")
            self.data = pickle.load(data_file)
        except IOError:
            self.data = []
            data_file = open(self.data_filename, "w")
            pickle.dump(self.data, data_file)
            data_file.close()

    def detect_and_save_branch(self, path):
        try:
            tree, rel_path = WorkingTree.open_containing(path)

            # TODO: Still can't figure out how to get the path from the tree itself
            if len(rel_path) > 0: 
                root = path[:-len(rel_path)]
            else:
                root = path

            root = root.rstrip(os.path.sep)

            if root not in self.data: 
                print "Added not seen before branch %s to cache..." % root
                self.data.append(root)
                data_file = open(self.data_filename, "w")
                pickle.dump(self.data, data_file)
                data_file.close()

        except NotBranchError:
            return

    def update_file_info(self, item):
        """
        This function is called when:

          - When you enter a directory (once for each item but only when the
            item was modified since the last time it was listed)
          - When you refresh (once for each item visible)
          - When an item viewable from the current window is created or modified
        """
        self.detect_and_save_branch(gio.File(item.get_uri()).get_path())

    def get_file_items(self, window, items):
        """
        Menu activated with items selected. Nautilus also calls this function
        when rendering submenus, even though this is not needed since the entire
        menu has already been returned.
        """

        pass

    def get_background_items(self, window, item):
        """
        Menu activated on entering a directory. Builds context menu for File
        menu and for window background.
        """

        self.detect_and_save_branch(gio.File(item.get_uri()).get_path())

RabbitVCSの拡張コードからさまざまなdocstringを借りました;-)

workingcopies.dbモニターでは、ファイルの追加を監視し、見つかった新しい作業コピーに監視を登録することをお勧めします。

資力

于 2010-08-14T20:28:55.763 に答える
1

RabbitVCSの開発者の一人として、私はそのようなことは現在不可能であると確信しています。Nautilus拡張機能は、コンテキストメニュー、プロパティページ、追加の列を提供し、ブラウザのメインウィンドウに表示されているファイルに応答できます。移動や削除などの任意のイベントにフックすることはできません。(その場合は気に入っていますが、現時点では優先事項ではありません。)Nautilus拡張APIを自分で変更する必要があります。

それに満足しているが、どこから始めればよいかわからない場合は、Nautilusのソースを調べて、Nautilusメーリングリストで質問する必要があります。あなたがこれについて間違った木を吠えているなら、彼らは確かにあなたに言うことができます。

Nautilus拡張機能がこの種のものにとって間違った場所である可能性があります。Nautilus拡張機能の代わりにGVFSを使用して何かを行うことは可能かもしれませんが、私はそれについて深く理解していません。

于 2010-04-20T07:12:28.547 に答える