Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
G
git-repo
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux-tools
git-repo
Commits
3568b211
Commit
3568b211
authored
Sep 11, 2015
by
Matthias Putz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Portable: symlink, using mklink in Windows
parent
8368c65f
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
155 additions
and
7 deletions
+155
-7
manifest_xml.py
manifest_xml.py
+3
-1
portable.py
portable.py
+135
-0
project.py
project.py
+17
-6
No files found.
manifest_xml.py
View file @
3568b211
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
from
__future__
import
print_function
from
__future__
import
print_function
import
itertools
import
itertools
import
os
import
os
import
portable
import
re
import
re
import
sys
import
sys
import
xml.dom.minidom
import
xml.dom.minidom
...
@@ -148,7 +149,8 @@ class XmlManifest(object):
...
@@ -148,7 +149,8 @@ class XmlManifest(object):
try
:
try
:
if
os
.
path
.
lexists
(
self
.
manifestFile
):
if
os
.
path
.
lexists
(
self
.
manifestFile
):
os
.
remove
(
self
.
manifestFile
)
os
.
remove
(
self
.
manifestFile
)
os
.
symlink
(
'manifests/
%
s'
%
name
,
self
.
manifestFile
)
# os.symlink('manifests/%s' % name, self.manifestFile)
portable
.
os_symlink
(
'manifests/
%
s'
%
name
,
self
.
manifestFile
)
except
OSError
as
e
:
except
OSError
as
e
:
raise
ManifestParseError
(
'cannot link manifest
%
s:
%
s'
%
(
name
,
str
(
e
)))
raise
ManifestParseError
(
'cannot link manifest
%
s:
%
s'
%
(
name
,
str
(
e
)))
...
...
portable.py
View file @
3568b211
import
git_config
import
os
import
os
import
pager
import
pager
import
platform
import
platform
import
re
import
socket
import
socket
import
sys
import
sys
import
subprocess
import
subprocess
...
@@ -83,6 +85,139 @@ class socket_reader():
...
@@ -83,6 +85,139 @@ class socket_reader():
return
self
.
server_socket
.
fileno
()
return
self
.
server_socket
.
fileno
()
def
os_symlink
(
src
,
dst
):
if
isUnix
():
os
.
symlink
(
src
,
dst
)
else
:
windows_symlink
(
src
,
dst
)
def
windows_symlink
(
src
,
dst
):
globalConfig
=
git_config
.
GitConfig
.
ForUser
()
src
=
to_windows_path
(
src
)
dst
=
to_windows_path
(
dst
)
is_dir
=
True
if
os
.
path
.
isdir
(
os
.
path
.
realpath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
dst
),
src
)))
else
False
no_symlinks
=
globalConfig
.
GetBoolean
(
"portable.windowsNoSymlinks"
)
if
no_symlinks
is
None
or
no_symlinks
==
False
:
symlink_options_dir
=
'/D'
symlink_options_file
=
''
else
:
src
=
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
dst
),
src
))
Trace
(
"Using no symlinks for
%
s from
%
s to
%
s"
,
"dir"
if
is_dir
else
"file"
,
src
,
dst
)
symlink_options_dir
=
'/J'
symlink_options_file
=
'/H'
if
is_dir
:
cmd
=
[
'cmd'
,
'/c'
,
'mklink'
,
symlink_options_dir
,
dst
,
src
]
cmd
=
filter
(
len
,
cmd
)
Trace
(
' '
.
join
(
cmd
))
try
:
subprocess
.
Popen
(
cmd
,
stdout
=
subprocess
.
PIPE
)
.
wait
()
except
Exception
as
e
:
Trace
(
"failed to create dir symlink:
%
s"
,
e
.
strerror
)
pass
else
:
cmd
=
[
'cmd'
,
'/c'
,
'mklink'
,
symlink_options_file
,
dst
,
src
]
cmd
=
filter
(
len
,
cmd
)
Trace
(
' '
.
join
(
cmd
))
try
:
subprocess
.
Popen
(
cmd
,
stdout
=
subprocess
.
PIPE
)
.
wait
()
except
Exception
as
e
:
Trace
(
"failed to create file symlink:
%
s"
,
e
.
strerror
)
pass
def
os_path_islink
(
path
):
if
isUnix
():
os
.
path
.
islink
(
path
)
else
:
if
get_windows_symlink
(
path
)
is
not
None
:
return
True
if
get_windows_hardlink
(
path
)
is
not
None
:
return
True
return
False
def
os_path_realpath
(
file_path
):
if
isUnix
():
os
.
path
.
realpath
(
file_path
)
else
:
if
not
os
.
path
.
exists
(
file_path
):
return
file_path
return
windows_realpath
(
file_path
)
def
windows_realpath
(
file_path
):
symlink
=
file_path
while
True
:
s
=
get_windows_symlink
(
symlink
)
if
s
is
None
:
break
else
:
symlink
=
s
hardlink
=
get_windows_hardlink
(
symlink
)
if
hardlink
is
not
None
:
return
hardlink
else
:
return
symlink
def
get_windows_symlink
(
file_path
):
if
os
.
path
.
isdir
(
file_path
):
root
=
os
.
path
.
abspath
(
os
.
path
.
join
(
file_path
,
os
.
pardir
))
file_object
=
os
.
path
.
split
(
file_path
)[
1
]
if
not
file_object
:
file_object
=
os
.
path
.
split
(
os
.
path
.
split
(
file_object
)[
0
])[
1
]
else
:
root
=
os
.
path
.
dirname
(
file_path
)
file_object
=
os
.
path
.
split
(
file_path
)[
1
]
cmd
=
[
'cmd'
,
'/c'
,
'dir'
,
'/AL'
,
root
]
try
:
Trace
(
' '
.
join
(
cmd
))
out
=
subprocess
.
check_output
(
cmd
,
stderr
=
subprocess
.
STDOUT
)
except
:
return
None
lines
=
[
s
.
strip
()
for
s
in
out
.
split
(
'
\n
'
)]
if
len
(
lines
)
<
6
:
return
None
pattern
=
re
.
compile
(
'.*<(.*)>
\\
s*(.*)
\
[(.*)
\
]$'
)
for
line
in
lines
[
5
:]:
result
=
pattern
.
match
(
line
)
if
result
:
ftype
=
result
.
group
(
1
)
fname
=
result
.
group
(
2
)
flink
=
result
.
group
(
3
)
if
file_object
==
fname
:
if
ftype
==
'SYMLINK'
or
ftype
==
'SYMLINKD'
:
new_path
=
os
.
path
.
realpath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
file_path
),
flink
))
Trace
(
"Relative link found:
%
s ->
%
s ->
%
s"
,
fname
,
flink
,
new_path
)
else
:
new_path
=
flink
Trace
(
"Absolute link found:
%
s ->
%
s"
,
fname
,
flink
)
return
new_path
return
None
def
get_windows_hardlink
(
file_path
):
if
os
.
path
.
isdir
(
file_path
):
return
None
cmd
=
[
'cmd'
,
'/c'
,
'fsutil'
,
'hardlink'
,
'list'
,
file_path
]
try
:
Trace
(
' '
.
join
(
cmd
))
out
=
subprocess
.
check_output
(
cmd
,
stderr
=
subprocess
.
STDOUT
)
except
:
return
None
lines
=
[
s
.
strip
()
for
s
in
out
.
split
(
'
\n
'
)]
if
len
(
lines
)
>=
2
and
len
(
lines
[
1
])
>
0
:
hardlink
=
file_path
[
0
:
2
]
+
lines
[
0
]
Trace
(
"Hard link found:
%
s ->
%
s"
,
file_path
,
hardlink
)
return
hardlink
else
:
return
None
child_process
=
None
child_process
=
None
def
RunPager
(
cmd
):
def
RunPager
(
cmd
):
...
...
project.py
View file @
3568b211
...
@@ -17,6 +17,7 @@ import errno
...
@@ -17,6 +17,7 @@ import errno
import
filecmp
import
filecmp
import
glob
import
glob
import
os
import
os
import
portable
import
random
import
random
import
re
import
re
import
shutil
import
shutil
...
@@ -246,7 +247,8 @@ class _LinkFile(object):
...
@@ -246,7 +247,8 @@ class _LinkFile(object):
def
__linkIt
(
self
,
relSrc
,
absDest
):
def
__linkIt
(
self
,
relSrc
,
absDest
):
# link file if it does not exist or is out of date
# link file if it does not exist or is out of date
if
not
os
.
path
.
islink
(
absDest
)
or
(
os
.
readlink
(
absDest
)
!=
relSrc
):
# if not os.path.islink(absDest) or (os.readlink(absDest) != relSrc):
if
not
portable
.
os_path_islink
(
absDest
)
or
(
portable
.
os_path_realpath
(
absDest
)
!=
relSrc
):
try
:
try
:
# remove existing file first, since it might be read-only
# remove existing file first, since it might be read-only
if
os
.
path
.
exists
(
absDest
):
if
os
.
path
.
exists
(
absDest
):
...
@@ -255,7 +257,8 @@ class _LinkFile(object):
...
@@ -255,7 +257,8 @@ class _LinkFile(object):
dest_dir
=
os
.
path
.
dirname
(
absDest
)
dest_dir
=
os
.
path
.
dirname
(
absDest
)
if
not
os
.
path
.
isdir
(
dest_dir
):
if
not
os
.
path
.
isdir
(
dest_dir
):
os
.
makedirs
(
dest_dir
)
os
.
makedirs
(
dest_dir
)
os
.
symlink
(
relSrc
,
absDest
)
# os.symlink(relSrc, absDest)
portable
.
os_symlink
(
relSrc
,
absDest
)
except
IOError
:
except
IOError
:
_error
(
'Cannot link file
%
s to
%
s'
,
relSrc
,
absDest
)
_error
(
'Cannot link file
%
s to
%
s'
,
relSrc
,
absDest
)
...
@@ -2231,7 +2234,8 @@ class Project(object):
...
@@ -2231,7 +2234,8 @@ class Project(object):
continue
continue
dst
=
os
.
path
.
join
(
hooks
,
name
)
dst
=
os
.
path
.
join
(
hooks
,
name
)
if
os
.
path
.
islink
(
dst
):
# if os.path.islink(dst):
if
portable
.
os_path_islink
(
dst
):
continue
continue
if
os
.
path
.
exists
(
dst
):
if
os
.
path
.
exists
(
dst
):
if
filecmp
.
cmp
(
stock_hook
,
dst
,
shallow
=
False
):
if
filecmp
.
cmp
(
stock_hook
,
dst
,
shallow
=
False
):
...
@@ -2240,7 +2244,8 @@ class Project(object):
...
@@ -2240,7 +2244,8 @@ class Project(object):
_warn
(
"
%
s: Not replacing locally modified
%
s hook"
,
self
.
relpath
,
name
)
_warn
(
"
%
s: Not replacing locally modified
%
s hook"
,
self
.
relpath
,
name
)
continue
continue
try
:
try
:
os
.
symlink
(
os
.
path
.
relpath
(
stock_hook
,
os
.
path
.
dirname
(
dst
)),
dst
)
# os.symlink(os.path.relpath(stock_hook, os.path.dirname(dst)), dst)
portable
.
os_symlink
(
os
.
path
.
relpath
(
stock_hook
,
os
.
path
.
dirname
(
dst
)),
dst
)
except
OSError
as
e
:
except
OSError
as
e
:
if
e
.
errno
==
errno
.
EPERM
:
if
e
.
errno
==
errno
.
EPERM
:
raise
GitError
(
'filesystem must support symlinks'
)
raise
GitError
(
'filesystem must support symlinks'
)
...
@@ -2293,6 +2298,10 @@ class Project(object):
...
@@ -2293,6 +2298,10 @@ class Project(object):
dst
=
os
.
path
.
realpath
(
os
.
path
.
join
(
destdir
,
name
))
dst
=
os
.
path
.
realpath
(
os
.
path
.
join
(
destdir
,
name
))
if
os
.
path
.
lexists
(
dst
):
if
os
.
path
.
lexists
(
dst
):
src
=
os
.
path
.
realpath
(
os
.
path
.
join
(
srcdir
,
name
))
src
=
os
.
path
.
realpath
(
os
.
path
.
join
(
srcdir
,
name
))
src
=
portable
.
os_path_realpath
(
src
)
dst
=
portable
.
os_path_realpath
(
dst
)
Trace
(
"
%
s ~=
%
s"
,
src
,
dst
)
# Fail if the links are pointing to the wrong place
# Fail if the links are pointing to the wrong place
if
src
!=
dst
:
if
src
!=
dst
:
raise
GitError
(
'--force-sync not enabled; cannot overwrite a local '
raise
GitError
(
'--force-sync not enabled; cannot overwrite a local '
...
@@ -2345,8 +2354,10 @@ class Project(object):
...
@@ -2345,8 +2354,10 @@ class Project(object):
pass
pass
if
name
in
to_symlink
:
if
name
in
to_symlink
:
os
.
symlink
(
os
.
path
.
relpath
(
src
,
os
.
path
.
dirname
(
dst
)),
dst
)
# os.symlink(os.path.relpath(src, os.path.dirname(dst)), dst)
elif
copy_all
and
not
os
.
path
.
islink
(
dst
):
portable
.
os_symlink
(
os
.
path
.
relpath
(
src
,
os
.
path
.
dirname
(
dst
)),
dst
)
# elif copy_all and not os.path.islink(dst):
elif
copy_all
and
not
portable
.
os_path_islink
(
dst
):
if
os
.
path
.
isdir
(
src
):
if
os
.
path
.
isdir
(
src
):
shutil
.
copytree
(
src
,
dst
)
shutil
.
copytree
(
src
,
dst
)
elif
os
.
path
.
isfile
(
src
):
elif
os
.
path
.
isfile
(
src
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment