RonnyPfannschmidt / anyvc

generic vcs abstraction (used in pida)

Clone this repository (size: 300.7 KB): HTTPS / SSH
$ hg clone http://bitbucket.org/RonnyPfannschmidt/anyvc/

Changed (Δ1.3 KB):

raw changeset »

anyvc/workdir/git.py (47 lines added, 72 lines removed)

tests/test_workdir.py (0 lines added, 6 lines removed)

Up to file-list anyvc/workdir/git.py:

@@ -15,28 +15,13 @@ import re
15
15
16
16
class Git(CommandBased):
17
17
    """
18
    experimental
19
    copyed processing from http://www.geekfire.com/~alex/pida-git.py by alex
18
    fooked liek hell
19
    git wants 3 subprocess calls to get all needed infos
20
    data might be wrong in coner cases
20
21
    """
21
22
    cmd = 'git'
22
23
    detect_subdir = '.git'
23
24
24
    state_map = {
25
        #XXX: sane mapping?!
26
        'H': 'clean', #git calls it cached (ie added to the index,
27
        'M': 'unmerged',
28
        'R': 'removed', #XXX: figure a way to decide
29
        'C': 'changed',
30
        'K': 'to be killed',
31
        '?': 'ignored',
32
        }
33
34
    cache_map = {
35
        'modified' : 'modified',
36
        'new file':  'added',
37
        'deleted' : 'removed',
38
    }
39
40
25
    def get_diff_args(self, paths=(), **kw):
41
26
        return ['diff', '--no-color'] + self.process_paths(paths)
42
27
@@ -56,71 +41,61 @@ class Git(CommandBased):
56
41
    def get_revert_args(self, paths=(), recursive=False, **kw):
57
42
        return ['checkout','HEAD'] + self.process_paths(paths)
58
43
59
    def get_status_args(self, **kw):
60
        return ['ls-files',
61
                '-c', '-d', '-o',
62
                '-k', '-m', '-t',
63
                ]
64
65
    def parse_status_item(self, item, cache):
66
        state , name = item[0], item[2:].rstrip()
67
        return Path(name, self.state_map[state], self.base_path)
68
69
    
70
44
    def get_remove_args(self, paths=(), recursive=False, execute=False, **kw):
71
45
        return ['rm'] +  self.process_paths(paths)
72
46
73
47
    def get_rename_args(self, source, target):
74
48
        return ['mv', source, target]
75
49
76
    def cache_impl(self, recursive, **kw):
77
        """
78
        only runs caching if it knows, how
79
        """
80
        args = self.get_cache_args(**kw)
81
        if args:
82
            return self.execute_command(args, result_type=str, **kw)
50
    def parse_status_item(self, item, cache):
51
        print item
52
        return item
53
54
    def status_impl(self, *k, **kw):
55
        #XXX: OMG HELLISH FRAGILE SHIT
56
        if self.execute_command(['branch']).strip():
57
            tree = set(self.execute_command([
58
            'ls-tree', '-r', '--name-only', 'HEAD'
59
            ]).splitlines())
83
60
        else:
84
            return []
61
            print "FAIL?"
62
            tree = set()
85
63
64
        def ls_files(args):
65
            files = self.execute_command([
66
                    'ls-files' ] + [
67
                    '-%s'%c for c in args
68
                ]).splitlines()
86
69
87
    def get_cache_args(self, **kw):
88
        return ["status"]
70
            d = dict()
71
            for item in files:
72
                state, name = item.split(" ", 1)
73
                d.setdefault(name, set()).add(state)
74
            return dict(reversed(x.split(" ", 1))
75
                        for x in files)
89
76
90
    def parse_cache_items(self, items):
91
        untracked = re.search("include in what will be committed\)\n#\n(#\t[\w\.\-/]*\n)+",items)        
92
        index = re.search("to unstage\)\n#\n(#\t[\w\.\- :>/]*\n)+",items)        
93
        changed = re.search("update what will be committed\)\n#\n(#\t[\w\.\-: /]*\n)+",items)
94
        if untracked:
95
            state = 'unknown'
96
            for fn in re.findall("#\t([\w\.\-/]*)\n",untracked.group()):
97
                yield fn,state
98
        if changed:
99
            for state in re.findall("#\t([\w\.\-:/ ]*)",changed.group()):
100
                (state , fn ) = state.split(':')
101
                yield fn.strip(),self.cache_map[state.strip()]
102
        if index:
103
           for state in re.findall("#\t([\w\.\-:/> ]*)\n",index.group()):
104
                (state , fn ) = state.split(':')
105
                if  state == "renamed":
106
                    oldf,newf = fn.split('->')
107
                    yield newf.strip(),(state,oldf.strip())
108
                else:
109
                    yield fn.strip(),self.cache_map[state.strip()]
77
        wd = ls_files("tdmo")
78
        index = ls_files("tcdo")
79
        all = sorted(tree | set(wd) | set(index))
110
80
111
#        if not index and not untracked and not changed:
112
            
113
    def parse_status_items(self, items, cache):
114
        for item in items:
115
            state , name = item[0], item[2:].rstrip()
116
            if name in cache:
117
                if cache[name][0] == "renamed":
118
                    yield Path(name ,"added", self.base_path)
119
                    yield Path(cache[name][1], "removed", self.base_path)
120
                elif state != 'C':               
121
                    yield Path(name, cache[name], self.base_path)
122
            else:
123
                yield Path(name, self.state_map[state], self.base_path)
81
        for name in all:
82
            it = name in tree
83
            w = wd.get(name, [])
84
            i = index.get(name, [])
85
            print name, it, w, i
86
            #XXX: factor into parse_status_item
87
            if '?' in w:
88
                yield 'unknown', name
89
            elif 'H' in i and not w and not it:
90
                yield 'added', name
91
            elif 'H' in i and not w and it:
92
                yield 'clean', name
93
            elif not w and not i and it:
94
                yield 'removed', name
124
95
96
            elif 'C' in w and 'R' in i:
97
                yield 'missing', name
98
            elif 'C' in w and 'H' in i:
99
                yield 'modified', name
125
100
126
101

Up to file-list tests/test_workdir.py:

@@ -47,8 +47,6 @@ def test_subdir_state_add(mgr):
47
47
48
48
49
49
def test_workdir_remove(mgr):
50
    if mgr.vc.__name__ == 'Git':
51
        py.test.skip('git remove metadata is broken')
52
50
53
51
    wd = initial(mgr, commit=True)
54
52
    wd.check_states({
@@ -75,8 +73,6 @@ def test_workdir_rename(mgr):
75
73
    wd.check_states({'test2.py': 'clean'})
76
74
77
75
def test_workdir_revert(mgr):
78
    if mgr.vc.__name__ == 'Git':
79
        py.test.skip('git remove metadata is broken')
80
76
    wd = initial(mgr, commit=True)
81
77
82
78
    wd.remove(paths=['test.py'])
@@ -109,8 +105,6 @@ def test_diff_all(mgr):
109
105
110
106
111
107
def test_file_missing(mgr):
112
    if mgr.vc.__name__ == 'Git':
113
        py.test.skip('git remove metadata is broken')
114
108
    wd = initial(mgr, commit=True)
115
109
    wd.delete_files('test.py')
116
110
    wd.check_states({'test.py':'missing'})