Skip to content

Commit ab20e1a

Browse files
Add --constant-sha flag to use constant values for commit author, email, and commit date parameters to yield consistent sha1 values across git-dummy runs
Signed-off-by: Jacob Stopak <[email protected]>
1 parent 2466457 commit ab20e1a

File tree

3 files changed

+67
-38
lines changed

3 files changed

+67
-38
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ Available options and flags include:
6464
`--branches`: The number of branches to generate in the dummy Git repo, defaults to 1.
6565
`--diverge-at`: The commit number at which branches diverge from `main`.
6666
`--merge`: A comma separated list of branch postfix ids to merge back into `main`.
67-
`--git-dir`: The path at which to store the dummy Git repo, defaults to current directory.
68-
`--no-subdir`: Initialize the dummy Git repo in the current directory instead of in a subdirectory.
67+
`--git-dir`: The path at which to store the dummy Git repo, defaults to current directory.
68+
`--no-subdir`: Initialize the dummy Git repo in the current directory instead of in a subdirectory.
69+
`--constant_sha`: Use constant values for commit author, email, and commit date parameters to yield consistent sha1 values across git-dummy runs.
6970

7071
## Command examples
7172
Generate a dummy Git repo called "cheese" on your Desktop, with 2 branches and 10 commits on each branch:

git_dummy/__main__.py

+63-36
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
from git_dummy.settings import settings
99

10+
11+
12+
1013
app = typer.Typer(context_settings={"help_option_names": ["-h", "--help"]})
1114

1215

@@ -40,13 +43,18 @@ def main(
4043
settings.no_subdir,
4144
help="Initialize the dummy Git repo in the current directory instead of in a subdirectory",
4245
),
46+
constant_sha: bool = typer.Option(
47+
settings.constant_sha,
48+
help="Use constant values for commit author, email, and commit date parameters to yield consistent sha1 values across git-dummy runs",
49+
),
4350
):
4451
settings.name = name
4552
settings.commits = commits
4653
settings.branches = branches
4754
settings.diverge_at = diverge_at
4855
settings.merge = merge
4956
settings.no_subdir = no_subdir
57+
settings.constant_sha = constant_sha
5058

5159
settings.git_dir = os.path.expanduser(git_dir)
5260
if not settings.no_subdir:
@@ -71,46 +79,65 @@ def main(
7179
)
7280

7381
repo = git.Repo.init(settings.git_dir)
74-
repo.config_writer().set_value("init", "defaultBranch", "main").release()
7582

76-
for c in range(1, settings.commits + 1):
77-
open(os.path.join(settings.git_dir, f"main.{c}"), "a").close()
78-
repo.index.add([f"main.{c}"])
79-
repo.index.commit(f"Dummy commit #{c} on main")
83+
config_writer = repo.config_writer()
84+
config_writer.set_value("init", "defaultBranch", "main").release()
85+
if settings.constant_sha:
86+
config_writer.set_value("user", "name", "Git Dummy")
87+
config_writer.set_value("user", "email", "[email protected]")
88+
config_writer.release()
89+
90+
if settings.constant_sha:
91+
os.environ["GIT_AUTHOR_DATE"] = "2023-01-01T00:00:00"
92+
os.environ["GIT_COMMITTER_DATE"] = "2023-01-01T00:00:00"
93+
94+
try:
95+
for c in range(1, settings.commits + 1):
96+
open(os.path.join(settings.git_dir, f"main.{c}"), "a").close()
97+
repo.index.add([f"main.{c}"])
98+
repo.index.commit(f"Dummy commit #{c} on main")
99+
100+
while settings.branches - 1 > 0:
101+
repo.git.checkout("main")
102+
r = (
103+
(settings.commits - settings.diverge_at)
104+
if settings.diverge_at
105+
else random.choice(range(1, settings.commits))
106+
)
107+
repo.git.checkout(f"HEAD~{r}")
108+
branch_name = f"branch{settings.branches - 1}"
109+
repo.create_head(branch_name)
110+
repo.git.checkout(branch_name)
111+
for d in range(settings.commits - r + 1, settings.commits + 1):
112+
open(os.path.join(settings.git_dir, f"{branch_name}.{d}"), "a").close()
113+
repo.index.add([f"{branch_name}.{d}"])
114+
repo.index.commit(f"Dummy commit #{d} on {branch_name}")
115+
if settings.merge:
116+
to_merge = settings.merge.split(",")
117+
if str(settings.branches - 1) in to_merge:
118+
repo.git.checkout("main")
119+
main = repo.branches["main"]
120+
branch = repo.branches[branch_name]
121+
base = repo.git.merge_base(main, branch)
122+
repo.index.merge_tree(branch, base=base)
123+
repo.index.commit(
124+
f"Merge {branch_name} into main",
125+
parent_commits=(branch.commit, main.commit),
126+
)
127+
main.checkout(force=True)
128+
129+
settings.branches -= 1
80130

81-
while settings.branches - 1 > 0:
82131
repo.git.checkout("main")
83-
r = (
84-
(settings.commits - settings.diverge_at)
85-
if settings.diverge_at
86-
else random.choice(range(1, settings.commits))
87-
)
88-
repo.git.checkout(f"HEAD~{r}")
89-
branch_name = f"branch{settings.branches - 1}"
90-
repo.create_head(branch_name)
91-
repo.git.checkout(branch_name)
92-
for d in range(settings.commits - r + 1, settings.commits + 1):
93-
open(os.path.join(settings.git_dir, f"{branch_name}.{d}"), "a").close()
94-
repo.index.add([f"{branch_name}.{d}"])
95-
repo.index.commit(f"Dummy commit #{d} on {branch_name}")
96-
if settings.merge:
97-
to_merge = settings.merge.split(",")
98-
if str(settings.branches - 1) in to_merge:
99-
repo.git.checkout("main")
100-
main = repo.branches["main"]
101-
branch = repo.branches[branch_name]
102-
base = repo.git.merge_base(main, branch)
103-
repo.index.merge_tree(branch, base=base)
104-
repo.index.commit(
105-
f"Merge {branch_name} into main",
106-
parent_commits=(branch.commit, main.commit),
107-
)
108-
main.checkout(force=True)
109-
110-
settings.branches -= 1
111-
112-
repo.git.checkout("main")
113132

133+
except Exception as e:
134+
raise e
135+
136+
finally:
137+
# If needed, delete the environment variables set by git-dummy
138+
if settings.constant_sha:
139+
del os.environ["GIT_AUTHOR_DATE"]
140+
del os.environ["GIT_COMMITTER_DATE"]
114141

115142
if __name__ == "__main__":
116143
app()

git_dummy/settings.py

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class Settings(BaseSettings):
1010
diverge_at = 0
1111
merge = ""
1212
no_subdir = False
13+
constant_sha = False
1314

1415
class Config:
1516
env_prefix = "git_dummy_"

0 commit comments

Comments
 (0)