ParaView/Git/Maintain: Difference between revisions
Line 29: | Line 29: | ||
==Gatekeeper Review Script== | ==Gatekeeper Review Script== | ||
</ | Script used for weekly ParaView Gatekeeper Review. | ||
<source lang="python"> | |||
#!/usr/bin/env python | |||
import subprocess | |||
import sys | |||
import re | |||
#------------------------------------------------------------------------------ | |||
class UserCancelled(Exception): | |||
def __str__(self): | |||
return "Cancelled by user" | |||
pv_only = re.compile("^\\s*([a-zA-Z0-9_-]+)\\s*\|?\\s*$"); | |||
pv_and_vtk = re.compile("^\\s*([a-zA-Z0-9_-]+)\\s*|\\s*VTK\\s*$"); | |||
def execute(command, **kwargs): | |||
no_echo = kwargs.get("no_echo") | |||
if not no_echo: | |||
print "> %s" % command | |||
process = subprocess.Popen(command, shell=True, | |||
stdout=subprocess.PIPE, | |||
stderr=subprocess.STDOUT) | |||
output,_ = process.communicate() | |||
if output and not no_echo: | |||
print " ------------------------------------------------------------------------------" | |||
for part in output.splitlines(): | |||
print " | %s" % part | |||
print " ------------------------------------------------------------------------------" | |||
if process.returncode: | |||
raise subprocess.CalledProcessError(command, process.returncode) | |||
return output.strip() | |||
def execute_vtk(command, **kwargs): | |||
return execute("cd VTK && %s" % command, **kwargs) | |||
def check(text): | |||
if raw_input("\n> %s : (y/n) : " % text) != 'y': | |||
raise UserCancelled() | |||
#def merge_paraview_topic(name): | |||
# execute("git log --oneline --decorate --graph origin/master..stage/%s" % name) | |||
# check("Merge %s into ParaView?" % name) | |||
# execute("ssh git@paraview.org stage ParaView merge -b master %s" % name) | |||
# | |||
#def merge_paraview_vtk_topic(name): | |||
# execute("cd VTK && git log --oneline --decorate --graph pvvtk/pv-master..pvvtk/%s" % name) | |||
# check("Merge %s into PVVTK?" % name) | |||
# execute("ssh git@paraview.org stage PVVTK merge -b pv-master %s" % name) | |||
# merge_paraview_topic(name) | |||
def git_reachable(shaA, shaB): | |||
"Returns true when shaB is reachable from shaA i.e. shaA is ancestor of shaB" | |||
# based on logic from: | |||
# http://stackoverflow.com/a/3006203 | |||
merge_base = execute("git merge-base %s %s" % (shaB, shaA), no_echo=True) | |||
rev_parse = execute("git rev-parse --verify %s" % shaA, no_echo=True) | |||
return merge_base == rev_parse | |||
def git_vtk_reachable(shaA, shaB): | |||
"Returns true when shaB is reachable from shaA i.e. shaA is ancestor of shaB" | |||
# based on logic from: | |||
# http://stackoverflow.com/a/3006203 | |||
merge_base = execute_vtk("git merge-base %s %s" % (shaB, shaA), no_echo=True) | |||
rev_parse = execute_vtk("git rev-parse --verify %s" % shaA, no_echo=True) | |||
return merge_base == rev_parse | |||
def interactive_merge(topic, vtk_sha): | |||
"""Merge a ParaView topic interactively.""" | |||
print "--------------------------------------------------" | |||
print "Topic:", topic | |||
execute("git log --oneline --decorate --graph origin/master..stage/%s" % topic) | |||
try: | |||
if vtk_sha: | |||
check("Merge '%s' into ParaView (+VTK)?" % topic) | |||
else: | |||
check("Merge '%s' into ParaView?" % topic) | |||
except UserCancelled as e: | |||
print " ", e, ", skipping..." | |||
return False | |||
if vtk_sha: | |||
# this topic has a VTK change. Locate the VTK topic that brings in this | |||
# change. Because people never name the two topic the same, we have to do | |||
# some extra juggling here. | |||
# find all topics on pvvtk that this vtk_sha is available in. | |||
vtk_topics = execute_vtk("git branch --contains=%s -r | grep pvvtk | sed -e 's|pvvtk/||' | sort" % vtk_sha, no_echo=True) | |||
vtk_topics = vtk_topics.split() | |||
if not "master" in vtk_topics: | |||
raise RuntimeError, "VTK topic not merged into vtk-master. Cannot proceed with the merge." | |||
vtk_topics.remove("master") | |||
vtk_topics.remove("pv-next") | |||
try: | |||
vtk_topics.remove("pv-master") | |||
except ValueError: | |||
pass | |||
try: | |||
vtk_topics.remove("nightly-pv-next") | |||
except ValueError: | |||
pass | |||
if len(vtk_topics) > 1: | |||
# ask the user which topic to merge. | |||
print " Possible VTK topics for SHA-1 ", vtk_sha | |||
index = 1 | |||
for vtk_topic in vtk_topics: | |||
print " ", index,":", vtk_topic | |||
index = index + 1 | |||
choice = int(raw_input(" Pick VTK Topic (1-%d): " % index)) | |||
if choice >= 1 and choice < index: | |||
# narrow down the available topics to the one chosen by the user. | |||
vtk_topics = [vtk_topics[index]] | |||
else: | |||
raise RuntimeError, "Invalid VTK topic chosen %d" % choice | |||
elif len(vtk_topics) == 1: | |||
try: | |||
check(" - Merge vtk_topic '%s'" % vtk_topics[0]) | |||
except UserCancelled: | |||
return False | |||
# at this point vtk_topics must have only 1 topic of interest. | |||
if len(vtk_topics) != 1: | |||
raise RuntimeError, "No VTK topic found/picked for ", vtk_sha | |||
# warn the user if the vtk_topic has more commits than the one the ParaView topic refers to. | |||
vtk_topic_head_sha = execute_vtk("git show --raw pvvtk/%s | head -n1 | sed -e 's|commit ||'" % vtk_topics[0], no_echo=True) | |||
if vtk_topic_head_sha != vtk_sha: | |||
print "WARNING: VTK topic '%s' has more commits than those refered by ParaView topic" % vtk_topics[0] | |||
try: | |||
check("Are you sure you want to merge it?") | |||
except UserCancelled as e: | |||
print " ", e, ", skipping..." | |||
return False | |||
# execute("ssh git@paraview.org stage PVVTK merge -b pv-master %s" % vtk_topics[0]) | |||
# execute("ssh git@paraview.org stage ParaView merge -b master %s" % topic) | |||
print "Merge successful!!!" | |||
return True | |||
#------------------------------------------------------------------------------ | |||
print """ | |||
( | |||
)\ ) | |||
(()/( ) ( ) ) ( ( ( ( | |||
/(_))( /( )( ( /( /(( )\ ))\ )\))( | |||
(_)) )(_))(()\ )(_))(_))\((_) /((_)((_)()\ | |||
| _ \((_)_ ((_)((_)_ _)((_)(_)(_)) _(()((_) | |||
| _// _` || '_|/ _` |\ V / | |/ -_) \ V V / | |||
|_| \__,_||_| \__,_| \_/ |_|\___| \_/\_/ """ | |||
print """ | |||
_____ _ _ _____ _ | |||
/ ____| | | | | | __ \ (_) | |||
| | __ __ _| |_ ___| | _____ ___ _ __ ___ _ __ | |__) |_____ ___ _____ __ | |||
| | |_ |/ _` | __/ _ | |/ / _ \/ _ | '_ \ / _ | '__| | _ // _ \ \ / | |/ _ \ \ /\ / / | |||
| |__| | (_| | || __| | __| __| |_) | __| | | | \ | __/\ V /| | __/\ V V / | |||
\_____|\__,_|\__\___|_|\_\___|\___| .__/ \___|_| |_| \_\___| \_/ |_|\___| \_/\_/ | |||
| | | |||
|_| | |||
""" | |||
print""" **** LOCAL CHANGES MAY BE OVERWRITTEN !!! **** """ | |||
print""" **** LOCAL CHANGES MAY BE OVERWRITTEN !!! **** """ | |||
print""" **** LOCAL CHANGES MAY BE OVERWRITTEN !!! **** """ | |||
print""" **** LOCAL CHANGES MAY BE OVERWRITTEN !!! **** \n\n""" | |||
#------------------------------------------------------------------------------ | |||
print "Preparing repository for Gatekeeper Review..." | |||
# Ensure all "core" remotes are up-to-date. | |||
execute("git fetch origin -p") | |||
execute("git fetch stage -p") | |||
execute_vtk("git fetch origin -p") | |||
execute_vtk("git fetch pvvtk -p") | |||
#------------------------------------------------------------------------------ | |||
# Locate all topics merged into next that are currently on stage. | |||
topics = execute("git branch -r --merged stage/next | grep stage | sed -e 's|stage/||' | sort", no_echo=True) | |||
topics = topics.split() | |||
try: | |||
topics.remove("master");topics.remove("next") | |||
except ValueError: | |||
pass | |||
#------------------------------------------------------------------------------ | |||
# For each topic, determine if is changes VTK. | |||
# A topic changes VTK if the VTK SHA it refers to is not reachable form the | |||
# VTK SHA in master. | |||
master_vtk_ref = execute("git ls-tree origin/master VTK | awk '{print $3}'", no_echo=True) | |||
vtk_topics_map = {} | |||
for topic in topics: | |||
topic_vtk_ref = execute("git ls-tree stage/%s VTK | awk '{print $3}'" % topic , no_echo=True) | |||
already_in_master = git_vtk_reachable(topic_vtk_ref, master_vtk_ref) | |||
if already_in_master: | |||
vtk_topics_map[topic] = None | |||
else: | |||
vtk_topics_map[topic] = topic_vtk_ref | |||
#------------------------------------------------------------------------------ | |||
# Print some status messages for the human. | |||
print "" | |||
print "---------------------------------------------" | |||
print "Topics in next that can be merged: " | |||
for topic in topics: | |||
if vtk_topics_map[topic]: | |||
print "(VTK) ", topic | |||
else: | |||
print " ", topic | |||
print "" | |||
print "" | |||
#------------------------------------------------------------------------------ | |||
# Interactively merge the topics. | |||
topics_merged = [] | |||
for topic in topics: | |||
if interactive_merge(topic, vtk_topics_map[topic]): | |||
topics_merged.append(topic) | |||
#------------------------------------------------------------------------------ | |||
check("Wrapup gatekeeper review?") | |||
execute("git fetch origin -p") | |||
execute("git fetch stage -p") | |||
execute_vtk("git fetch origin -p") | |||
execute_vtk("git fetch pvvtk -p") | |||
# merge pvvtk/pv-master into origin/master | |||
execute_vtk("git checkout -f origin/master") | |||
execute_vtk("git merge --no-ff pvvtk/pv-master") | |||
execute_vtk("git push gerrit HEAD:master") | |||
# reset pv-next. | |||
execute_vtk("git checkout -f pvvtk/pv-master") | |||
# dfff5bee7e6dd05e3b763dde829841766679056d is the pv-next deny commit. | |||
execute_vtk("git merge --no-ff dfff5bee7e6dd05e3b763dde829841766679056d -m 'Merge pv-master into pv-next'") | |||
execute_vtk("git push -f pvvtk HEAD:pv-next") | |||
# reset next. | |||
# first get the list of topics merged in next that will get unmerged. | |||
dangling_topics = execute("git branch -r --merged stage/next | grep stage | sed -e 's|stage/||' | sort", no_echo=True) | |||
dangling_topics.split() | |||
try: | |||
dangling_topics.remove("master") | |||
except ValueError: | |||
pass | |||
try: | |||
dangling_topics.remove("next") | |||
except ValueError: | |||
pass | |||
execute("git checkout -f origin/master") | |||
execute("git merge --no-ff aa525d5d662ea6c7036e47a07e4c8a146a773e5f -m 'Merge master into next'") | |||
execute("git push -f origin HEAD:next") | |||
print "" | |||
print "" | |||
print "SUMMARY" | |||
print "---------------------------------------------" | |||
print "Topics merged into master: " | |||
for topic in topics_merged: | |||
if vtk_topics_map[topic]: | |||
print "(VTK) ", topic | |||
else: | |||
print " ", topic | |||
print "" | |||
print "" | |||
print "---------------------------------------------" | |||
print "Topics reverted from next: " | |||
for topic in dangling_topics: | |||
print " ", topic | |||
</source> | |||
==Miscellaneous Commands== | ==Miscellaneous Commands== |
Revision as of 17:56, 28 September 2012
This page documents how to maintain ParaView branches through Git.
See our table of contents for more information.
Merging next topics into master
Before you begin, perform initial setup:
1. | |
2. | |
|
|
3. | |
|
Gatekeeper Review Script
Script used for weekly ParaView Gatekeeper Review.
<source lang="python">
- !/usr/bin/env python
import subprocess import sys import re
- ------------------------------------------------------------------------------
class UserCancelled(Exception):
def __str__(self): return "Cancelled by user"
pv_only = re.compile("^\\s*([a-zA-Z0-9_-]+)\\s*\|?\\s*$"); pv_and_vtk = re.compile("^\\s*([a-zA-Z0-9_-]+)\\s*|\\s*VTK\\s*$");
def execute(command, **kwargs):
no_echo = kwargs.get("no_echo") if not no_echo: print "> %s" % command process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) output,_ = process.communicate() if output and not no_echo: print " ------------------------------------------------------------------------------" for part in output.splitlines(): print " | %s" % part print " ------------------------------------------------------------------------------" if process.returncode: raise subprocess.CalledProcessError(command, process.returncode) return output.strip()
def execute_vtk(command, **kwargs):
return execute("cd VTK && %s" % command, **kwargs)
def check(text):
if raw_input("\n> %s : (y/n) : " % text) != 'y': raise UserCancelled()
- def merge_paraview_topic(name):
- execute("git log --oneline --decorate --graph origin/master..stage/%s" % name)
- check("Merge %s into ParaView?" % name)
- execute("ssh git@paraview.org stage ParaView merge -b master %s" % name)
- def merge_paraview_vtk_topic(name):
- execute("cd VTK && git log --oneline --decorate --graph pvvtk/pv-master..pvvtk/%s" % name)
- check("Merge %s into PVVTK?" % name)
- execute("ssh git@paraview.org stage PVVTK merge -b pv-master %s" % name)
- merge_paraview_topic(name)
def git_reachable(shaA, shaB):
"Returns true when shaB is reachable from shaA i.e. shaA is ancestor of shaB" # based on logic from: # http://stackoverflow.com/a/3006203 merge_base = execute("git merge-base %s %s" % (shaB, shaA), no_echo=True) rev_parse = execute("git rev-parse --verify %s" % shaA, no_echo=True) return merge_base == rev_parse
def git_vtk_reachable(shaA, shaB):
"Returns true when shaB is reachable from shaA i.e. shaA is ancestor of shaB" # based on logic from: # http://stackoverflow.com/a/3006203 merge_base = execute_vtk("git merge-base %s %s" % (shaB, shaA), no_echo=True) rev_parse = execute_vtk("git rev-parse --verify %s" % shaA, no_echo=True) return merge_base == rev_parse
def interactive_merge(topic, vtk_sha):
"""Merge a ParaView topic interactively.""" print "--------------------------------------------------" print "Topic:", topic execute("git log --oneline --decorate --graph origin/master..stage/%s" % topic) try: if vtk_sha: check("Merge '%s' into ParaView (+VTK)?" % topic) else: check("Merge '%s' into ParaView?" % topic) except UserCancelled as e: print " ", e, ", skipping..." return False if vtk_sha: # this topic has a VTK change. Locate the VTK topic that brings in this # change. Because people never name the two topic the same, we have to do # some extra juggling here.
# find all topics on pvvtk that this vtk_sha is available in. vtk_topics = execute_vtk("git branch --contains=%s -r | grep pvvtk | sed -e 's|pvvtk/||' | sort" % vtk_sha, no_echo=True) vtk_topics = vtk_topics.split() if not "master" in vtk_topics: raise RuntimeError, "VTK topic not merged into vtk-master. Cannot proceed with the merge." vtk_topics.remove("master") vtk_topics.remove("pv-next") try: vtk_topics.remove("pv-master") except ValueError: pass try: vtk_topics.remove("nightly-pv-next") except ValueError: pass
if len(vtk_topics) > 1: # ask the user which topic to merge. print " Possible VTK topics for SHA-1 ", vtk_sha index = 1 for vtk_topic in vtk_topics: print " ", index,":", vtk_topic index = index + 1 choice = int(raw_input(" Pick VTK Topic (1-%d): " % index)) if choice >= 1 and choice < index: # narrow down the available topics to the one chosen by the user. vtk_topics = [vtk_topics[index]] else: raise RuntimeError, "Invalid VTK topic chosen %d" % choice elif len(vtk_topics) == 1: try: check(" - Merge vtk_topic '%s'" % vtk_topics[0]) except UserCancelled: return False
# at this point vtk_topics must have only 1 topic of interest. if len(vtk_topics) != 1: raise RuntimeError, "No VTK topic found/picked for ", vtk_sha # warn the user if the vtk_topic has more commits than the one the ParaView topic refers to. vtk_topic_head_sha = execute_vtk("git show --raw pvvtk/%s | head -n1 | sed -e 's|commit ||'" % vtk_topics[0], no_echo=True) if vtk_topic_head_sha != vtk_sha: print "WARNING: VTK topic '%s' has more commits than those refered by ParaView topic" % vtk_topics[0] try: check("Are you sure you want to merge it?") except UserCancelled as e: print " ", e, ", skipping..." return False
- execute("ssh git@paraview.org stage PVVTK merge -b pv-master %s" % vtk_topics[0])
- execute("ssh git@paraview.org stage ParaView merge -b master %s" % topic)
print "Merge successful!!!" return True
- ------------------------------------------------------------------------------
print """
( )\ ) (()/( ) ( ) ) ( ( ( ( /(_))( /( )( ( /( /(( )\ ))\ )\))( (_)) )(_))(()\ )(_))(_))\((_) /((_)((_)()\ | _ \((_)_ ((_)((_)_ _)((_)(_)(_)) _(()((_) | _// _` || '_|/ _` |\ V / | |/ -_) \ V V / |_| \__,_||_| \__,_| \_/ |_|\___| \_/\_/ """
print """
_____ _ _ _____ _ / ____| | | | | | __ \ (_) | | __ __ _| |_ ___| | _____ ___ _ __ ___ _ __ | |__) |_____ ___ _____ __ | | |_ |/ _` | __/ _ | |/ / _ \/ _ | '_ \ / _ | '__| | _ // _ \ \ / | |/ _ \ \ /\ / / | |__| | (_| | || __| | __| __| |_) | __| | | | \ | __/\ V /| | __/\ V V / \_____|\__,_|\__\___|_|\_\___|\___| .__/ \___|_| |_| \_\___| \_/ |_|\___| \_/\_/ | | |_|
"""
print""" **** LOCAL CHANGES MAY BE OVERWRITTEN !!! **** """ print""" **** LOCAL CHANGES MAY BE OVERWRITTEN !!! **** """ print""" **** LOCAL CHANGES MAY BE OVERWRITTEN !!! **** """ print""" **** LOCAL CHANGES MAY BE OVERWRITTEN !!! **** \n\n"""
- ------------------------------------------------------------------------------
print "Preparing repository for Gatekeeper Review..."
- Ensure all "core" remotes are up-to-date.
execute("git fetch origin -p") execute("git fetch stage -p") execute_vtk("git fetch origin -p") execute_vtk("git fetch pvvtk -p")
- ------------------------------------------------------------------------------
- Locate all topics merged into next that are currently on stage.
topics = execute("git branch -r --merged stage/next | grep stage | sed -e 's|stage/||' | sort", no_echo=True) topics = topics.split() try:
topics.remove("master");topics.remove("next")
except ValueError:
pass
- ------------------------------------------------------------------------------
- For each topic, determine if is changes VTK.
- A topic changes VTK if the VTK SHA it refers to is not reachable form the
- VTK SHA in master.
master_vtk_ref = execute("git ls-tree origin/master VTK | awk '{print $3}'", no_echo=True) vtk_topics_map = {} for topic in topics:
topic_vtk_ref = execute("git ls-tree stage/%s VTK | awk '{print $3}'" % topic , no_echo=True) already_in_master = git_vtk_reachable(topic_vtk_ref, master_vtk_ref) if already_in_master: vtk_topics_map[topic] = None else: vtk_topics_map[topic] = topic_vtk_ref
- ------------------------------------------------------------------------------
- Print some status messages for the human.
print "" print "---------------------------------------------" print "Topics in next that can be merged: " for topic in topics:
if vtk_topics_map[topic]: print "(VTK) ", topic else: print " ", topic
print "" print ""
- ------------------------------------------------------------------------------
- Interactively merge the topics.
topics_merged = [] for topic in topics:
if interactive_merge(topic, vtk_topics_map[topic]): topics_merged.append(topic)
- ------------------------------------------------------------------------------
check("Wrapup gatekeeper review?") execute("git fetch origin -p") execute("git fetch stage -p") execute_vtk("git fetch origin -p") execute_vtk("git fetch pvvtk -p")
- merge pvvtk/pv-master into origin/master
execute_vtk("git checkout -f origin/master") execute_vtk("git merge --no-ff pvvtk/pv-master") execute_vtk("git push gerrit HEAD:master")
- reset pv-next.
execute_vtk("git checkout -f pvvtk/pv-master")
- dfff5bee7e6dd05e3b763dde829841766679056d is the pv-next deny commit.
execute_vtk("git merge --no-ff dfff5bee7e6dd05e3b763dde829841766679056d -m 'Merge pv-master into pv-next'") execute_vtk("git push -f pvvtk HEAD:pv-next")
- reset next.
- first get the list of topics merged in next that will get unmerged.
dangling_topics = execute("git branch -r --merged stage/next | grep stage | sed -e 's|stage/||' | sort", no_echo=True) dangling_topics.split() try:
dangling_topics.remove("master")
except ValueError:
pass
try:
dangling_topics.remove("next")
except ValueError:
pass
execute("git checkout -f origin/master") execute("git merge --no-ff aa525d5d662ea6c7036e47a07e4c8a146a773e5f -m 'Merge master into next'") execute("git push -f origin HEAD:next")
print "" print "" print "SUMMARY"
print "---------------------------------------------" print "Topics merged into master: " for topic in topics_merged:
if vtk_topics_map[topic]: print "(VTK) ", topic else: print " ", topic
print "" print "" print "---------------------------------------------" print "Topics reverted from next: " for topic in dangling_topics:
print " ", topic
</source>
Miscellaneous Commands
- Show branches merged in next or master on stage
$ git fetch stage -p
$ git branch -r --merged stage/next | grep stage
$ git branch -r --merged stage/master | grep stage
- Find the SHA1 for the VTK submodule that a branch is referring to.
$ git ls-tree <branchname> VTK | awk '{print $3}'