RonnyPfannschmidt / anyvc
generic vcs abstraction (used in pida)
Clone this repository (size: 300.7 KB): HTTPS / SSH
$ hg clone http://bitbucket.org/RonnyPfannschmidt/anyvc/
| commit 153: | 66cc4fdc8aaf |
| parent 152: | 4d01dcd44afc |
| branch: | default |
use propper subprocess calls for git status
- View RonnyPfannschmidt's profile
-
RonnyPfannschmidt's public repos »
- pida-patches
- vimish
- pida-hacks
- virtualenvmanager
- py-virtualenv
- distribute-0.6
- distribute-resources
- pytest-codecheckers
- py-execnet3k
- gexcept
- glashammer-main
- flatland-htmlwidgets
- django-vcstorage-new-anyvc
- hgpaste
- chrome-markman
- apipkg
- kij
- gtkarchitect-main
- gazpacho
- plugpost
- rope-qickfix
- pyscope
- anyvc
- prolog
- Send message
10 months ago
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 |
|
|
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 |
|
|
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 |
|
|
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'}) |
