Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: depot_tools/drover.py

Issue 651022: Add option --local allowing for merging changes into a local working copy.... (Closed) Base URL: http://src.chromium.org/svn/trunk/tools/depot_tools/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2009 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2009 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import optparse 6 import optparse
7 import os 7 import os
8 import re 8 import re
9 import subprocess 9 import subprocess
10 import sys 10 import sys
11 import webbrowser 11 import webbrowser
12 12
13 import breakpad 13 import breakpad
14 14
15 USAGE = """ 15 USAGE = """
16 WARNING: Please use this tool in an empty directory 16 WARNING: Please use this tool in an empty directory
17 (or at least one that you don't mind clobbering.) 17 (or at least one that you don't mind clobbering.)
18 18
19 REQUIRES: SVN 1.5+ 19 REQUIRES: SVN 1.5+
20 NOTE: NO NEED TO CHECKOUT ANYTHING IN ADVANCE OF USING THIS TOOL." 20 NOTE: NO NEED TO CHECKOUT ANYTHING IN ADVANCE OF USING THIS TOOL."
21 Valid parameters: 21 Valid parameters:
22 22
23 [Merge from trunk to branch] 23 [Merge from trunk to branch]
24 --merge <revision> --branch <branch_num> 24 --merge <revision> --branch <branch_num>
25 Example: %(app)s --merge 12345 --branch 187 25 Example: %(app)s --merge 12345 --branch 187
26 26
27 [Merge from trunk to local copy]
28 --merge <revision> --local
29 Example: %(app)s --merge 12345 --local
30
27 [Merge from branch to branch] 31 [Merge from branch to branch]
28 --merge <revision> --sbranch <branch_num> --branch <branch_num> 32 --merge <revision> --sbranch <branch_num> --branch <branch_num>
29 Example: %(app)s --merge 12345 --sbranch 248 --branch 249 33 Example: %(app)s --merge 12345 --sbranch 248 --branch 249
30 34
31 [Revert from trunk] 35 [Revert from trunk]
32 --revert <revision> 36 --revert <revision>
33 Example: %(app)s --revert 12345 37 Example: %(app)s --revert 12345
34 38
35 [Revert from branch] 39 [Revert from branch]
36 --revert <revision> --branch <branch_num> 40 --revert <revision> --branch <branch_num>
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 stdout=subprocess.PIPE, 93 stdout=subprocess.PIPE,
90 stderr=subprocess.PIPE).stdout.readlines() 94 stderr=subprocess.PIPE).stdout.readlines()
91 info = {} 95 info = {}
92 for line in svn_info: 96 for line in svn_info:
93 match = re.search(r"(.*?):(.*)", line) 97 match = re.search(r"(.*?):(.*)", line)
94 if match: 98 if match:
95 info[match.group(1).strip()]=match.group(2).strip() 99 info[match.group(1).strip()]=match.group(2).strip()
96 100
97 return info 101 return info
98 102
103 def isSVNDirty():
104 command = 'svn status'
105 svn_status = subprocess.Popen(command,
106 shell=True,
107 stdout=subprocess.PIPE,
108 stderr=subprocess.PIPE).stdout.readlines()
109 for line in svn_status:
110 match = re.search(r"^[^X?]", line)
111 if match:
112 return True
113
114 return False
115
99 def getAuthor(url, revision): 116 def getAuthor(url, revision):
100 info = getSVNInfo(url, revision) 117 info = getSVNInfo(url, revision)
101 if (info.has_key("Last Changed Author")): 118 if (info.has_key("Last Changed Author")):
102 return info["Last Changed Author"] 119 return info["Last Changed Author"]
103 return None 120 return None
104 121
105 def isSVNFile(url, revision): 122 def isSVNFile(url, revision):
106 info = getSVNInfo(url, revision) 123 info = getSVNInfo(url, revision)
107 if (info.has_key("Node Kind")): 124 if (info.has_key("Node Kind")):
108 if (info["Node Kind"] == "file"): 125 if (info["Node Kind"] == "file"):
109 return True 126 return True
110 return False 127 return False
111 128
112 def isSVNDirectory(url, revision): 129 def isSVNDirectory(url, revision):
113 info = getSVNInfo(url, revision) 130 info = getSVNInfo(url, revision)
114 if (info.has_key("Node Kind")): 131 if (info.has_key("Node Kind")):
115 if (info["Node Kind"] == "directory"): 132 if (info["Node Kind"] == "directory"):
116 return True 133 return True
117 return False 134 return False
118 135
136 def inCheckoutRoot(path):
137 info = getSVNInfo(path, "HEAD")
138 if (not info.has_key("Repository Root")):
139 return False
140 repo_root = info["Repository Root"];
141 info = getSVNInfo(os.path.dirname(os.path.abspath(path)), "HEAD")
142 if (info.get("Repository Root", None) != repo_root):
143 return True
144 return False
145
119 def getRevisionLog(url, revision): 146 def getRevisionLog(url, revision):
120 """Takes an svn url and gets the associated revision.""" 147 """Takes an svn url and gets the associated revision."""
121 command = 'svn log ' + url + " -r"+str(revision) 148 command = 'svn log ' + url + " -r"+str(revision)
122 svn_log = subprocess.Popen(command, 149 svn_log = subprocess.Popen(command,
123 shell=True, 150 shell=True,
124 stdout=subprocess.PIPE, 151 stdout=subprocess.PIPE,
125 stderr=subprocess.PIPE).stdout.readlines() 152 stderr=subprocess.PIPE).stdout.readlines()
126 log = "" 153 log = ""
127 pos = 0 154 pos = 0
128 for line in svn_log: 155 for line in svn_log:
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 462
436 if options.revert and options.branch: 463 if options.revert and options.branch:
437 url = BRANCH_URL.replace("$branch", options.branch) 464 url = BRANCH_URL.replace("$branch", options.branch)
438 elif options.merge and options.sbranch: 465 elif options.merge and options.sbranch:
439 url = BRANCH_URL.replace("$branch", options.sbranch) 466 url = BRANCH_URL.replace("$branch", options.sbranch)
440 else: 467 else:
441 url = TRUNK_URL 468 url = TRUNK_URL
442 469
443 working = options.workdir or DEFAULT_WORKING 470 working = options.workdir or DEFAULT_WORKING
444 471
472 if options.local:
473 working = os.getcwd()
474 if not inCheckoutRoot(working):
475 print "'%s' appears not to be the root of a working copy" % working
476 sys.exit(1)
477 if isSVNDirty():
478 print "Working copy contains uncommitted files"
479 sys.exit(1)
480
445 command = 'svn log ' + url + " -r "+str(revision) + " -v" 481 command = 'svn log ' + url + " -r "+str(revision) + " -v"
446 os.system(command) 482 os.system(command)
447 483
448 if not (options.revertbot or prompt("Is this the correct revision?")): 484 if not (options.revertbot or prompt("Is this the correct revision?")):
449 sys.exit(0) 485 sys.exit(0)
450 486
451 if (os.path.exists(working)): 487 if (os.path.exists(working)) and not options.local:
452 if not (options.revertbot or SKIP_CHECK_WORKING or 488 if not (options.revertbot or SKIP_CHECK_WORKING or
453 prompt("Working directory: '%s' already exists, clobber?" % working)): 489 prompt("Working directory: '%s' already exists, clobber?" % working)):
454 sys.exit(0) 490 sys.exit(0)
455 deltree(working) 491 deltree(working)
456 492
457 os.makedirs(working) 493 if not options.local:
458 os.chdir(working) 494 os.makedirs(working)
495 os.chdir(working)
459 496
460 if options.merge: 497 if options.merge:
461 action = "Merge" 498 action = "Merge"
462 branch_url = BRANCH_URL.replace("$branch", options.branch) 499 if not options.local:
463 # Checkout everything but stuff that got added into a new dir 500 branch_url = BRANCH_URL.replace("$branch", options.branch)
464 checkoutRevision(url, revision, branch_url) 501 # Checkout everything but stuff that got added into a new dir
502 checkoutRevision(url, revision, branch_url)
465 # Merge everything that changed 503 # Merge everything that changed
466 mergeRevision(url, revision) 504 mergeRevision(url, revision)
467 # "Export" files that were added from the source and add them to branch 505 # "Export" files that were added from the source and add them to branch
468 exportRevision(url, revision) 506 exportRevision(url, revision)
469 # Delete directories that were deleted (file deletes are handled in the 507 # Delete directories that were deleted (file deletes are handled in the
470 # merge). 508 # merge).
471 deleteRevision(url, revision) 509 deleteRevision(url, revision)
472 elif options.revert: 510 elif options.revert:
473 action = "Revert" 511 action = "Revert"
474 if options.branch: 512 if options.branch:
(...skipping 16 matching lines...) Expand all
491 out.write(getRevisionLog(url, revision)) 529 out.write(getRevisionLog(url, revision))
492 if (author): 530 if (author):
493 out.write("TBR=" + author) 531 out.write("TBR=" + author)
494 out.close() 532 out.close()
495 533
496 change_cmd = 'change ' + str(revision) + " " + filename 534 change_cmd = 'change ' + str(revision) + " " + filename
497 if options.revertbot: 535 if options.revertbot:
498 change_cmd += ' --silent' 536 change_cmd += ' --silent'
499 runGcl(change_cmd) 537 runGcl(change_cmd)
500 os.unlink(filename) 538 os.unlink(filename)
539
540 if options.local:
541 sys.exit(0)
542
501 print author 543 print author
502 print revision 544 print revision
503 print ("gcl upload " + str(revision) + 545 print ("gcl upload " + str(revision) +
504 " --send_mail --no_try --no_presubmit --reviewers=" + author) 546 " --send_mail --no_try --no_presubmit --reviewers=" + author)
505 547
506 if options.revertbot or prompt("Would you like to upload?"): 548 if options.revertbot or prompt("Would you like to upload?"):
507 if PROMPT_FOR_AUTHOR: 549 if PROMPT_FOR_AUTHOR:
508 author = text_prompt("Enter new author or press enter to accept default", 550 author = text_prompt("Enter new author or press enter to accept default",
509 author) 551 author)
510 if options.revertbot and options.revertbot_reviewers: 552 if options.revertbot and options.revertbot_reviewers:
(...skipping 14 matching lines...) Expand all
525 runGcl("commit " + str(revision) + " --no_presubmit --force") 567 runGcl("commit " + str(revision) + " --no_presubmit --force")
526 else: 568 else:
527 sys.exit(0) 569 sys.exit(0)
528 570
529 if __name__ == "__main__": 571 if __name__ == "__main__":
530 option_parser = optparse.OptionParser(usage=USAGE % {"app": sys.argv[0]}) 572 option_parser = optparse.OptionParser(usage=USAGE % {"app": sys.argv[0]})
531 option_parser.add_option('-m', '--merge', type="int", 573 option_parser.add_option('-m', '--merge', type="int",
532 help='Revision to merge from trunk to branch') 574 help='Revision to merge from trunk to branch')
533 option_parser.add_option('-b', '--branch', 575 option_parser.add_option('-b', '--branch',
534 help='Branch to revert or merge from') 576 help='Branch to revert or merge from')
577 option_parser.add_option('-l', '--local', action='store_true',
578 help='Local working copy to merge to')
535 option_parser.add_option('-s', '--sbranch', 579 option_parser.add_option('-s', '--sbranch',
536 help='Source branch for merge') 580 help='Source branch for merge')
537 option_parser.add_option('-r', '--revert', type="int", 581 option_parser.add_option('-r', '--revert', type="int",
538 help='Revision to revert') 582 help='Revision to revert')
539 option_parser.add_option('-w', '--workdir', 583 option_parser.add_option('-w', '--workdir',
540 help='subdir to use for the revert') 584 help='subdir to use for the revert')
541 option_parser.add_option('-a', '--auditor', 585 option_parser.add_option('-a', '--auditor',
542 help='overrides the author for reviewer') 586 help='overrides the author for reviewer')
543 option_parser.add_option('', '--revertbot', action='store_true', 587 option_parser.add_option('', '--revertbot', action='store_true',
544 default=False) 588 default=False)
545 option_parser.add_option('', '--revertbot-commit', action='store_true', 589 option_parser.add_option('', '--revertbot-commit', action='store_true',
546 default=False) 590 default=False)
547 option_parser.add_option('', '--revertbot-reviewers') 591 option_parser.add_option('', '--revertbot-reviewers')
548 options, args = option_parser.parse_args() 592 options, args = option_parser.parse_args()
549 593
550 if not options.merge and not options.revert: 594 if not options.merge and not options.revert:
551 option_parser.error("You need at least --merge or --revert") 595 option_parser.error("You need at least --merge or --revert")
552 sys.exit(1) 596 sys.exit(1)
553 597
554 if options.merge and not options.branch: 598 if options.merge and not options.branch and not options.local:
555 option_parser.error("--merge requires a --branch") 599 option_parser.error("--merge requires either --branch or --local")
600 sys.exit(1)
601
602 if options.local and (options.revert or options.branch):
603 option_parser.error("--local cannot be used with --revert or --branch")
556 sys.exit(1) 604 sys.exit(1)
557 605
558 sys.exit(main(options, args)) 606 sys.exit(main(options, args))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698