Skip to content

Commit 9c272ab

Browse files
committed
fix(encoding): in untracked_files() and index
* untracked_files could, if there were spaces in the path returned, re-rencode the previously decoded unicode string thanks to a `decode("string_escape")` call. Now re-encode into utf-8 afterwards - added test to assure this works indeed * IndexFile.add() didn't handle unicode correctly and would write broken index files. The solution was to compute the path length after encoding it into utf-8 bytes, not before ... . Closes gitpython-developers#320
1 parent af44258 commit 9c272ab

File tree

4 files changed

+20
-17
lines changed

4 files changed

+20
-17
lines changed

git/index/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ def _store_path(self, filepath, fprogress):
583583
stream = None
584584
if S_ISLNK(st.st_mode):
585585
# in PY3, readlink is string, but we need bytes. In PY2, it's just OS encoded bytes, we assume UTF-8
586-
stream = BytesIO(force_bytes(os.readlink(filepath), encoding='utf-8'))
586+
stream = BytesIO(force_bytes(os.readlink(filepath), encoding=defenc))
587587
else:
588588
stream = open(filepath, 'rb')
589589
# END handle stream
@@ -610,7 +610,7 @@ def _entries_for_paths(self, paths, path_rewriter, fprogress, entries):
610610

611611
blob = Blob(self.repo, Blob.NULL_BIN_SHA,
612612
stat_mode_to_index_mode(os.stat(abspath).st_mode),
613-
to_native_path_linux(gitrelative_path))
613+
to_native_path_linux(gitrelative_path), encoding=defenc)
614614
# TODO: variable undefined
615615
entries.append(BaseIndexEntry.from_blob(blob))
616616
# END for each path

git/index/fun.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,13 @@ def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1
124124
write(entry[4]) # ctime
125125
write(entry[5]) # mtime
126126
path = entry[3]
127+
path = path.encode(defenc)
127128
plen = len(path) & CE_NAMEMASK # path length
128129
assert plen == len(path), "Path %s too long to fit into index" % entry[3]
129130
flags = plen | (entry[2] & CE_NAMEMASK_INV) # clear possible previous values
130131
write(pack(">LLLLLL20sH", entry[6], entry[7], entry[0],
131132
entry[8], entry[9], entry[10], entry[1], flags))
132-
write(path.encode(defenc))
133+
write(path)
133134
real_size = ((tell() - beginoffset + 8) & ~7)
134135
write(b"\0" * ((beginoffset + real_size) - tell()))
135136
# END for each entry

git/repo/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ def _get_untracked_files(self, **kwargs):
625625
filename = line[len(prefix):].rstrip('\n')
626626
# Special characters are escaped
627627
if filename[0] == filename[-1] == '"':
628-
filename = filename[1:-1].decode('string_escape')
628+
filename = filename[1:-1].decode('string_escape').decode(defenc)
629629
untracked_files.append(filename)
630630
finalize_process(proc)
631631
return untracked_files

git/test/test_repo.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#-*-coding:utf-8-*-
12
# test_repo.py
23
# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors
34
#
@@ -324,31 +325,32 @@ def test_blame_complex_revision(self, git):
324325
assert len(res) == 1
325326
assert len(res[0][1]) == 83, "Unexpected amount of parsed blame lines"
326327

327-
def test_untracked_files(self):
328-
base = self.rorepo.working_tree_dir
329-
files = (join_path_native(base, "__test_myfile"),
330-
join_path_native(base, "__test_other_file"))
331-
num_recently_untracked = 0
332-
try:
328+
@with_rw_repo('HEAD', bare=False)
329+
def test_untracked_files(self, rwrepo):
330+
for (run, repo_add) in enumerate((rwrepo.index.add, rwrepo.git.add)):
331+
base = rwrepo.working_tree_dir
332+
files = (join_path_native(base, u"%i_test _myfile" % run),
333+
join_path_native(base, "%i_test_other_file" % run),
334+
join_path_native(base, u"%i__çava verböten" % run),
335+
join_path_native(base, u"%i_çava-----verböten" % run))
336+
337+
num_recently_untracked = 0
333338
for fpath in files:
334339
fd = open(fpath, "wb")
335340
fd.close()
336341
# END for each filename
337-
untracked_files = self.rorepo.untracked_files
342+
untracked_files = rwrepo.untracked_files
338343
num_recently_untracked = len(untracked_files)
339344

340345
# assure we have all names - they are relative to the git-dir
341346
num_test_untracked = 0
342347
for utfile in untracked_files:
343348
num_test_untracked += join_path_native(base, utfile) in files
344349
assert len(files) == num_test_untracked
345-
finally:
346-
for fpath in files:
347-
if os.path.isfile(fpath):
348-
os.remove(fpath)
349-
# END handle files
350350

351-
assert len(self.rorepo.untracked_files) == (num_recently_untracked - len(files))
351+
repo_add(untracked_files)
352+
assert len(rwrepo.untracked_files) == (num_recently_untracked - len(files))
353+
# end for each run
352354

353355
def test_config_reader(self):
354356
reader = self.rorepo.config_reader() # all config files

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy