Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
R
regit
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Software Systems Engineering
regit
Compare revisions
25f78efe4cfdd21fc0a61e48693cebaa8d64cfeb to c5128291205a4ae22eb820681447879f10982a13
Compare revisions
Changes are shown as if the
source
revision was being merged into the
target
revision.
Learn more about comparing revisions.
Source
sse/regit
Select target project
No results found
c5128291205a4ae22eb820681447879f10982a13
Select Git revision
Branches
main
1 result
Swap
Target
sse/regit
Select target project
sse/regit
1 result
25f78efe4cfdd21fc0a61e48693cebaa8d64cfeb
Select Git revision
Branches
main
1 result
Show changes
Only incoming changes from source
Include changes to target since source was created
Compare
Commits on Source
2
More refactoring
· 3dab5452
chrg
authored
Mar 22, 2023
- Add logging for patterns
3dab5452
Add more logging
· c5128291
chrg
authored
Mar 22, 2023
c5128291
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/regit/__main__.py
+26
-67
26 additions, 67 deletions
src/regit/__main__.py
src/regit/utils.py
+49
-0
49 additions, 0 deletions
src/regit/utils.py
with
75 additions
and
67 deletions
src/regit/__main__.py
View file @
c5128291
...
...
@@ -4,9 +4,6 @@ from pathlib import Path
from
typing
import
Callable
import
csv
import
logging
import
os
import
shutil
import
subprocess
import
tempfile
import
click
...
...
@@ -14,31 +11,30 @@ import git
import
git_filter_repo
as
fr
from
.types
import
Executable
,
Repository
from
.
import
utils
log
=
logging
.
getLogger
(
"
regit
"
)
def
popen
(
cmd
,
**
kwargs
):
"""
A wrapper around subprocess.Popen that logs the command.
"""
log
.
debug
(
"
Running cmd %s
"
,
cmd
)
return
subprocess
.
Popen
(
cmd
,
**
kwargs
)
@dataclass
class
BlobHandler
:
from
subprocess
import
Popen
repo
:
git
.
Repo
blobs_handled
:
dict
[
int
,
int
]
=
field
(
default_factory
=
dict
)
is_relevant
:
Callable
[[
Path
],
bool
]
=
lambda
_
:
True
transform
:
Callable
[[
Path
,
bytes
],
bytes
]
=
lambda
_
,
b
:
b
filter
:
fr
.
RepoFilter
|
None
=
None
gitcat
:
subprocess
.
Popen
|
None
=
None
gitcat
:
Popen
|
None
=
None
def
__enter__
(
self
)
->
"
BlobHandler
"
:
from
subprocess
import
PIPE
log
.
debug
(
"
Starting blob handler
"
)
self
.
gitcat
=
popen
(
self
.
gitcat
=
utils
.
popen
(
[
"
git
"
,
"
-C
"
,
self
.
repo
.
working_dir
,
"
cat-file
"
,
"
--batch
"
],
stdin
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
,
stdin
=
PIPE
,
stdout
=
PIPE
,
)
if
self
.
gitcat
.
stdin
is
None
or
self
.
gitcat
.
stdout
is
None
:
raise
RuntimeError
(
"
Could not start git cat-file
"
)
...
...
@@ -78,15 +74,6 @@ class BlobHandler:
return
stdout
.
read
(
int
(
objsize
)
+
1
)[:
-
1
]
@contextmanager
def
tfile
(
folder
:
Path
,
filename
,
content
):
tmp_file
=
folder
/
filename
with
open
(
tmp_file
,
"
wb
"
)
as
f
:
f
.
write
(
content
)
yield
tmp_file
os
.
remove
(
tmp_file
)
@click.command
()
@click.option
(
"
--repo
"
,
...
...
@@ -118,17 +105,8 @@ def tfile(folder: Path, filename, content):
help
=
"
The verbosity of logging
"
,
count
=
True
,
)
@click.argument
(
"
program
"
,
# help="The program to execute on each file",
type
=
Executable
(),
)
@click.argument
(
"
args
"
,
# help="The argurments, choose '{}' to mean the file in question, omit a '{}' to use stdin",
nargs
=-
1
,
type
=
str
,
)
@click.argument
(
"
program
"
,
type
=
Executable
())
@click.argument
(
"
args
"
,
nargs
=-
1
,
type
=
str
)
def
regit
(
repo
,
pattern
:
str
|
None
,
...
...
@@ -155,37 +133,37 @@ def regit(
log
.
debug
(
"
Cloned repo to %s
"
,
output
)
with
tempfile
.
TemporaryDirectory
()
as
folder
:
folder
=
Path
(
folder
)
def
transformer
(
file
:
Path
,
content
:
bytes
):
pargs
=
list
(
args
)
try
:
ix
=
pargs
.
index
(
"
{}
"
)
except
ValueError
:
cmd
=
[
program
]
+
pargs
log
.
debug
(
"
Running cmd %s
"
,
cmd
)
return
subprocess
.
run
(
cmd
,
input
=
content
,
capture_output
=
True
,
check
=
True
return
utils
.
run
(
[
program
]
+
pargs
,
input
=
content
,
capture_output
=
True
,
check
=
True
).
stdout
else
:
with
tfile
(
Path
(
folder
)
,
file
.
name
,
content
)
as
tmp_file
:
with
utils
.
tfile
(
folder
,
file
.
name
,
content
)
as
tmp_file
:
pargs
[
ix
]
=
str
(
tmp_file
)
cmd
=
[
program
]
+
pargs
log
.
debug
(
"
Running cmd %s
"
,
cmd
)
subprocess
.
run
(
cmd
,
check
=
True
)
utils
.
run
([
program
]
+
pargs
,
check
=
True
)
with
open
(
tmp_file
,
"
rb
"
)
as
f
:
return
f
.
read
()
handler
=
BlobHandler
(
repo
,
is_relevant
=
lambda
a
:
pattern
is
None
or
a
.
match
(
pattern
),
transform
=
transformer
,
)
def
is_relevant
(
file
:
Path
):
if
pattern
is
None
:
return
True
match
=
file
.
match
(
pattern
)
log
.
debug
(
"
Check if %s matched pattern %s
"
,
file
,
match
)
return
match
handler
=
BlobHandler
(
repo
,
is_relevant
=
is_relevant
,
transform
=
transformer
)
log
.
debug
(
"
Starting handler
"
)
with
handler
:
options
=
fr
.
FilteringOptions
.
parse_args
([],
error_on_empty
=
False
)
filter
=
fr
.
RepoFilter
(
options
,
commit_callback
=
handler
)
handler
.
filter
=
filter
with
chdir
(
repo
.
working_dir
):
with
utils
.
chdir
(
repo
.
working_dir
):
log
.
debug
(
"
Starting git filter
"
)
filter
.
run
()
log
.
debug
(
"
Finished git filter
"
)
...
...
@@ -194,29 +172,10 @@ def regit(
writer
=
csv
.
writer
(
mapping
)
writer
.
writerow
([
"
from
"
,
"
to
"
])
for
fm
,
to
in
filter
.
_commit_renames
.
items
():
writer
.
writerow
([
handle
(
m
)
for
m
in
[
fm
,
to
]])
writer
.
writerow
([
utils
.
commit_id_to_string
(
m
)
for
m
in
[
fm
,
to
]])
print
(
repo
.
working_dir
)
@contextmanager
def
chdir
(
path
:
Path
):
old
=
Path
.
cwd
()
log
.
debug
(
"
Changing dir from %s to %s
"
,
old
,
path
)
os
.
chdir
(
path
)
yield
log
.
debug
(
"
Changing dir back to %s
"
,
old
)
os
.
chdir
(
old
)
def
handle
(
a
):
"""
Handle the result of a git renames of commits.
"""
if
isinstance
(
a
,
bytes
):
return
a
.
decode
()
else
:
log
.
warning
(
"
Unexpected result %s
"
,
a
)
return
str
(
a
)
if
__name__
==
"
__main__
"
:
regit
()
This diff is collapsed.
Click to expand it.
src/regit/utils.py
0 → 100644
View file @
c5128291
from
contextlib
import
contextmanager
from
pathlib
import
Path
import
logging
import
os
import
subprocess
log
=
logging
.
getLogger
(
"
regit
"
)
def
run
(
cmd
,
**
kwargs
):
"""
A wrapper around subprocess.run that logs the command.
"""
log
.
debug
(
"
Running cmd %s
"
,
cmd
)
return
subprocess
.
run
(
cmd
,
**
kwargs
)
def
popen
(
cmd
,
**
kwargs
):
"""
A wrapper around subprocess.Popen that logs the command.
"""
log
.
debug
(
"
Running cmd %s
"
,
cmd
)
return
subprocess
.
Popen
(
cmd
,
**
kwargs
)
@contextmanager
def
chdir
(
path
:
Path
):
"""
Change the current working directory to the given path and back when done.
"""
old
=
Path
.
cwd
()
log
.
debug
(
"
Changing dir from %s to %s
"
,
old
,
path
)
os
.
chdir
(
path
)
yield
log
.
debug
(
"
Changing dir back to %s
"
,
old
)
os
.
chdir
(
old
)
def
commit_id_to_string
(
commit_id
):
"""
Convert a commit id to a string.
"""
if
isinstance
(
commit_id
,
bytes
):
return
commit_id
.
decode
()
else
:
log
.
warning
(
"
Unexpected result %s
"
,
commit_id
)
return
str
(
commit_id
)
@contextmanager
def
tfile
(
folder
:
Path
,
filename
,
content
):
"""
Create a temporary file with the given content and delete it when done.
"""
tmp_file
=
folder
/
filename
with
open
(
tmp_file
,
"
wb
"
)
as
f
:
f
.
write
(
content
)
yield
tmp_file
os
.
remove
(
tmp_file
)
This diff is collapsed.
Click to expand it.