8 testPath
= os
.path
.join(tempfile
.gettempdir(), "testrepo")
9 metricsPath
= os
.path
.join(tempfile
.gettempdir(), "metricsrepo")
11 class InitializationException(Exception):
12 """This exception is raised when something goes wrong during initialization.
16 """Creates a fresh repo under the specified path
18 If the specified path exists an exception is raised.
21 path: The path where the new repo should be created at.
24 print("Creating a new repository in " + path
)
26 # Check if the path exists already, if so bail out
27 if os
.path
.exists(path
):
28 raise InitializationException(
29 "The specified path, " + path
+ ", exists already, "
30 "please remove it or change the target path.")
33 repo
= Repo
.create(path
)
37 """Configures GIT_COMMITTER_DATE and GIT_AUTHOR_DATE to a default value
39 The actual date set is 2005-05-26 23:30, which was taken
40 from t/t1400-update-ref.sh and then converted to UNIX
44 os
.environ
["GIT_COMMITTER_DATE"] = "1211844600"
45 os
.environ
["GIT_AUTHOR_DATE"] = "1211844600"
46 os
.environ
["TZ"] = "UTC"
49 """Configures GIT_COMMITTER_NAME etc. to a default value.
51 These values are taken from t/test-lib.sh from git.git.
54 os
.environ
["GIT_COMMITTER_NAME"] = "C O Mitter"
55 os
.environ
["GIT_COMMITTER_EMAIL"] = "committer@example.com"
56 os
.environ
["GIT_AUTHOR_NAME"] = "A U Thor"
57 os
.environ
["GIT_AUTHOR_EMAIL"] = "author@example.com"
59 def setSecondaryInfo():
60 """Configures GIT_COMMITTER_NAME etc. to a secondary value.
62 The values are the default values but in reverse.
65 os
.environ
["GIT_COMMITTER_NAME"] = "Retti Mmoc"
66 os
.environ
["GIT_COMMITTER_EMAIL"] = "retti.mmoc@example.com"
67 os
.environ
["GIT_AUTHOR_NAME"] = "Roh Tua"
68 os
.environ
["GIT_AUTHOR_EMAIL"] = "roh.tua@example.com"
70 def bumpTime(amount
= 60*60):
71 """Bumps the date in GIT_AUTHOR_DATE and GIT_COMMITTER_DATE
74 amount: The amount by which they should be bumped.
77 time
= os
.environ
["GIT_AUTHOR_DATE"]
82 os
.environ
["GIT_AUTHOR_DATE"] = time
83 os
.environ
["GIT_COMMITTER_DATE"] = time
86 def addFile(filename
, createFile
=True, commit
=True):
87 """Adds the specified file
90 filename: The name of the file to add.
91 createFile: Whether the file should be created.
95 file = open(filename
, "w")
103 git
.commit("-m", "Added file " + filename
)
106 def deleteFile(filename
, leaveOnDisk
=False):
107 """Deletes the specified file
110 filename: The name of the file to delete.
111 leaveOnDisk: Whether the file should not be physically deleted.
116 # If the file should not be deleted, tell 'git rm' so
118 args
.append("--cached")
120 args
.append(filename
)
126 git
.commit("-m", "Deleted file " + filename
)
129 def createLinearHistory(filename
, createFile
=False, initialCommit
=False, start
=1, count
=10, finalCommit
=False):
130 """Creates a linear history in the directory of the current repository.
132 The history is fairly simple and is all acted upon the specified file.
133 Any exceptions thrown during IO operations are _not_ cought.
136 filename: The name of the file in which to generate the history.
137 createFile: Whether the specified file has to be created first.
138 initialCommit: Whether to create an initial commit.
139 start: Which commit to start the history at.
140 count: The size of the history.
141 finalCommit: Whether to create a final commit.
149 addFile(filename
, commit
=False)
151 # Create or open the content file
152 file = open(filename
, "a")
155 # Start out with an initial change
156 file.write("Initial change\n")
159 # Add the file and create the initial commit
160 git
.commit("-a", "-m", "Initial commit")
163 # Create a linear history
164 for i
in range(start
, stop
):
165 file.write("Change " + str(i
) + "\n")
168 git
.commit("-a", "-m", "Commit " + str(i
))
172 # Finish it up with a final change
173 file.write("Last change\n")
177 git
.commit("-a", "-m", "Last commit")
180 def createBranch(name
, checkout
=True):
181 """Creates a branch with the specified name and optionally checks it out
184 name: The name of the new branch.
185 checkout: Whether to perform a checkout of the branch.
196 def deleteBranch(name
):
199 The branch that is to be deleted should be a subset of the current branch.
202 name: The name of the branch to delete.
207 git
.branch("-d", name
)
210 def createDir(name
, changeDir
=False):
211 """Creates a directory with the specified name
214 name: The name of the directory
219 def checkoutBranch(name
):
220 """Switches to the specified branch
223 name: The name of the branch to be switched to.
230 def checkoutRelease(release
):
231 """Switches to the specified release
234 release: The release to check out
237 checkoutBranch('v' + str(release
))
239 def mergeBranch(name
):
240 """Merges the current branch with the specified branch
243 name: The name of the branch to merge with.
251 def revertLastCommit(commitChanges
=True):
252 """Reverts the last commit made
255 commitChanges: Whether to commit the revert.
260 options
= ["--no-edit", "HEAD"]
262 if not commitChanges
:
270 def tagRelease(releaseNumber
, head
="HEAD"):
273 The created tag is 'v' + releaseNumber.
276 releaseNumber: The number of the release.
281 git
.tag('v' + str(releaseNumber
), head
)
283 def createRemoteBranch(name
, start
="HEAD"):
284 """Creates a new remote branch with the specified name
287 name: The plain name of the remote (no '/refs/remotes/' prefix)
288 start: The revision to branch off from
293 git
.update_ref('refs/remotes/' + name
, start
)
297 """Verifies that the HEAD is as expected.
300 HEAD: The expected value of HEAD.
305 result
= git
.rev_parse("HEAD")
307 # Eat the trailing newline
308 currentHEAD
= result
[:-1]
310 scriptSuccessful
= (HEAD
== currentHEAD
)
313 print("Done, repo created successfully")
316 print("Something went wrong, current HEAD doesn't match.")
317 print("Expected: '" + HEAD
+ "'.")
318 print("Actual: '" + currentHEAD
+ "'.")
321 def createTestRepository():
322 """Creates a test repository under setupRepo.testpath
332 r
= os
.path
.join(d
, "README.txt")
344 # Set the default author/committer
348 # Create some linear history
349 createLinearHistory(c
, createFile
=True, initialCommit
=True, finalCommit
=True)
351 # Create a maintenance branch
354 # Create some history there too
355 createLinearHistory(n
, createFile
=True, count
=3)
357 # Go back to master and merge with maint
361 # Create a playground branch and create some history
362 # This branch will be left 'dead', e.g., unused after this
364 createLinearHistory(t
, createFile
=True, count
=7, finalCommit
=True)
366 # Start out with release 0
367 tagRelease(0, head
="HEAD~3")
372 # Go back to master and continue some history
374 createLinearHistory(c
, start
=10, count
=5)
376 # Yay, our first release!
379 # Merge current master into maint
383 # Ouch! Brown paper bag fix there, correct it and merge into master
384 revertLastCommit(commitChanges
=False)
385 createLinearHistory(c
, start
=42, count
=1)
389 # Continue some work on master
390 createLinearHistory(c
, start
=16, count
=6)
392 # Have someone else do some work on master
394 createLinearHistory(c
, start
=22, count
=2)
396 # Go back to the initial data
399 # Create a directory for the documentation
402 # Create a readme and add some content to it
403 createLinearHistory(r
, createFile
=True, count
=5, finalCommit
=True)
406 # Ah, but that last one was bad, we don't want it
409 # Instead, continue the linear history
410 createLinearHistory(r
, start
=6, count
=1)
413 # Come to think of it, that -was- a really good change after all
416 # Reinstate that final commit
417 createLinearHistory(r
, count
=0, finalCommit
=True)
419 tagRelease(4, head
="HEAD~1")
421 # Create a branch to delete a file on
424 # Remove a file from git
425 deleteFile(r
, leaveOnDisk
=True)
427 # Only to add it back later so that we don't have any dangling files
428 addFile(r
, createFile
=False)
430 # Create a release at this point for easy switching later
433 # Switch back to master for the test suite
436 # Create a remote branch
437 createRemoteBranch(j
, start
="HEAD^")
441 def createMetricsRepository():
442 """Creates a metrics repository in setupRepo.metricspath
457 # Create a repository to work in
458 setupRepo(metricsPath
)
464 # And create some history
465 createLinearHistory(c
, createFile
=True, count
=2)
467 # Mark this commit so that we can jump back to it later
470 # And create some more history
471 createLinearHistory(c
, start
=3, count
=3)
473 # Go back to that marked commit
476 # Now create a new branch to work on
479 # Fix us up some more history
480 createLinearHistory(n
, createFile
=True, count
=2)
482 # Mark this commit too so we can jump back
485 # And make some more history
486 createLinearHistory(n
, start
=2, count
=1)
488 # Now merge this back into master
492 # Go back to maint to create some more there
494 createLinearHistory(n
, start
=3, count
=1)
496 # Now let's go back and fix that one commit
499 createLinearHistory(r
, createFile
=True, count
=2)
501 # Go back to maint, and merge it in
505 # Now that we merged that one in, kick it out
508 # We can create some more history here
509 createLinearHistory(n
, start
=4, count
=3)
511 # Remember for branching off later
514 # And a healthy bit of content on master too
516 createLinearHistory(c
, start
=6, count
=4)
518 # Create one more commit
520 createLinearHistory(n
, start
=7, count
=1)
522 # Merge master in here
525 # And create another commit
526 createLinearHistory(n
, start
=8, count
=1)
528 # Hacking on master some more
530 createLinearHistory(c
, start
=10, count
=4)
532 # Go back a bit and branch off
535 createLinearHistory(l
, createFile
=True, count
=3)
537 # Merge back into maint and work some more
540 createLinearHistory(n
, start
=9, count
=1)
542 # Merge that into master and finish up
545 createLinearHistory(c
, start
=14, count
=1)
549 createLinearHistory(l
, start
=4, count
=4)
551 # Lastly finish up maint
553 createLinearHistory(n
, start
=10, count
=2)
558 """Creates a test and a metrics repository
561 args: An array of arguments, when 2 in size the second
562 element should either be 'test' to just create the test
563 repo, or 'metrics' to just create the metrics
564 repository. If both should be created then the size of
565 args should be 1. When the third argument is 'path',
566 instead of creating the repository the path where it
567 will be created is printed. If there is a fourth
568 argument it is interpreted as the path where the
569 repository should be created. The first element in the
570 array is always ignored.
572 Returns: 0 upon success, or nonzero upon failure.
581 str = "Please specify either 'test', 'metrics', or nothing to run both." \
582 "\nSuffix with 'path' to print the path where the repo will be created." \
583 "\nAs third argument you may provide the path to create the repo in."
592 if args
[2] != "path":
596 createTestRepo
= False
597 createMetricsRepo
= False
598 printTestRepoPath
= False
599 printMetricsRepoPath
= False
602 createTestRepo
= True
603 createMetricsRepo
= True
605 if size
== 2 or size
== 4:
606 if args
[1] == "test":
607 createTestRepo
= True
609 if args
[1] == "metrics":
610 createMetricsRepo
= True
613 if args
[1] == "test":
614 printTestRepoPath
= True
616 if args
[1] == "metrics":
617 printMetricsRepoPath
= True
619 if not createTestRepo
and not createMetricsRepo \
620 and not printTestRepoPath
and not printMetricsRepoPath
:
628 ret
= createTestRepository()
632 if createMetricsRepo
:
634 metricsPath
= args
[3]
636 ret
= createMetricsRepository()
640 if printTestRepoPath
:
643 if printMetricsRepoPath
:
648 if __name__
== '__main__':